btrfs: introduce new ioctl to unregister a btrfs device
authorAnand Jain <anand.jain@oracle.com>
Fri, 4 Jan 2019 05:31:54 +0000 (13:31 +0800)
committerDavid Sterba <dsterba@suse.com>
Mon, 25 Feb 2019 13:13:30 +0000 (14:13 +0100)
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>
fs/btrfs/super.c
fs/btrfs/volumes.c
fs/btrfs/volumes.h
include/uapi/linux/btrfs.h

index 0a3f122dd61fe1858461c0c760b94b78412f3368..f9d13a30aa8aa6eb21358e8688ce7c7dba2b14ad 100644 (file)
@@ -2190,6 +2190,9 @@ static long btrfs_control_ioctl(struct file *file, unsigned int cmd,
                ret = PTR_ERR_OR_ZERO(device);
                mutex_unlock(&uuid_mutex);
                break;
+       case BTRFS_IOC_FORGET_DEV:
+               ret = btrfs_forget_devices(vol->name);
+               break;
        case BTRFS_IOC_DEVICES_READY:
                mutex_lock(&uuid_mutex);
                device = btrfs_scan_one_device(vol->name, FMODE_READ,
index 7ca31c83e7307321456cc9c996ee46b68c5345ca..fe122e6099ae7e59f46705a9c7e000770ad6e6c4 100644 (file)
@@ -1446,6 +1446,17 @@ static int btrfs_read_disk_super(struct block_device *bdev, u64 bytenr,
        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
  * and we are not allowed to call set_blocksize during the scan. The superblock
index 656ea8d857709e1fc3871829cfce84dd7d8907bc..3ad9d58d1b6618aea5d79220e48fdf98ac243360 100644 (file)
@@ -416,6 +416,7 @@ int btrfs_open_devices(struct btrfs_fs_devices *fs_devices,
                       fmode_t flags, void *holder);
 struct btrfs_device *btrfs_scan_one_device(const char *path,
                                           fmode_t flags, void *holder);
+int btrfs_forget_devices(const char *path);
 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_assign_next_active_device(struct btrfs_device *device,
index e0763bc4158e1a514f4647f4238226caeea642ef..c195896d478f295ee80b667597a6c400696ac0dc 100644 (file)
@@ -837,6 +837,8 @@ enum btrfs_err_code {
                                   struct btrfs_ioctl_vol_args)
 #define BTRFS_IOC_SCAN_DEV _IOW(BTRFS_IOCTL_MAGIC, 4, \
                                   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
  * use by applications that know how to avoid the
  * resulting deadlocks