summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@linux.dev>2024-05-01 19:10:17 -0400
committerKent Overstreet <kent.overstreet@linux.dev>2024-05-09 16:23:36 -0400
commit2f4b4a3b44755d8c86eff64b9c54e3242a9b659c (patch)
tree1679e83aabf27689eb0fbfa93dcbcb1940ebe45a
parent02b7fa4fe5307b1de74e734e28192623b7af7020 (diff)
bcachefs: kill bch2_dev_bkey_exists() in bch2_check_fix_ptrs()
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
-rw-r--r--fs/bcachefs/buckets.c27
-rw-r--r--fs/bcachefs/sb-members.h11
2 files changed, 24 insertions, 14 deletions
diff --git a/fs/bcachefs/buckets.c b/fs/bcachefs/buckets.c
index ae6d6879e2e0..e28d28ac2a13 100644
--- a/fs/bcachefs/buckets.c
+++ b/fs/bcachefs/buckets.c
@@ -479,8 +479,20 @@ int bch2_check_fix_ptrs(struct btree_trans *trans,
percpu_down_read(&c->mark_lock);
+ rcu_read_lock();
bkey_for_each_ptr_decode(k.k, ptrs_c, p, entry_c) {
- struct bch_dev *ca = bch2_dev_bkey_exists(c, p.ptr.dev);
+ struct bch_dev *ca = bch2_dev_rcu(c, p.ptr.dev);
+ if (!ca) {
+ if (fsck_err(c, ptr_to_invalid_device,
+ "pointer to missing device %u\n"
+ "while marking %s",
+ p.ptr.dev,
+ (printbuf_reset(&buf),
+ bch2_bkey_val_to_text(&buf, c, k), buf.buf)))
+ do_update = true;
+ continue;
+ }
+
struct bucket *g = PTR_GC_BUCKET(ca, &p.ptr);
enum bch_data_type data_type = bch2_bkey_ptr_data_type(k, p, entry_c);
@@ -590,6 +602,7 @@ int bch2_check_fix_ptrs(struct btree_trans *trans,
do_update = true;
}
}
+ rcu_read_unlock();
if (do_update) {
if (flags & BTREE_TRIGGER_is_root) {
@@ -603,6 +616,10 @@ int bch2_check_fix_ptrs(struct btree_trans *trans,
if (ret)
goto err;
+ rcu_read_lock();
+ bch2_bkey_drop_ptrs(bkey_i_to_s(new), ptr, !bch2_dev_rcu(c, ptr->dev));
+ rcu_read_unlock();
+
if (level) {
/*
* We don't want to drop btree node pointers - if the
@@ -610,19 +627,22 @@ int bch2_check_fix_ptrs(struct btree_trans *trans,
* sort it out:
*/
struct bkey_ptrs ptrs = bch2_bkey_ptrs(bkey_i_to_s(new));
+ rcu_read_lock();
bkey_for_each_ptr(ptrs, ptr) {
- struct bch_dev *ca = bch2_dev_bkey_exists(c, ptr->dev);
+ struct bch_dev *ca = bch2_dev_rcu(c, ptr->dev);
struct bucket *g = PTR_GC_BUCKET(ca, ptr);
ptr->gen = g->gen;
}
+ rcu_read_unlock();
} else {
struct bkey_ptrs ptrs;
union bch_extent_entry *entry;
restart_drop_ptrs:
ptrs = bch2_bkey_ptrs(bkey_i_to_s(new));
+ rcu_read_lock();
bkey_for_each_ptr_decode(bkey_i_to_s(new).k, ptrs, p, entry) {
- struct bch_dev *ca = bch2_dev_bkey_exists(c, p.ptr.dev);
+ struct bch_dev *ca = bch2_dev_rcu(c, p.ptr.dev);
struct bucket *g = PTR_GC_BUCKET(ca, &p.ptr);
enum bch_data_type data_type = bch2_bkey_ptr_data_type(bkey_i_to_s_c(new), p, entry);
@@ -637,6 +657,7 @@ restart_drop_ptrs:
goto restart_drop_ptrs;
}
}
+ rcu_read_unlock();
again:
ptrs = bch2_bkey_ptrs(bkey_i_to_s(new));
bkey_extent_entry_for_each(ptrs, entry) {
diff --git a/fs/bcachefs/sb-members.h b/fs/bcachefs/sb-members.h
index ae28b5d401e3..dd93192ec065 100644
--- a/fs/bcachefs/sb-members.h
+++ b/fs/bcachefs/sb-members.h
@@ -189,17 +189,6 @@ static inline struct bch_dev *bch2_dev_have_ref(const struct bch_fs *c, unsigned
return rcu_dereference_check(c->devs[dev], 1);
}
-/*
- * If a key exists that references a device, the device won't be going away and
- * we can omit rcu_read_lock():
- */
-static inline struct bch_dev *bch2_dev_bkey_exists(const struct bch_fs *c, unsigned dev)
-{
- EBUG_ON(!bch2_dev_exists(c, dev));
-
- return rcu_dereference_check(c->devs[dev], 1);
-}
-
static inline struct bch_dev *bch2_dev_locked(struct bch_fs *c, unsigned dev)
{
EBUG_ON(!bch2_dev_exists(c, dev));