Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 899f9307 authored by David Sterba's avatar David Sterba
Browse files

btrfs: lift uuid_mutex to callers of btrfs_scan_one_device



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.

Reviewed-by: default avatarAnand Jain <anand.jain@oracle.com>
Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
parent 7bcb8164
Loading
Loading
Loading
Loading
+11 −1
Original line number Diff line number Diff line
@@ -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;
@@ -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;

@@ -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);
+2 −2
Original line number Diff line number Diff line
@@ -1224,6 +1224,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.
@@ -1242,7 +1244,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);
@@ -1251,7 +1252,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);