summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2017-12-29 21:51:38 -0500
committerKent Overstreet <kent.overstreet@gmail.com>2018-05-22 00:44:18 -0400
commit63d9b3a02aed31f920636cb6a85381a8ce1a25f4 (patch)
treee625b6d903a9d13a5b3cdb8b335beb183ff6ccce
parent4a06998b66789ae95fa739c207eb3f12dfd52706 (diff)
bcachefs: fix a lockdep pop
-rw-r--r--fs/bcachefs/super.c31
1 files changed, 16 insertions, 15 deletions
diff --git a/fs/bcachefs/super.c b/fs/bcachefs/super.c
index 69290d27a582..bdf398680663 100644
--- a/fs/bcachefs/super.c
+++ b/fs/bcachefs/super.c
@@ -1107,6 +1107,8 @@ static int __bch2_dev_online(struct bch_fs *c, struct bch_sb_handle *sb)
struct bch_dev *ca;
int ret;
+ lockdep_assert_held(&c->state_lock);
+
if (le64_to_cpu(sb->sb->seq) >
le64_to_cpu(c->disk_sb->seq))
bch2_sb_to_fs(c, sb->sb);
@@ -1153,7 +1155,9 @@ static int __bch2_dev_online(struct bch_fs *c, struct bch_sb_handle *sb)
bdevname(ca->disk_sb.bdev, c->name);
bdevname(ca->disk_sb.bdev, ca->name);
+ mutex_lock(&c->sb_lock);
bch2_mark_dev_superblock(c, ca, BCH_BUCKET_MARK_MAY_MAKE_UNAVAILABLE);
+ mutex_unlock(&c->sb_lock);
if (ca->mi.state == BCH_MEMBER_STATE_RW)
bch2_dev_allocator_add(c, ca);
@@ -1479,14 +1483,14 @@ have_slot:
sizeof(struct bch_member) * nr_devices) / sizeof(u64);
err = "no space in superblock for member info";
- mi = bch2_fs_sb_resize_members(c, u64s);
- if (!mi)
- goto err_unlock;
-
dev_mi = bch2_sb_resize_members(&sb, u64s);
if (!dev_mi)
goto err_unlock;
+ mi = bch2_fs_sb_resize_members(c, u64s);
+ if (!mi)
+ goto err_unlock;
+
memcpy(dev_mi, mi, u64s * sizeof(u64));
dev_mi->members[dev_idx] = saved_mi;
@@ -1499,21 +1503,21 @@ have_slot:
c->disk_sb->nr_devices = nr_devices;
c->sb.nr_devices = nr_devices;
+ bch2_write_super(c);
+ mutex_unlock(&c->sb_lock);
+
if (bch2_dev_alloc(c, dev_idx)) {
err = "cannot allocate memory";
ret = -ENOMEM;
- goto err_unlock;
+ goto err;
}
if (__bch2_dev_online(c, &sb)) {
err = "bch2_dev_online() error";
ret = -ENOMEM;
- goto err_unlock;
+ goto err;
}
- bch2_write_super(c);
- mutex_unlock(&c->sb_lock);
-
ca = bch_dev_locked(c, dev_idx);
if (ca->mi.state == BCH_MEMBER_STATE_RW) {
err = "journal alloc failed";
@@ -1557,13 +1561,10 @@ int bch2_dev_online(struct bch_fs *c, const char *path)
if (err)
goto err;
- mutex_lock(&c->sb_lock);
if (__bch2_dev_online(c, &sb)) {
err = "__bch2_dev_online() error";
- mutex_unlock(&c->sb_lock);
goto err;
}
- mutex_unlock(&c->sb_lock);
ca = bch_dev_locked(c, dev_idx);
if (ca->mi.state == BCH_MEMBER_STATE_RW) {
@@ -1716,13 +1717,13 @@ const char *bch2_fs_open(char * const *devices, unsigned nr_devices,
goto err;
err = "bch2_dev_online() error";
- mutex_lock(&c->sb_lock);
+ mutex_lock(&c->state_lock);
for (i = 0; i < nr_devices; i++)
if (__bch2_dev_online(c, &sb[i])) {
- mutex_unlock(&c->sb_lock);
+ mutex_unlock(&c->state_lock);
goto err;
}
- mutex_unlock(&c->sb_lock);
+ mutex_unlock(&c->state_lock);
err = "insufficient devices";
if (!bch2_fs_may_start(c))