diff options
Diffstat (limited to 'fs/bcachefs/extents.c')
-rw-r--r-- | fs/bcachefs/extents.c | 47 |
1 files changed, 34 insertions, 13 deletions
diff --git a/fs/bcachefs/extents.c b/fs/bcachefs/extents.c index 86aa93ea2345..3274ba42c995 100644 --- a/fs/bcachefs/extents.c +++ b/fs/bcachefs/extents.c @@ -12,6 +12,7 @@ #include "btree_gc.h" #include "btree_io.h" #include "btree_iter.h" +#include "btree_update.h" #include "buckets.h" #include "checksum.h" #include "compress.h" @@ -1213,6 +1214,21 @@ drop: bch2_bkey_drop_ptr_noerror(k, ptr); } +static bool bch2_bkey_has_stale_ptrs(struct bch_fs *c, struct bkey_s_c k) +{ + struct bkey_ptrs_c ptrs = bch2_bkey_ptrs_c(k); + struct bch_dev *ca; + + guard(rcu)(); + bkey_for_each_ptr(ptrs, ptr) + if (ptr->cached && + (ca = bch2_dev_rcu_noerror(c, ptr->dev)) && + dev_ptr_stale_rcu(ca, ptr) > 0) + return true; + + return false; +} + /* * bch2_extent_normalize - clean up an extent, dropping stale pointers etc. * @@ -1221,7 +1237,7 @@ drop: * For existing keys, only called when btree nodes are being rewritten, not when * they're merely being compacted/resorted in memory. */ -bool bch2_extent_normalize(struct bch_fs *c, struct bkey_s k) +static void __bch2_bkey_drop_stale_ptrs(struct bch_fs *c, struct bkey_s k) { struct bch_dev *ca; @@ -1230,19 +1246,26 @@ bool bch2_extent_normalize(struct bch_fs *c, struct bkey_s k) ptr->cached && (!(ca = bch2_dev_rcu_noerror(c, ptr->dev)) || dev_ptr_stale_rcu(ca, ptr) > 0)); +} + +int bch2_bkey_drop_stale_ptrs(struct btree_trans *trans, struct btree_iter *iter, struct bkey_s_c k) +{ + if (bch2_bkey_has_stale_ptrs(trans->c, k)) { + struct bkey_i *u = bch2_bkey_make_mut(trans, iter, &k, + BTREE_UPDATE_internal_snapshot_node); + int ret = PTR_ERR_OR_ZERO(u); + if (ret) + return ret; + + __bch2_bkey_drop_stale_ptrs(trans->c, bkey_i_to_s(u)); + } - return bkey_deleted(k.k); + return 0; } -/* - * bch2_extent_normalize_by_opts - clean up an extent, dropping stale pointers etc. - * - * Like bch2_extent_normalize(), but also only keeps a single cached pointer on - * the promote target. - */ -bool bch2_extent_normalize_by_opts(struct bch_fs *c, - struct bch_inode_opts *opts, - struct bkey_s k) +void bch2_bkey_drop_extra_cached_ptrs(struct bch_fs *c, + struct bch_inode_opts *opts, + struct bkey_s k) { struct bkey_ptrs ptrs; bool have_cached_ptr; @@ -1260,8 +1283,6 @@ restart_drop_ptrs: } have_cached_ptr = true; } - - return bkey_deleted(k.k); } void bch2_extent_ptr_to_text(struct printbuf *out, struct bch_fs *c, const struct bch_extent_ptr *ptr) |