summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2020-08-06 15:22:24 -0400
committerKent Overstreet <kent.overstreet@gmail.com>2020-08-25 13:09:38 -0400
commitf7160b419df8870185e7000c562c0ec3fffde63c (patch)
tree70e827e10711b965210c2b33f66f69b039d5fea6
parent08033673ba0173d5dbe4d37068f2ee09b1b44c9b (diff)
bcachefs: Fix a couple null ptr derefs when no disk groups exist
Normally successfully parsing a target means disk groups should exist, but we don't want a BUG() or null ptr deref if we end up with an invalid target. Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com>
-rw-r--r--fs/bcachefs/disk_groups.c4
-rw-r--r--fs/bcachefs/io.c4
-rw-r--r--fs/bcachefs/super.c7
3 files changed, 8 insertions, 7 deletions
diff --git a/fs/bcachefs/disk_groups.c b/fs/bcachefs/disk_groups.c
index b6e3152312ba..c52b6faac9b4 100644
--- a/fs/bcachefs/disk_groups.c
+++ b/fs/bcachefs/disk_groups.c
@@ -183,7 +183,7 @@ const struct bch_devs_mask *bch2_target_to_mask(struct bch_fs *c, unsigned targe
case TARGET_GROUP: {
struct bch_disk_groups_cpu *g = rcu_dereference(c->disk_groups);
- return t.group < g->nr && !g->entries[t.group].deleted
+ return g && t.group < g->nr && !g->entries[t.group].deleted
? &g->entries[t.group].devs
: NULL;
}
@@ -208,7 +208,7 @@ bool bch2_dev_in_target(struct bch_fs *c, unsigned dev, unsigned target)
rcu_read_lock();
g = rcu_dereference(c->disk_groups);
- m = t.group < g->nr && !g->entries[t.group].deleted
+ m = g && t.group < g->nr && !g->entries[t.group].deleted
? &g->entries[t.group].devs
: NULL;
diff --git a/fs/bcachefs/io.c b/fs/bcachefs/io.c
index 92d2ec5662a5..5c9c3cf54edd 100644
--- a/fs/bcachefs/io.c
+++ b/fs/bcachefs/io.c
@@ -54,7 +54,9 @@ static bool bch2_target_congested(struct bch_fs *c, u16 target)
return false;
rcu_read_lock();
- devs = bch2_target_to_mask(c, target);
+ devs = bch2_target_to_mask(c, target) ?:
+ &c->rw_devs[BCH_DATA_user];
+
for_each_set_bit(d, devs->d, BCH_SB_MEMBERS_MAX) {
ca = rcu_dereference(c->devs[d]);
if (!ca)
diff --git a/fs/bcachefs/super.c b/fs/bcachefs/super.c
index d30800d76fdc..94288fc92ec4 100644
--- a/fs/bcachefs/super.c
+++ b/fs/bcachefs/super.c
@@ -169,10 +169,9 @@ int bch2_congested(void *data, int bdi_bits)
}
}
} else {
- unsigned target = READ_ONCE(c->opts.foreground_target);
- const struct bch_devs_mask *devs = target
- ? bch2_target_to_mask(c, target)
- : &c->rw_devs[BCH_DATA_user];
+ const struct bch_devs_mask *devs =
+ bch2_target_to_mask(c, c->opts.foreground_target) ?:
+ &c->rw_devs[BCH_DATA_user];
for_each_member_device_rcu(ca, c, i, devs) {
bdi = ca->disk_sb.bdev->bd_bdi;