Skip to content

Commit

Permalink
btrfs: lift uuid_mutex to callers of btrfs_scan_one_device
Browse files Browse the repository at this point in the history
Prepartory work to fix race between mount and device scan.

The callers will have to manage the critical section, eg. mount wants to
scan and then call btrfs_open_devices without the ioctl scan walking in
and modifying the fs devices in the meantime.

Signed-off-by: David Sterba <dsterba@suse.com>
Reviewed-by: Anand Jain <anand.jain@oracle.com>
  • Loading branch information
kdave authored and asj committed Jul 11, 2018
1 parent e735e86 commit 39a2036
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 3 deletions.
12 changes: 11 additions & 1 deletion fs/btrfs/super.c
Original file line number Diff line number Diff line change
Expand Up @@ -915,8 +915,10 @@ static int btrfs_parse_early_options(const char *options, fmode_t flags,
error = -ENOMEM;
goto out;
}
mutex_lock(&uuid_mutex);
error = btrfs_scan_one_device(device_name,
flags, holder, fs_devices);
mutex_unlock(&uuid_mutex);
kfree(device_name);
if (error)
goto out;
Expand Down Expand Up @@ -1537,7 +1539,9 @@ static struct dentry *btrfs_mount_root(struct file_system_type *fs_type,
return ERR_PTR(error);
}

mutex_lock(&uuid_mutex);
error = btrfs_scan_one_device(device_name, mode, fs_type, &fs_devices);
mutex_unlock(&uuid_mutex);
if (error)
goto error_sec_opts;

Expand Down Expand Up @@ -2232,15 +2236,21 @@ static long btrfs_control_ioctl(struct file *file, unsigned int cmd,

switch (cmd) {
case BTRFS_IOC_SCAN_DEV:
mutex_lock(&uuid_mutex);
ret = btrfs_scan_one_device(vol->name, FMODE_READ,
&btrfs_root_fs_type, &fs_devices);
mutex_unlock(&uuid_mutex);
break;
case BTRFS_IOC_DEVICES_READY:
mutex_lock(&uuid_mutex);
ret = btrfs_scan_one_device(vol->name, FMODE_READ,
&btrfs_root_fs_type, &fs_devices);
if (ret)
if (ret) {
mutex_unlock(&uuid_mutex);
break;
}
ret = !(fs_devices->num_devices == fs_devices->total_devices);
mutex_unlock(&uuid_mutex);
break;
case BTRFS_IOC_GET_SUPPORTED_FEATURES:
ret = btrfs_ioctl_get_supported_features((void __user*)arg);
Expand Down
4 changes: 2 additions & 2 deletions fs/btrfs/volumes.c
Original file line number Diff line number Diff line change
Expand Up @@ -1226,6 +1226,8 @@ int btrfs_scan_one_device(const char *path, fmode_t flags, void *holder,
int ret = 0;
u64 bytenr;

lockdep_assert_held(&uuid_mutex);

/*
* we would like to check all the supers, but that would make
* a btrfs mount succeed after a mkfs from a different FS.
Expand All @@ -1244,7 +1246,6 @@ int btrfs_scan_one_device(const char *path, fmode_t flags, void *holder,
goto error_bdev_put;
}

mutex_lock(&uuid_mutex);
device = device_list_add(path, disk_super, &new_device_added);
if (IS_ERR(device)) {
ret = PTR_ERR(device);
Expand All @@ -1253,7 +1254,6 @@ int btrfs_scan_one_device(const char *path, fmode_t flags, void *holder,
if (new_device_added)
btrfs_free_stale_devices(path, device);
}
mutex_unlock(&uuid_mutex);

btrfs_release_disk_super(page);

Expand Down

0 comments on commit 39a2036

Please sign in to comment.