You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
btrfs: introduce device delete by devid
This introduces new ioctl BTRFS_IOC_RM_DEV_V2, which uses enhanced struct btrfs_ioctl_vol_args_v2 to carry devid as an user argument. The patch won't delete the old ioctl interface and so kernel remains backward compatible with user land progs. Test case/script: echo "0 $(blockdev --getsz /dev/sdf) linear /dev/sdf 0" | dmsetup create bad_disk mkfs.btrfs -f -d raid1 -m raid1 /dev/sdd /dev/sde /dev/mapper/bad_disk mount /dev/sdd /btrfs dmsetup suspend bad_disk echo "0 $(blockdev --getsz /dev/sdf) error /dev/sdf 0" | dmsetup load bad_disk dmsetup resume bad_disk echo "bad disk failed. now deleting/replacing" btrfs dev del 3 /btrfs echo $? btrfs fi show /btrfs umount /btrfs btrfs-show-super /dev/sdd | egrep num_device dmsetup remove bad_disk wipefs -a /dev/sdf Signed-off-by: Anand Jain <anand.jain@oracle.com> Reported-by: Martin <m_btrfs@ml1.co.uk> [ adjust messages, s/disk/device/ ] Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
+57
-1
@@ -2667,6 +2667,60 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static long btrfs_ioctl_rm_dev_v2(struct file *file, void __user *arg)
|
||||
{
|
||||
struct btrfs_root *root = BTRFS_I(file_inode(file))->root;
|
||||
struct btrfs_ioctl_vol_args_v2 *vol_args;
|
||||
int ret;
|
||||
|
||||
if (!capable(CAP_SYS_ADMIN))
|
||||
return -EPERM;
|
||||
|
||||
ret = mnt_want_write_file(file);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
vol_args = memdup_user(arg, sizeof(*vol_args));
|
||||
if (IS_ERR(vol_args)) {
|
||||
ret = PTR_ERR(vol_args);
|
||||
goto err_drop;
|
||||
}
|
||||
|
||||
/* Check for compatibility reject unknown flags */
|
||||
if (vol_args->flags & ~BTRFS_VOL_ARG_V2_FLAGS)
|
||||
return -ENOTTY;
|
||||
|
||||
if (atomic_xchg(&root->fs_info->mutually_exclusive_operation_running,
|
||||
1)) {
|
||||
ret = BTRFS_ERROR_DEV_EXCL_RUN_IN_PROGRESS;
|
||||
goto out;
|
||||
}
|
||||
|
||||
mutex_lock(&root->fs_info->volume_mutex);
|
||||
if (vol_args->flags & BTRFS_DEVICE_BY_ID) {
|
||||
ret = btrfs_rm_device(root, NULL, vol_args->devid);
|
||||
} else {
|
||||
vol_args->name[BTRFS_SUBVOL_NAME_MAX] = '\0';
|
||||
ret = btrfs_rm_device(root, vol_args->name, 0);
|
||||
}
|
||||
mutex_unlock(&root->fs_info->volume_mutex);
|
||||
atomic_set(&root->fs_info->mutually_exclusive_operation_running, 0);
|
||||
|
||||
if (!ret) {
|
||||
if (vol_args->flags & BTRFS_DEVICE_BY_ID)
|
||||
btrfs_info(root->fs_info, "device deleted: id %llu",
|
||||
vol_args->devid);
|
||||
else
|
||||
btrfs_info(root->fs_info, "device deleted: %s",
|
||||
vol_args->name);
|
||||
}
|
||||
out:
|
||||
kfree(vol_args);
|
||||
err_drop:
|
||||
mnt_drop_write_file(file);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static long btrfs_ioctl_rm_dev(struct file *file, void __user *arg)
|
||||
{
|
||||
struct btrfs_root *root = BTRFS_I(file_inode(file))->root;
|
||||
@@ -2695,7 +2749,7 @@ static long btrfs_ioctl_rm_dev(struct file *file, void __user *arg)
|
||||
}
|
||||
|
||||
mutex_lock(&root->fs_info->volume_mutex);
|
||||
ret = btrfs_rm_device(root, vol_args->name);
|
||||
ret = btrfs_rm_device(root, vol_args->name, 0);
|
||||
mutex_unlock(&root->fs_info->volume_mutex);
|
||||
atomic_set(&root->fs_info->mutually_exclusive_operation_running, 0);
|
||||
|
||||
@@ -5459,6 +5513,8 @@ long btrfs_ioctl(struct file *file, unsigned int
|
||||
return btrfs_ioctl_add_dev(root, argp);
|
||||
case BTRFS_IOC_RM_DEV:
|
||||
return btrfs_ioctl_rm_dev(file, argp);
|
||||
case BTRFS_IOC_RM_DEV_V2:
|
||||
return btrfs_ioctl_rm_dev_v2(file, argp);
|
||||
case BTRFS_IOC_FS_INFO:
|
||||
return btrfs_ioctl_fs_info(root, argp);
|
||||
case BTRFS_IOC_DEV_INFO:
|
||||
|
||||
Reference in New Issue
Block a user