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);
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;
#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;
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;
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));
}
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,
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;
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;
}
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)
{