Commit 3a402c8d authored by Kent Overstreet's avatar Kent Overstreet Committed by Kent Overstreet

bcachefs: Fix some refcounting bugs

We really need debug mode assertions that ca->ref and ca->io_ref are
used correctly.
Signed-off-by: default avatarKent Overstreet <kent.overstreet@gmail.com>
Signed-off-by: default avatarKent Overstreet <kent.overstreet@linux.dev>
parent 5bc38f44
......@@ -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);
......
......@@ -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 @@ static int bch2_gc_done(struct bch_fs *c,
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;
......
......@@ -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));
}
......
......@@ -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,
......
......@@ -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;
}
......
......@@ -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)
{
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment