diff options
author | Brian Foster <bfoster@redhat.com> | 2023-05-30 14:48:58 -0400 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@linux.dev> | 2023-10-22 17:10:03 -0400 |
commit | a1dd428b8bb78a03f210e18b05b0d73cac86fb7d (patch) | |
tree | 25847a81aafd3df4b662242dc11dfdb1e906ee4c | |
parent | fec4fc82b531beb2cc67b734140ffe776af33f7c (diff) | |
download | lwn-a1dd428b8bb78a03f210e18b05b0d73cac86fb7d.tar.gz lwn-a1dd428b8bb78a03f210e18b05b0d73cac86fb7d.zip |
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 <bfoster@redhat.com>
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
-rw-r--r-- | fs/bcachefs/alloc_foreground.c | 2 | ||||
-rw-r--r-- | fs/bcachefs/disk_groups.c | 16 |
2 files changed, 13 insertions, 5 deletions
diff --git a/fs/bcachefs/alloc_foreground.c b/fs/bcachefs/alloc_foreground.c index ec77601ebd0c..a7e6852271d2 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 aa3a4e5a8b2e..52b640077970 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) |