From: Brian Foster Date: Tue, 30 May 2023 18:48:58 +0000 (-0400) Subject: bcachefs: push rcu lock down into bch2_target_to_mask() X-Git-Url: http://git.maquefel.me/?a=commitdiff_plain;h=a1dd428b8bb78a03f210e18b05b0d73cac86fb7d;p=linux.git bcachefs: push rcu lock down into bch2_target_to_mask() We have one caller that cycles the rcu lock solely for this call (via target_rw_devs()), and we'd like to add another. Simplify things by pushing the rcu lock down into bch2_target_to_mask(), similar to how bch2_dev_in_target() works. Signed-off-by: Brian Foster Signed-off-by: Kent Overstreet --- diff --git a/fs/bcachefs/alloc_foreground.c b/fs/bcachefs/alloc_foreground.c index ec77601ebd0cb..a7e6852271d2b 100644 --- a/fs/bcachefs/alloc_foreground.c +++ b/fs/bcachefs/alloc_foreground.c @@ -934,9 +934,7 @@ static int __open_bucket_add_buckets(struct btree_trans *trans, unsigned i; int ret; - rcu_read_lock(); devs = target_rw_devs(c, wp->data_type, target); - rcu_read_unlock(); /* Don't allocate from devices we already have pointers to: */ for (i = 0; i < devs_have->nr; i++) diff --git a/fs/bcachefs/disk_groups.c b/fs/bcachefs/disk_groups.c index aa3a4e5a8b2ec..52b6400779704 100644 --- a/fs/bcachefs/disk_groups.c +++ b/fs/bcachefs/disk_groups.c @@ -208,26 +208,36 @@ int bch2_sb_disk_groups_to_cpu(struct bch_fs *c) const struct bch_devs_mask *bch2_target_to_mask(struct bch_fs *c, unsigned target) { struct target t = target_decode(target); + struct bch_devs_mask *devs; + + rcu_read_lock(); switch (t.type) { case TARGET_NULL: - return NULL; + devs = NULL; + break; case TARGET_DEV: { struct bch_dev *ca = t.dev < c->sb.nr_devices ? rcu_dereference(c->devs[t.dev]) : NULL; - return ca ? &ca->self : NULL; + devs = ca ? &ca->self : NULL; + break; } case TARGET_GROUP: { struct bch_disk_groups_cpu *g = rcu_dereference(c->disk_groups); - return g && t.group < g->nr && !g->entries[t.group].deleted + devs = g && t.group < g->nr && !g->entries[t.group].deleted ? &g->entries[t.group].devs : NULL; + break; } default: BUG(); } + + rcu_read_unlock(); + + return devs; } bool bch2_dev_in_target(struct bch_fs *c, unsigned dev, unsigned target)