diff options
author | Kent Overstreet <kent.overstreet@gmail.com> | 2018-11-07 17:48:32 -0500 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@linux.dev> | 2023-10-22 17:08:11 -0400 |
commit | 1d25849c2c2d552b09494b984da915be4a703a18 (patch) | |
tree | 1eb55b0237563aabdde313ee46176d30a640a4fa /fs/bcachefs/replicas.c | |
parent | b35b1925832e6384fcb64c347a70ee205f6e89ea (diff) |
bcachefs: Centralize marking of replicas in btree update path
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
Diffstat (limited to 'fs/bcachefs/replicas.c')
-rw-r--r-- | fs/bcachefs/replicas.c | 67 |
1 files changed, 34 insertions, 33 deletions
diff --git a/fs/bcachefs/replicas.c b/fs/bcachefs/replicas.c index ef62756e8908..83fc9c93d295 100644 --- a/fs/bcachefs/replicas.c +++ b/fs/bcachefs/replicas.c @@ -160,8 +160,8 @@ cpu_replicas_add_entry(struct bch_replicas_cpu *old, return new; } -static bool replicas_has_entry(struct bch_replicas_cpu *r, - struct bch_replicas_entry *search) +static bool __replicas_has_entry(struct bch_replicas_cpu *r, + struct bch_replicas_entry *search) { return replicas_entry_bytes(search) <= r->entry_size && eytzinger0_find(r->entries, r->nr, @@ -169,6 +169,24 @@ static bool replicas_has_entry(struct bch_replicas_cpu *r, memcmp, search) < r->nr; } +static bool replicas_has_entry(struct bch_fs *c, + struct bch_replicas_entry *search, + bool check_gc_replicas) +{ + struct bch_replicas_cpu *r, *gc_r; + bool marked; + + rcu_read_lock(); + r = rcu_dereference(c->replicas); + marked = __replicas_has_entry(r, search) && + (!check_gc_replicas || + likely(!(gc_r = rcu_dereference(c->replicas_gc))) || + __replicas_has_entry(gc_r, search)); + rcu_read_unlock(); + + return marked; +} + noinline static int bch2_mark_replicas_slowpath(struct bch_fs *c, struct bch_replicas_entry *new_entry) @@ -180,7 +198,7 @@ static int bch2_mark_replicas_slowpath(struct bch_fs *c, old_gc = rcu_dereference_protected(c->replicas_gc, lockdep_is_held(&c->sb_lock)); - if (old_gc && !replicas_has_entry(old_gc, new_entry)) { + if (old_gc && !__replicas_has_entry(old_gc, new_entry)) { new_gc = cpu_replicas_add_entry(old_gc, new_entry); if (!new_gc) goto err; @@ -188,7 +206,7 @@ static int bch2_mark_replicas_slowpath(struct bch_fs *c, old_r = rcu_dereference_protected(c->replicas, lockdep_is_held(&c->sb_lock)); - if (!replicas_has_entry(old_r, new_entry)) { + if (!__replicas_has_entry(old_r, new_entry)) { new_r = cpu_replicas_add_entry(old_r, new_entry); if (!new_r) goto err; @@ -227,17 +245,8 @@ err: static int __bch2_mark_replicas(struct bch_fs *c, struct bch_replicas_entry *devs) { - struct bch_replicas_cpu *r, *gc_r; - bool marked; - - rcu_read_lock(); - r = rcu_dereference(c->replicas); - gc_r = rcu_dereference(c->replicas_gc); - marked = replicas_has_entry(r, devs) && - (!likely(gc_r) || replicas_has_entry(gc_r, devs)); - rcu_read_unlock(); - - return likely(marked) ? 0 + return likely(replicas_has_entry(c, devs, true)) + ? 0 : bch2_mark_replicas_slowpath(c, devs); } @@ -666,10 +675,10 @@ const struct bch_sb_field_ops bch_sb_field_ops_replicas_v0 = { bool bch2_replicas_marked(struct bch_fs *c, enum bch_data_type data_type, - struct bch_devs_list devs) + struct bch_devs_list devs, + bool check_gc_replicas) { struct bch_replicas_entry_padded search; - bool ret; if (!devs.nr) return true; @@ -678,19 +687,15 @@ bool bch2_replicas_marked(struct bch_fs *c, devlist_to_replicas(devs, data_type, &search.e); - rcu_read_lock(); - ret = replicas_has_entry(rcu_dereference(c->replicas), &search.e); - rcu_read_unlock(); - - return ret; + return replicas_has_entry(c, &search.e, check_gc_replicas); } bool bch2_bkey_replicas_marked(struct bch_fs *c, enum bkey_type type, - struct bkey_s_c k) + struct bkey_s_c k, + bool check_gc_replicas) { struct bch_replicas_entry_padded search; - bool ret; memset(&search, 0, sizeof(search)); @@ -700,20 +705,16 @@ bool bch2_bkey_replicas_marked(struct bch_fs *c, for (i = 0; i < cached.nr; i++) if (!bch2_replicas_marked(c, BCH_DATA_CACHED, - bch2_dev_list_single(cached.devs[i]))) + bch2_dev_list_single(cached.devs[i]), + check_gc_replicas)) return false; } bkey_to_replicas(type, k, &search.e); - if (!search.e.nr_devs) - return true; - - rcu_read_lock(); - ret = replicas_has_entry(rcu_dereference(c->replicas), &search.e); - rcu_read_unlock(); - - return ret; + return search.e.nr_devs + ? replicas_has_entry(c, &search.e, check_gc_replicas) + : true; } struct replicas_status __bch2_replicas_status(struct bch_fs *c, |