aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/btrfs/ioctl.c48
-rw-r--r--fs/btrfs/ioctl.h7
2 files changed, 52 insertions, 3 deletions
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index e54b5e50c927..9a71fec86152 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -55,6 +55,7 @@
55#include "backref.h" 55#include "backref.h"
56#include "rcu-string.h" 56#include "rcu-string.h"
57#include "send.h" 57#include "send.h"
58#include "dev-replace.h"
58 59
59/* Mask out flags that are inappropriate for the given type of inode. */ 60/* Mask out flags that are inappropriate for the given type of inode. */
60static inline __u32 btrfs_mask_flags(umode_t mode, __u32 flags) 61static inline __u32 btrfs_mask_flags(umode_t mode, __u32 flags)
@@ -3171,6 +3172,51 @@ static long btrfs_ioctl_get_dev_stats(struct btrfs_root *root,
3171 return ret; 3172 return ret;
3172} 3173}
3173 3174
3175static long btrfs_ioctl_dev_replace(struct btrfs_root *root, void __user *arg)
3176{
3177 struct btrfs_ioctl_dev_replace_args *p;
3178 int ret;
3179
3180 if (!capable(CAP_SYS_ADMIN))
3181 return -EPERM;
3182
3183 p = memdup_user(arg, sizeof(*p));
3184 if (IS_ERR(p))
3185 return PTR_ERR(p);
3186
3187 switch (p->cmd) {
3188 case BTRFS_IOCTL_DEV_REPLACE_CMD_START:
3189 if (atomic_xchg(
3190 &root->fs_info->mutually_exclusive_operation_running,
3191 1)) {
3192 pr_info("btrfs: dev add/delete/balance/replace/resize operation in progress\n");
3193 ret = -EINPROGRESS;
3194 } else {
3195 ret = btrfs_dev_replace_start(root, p);
3196 atomic_set(
3197 &root->fs_info->mutually_exclusive_operation_running,
3198 0);
3199 }
3200 break;
3201 case BTRFS_IOCTL_DEV_REPLACE_CMD_STATUS:
3202 btrfs_dev_replace_status(root->fs_info, p);
3203 ret = 0;
3204 break;
3205 case BTRFS_IOCTL_DEV_REPLACE_CMD_CANCEL:
3206 ret = btrfs_dev_replace_cancel(root->fs_info, p);
3207 break;
3208 default:
3209 ret = -EINVAL;
3210 break;
3211 }
3212
3213 if (copy_to_user(arg, p, sizeof(*p)))
3214 ret = -EFAULT;
3215
3216 kfree(p);
3217 return ret;
3218}
3219
3174static long btrfs_ioctl_ino_to_path(struct btrfs_root *root, void __user *arg) 3220static long btrfs_ioctl_ino_to_path(struct btrfs_root *root, void __user *arg)
3175{ 3221{
3176 int ret = 0; 3222 int ret = 0;
@@ -3826,6 +3872,8 @@ long btrfs_ioctl(struct file *file, unsigned int
3826 return btrfs_ioctl_qgroup_create(root, argp); 3872 return btrfs_ioctl_qgroup_create(root, argp);
3827 case BTRFS_IOC_QGROUP_LIMIT: 3873 case BTRFS_IOC_QGROUP_LIMIT:
3828 return btrfs_ioctl_qgroup_limit(root, argp); 3874 return btrfs_ioctl_qgroup_limit(root, argp);
3875 case BTRFS_IOC_DEV_REPLACE:
3876 return btrfs_ioctl_dev_replace(root, argp);
3829 } 3877 }
3830 3878
3831 return -ENOTTY; 3879 return -ENOTTY;
diff --git a/fs/btrfs/ioctl.h b/fs/btrfs/ioctl.h
index 62006ba02719..dabca9cc8c2e 100644
--- a/fs/btrfs/ioctl.h
+++ b/fs/btrfs/ioctl.h
@@ -30,6 +30,8 @@ struct btrfs_ioctl_vol_args {
30 char name[BTRFS_PATH_NAME_MAX + 1]; 30 char name[BTRFS_PATH_NAME_MAX + 1];
31}; 31};
32 32
33#define BTRFS_DEVICE_PATH_NAME_MAX 1024
34
33#define BTRFS_SUBVOL_CREATE_ASYNC (1ULL << 0) 35#define BTRFS_SUBVOL_CREATE_ASYNC (1ULL << 0)
34#define BTRFS_SUBVOL_RDONLY (1ULL << 1) 36#define BTRFS_SUBVOL_RDONLY (1ULL << 1)
35#define BTRFS_SUBVOL_QGROUP_INHERIT (1ULL << 2) 37#define BTRFS_SUBVOL_QGROUP_INHERIT (1ULL << 2)
@@ -127,10 +129,10 @@ struct btrfs_ioctl_scrub_args {
127#define BTRFS_IOCTL_DEV_REPLACE_CONT_READING_FROM_SRCDEV_MODE_AVOID 1 129#define BTRFS_IOCTL_DEV_REPLACE_CONT_READING_FROM_SRCDEV_MODE_AVOID 1
128struct btrfs_ioctl_dev_replace_start_params { 130struct btrfs_ioctl_dev_replace_start_params {
129 __u64 srcdevid; /* in, if 0, use srcdev_name instead */ 131 __u64 srcdevid; /* in, if 0, use srcdev_name instead */
130 __u8 srcdev_name[BTRFS_PATH_NAME_MAX + 1]; /* in */
131 __u8 tgtdev_name[BTRFS_PATH_NAME_MAX + 1]; /* in */
132 __u64 cont_reading_from_srcdev_mode; /* in, see #define 132 __u64 cont_reading_from_srcdev_mode; /* in, see #define
133 * above */ 133 * above */
134 __u8 srcdev_name[BTRFS_DEVICE_PATH_NAME_MAX + 1]; /* in */
135 __u8 tgtdev_name[BTRFS_DEVICE_PATH_NAME_MAX + 1]; /* in */
134}; 136};
135 137
136#define BTRFS_IOCTL_DEV_REPLACE_STATE_NEVER_STARTED 0 138#define BTRFS_IOCTL_DEV_REPLACE_STATE_NEVER_STARTED 0
@@ -165,7 +167,6 @@ struct btrfs_ioctl_dev_replace_args {
165 __u64 spare[64]; 167 __u64 spare[64];
166}; 168};
167 169
168#define BTRFS_DEVICE_PATH_NAME_MAX 1024
169struct btrfs_ioctl_dev_info_args { 170struct btrfs_ioctl_dev_info_args {
170 __u64 devid; /* in/out */ 171 __u64 devid; /* in/out */
171 __u8 uuid[BTRFS_UUID_SIZE]; /* in/out */ 172 __u8 uuid[BTRFS_UUID_SIZE]; /* in/out */