Commit 2f4b4a3b authored by Kent Overstreet's avatar Kent Overstreet

bcachefs: kill bch2_dev_bkey_exists() in bch2_check_fix_ptrs()

Signed-off-by: default avatarKent Overstreet <kent.overstreet@linux.dev>
parent 02b7fa4f
...@@ -479,8 +479,20 @@ int bch2_check_fix_ptrs(struct btree_trans *trans, ...@@ -479,8 +479,20 @@ int bch2_check_fix_ptrs(struct btree_trans *trans,
percpu_down_read(&c->mark_lock); percpu_down_read(&c->mark_lock);
rcu_read_lock();
bkey_for_each_ptr_decode(k.k, ptrs_c, p, entry_c) { 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); struct bucket *g = PTR_GC_BUCKET(ca, &p.ptr);
enum bch_data_type data_type = bch2_bkey_ptr_data_type(k, p, entry_c); 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, ...@@ -590,6 +602,7 @@ int bch2_check_fix_ptrs(struct btree_trans *trans,
do_update = true; do_update = true;
} }
} }
rcu_read_unlock();
if (do_update) { if (do_update) {
if (flags & BTREE_TRIGGER_is_root) { if (flags & BTREE_TRIGGER_is_root) {
...@@ -603,6 +616,10 @@ int bch2_check_fix_ptrs(struct btree_trans *trans, ...@@ -603,6 +616,10 @@ int bch2_check_fix_ptrs(struct btree_trans *trans,
if (ret) if (ret)
goto err; 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) { if (level) {
/* /*
* We don't want to drop btree node pointers - if the * We don't want to drop btree node pointers - if the
...@@ -610,19 +627,22 @@ int bch2_check_fix_ptrs(struct btree_trans *trans, ...@@ -610,19 +627,22 @@ int bch2_check_fix_ptrs(struct btree_trans *trans,
* sort it out: * sort it out:
*/ */
struct bkey_ptrs ptrs = bch2_bkey_ptrs(bkey_i_to_s(new)); struct bkey_ptrs ptrs = bch2_bkey_ptrs(bkey_i_to_s(new));
rcu_read_lock();
bkey_for_each_ptr(ptrs, ptr) { 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); struct bucket *g = PTR_GC_BUCKET(ca, ptr);
ptr->gen = g->gen; ptr->gen = g->gen;
} }
rcu_read_unlock();
} else { } else {
struct bkey_ptrs ptrs; struct bkey_ptrs ptrs;
union bch_extent_entry *entry; union bch_extent_entry *entry;
restart_drop_ptrs: restart_drop_ptrs:
ptrs = bch2_bkey_ptrs(bkey_i_to_s(new)); 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) { 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); 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); enum bch_data_type data_type = bch2_bkey_ptr_data_type(bkey_i_to_s_c(new), p, entry);
...@@ -637,6 +657,7 @@ int bch2_check_fix_ptrs(struct btree_trans *trans, ...@@ -637,6 +657,7 @@ int bch2_check_fix_ptrs(struct btree_trans *trans,
goto restart_drop_ptrs; goto restart_drop_ptrs;
} }
} }
rcu_read_unlock();
again: again:
ptrs = bch2_bkey_ptrs(bkey_i_to_s(new)); ptrs = bch2_bkey_ptrs(bkey_i_to_s(new));
bkey_extent_entry_for_each(ptrs, entry) { bkey_extent_entry_for_each(ptrs, entry) {
......
...@@ -189,17 +189,6 @@ static inline struct bch_dev *bch2_dev_have_ref(const struct bch_fs *c, unsigned ...@@ -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); 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) static inline struct bch_dev *bch2_dev_locked(struct bch_fs *c, unsigned dev)
{ {
EBUG_ON(!bch2_dev_exists(c, dev)); EBUG_ON(!bch2_dev_exists(c, dev));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment