@@ -565,6 +565,8 @@ static int btrfs_test_super(struct super_block *s, void *data)
struct btrfs_fs_devices *test_fs_devices = data;
struct btrfs_root *root = btrfs_sb(s);
+ if (!root)
+ return 0;
return root->fs_info->fs_devices == test_fs_devices;
}
@@ -585,6 +587,7 @@ static int btrfs_get_sb(struct file_system_type *fs_type, int flags,
char *subvol_name = NULL;
u64 subvol_objectid = 0;
int error = 0;
+ DEFINE_MUTEX(super_mutex);
if (!(flags & MS_RDONLY))
mode |= FMODE_WRITE;
@@ -613,8 +616,10 @@ static int btrfs_get_sb(struct file_system_type *fs_type, int flags,
if (IS_ERR(s))
goto error_s;
+ mutex_lock(&super_mutex);
if (s->s_root) {
if ((flags ^ s->s_flags) & MS_RDONLY) {
+ mutex_unlock(&super_mutex);
deactivate_locked_super(s);
error = -EBUSY;
goto error_close_devices;
@@ -629,6 +634,7 @@ static int btrfs_get_sb(struct file_system_type *fs_type, int flags,
error = btrfs_fill_super(s, fs_devices, data,
flags & MS_SILENT ? 1 : 0);
if (error) {
+ mutex_unlock(&super_mutex);
deactivate_locked_super(s);
goto error_free_subvol_name;
}
@@ -636,6 +642,7 @@ static int btrfs_get_sb(struct file_system_type *fs_type, int flags,
btrfs_sb(s)->fs_info->bdev_holder = fs_type;
s->s_flags |= MS_ACTIVE;
}
+ mutex_unlock(&super_mutex);
root = get_default_root(s, subvol_objectid);
if (IS_ERR(root)) {