@@ -2213,7 +2213,12 @@ static long btrfs_control_ioctl(struct file *file, unsigned int cmd,
&btrfs_fs_type, &fs_devices);
break;
case BTRFS_IOC_PURGE_DEV:
- ret = btrfs_purge_one_device(vol->name, FMODE_READ,
+ if (vol->ioctl_flag & ~BTRFS_IOCTL_PURGE_ALL_DEVS)
+ return -EOPNOTSUPP;
+ if (vol->ioctl_flag & BTRFS_IOCTL_PURGE_ALL_DEVS)
+ ret = btrfs_purge_devices();
+ else
+ ret = btrfs_purge_one_device(vol->name, FMODE_READ,
&btrfs_fs_type, &fs_devices);
break;
case BTRFS_IOC_DEVICES_READY:
@@ -1336,6 +1336,29 @@ int btrfs_purge_one_device(const char *path, fmode_t flags, void *holder,
return ret;
}
+int btrfs_purge_devices(void)
+{
+ struct btrfs_fs_devices *fs_devices, *tmp;
+
+ mutex_lock(&uuid_mutex);
+ list_for_each_entry_safe(fs_devices, tmp, &fs_uuids, list) {
+ /*
+ * For now ignore stale device within a mounted FS.
+ */
+ if (fs_devices->opened)
+ continue;
+
+ pr_info("BTRFS: %pU num_devices %llu deregistered",
+ fs_devices->fsid, fs_devices->num_devices);
+ btrfs_sysfs_remove_fsid(fs_devices);
+ list_del(&fs_devices->list);
+ free_fs_devices(fs_devices);
+ }
+ mutex_unlock(&uuid_mutex);
+
+ return 0;
+}
+
/*
* 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
@@ -424,6 +424,7 @@ int btrfs_scan_one_device(const char *path, fmode_t flags, void *holder,
struct btrfs_fs_devices **fs_devices_ret);
int btrfs_purge_one_device(const char *path, fmode_t flags, void *holder,
struct btrfs_fs_devices **fs_devices_ret);
+int btrfs_purge_devices(void);
int btrfs_close_devices(struct btrfs_fs_devices *fs_devices);
void btrfs_close_extra_devices(struct btrfs_fs_devices *fs_devices, int step);
void btrfs_assign_next_active_device(struct btrfs_fs_info *fs_info,
@@ -28,8 +28,12 @@
/* this should be 4k */
#define BTRFS_PATH_NAME_MAX 4087
+#define BTRFS_IOCTL_PURGE_ALL_DEVS (1ULL << 0)
struct btrfs_ioctl_vol_args {
- __s64 fd;
+ union {
+ __s64 fd;
+ __u64 ioctl_flag;
+ };
char name[BTRFS_PATH_NAME_MAX + 1];
};
This adds a feature to remove all registered/scanned devices, which are not mounted or it got staled by some means. Signed-off-by: Anand Jain <anand.jain@oracle.com> Suggested-by: David Sterba <dsterba@suse.cz> --- v2-4: Does not exist. fs/btrfs/super.c | 7 ++++++- fs/btrfs/volumes.c | 23 +++++++++++++++++++++++ fs/btrfs/volumes.h | 1 + include/uapi/linux/btrfs.h | 6 +++++- 4 files changed, 35 insertions(+), 2 deletions(-)