btrfs: introduce new ioctl to unregister a btrfs device
Support for a new command that can be used eg. as a command $ btrfs device scan --forget [dev]' (the final name may change though) to undo the effects of 'btrfs device scan [dev]'. For this purpose this patch proposes to use ioctl #5 as it was empty and is next to the SCAN ioctl. The new ioctl BTRFS_IOC_FORGET_DEV works only on the control device (/dev/btrfs-control) to unregister one or all devices, devices that are not mounted. The argument is struct btrfs_ioctl_vol_args, ::name specifies the device path. To unregister all device, the path is an empty string. Again, the devices are removed only if they aren't part of a mounte filesystem. This new ioctl provides: - release of unwanted btrfs_fs_devices and btrfs_devices structures from memory if the device is not going to be mounted - ability to mount filesystem in degraded mode, when one devices is corrupted like in split brain raid1 - running test cases which would require reloading the kernel module but this is not possible eg. due to mounted filesystem or built-in Signed-off-by: Anand Jain <anand.jain@oracle.com> Reviewed-by: David Sterba <dsterba@suse.com> [ update changelog ] Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
Родитель
034f784d7c
Коммит
228a73abde
|
@ -2190,6 +2190,9 @@ static long btrfs_control_ioctl(struct file *file, unsigned int cmd,
|
||||||
ret = PTR_ERR_OR_ZERO(device);
|
ret = PTR_ERR_OR_ZERO(device);
|
||||||
mutex_unlock(&uuid_mutex);
|
mutex_unlock(&uuid_mutex);
|
||||||
break;
|
break;
|
||||||
|
case BTRFS_IOC_FORGET_DEV:
|
||||||
|
ret = btrfs_forget_devices(vol->name);
|
||||||
|
break;
|
||||||
case BTRFS_IOC_DEVICES_READY:
|
case BTRFS_IOC_DEVICES_READY:
|
||||||
mutex_lock(&uuid_mutex);
|
mutex_lock(&uuid_mutex);
|
||||||
device = btrfs_scan_one_device(vol->name, FMODE_READ,
|
device = btrfs_scan_one_device(vol->name, FMODE_READ,
|
||||||
|
|
|
@ -1446,6 +1446,17 @@ static int btrfs_read_disk_super(struct block_device *bdev, u64 bytenr,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int btrfs_forget_devices(const char *path)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
mutex_lock(&uuid_mutex);
|
||||||
|
ret = btrfs_free_stale_devices(strlen(path) ? path : NULL, NULL);
|
||||||
|
mutex_unlock(&uuid_mutex);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Look for a btrfs signature on a device. This may be called out of the mount path
|
* Look for a btrfs signature on a device. This may be called out of the mount path
|
||||||
* and we are not allowed to call set_blocksize during the scan. The superblock
|
* and we are not allowed to call set_blocksize during the scan. The superblock
|
||||||
|
|
|
@ -416,6 +416,7 @@ int btrfs_open_devices(struct btrfs_fs_devices *fs_devices,
|
||||||
fmode_t flags, void *holder);
|
fmode_t flags, void *holder);
|
||||||
struct btrfs_device *btrfs_scan_one_device(const char *path,
|
struct btrfs_device *btrfs_scan_one_device(const char *path,
|
||||||
fmode_t flags, void *holder);
|
fmode_t flags, void *holder);
|
||||||
|
int btrfs_forget_devices(const char *path);
|
||||||
int btrfs_close_devices(struct btrfs_fs_devices *fs_devices);
|
int btrfs_close_devices(struct btrfs_fs_devices *fs_devices);
|
||||||
void btrfs_free_extra_devids(struct btrfs_fs_devices *fs_devices, int step);
|
void btrfs_free_extra_devids(struct btrfs_fs_devices *fs_devices, int step);
|
||||||
void btrfs_assign_next_active_device(struct btrfs_device *device,
|
void btrfs_assign_next_active_device(struct btrfs_device *device,
|
||||||
|
|
|
@ -837,6 +837,8 @@ enum btrfs_err_code {
|
||||||
struct btrfs_ioctl_vol_args)
|
struct btrfs_ioctl_vol_args)
|
||||||
#define BTRFS_IOC_SCAN_DEV _IOW(BTRFS_IOCTL_MAGIC, 4, \
|
#define BTRFS_IOC_SCAN_DEV _IOW(BTRFS_IOCTL_MAGIC, 4, \
|
||||||
struct btrfs_ioctl_vol_args)
|
struct btrfs_ioctl_vol_args)
|
||||||
|
#define BTRFS_IOC_FORGET_DEV _IOW(BTRFS_IOCTL_MAGIC, 5, \
|
||||||
|
struct btrfs_ioctl_vol_args)
|
||||||
/* trans start and trans end are dangerous, and only for
|
/* trans start and trans end are dangerous, and only for
|
||||||
* use by applications that know how to avoid the
|
* use by applications that know how to avoid the
|
||||||
* resulting deadlocks
|
* resulting deadlocks
|
||||||
|
|
Загрузка…
Ссылка в новой задаче