diff options
author | Kent Overstreet <kent.overstreet@gmail.com> | 2021-05-07 20:43:43 -0400 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@linux.dev> | 2023-10-22 17:09:03 -0400 |
commit | 3a402c8dabf11142d78d0f6174b50db6ba846c4e (patch) | |
tree | 5bdb84c3f734a1a74a9332f31d368f922d33f2a9 /fs/bcachefs | |
parent | 5bc38f44fa8e938044bb3b69c8881f3682fe97f6 (diff) |
bcachefs: Fix some refcounting bugs
We really need debug mode assertions that ca->ref and ca->io_ref are
used correctly.
Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com>
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
Diffstat (limited to 'fs/bcachefs')
-rw-r--r-- | fs/bcachefs/alloc_background.c | 2 | ||||
-rw-r--r-- | fs/bcachefs/btree_gc.c | 6 | ||||
-rw-r--r-- | fs/bcachefs/buckets.c | 2 | ||||
-rw-r--r-- | fs/bcachefs/recovery.c | 4 | ||||
-rw-r--r-- | fs/bcachefs/super.c | 12 | ||||
-rw-r--r-- | fs/bcachefs/super.h | 5 |
6 files changed, 18 insertions, 13 deletions
diff --git a/fs/bcachefs/alloc_background.c b/fs/bcachefs/alloc_background.c index 996b1afd1380..791066b6b39b 100644 --- a/fs/bcachefs/alloc_background.c +++ b/fs/bcachefs/alloc_background.c @@ -371,7 +371,7 @@ int bch2_alloc_write(struct bch_fs *c, unsigned flags) ret = bch2_alloc_write_key(&trans, iter, flags); if (ret) { - percpu_ref_put(&ca->io_ref); + percpu_ref_put(&ca->ref); goto err; } bch2_btree_iter_next_slot(iter); diff --git a/fs/bcachefs/btree_gc.c b/fs/bcachefs/btree_gc.c index 1c2eab41f7ca..bd4dd1d67a1d 100644 --- a/fs/bcachefs/btree_gc.c +++ b/fs/bcachefs/btree_gc.c @@ -1023,7 +1023,7 @@ static void bch2_gc_free(struct bch_fs *c) static int bch2_gc_done(struct bch_fs *c, bool initial, bool metadata_only) { - struct bch_dev *ca; + struct bch_dev *ca = NULL; bool verify = !metadata_only && (!initial || (c->sb.compat & (1ULL << BCH_COMPAT_alloc_info))); unsigned i, dev; @@ -1169,6 +1169,8 @@ static int bch2_gc_done(struct bch_fs *c, #undef copy_stripe_field #undef copy_field fsck_err: + if (ca) + percpu_ref_put(&ca->ref); if (ret) bch_err(c, "%s: ret %i", __func__, ret); return ret; @@ -1177,7 +1179,7 @@ fsck_err: static int bch2_gc_start(struct bch_fs *c, bool metadata_only) { - struct bch_dev *ca; + struct bch_dev *ca = NULL; unsigned i; int ret; diff --git a/fs/bcachefs/buckets.c b/fs/bcachefs/buckets.c index d6f0325affcc..a83d5de87d39 100644 --- a/fs/bcachefs/buckets.c +++ b/fs/bcachefs/buckets.c @@ -2071,7 +2071,7 @@ static int __bch2_trans_mark_dev_sb(struct btree_trans *trans, int bch2_trans_mark_dev_sb(struct bch_fs *c, struct bch_dev *ca) { - return bch2_trans_do(c, NULL, NULL, 0, + return bch2_trans_do(c, NULL, NULL, BTREE_INSERT_LAZY_RW, __bch2_trans_mark_dev_sb(&trans, ca)); } diff --git a/fs/bcachefs/recovery.c b/fs/bcachefs/recovery.c index b35b297d4446..cd538ecc1f3f 100644 --- a/fs/bcachefs/recovery.c +++ b/fs/bcachefs/recovery.c @@ -1328,8 +1328,10 @@ int bch2_fs_initialize(struct bch_fs *c) err = "error marking superblock and journal"; for_each_member_device(ca, c, i) { ret = bch2_trans_mark_dev_sb(c, ca); - if (ret) + if (ret) { + percpu_ref_put(&ca->ref); goto err; + } } bch2_inode_init(c, &root_inode, 0, 0, diff --git a/fs/bcachefs/super.c b/fs/bcachefs/super.c index 78db2c0a5f5a..9065e264c567 100644 --- a/fs/bcachefs/super.c +++ b/fs/bcachefs/super.c @@ -629,9 +629,11 @@ static const char *bch2_fs_online(struct bch_fs *c) down_write(&c->state_lock); err = "error creating sysfs objects"; - __for_each_member_device(ca, c, i, NULL) - if (bch2_dev_sysfs_online(c, ca)) + for_each_member_device(ca, c, i) + if (bch2_dev_sysfs_online(c, ca)) { + percpu_ref_put(&ca->ref); goto err; + } list_add(&c->list, &bch_fs_list); err = NULL; @@ -1839,12 +1841,14 @@ struct bch_dev *bch2_dev_lookup(struct bch_fs *c, const char *path) if (ret) return ERR_PTR(ret); - for_each_member_device(ca, c, i) + rcu_read_lock(); + for_each_member_device_rcu(ca, c, i, NULL) if (ca->disk_sb.bdev->bd_dev == dev) goto found; - ca = ERR_PTR(-ENOENT); found: + rcu_read_unlock(); + return ca; } diff --git a/fs/bcachefs/super.h b/fs/bcachefs/super.h index 28e6d78f9fcd..b151bffcd3a3 100644 --- a/fs/bcachefs/super.h +++ b/fs/bcachefs/super.h @@ -107,11 +107,8 @@ static inline struct bch_dev *__bch2_next_dev(struct bch_fs *c, unsigned *iter, return ca; } -#define __for_each_member_device(ca, c, iter, mask) \ - for ((iter) = 0; ((ca) = __bch2_next_dev((c), &(iter), mask)); (iter)++) - #define for_each_member_device_rcu(ca, c, iter, mask) \ - __for_each_member_device(ca, c, iter, mask) + for ((iter) = 0; ((ca) = __bch2_next_dev((c), &(iter), mask)); (iter)++) static inline struct bch_dev *bch2_get_next_dev(struct bch_fs *c, unsigned *iter) { |