Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v6.16 275 lines 7.6 kB view raw
1/* SPDX-License-Identifier: GPL-2.0 */ 2#ifndef _BCACHEFS_SNAPSHOT_H 3#define _BCACHEFS_SNAPSHOT_H 4 5void bch2_snapshot_tree_to_text(struct printbuf *, struct bch_fs *, struct bkey_s_c); 6int bch2_snapshot_tree_validate(struct bch_fs *, struct bkey_s_c, 7 struct bkey_validate_context); 8 9#define bch2_bkey_ops_snapshot_tree ((struct bkey_ops) { \ 10 .key_validate = bch2_snapshot_tree_validate, \ 11 .val_to_text = bch2_snapshot_tree_to_text, \ 12 .min_val_size = 8, \ 13}) 14 15struct bkey_i_snapshot_tree *__bch2_snapshot_tree_create(struct btree_trans *); 16 17int bch2_snapshot_tree_lookup(struct btree_trans *, u32, struct bch_snapshot_tree *); 18 19void bch2_snapshot_to_text(struct printbuf *, struct bch_fs *, struct bkey_s_c); 20int bch2_snapshot_validate(struct bch_fs *, struct bkey_s_c, 21 struct bkey_validate_context); 22int bch2_mark_snapshot(struct btree_trans *, enum btree_id, unsigned, 23 struct bkey_s_c, struct bkey_s, 24 enum btree_iter_update_trigger_flags); 25 26#define bch2_bkey_ops_snapshot ((struct bkey_ops) { \ 27 .key_validate = bch2_snapshot_validate, \ 28 .val_to_text = bch2_snapshot_to_text, \ 29 .trigger = bch2_mark_snapshot, \ 30 .min_val_size = 24, \ 31}) 32 33static inline struct snapshot_t *__snapshot_t(struct snapshot_table *t, u32 id) 34{ 35 u32 idx = U32_MAX - id; 36 37 return likely(t && idx < t->nr) 38 ? &t->s[idx] 39 : NULL; 40} 41 42static inline const struct snapshot_t *snapshot_t(struct bch_fs *c, u32 id) 43{ 44 return __snapshot_t(rcu_dereference(c->snapshots), id); 45} 46 47static inline u32 bch2_snapshot_tree(struct bch_fs *c, u32 id) 48{ 49 guard(rcu)(); 50 const struct snapshot_t *s = snapshot_t(c, id); 51 return s ? s->tree : 0; 52} 53 54static inline u32 __bch2_snapshot_parent_early(struct bch_fs *c, u32 id) 55{ 56 const struct snapshot_t *s = snapshot_t(c, id); 57 return s ? s->parent : 0; 58} 59 60static inline u32 bch2_snapshot_parent_early(struct bch_fs *c, u32 id) 61{ 62 guard(rcu)(); 63 return __bch2_snapshot_parent_early(c, id); 64} 65 66static inline u32 __bch2_snapshot_parent(struct bch_fs *c, u32 id) 67{ 68 const struct snapshot_t *s = snapshot_t(c, id); 69 if (!s) 70 return 0; 71 72 u32 parent = s->parent; 73 if (IS_ENABLED(CONFIG_BCACHEFS_DEBUG) && 74 parent && 75 s->depth != snapshot_t(c, parent)->depth + 1) 76 panic("id %u depth=%u parent %u depth=%u\n", 77 id, snapshot_t(c, id)->depth, 78 parent, snapshot_t(c, parent)->depth); 79 80 return parent; 81} 82 83static inline u32 bch2_snapshot_parent(struct bch_fs *c, u32 id) 84{ 85 guard(rcu)(); 86 return __bch2_snapshot_parent(c, id); 87} 88 89static inline u32 bch2_snapshot_nth_parent(struct bch_fs *c, u32 id, u32 n) 90{ 91 guard(rcu)(); 92 while (n--) 93 id = __bch2_snapshot_parent(c, id); 94 return id; 95} 96 97u32 bch2_snapshot_oldest_subvol(struct bch_fs *, u32, snapshot_id_list *); 98u32 bch2_snapshot_skiplist_get(struct bch_fs *, u32); 99 100static inline u32 bch2_snapshot_root(struct bch_fs *c, u32 id) 101{ 102 guard(rcu)(); 103 104 u32 parent; 105 while ((parent = __bch2_snapshot_parent(c, id))) 106 id = parent; 107 return id; 108} 109 110static inline enum snapshot_id_state __bch2_snapshot_id_state(struct bch_fs *c, u32 id) 111{ 112 const struct snapshot_t *s = snapshot_t(c, id); 113 return s ? s->state : SNAPSHOT_ID_empty; 114} 115 116static inline enum snapshot_id_state bch2_snapshot_id_state(struct bch_fs *c, u32 id) 117{ 118 guard(rcu)(); 119 return __bch2_snapshot_id_state(c, id); 120} 121 122static inline bool bch2_snapshot_exists(struct bch_fs *c, u32 id) 123{ 124 return bch2_snapshot_id_state(c, id) == SNAPSHOT_ID_live; 125} 126 127static inline int bch2_snapshot_is_internal_node(struct bch_fs *c, u32 id) 128{ 129 guard(rcu)(); 130 const struct snapshot_t *s = snapshot_t(c, id); 131 return s ? s->children[0] : -BCH_ERR_invalid_snapshot_node; 132} 133 134static inline int bch2_snapshot_is_leaf(struct bch_fs *c, u32 id) 135{ 136 int ret = bch2_snapshot_is_internal_node(c, id); 137 if (ret < 0) 138 return ret; 139 return !ret; 140} 141 142static inline u32 bch2_snapshot_depth(struct bch_fs *c, u32 parent) 143{ 144 guard(rcu)(); 145 return parent ? snapshot_t(c, parent)->depth + 1 : 0; 146} 147 148bool __bch2_snapshot_is_ancestor(struct bch_fs *, u32, u32); 149 150static inline bool bch2_snapshot_is_ancestor(struct bch_fs *c, u32 id, u32 ancestor) 151{ 152 return id == ancestor 153 ? true 154 : __bch2_snapshot_is_ancestor(c, id, ancestor); 155} 156 157static inline bool bch2_snapshot_has_children(struct bch_fs *c, u32 id) 158{ 159 guard(rcu)(); 160 const struct snapshot_t *t = snapshot_t(c, id); 161 return t && (t->children[0]|t->children[1]) != 0; 162} 163 164static inline bool snapshot_list_has_id(snapshot_id_list *s, u32 id) 165{ 166 return darray_find(*s, id) != NULL; 167} 168 169static inline bool snapshot_list_has_ancestor(struct bch_fs *c, snapshot_id_list *s, u32 id) 170{ 171 darray_for_each(*s, i) 172 if (bch2_snapshot_is_ancestor(c, id, *i)) 173 return true; 174 return false; 175} 176 177static inline int snapshot_list_add(struct bch_fs *c, snapshot_id_list *s, u32 id) 178{ 179 BUG_ON(snapshot_list_has_id(s, id)); 180 int ret = darray_push(s, id); 181 if (ret) 182 bch_err(c, "error reallocating snapshot_id_list (size %zu)", s->size); 183 return ret; 184} 185 186static inline int snapshot_list_add_nodup(struct bch_fs *c, snapshot_id_list *s, u32 id) 187{ 188 int ret = snapshot_list_has_id(s, id) 189 ? 0 190 : darray_push(s, id); 191 if (ret) 192 bch_err(c, "error reallocating snapshot_id_list (size %zu)", s->size); 193 return ret; 194} 195 196static inline int snapshot_list_merge(struct bch_fs *c, snapshot_id_list *dst, snapshot_id_list *src) 197{ 198 darray_for_each(*src, i) { 199 int ret = snapshot_list_add_nodup(c, dst, *i); 200 if (ret) 201 return ret; 202 } 203 204 return 0; 205} 206 207int bch2_snapshot_lookup(struct btree_trans *trans, u32 id, 208 struct bch_snapshot *s); 209int bch2_snapshot_get_subvol(struct btree_trans *, u32, 210 struct bch_subvolume *); 211 212/* only exported for tests: */ 213int bch2_snapshot_node_create(struct btree_trans *, u32, 214 u32 *, u32 *, unsigned); 215 216int bch2_check_snapshot_trees(struct bch_fs *); 217int bch2_check_snapshots(struct bch_fs *); 218int bch2_reconstruct_snapshots(struct bch_fs *); 219 220int __bch2_check_key_has_snapshot(struct btree_trans *, struct btree_iter *, struct bkey_s_c); 221 222static inline int bch2_check_key_has_snapshot(struct btree_trans *trans, 223 struct btree_iter *iter, 224 struct bkey_s_c k) 225{ 226 return likely(bch2_snapshot_exists(trans->c, k.k->p.snapshot)) 227 ? 0 228 : __bch2_check_key_has_snapshot(trans, iter, k); 229} 230 231int __bch2_get_snapshot_overwrites(struct btree_trans *, 232 enum btree_id, struct bpos, 233 snapshot_id_list *); 234 235/* 236 * Get a list of snapshot IDs that have overwritten a given key: 237 */ 238static inline int bch2_get_snapshot_overwrites(struct btree_trans *trans, 239 enum btree_id btree, struct bpos pos, 240 snapshot_id_list *s) 241{ 242 darray_init(s); 243 244 return bch2_snapshot_has_children(trans->c, pos.snapshot) 245 ? __bch2_get_snapshot_overwrites(trans, btree, pos, s) 246 : 0; 247 248} 249 250int bch2_snapshot_node_set_deleted(struct btree_trans *, u32); 251 252int __bch2_key_has_snapshot_overwrites(struct btree_trans *, enum btree_id, struct bpos); 253 254static inline int bch2_key_has_snapshot_overwrites(struct btree_trans *trans, 255 enum btree_id id, 256 struct bpos pos) 257{ 258 if (!btree_type_has_snapshots(id) || 259 bch2_snapshot_is_leaf(trans->c, pos.snapshot) > 0) 260 return 0; 261 262 return __bch2_key_has_snapshot_overwrites(trans, id, pos); 263} 264 265int __bch2_delete_dead_snapshots(struct bch_fs *); 266int bch2_delete_dead_snapshots(struct bch_fs *); 267void bch2_delete_dead_snapshots_work(struct work_struct *); 268void bch2_delete_dead_snapshots_async(struct bch_fs *); 269void bch2_snapshot_delete_status_to_text(struct printbuf *, struct bch_fs *); 270 271int bch2_snapshots_read(struct bch_fs *); 272void bch2_fs_snapshots_exit(struct bch_fs *); 273void bch2_fs_snapshots_init_early(struct bch_fs *); 274 275#endif /* _BCACHEFS_SNAPSHOT_H */