aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnand Jain <anand.jain@oracle.com>2016-02-12 21:01:39 -0500
committerDavid Sterba <dsterba@suse.com>2016-04-28 04:59:13 -0400
commit6b526ed70cf189660d009ea6f17af77a9cca0f38 (patch)
treeff2c8182649b216537ee8fd3012746db750348e1
parent42b674271566c26692c32f4ec1f4b4cf14d5046f (diff)
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>
-rw-r--r--fs/btrfs/ioctl.c58
-rw-r--r--fs/btrfs/volumes.c4
-rw-r--r--fs/btrfs/volumes.h2
-rw-r--r--include/uapi/linux/btrfs.h14
4 files changed, 73 insertions, 5 deletions
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index 5a23806ae418..7cf0f6328d99 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -2667,6 +2667,60 @@ out:
2667 return ret; 2667 return ret;
2668} 2668}
2669 2669
2670static 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 }
2717out:
2718 kfree(vol_args);
2719err_drop:
2720 mnt_drop_write_file(file);
2721 return ret;
2722}
2723
2670static long btrfs_ioctl_rm_dev(struct file *file, void __user *arg) 2724static long btrfs_ioctl_rm_dev(struct file *file, void __user *arg)
2671{ 2725{
2672 struct btrfs_root *root = BTRFS_I(file_inode(file))->root; 2726 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)
2695 } 2749 }
2696 2750
2697 mutex_lock(&root->fs_info->volume_mutex); 2751 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);
2699 mutex_unlock(&root->fs_info->volume_mutex); 2753 mutex_unlock(&root->fs_info->volume_mutex);
2700 atomic_set(&root->fs_info->mutually_exclusive_operation_running, 0); 2754 atomic_set(&root->fs_info->mutually_exclusive_operation_running, 0);
2701 2755
@@ -5459,6 +5513,8 @@ long btrfs_ioctl(struct file *file, unsigned int
5459 return btrfs_ioctl_add_dev(root, argp); 5513 return btrfs_ioctl_add_dev(root, argp);
5460 case BTRFS_IOC_RM_DEV: 5514 case BTRFS_IOC_RM_DEV:
5461 return btrfs_ioctl_rm_dev(file, argp); 5515 return btrfs_ioctl_rm_dev(file, argp);
5516 case BTRFS_IOC_RM_DEV_V2:
5517 return btrfs_ioctl_rm_dev_v2(file, argp);
5462 case BTRFS_IOC_FS_INFO: 5518 case BTRFS_IOC_FS_INFO:
5463 return btrfs_ioctl_fs_info(root, argp); 5519 return btrfs_ioctl_fs_info(root, argp);
5464 case BTRFS_IOC_DEV_INFO: 5520 case BTRFS_IOC_DEV_INFO:
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index 8264b06756e6..1421d711629f 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -1748,7 +1748,7 @@ static int __check_raid_min_devices(struct btrfs_fs_info *fs_info)
1748 return 0; 1748 return 0;
1749} 1749}
1750 1750
1751int btrfs_rm_device(struct btrfs_root *root, char *device_path) 1751int btrfs_rm_device(struct btrfs_root *root, char *device_path, u64 devid)
1752{ 1752{
1753 struct btrfs_device *device; 1753 struct btrfs_device *device;
1754 struct btrfs_device *next_device; 1754 struct btrfs_device *next_device;
@@ -1764,7 +1764,7 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path)
1764 if (ret) 1764 if (ret)
1765 goto out; 1765 goto out;
1766 1766
1767 ret = btrfs_find_device_by_user_input(root, 0, device_path, 1767 ret = btrfs_find_device_by_user_input(root, devid, device_path,
1768 &device); 1768 &device);
1769 if (ret) 1769 if (ret)
1770 goto out; 1770 goto out;
diff --git a/fs/btrfs/volumes.h b/fs/btrfs/volumes.h
index 508739314e43..c73d027e2f8b 100644
--- a/fs/btrfs/volumes.h
+++ b/fs/btrfs/volumes.h
@@ -454,7 +454,7 @@ int btrfs_find_device_by_user_input(struct btrfs_root *root, u64 srcdevid,
454struct btrfs_device *btrfs_alloc_device(struct btrfs_fs_info *fs_info, 454struct btrfs_device *btrfs_alloc_device(struct btrfs_fs_info *fs_info,
455 const u64 *devid, 455 const u64 *devid,
456 const u8 *uuid); 456 const u8 *uuid);
457int btrfs_rm_device(struct btrfs_root *root, char *device_path); 457int btrfs_rm_device(struct btrfs_root *root, char *device_path, u64 devid);
458void btrfs_cleanup_fs_uuids(void); 458void btrfs_cleanup_fs_uuids(void);
459int btrfs_num_copies(struct btrfs_fs_info *fs_info, u64 logical, u64 len); 459int btrfs_num_copies(struct btrfs_fs_info *fs_info, u64 logical, u64 len);
460int btrfs_grow_device(struct btrfs_trans_handle *trans, 460int btrfs_grow_device(struct btrfs_trans_handle *trans,
diff --git a/include/uapi/linux/btrfs.h b/include/uapi/linux/btrfs.h
index dea893199257..396a4efca775 100644
--- a/include/uapi/linux/btrfs.h
+++ b/include/uapi/linux/btrfs.h
@@ -36,6 +36,13 @@ struct btrfs_ioctl_vol_args {
36#define BTRFS_SUBVOL_CREATE_ASYNC (1ULL << 0) 36#define BTRFS_SUBVOL_CREATE_ASYNC (1ULL << 0)
37#define BTRFS_SUBVOL_RDONLY (1ULL << 1) 37#define BTRFS_SUBVOL_RDONLY (1ULL << 1)
38#define BTRFS_SUBVOL_QGROUP_INHERIT (1ULL << 2) 38#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
39#define BTRFS_FSID_SIZE 16 46#define BTRFS_FSID_SIZE 16
40#define BTRFS_UUID_SIZE 16 47#define BTRFS_UUID_SIZE 16
41#define BTRFS_UUID_UNPARSED_SIZE 37 48#define BTRFS_UUID_UNPARSED_SIZE 37
@@ -76,7 +83,10 @@ struct btrfs_ioctl_vol_args_v2 {
76 }; 83 };
77 __u64 unused[4]; 84 __u64 unused[4];
78 }; 85 };
79 char name[BTRFS_SUBVOL_NAME_MAX + 1]; 86 union {
87 char name[BTRFS_SUBVOL_NAME_MAX + 1];
88 u64 devid;
89 };
80}; 90};
81 91
82/* 92/*
@@ -659,5 +669,7 @@ static inline char *btrfs_err_str(enum btrfs_err_code err_code)
659 struct btrfs_ioctl_feature_flags[2]) 669 struct btrfs_ioctl_feature_flags[2])
660#define BTRFS_IOC_GET_SUPPORTED_FEATURES _IOR(BTRFS_IOCTL_MAGIC, 57, \ 670#define BTRFS_IOC_GET_SUPPORTED_FEATURES _IOR(BTRFS_IOCTL_MAGIC, 57, \
661 struct btrfs_ioctl_feature_flags[3]) 671 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)
662 674
663#endif /* _UAPI_LINUX_BTRFS_H */ 675#endif /* _UAPI_LINUX_BTRFS_H */