xref: /linux/fs/bcachefs/subvolume.h (revision 2622f290417001b0440f4a48dc6978f5f1e12a56)
1 /* SPDX-License-Identifier: GPL-2.0 */
2 #ifndef _BCACHEFS_SUBVOLUME_H
3 #define _BCACHEFS_SUBVOLUME_H
4 
5 #include "darray.h"
6 #include "subvolume_types.h"
7 
8 int bch2_check_subvols(struct bch_fs *);
9 int bch2_check_subvol_children(struct bch_fs *);
10 
11 int bch2_subvolume_validate(struct bch_fs *, struct bkey_s_c,
12 			    struct bkey_validate_context);
13 void bch2_subvolume_to_text(struct printbuf *, struct bch_fs *, struct bkey_s_c);
14 int bch2_subvolume_trigger(struct btree_trans *, enum btree_id, unsigned,
15 			   struct bkey_s_c, struct bkey_s,
16 			   enum btree_iter_update_trigger_flags);
17 
18 #define bch2_bkey_ops_subvolume ((struct bkey_ops) {		\
19 	.key_validate	= bch2_subvolume_validate,		\
20 	.val_to_text	= bch2_subvolume_to_text,		\
21 	.trigger	= bch2_subvolume_trigger,		\
22 	.min_val_size	= 16,					\
23 })
24 
25 int bch2_subvol_has_children(struct btree_trans *, u32);
26 int bch2_subvolume_get(struct btree_trans *, unsigned,
27 		       bool, struct bch_subvolume *);
28 int __bch2_subvolume_get_snapshot(struct btree_trans *, u32,
29 				  u32 *, bool);
30 int bch2_subvolume_get_snapshot(struct btree_trans *, u32, u32 *);
31 
32 int bch2_subvol_is_ro_trans(struct btree_trans *, u32);
33 int bch2_subvol_is_ro(struct bch_fs *, u32);
34 
35 static inline struct bkey_s_c
bch2_btree_iter_peek_in_subvolume_max_type(struct btree_iter * iter,struct bpos end,u32 subvolid,unsigned flags)36 bch2_btree_iter_peek_in_subvolume_max_type(struct btree_iter *iter, struct bpos end,
37 					    u32 subvolid, unsigned flags)
38 {
39 	u32 snapshot;
40 	int ret = bch2_subvolume_get_snapshot(iter->trans, subvolid, &snapshot);
41 	if (ret)
42 		return bkey_s_c_err(ret);
43 
44 	bch2_btree_iter_set_snapshot(iter, snapshot);
45 	return bch2_btree_iter_peek_max_type(iter, end, flags);
46 }
47 
48 #define for_each_btree_key_in_subvolume_max_continue(_trans, _iter,		\
49 					 _end, _subvolid, _flags, _k, _do)	\
50 ({										\
51 	struct bkey_s_c _k;							\
52 	int _ret3 = 0;								\
53 										\
54 	do {									\
55 		_ret3 = lockrestart_do(_trans, ({				\
56 			(_k) = bch2_btree_iter_peek_in_subvolume_max_type(&(_iter),	\
57 						_end, _subvolid, (_flags));	\
58 			if (!(_k).k)						\
59 				break;						\
60 										\
61 			bkey_err(_k) ?: (_do);					\
62 		}));								\
63 	} while (!_ret3 && bch2_btree_iter_advance(&(_iter)));			\
64 										\
65 	bch2_trans_iter_exit((_trans), &(_iter));				\
66 	_ret3;									\
67 })
68 
69 #define for_each_btree_key_in_subvolume_max(_trans, _iter, _btree_id,		\
70 				_start, _end, _subvolid, _flags, _k, _do)	\
71 ({										\
72 	struct btree_iter _iter;						\
73 	bch2_trans_iter_init((_trans), &(_iter), (_btree_id),			\
74 			     (_start), (_flags));				\
75 										\
76 	for_each_btree_key_in_subvolume_max_continue(_trans, _iter,		\
77 					_end, _subvolid, _flags, _k, _do);	\
78 })
79 
80 int bch2_delete_dead_snapshots(struct bch_fs *);
81 void bch2_delete_dead_snapshots_async(struct bch_fs *);
82 
83 int bch2_subvolume_unlink(struct btree_trans *, u32);
84 int bch2_subvolume_create(struct btree_trans *, u64, u32, u32, u32 *, u32 *, bool);
85 
86 int bch2_initialize_subvolumes(struct bch_fs *);
87 int bch2_fs_upgrade_for_subvolumes(struct bch_fs *);
88 
89 int bch2_fs_subvolumes_init(struct bch_fs *);
90 
91 #endif /* _BCACHEFS_SUBVOLUME_H */
92