--- x/fs/btrfs/volumes.h +++ y/fs/btrfs/volumes.h @@ -348,6 +348,7 @@ struct btrfs_fs_devices { /* Count fs-devices opened. */ int opened; + int user; /* Set when we find or add a device that doesn't have the nonrot flag set. */ bool rotating; --- x/fs/btrfs/volumes.c +++ y/fs/btrfs/volumes.c @@ -406,6 +406,8 @@ static void free_fs_devices(struct btrfs struct btrfs_device *device; WARN_ON(fs_devices->opened); + if (fs_devices->user) + return; while (!list_empty(&fs_devices->devices)) { device = list_entry(fs_devices->devices.next, struct btrfs_device, dev_list); --- x/fs/btrfs/super.c +++ y/fs/btrfs/super.c @@ -1486,13 +1486,14 @@ static struct dentry *btrfs_mount_root(s goto error_fs_info; } fs_info->fs_devices = device->fs_devices; + fs_info->fs_devices->user++; mutex_unlock(&uuid_mutex); s = sget(fs_type, btrfs_test_super, btrfs_set_super, flags | SB_NOSEC, fs_info); if (IS_ERR(s)) { error = PTR_ERR(s); - goto error_fs_info; + goto error_close_devices; } if (s->s_root) { @@ -1524,16 +1525,23 @@ static struct dentry *btrfs_mount_root(s if (error) goto out_deactivate; security_free_mnt_opts(&new_sec_opts); + mutex_lock(&uuid_mutex); + fs_info->fs_devices->user--; + mutex_unlock(&uuid_mutex); return dget(s->s_root); out_deactivate: deactivate_locked_super(s); error_sec_opts: security_free_mnt_opts(&new_sec_opts); - return ERR_PTR(error); +error_close_devices: + mutex_lock(&uuid_mutex); + fs_info->fs_devices->user--; + mutex_unlock(&uuid_mutex); + btrfs_close_devices(fs_info->fs_devices); error_fs_info: btrfs_free_fs_info(fs_info); - goto error_sec_opts; + return ERR_PTR(error); } /*