Skip to content

Commit 6b526ed

Browse files
asjkdave
authored andcommitted
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 <[email protected]> Reported-by: Martin <[email protected]> [ adjust messages, s/disk/device/ ] Signed-off-by: David Sterba <[email protected]>
1 parent 42b6742 commit 6b526ed

File tree

4 files changed

+73
-5
lines changed

4 files changed

+73
-5
lines changed

fs/btrfs/ioctl.c

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2667,6 +2667,60 @@ static long btrfs_ioctl_add_dev(struct btrfs_root *root, void __user *arg)
26672667
return ret;
26682668
}
26692669

2670+
static long btrfs_ioctl_rm_dev_v2(struct file *file, void __user *arg)
2671+
{
2672+
struct btrfs_root *root = BTRFS_I(file_inode(file))->root;
2673+
struct btrfs_ioctl_vol_args_v2 *vol_args;
2674+
int ret;
2675+
2676+
if (!capable(CAP_SYS_ADMIN))
2677+
return -EPERM;
2678+
2679+
ret = mnt_want_write_file(file);
2680+
if (ret)
2681+
return ret;
2682+
2683+
vol_args = memdup_user(arg, sizeof(*vol_args));
2684+
if (IS_ERR(vol_args)) {
2685+
ret = PTR_ERR(vol_args);
2686+
goto err_drop;
2687+
}
2688+
2689+
/* Check for compatibility reject unknown flags */
2690+
if (vol_args->flags & ~BTRFS_VOL_ARG_V2_FLAGS)
2691+
return -ENOTTY;
2692+
2693+
if (atomic_xchg(&root->fs_info->mutually_exclusive_operation_running,
2694+
1)) {
2695+
ret = BTRFS_ERROR_DEV_EXCL_RUN_IN_PROGRESS;
2696+
goto out;
2697+
}
2698+
2699+
mutex_lock(&root->fs_info->volume_mutex);
2700+
if (vol_args->flags & BTRFS_DEVICE_BY_ID) {
2701+
ret = btrfs_rm_device(root, NULL, vol_args->devid);
2702+
} else {
2703+
vol_args->name[BTRFS_SUBVOL_NAME_MAX] = '\0';
2704+
ret = btrfs_rm_device(root, vol_args->name, 0);
2705+
}
2706+
mutex_unlock(&root->fs_info->volume_mutex);
2707+
atomic_set(&root->fs_info->mutually_exclusive_operation_running, 0);
2708+
2709+
if (!ret) {
2710+
if (vol_args->flags & BTRFS_DEVICE_BY_ID)
2711+
btrfs_info(root->fs_info, "device deleted: id %llu",
2712+
vol_args->devid);
2713+
else
2714+
btrfs_info(root->fs_info, "device deleted: %s",
2715+
vol_args->name);
2716+
}
2717+
out:
2718+
kfree(vol_args);
2719+
err_drop:
2720+
mnt_drop_write_file(file);
2721+
return ret;
2722+
}
2723+
26702724
static long btrfs_ioctl_rm_dev(struct file *file, void __user *arg)
26712725
{
26722726
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)
26952749
}
26962750

26972751
mutex_lock(&root->fs_info->volume_mutex);
2698-
ret = btrfs_rm_device(root, vol_args->name);
2752+
ret = btrfs_rm_device(root, vol_args->name, 0);
26992753
mutex_unlock(&root->fs_info->volume_mutex);
27002754
atomic_set(&root->fs_info->mutually_exclusive_operation_running, 0);
27012755

@@ -5459,6 +5513,8 @@ long btrfs_ioctl(struct file *file, unsigned int
54595513
return btrfs_ioctl_add_dev(root, argp);
54605514
case BTRFS_IOC_RM_DEV:
54615515
return btrfs_ioctl_rm_dev(file, argp);
5516+
case BTRFS_IOC_RM_DEV_V2:
5517+
return btrfs_ioctl_rm_dev_v2(file, argp);
54625518
case BTRFS_IOC_FS_INFO:
54635519
return btrfs_ioctl_fs_info(root, argp);
54645520
case BTRFS_IOC_DEV_INFO:

fs/btrfs/volumes.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1748,7 +1748,7 @@ static int __check_raid_min_devices(struct btrfs_fs_info *fs_info)
17481748
return 0;
17491749
}
17501750

1751-
int btrfs_rm_device(struct btrfs_root *root, char *device_path)
1751+
int btrfs_rm_device(struct btrfs_root *root, char *device_path, u64 devid)
17521752
{
17531753
struct btrfs_device *device;
17541754
struct btrfs_device *next_device;
@@ -1764,7 +1764,7 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path)
17641764
if (ret)
17651765
goto out;
17661766

1767-
ret = btrfs_find_device_by_user_input(root, 0, device_path,
1767+
ret = btrfs_find_device_by_user_input(root, devid, device_path,
17681768
&device);
17691769
if (ret)
17701770
goto out;

fs/btrfs/volumes.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -454,7 +454,7 @@ int btrfs_find_device_by_user_input(struct btrfs_root *root, u64 srcdevid,
454454
struct btrfs_device *btrfs_alloc_device(struct btrfs_fs_info *fs_info,
455455
const u64 *devid,
456456
const u8 *uuid);
457-
int btrfs_rm_device(struct btrfs_root *root, char *device_path);
457+
int btrfs_rm_device(struct btrfs_root *root, char *device_path, u64 devid);
458458
void btrfs_cleanup_fs_uuids(void);
459459
int btrfs_num_copies(struct btrfs_fs_info *fs_info, u64 logical, u64 len);
460460
int btrfs_grow_device(struct btrfs_trans_handle *trans,

include/uapi/linux/btrfs.h

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,13 @@ struct btrfs_ioctl_vol_args {
3636
#define BTRFS_SUBVOL_CREATE_ASYNC (1ULL << 0)
3737
#define BTRFS_SUBVOL_RDONLY (1ULL << 1)
3838
#define BTRFS_SUBVOL_QGROUP_INHERIT (1ULL << 2)
39+
#define BTRFS_DEVICE_BY_ID (1ULL << 3)
40+
#define BTRFS_VOL_ARG_V2_FLAGS \
41+
(BTRFS_SUBVOL_CREATE_ASYNC | \
42+
BTRFS_SUBVOL_RDONLY | \
43+
BTRFS_SUBVOL_QGROUP_INHERIT | \
44+
BTRFS_DEVICE_BY_ID)
45+
3946
#define BTRFS_FSID_SIZE 16
4047
#define BTRFS_UUID_SIZE 16
4148
#define BTRFS_UUID_UNPARSED_SIZE 37
@@ -76,7 +83,10 @@ struct btrfs_ioctl_vol_args_v2 {
7683
};
7784
__u64 unused[4];
7885
};
79-
char name[BTRFS_SUBVOL_NAME_MAX + 1];
86+
union {
87+
char name[BTRFS_SUBVOL_NAME_MAX + 1];
88+
u64 devid;
89+
};
8090
};
8191

8292
/*
@@ -659,5 +669,7 @@ static inline char *btrfs_err_str(enum btrfs_err_code err_code)
659669
struct btrfs_ioctl_feature_flags[2])
660670
#define BTRFS_IOC_GET_SUPPORTED_FEATURES _IOR(BTRFS_IOCTL_MAGIC, 57, \
661671
struct btrfs_ioctl_feature_flags[3])
672+
#define BTRFS_IOC_RM_DEV_V2 _IOW(BTRFS_IOCTL_MAGIC, 58, \
673+
struct btrfs_ioctl_vol_args_v2)
662674

663675
#endif /* _UAPI_LINUX_BTRFS_H */

0 commit comments

Comments
 (0)