|
@@ -55,6 +55,7 @@
|
|
|
#include "backref.h"
|
|
|
#include "rcu-string.h"
|
|
|
#include "send.h"
|
|
|
+#include "dev-replace.h"
|
|
|
|
|
|
/* Mask out flags that are inappropriate for the given type of inode. */
|
|
|
static 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,
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
+static long btrfs_ioctl_dev_replace(struct btrfs_root *root, void __user *arg)
|
|
|
+{
|
|
|
+ struct btrfs_ioctl_dev_replace_args *p;
|
|
|
+ int ret;
|
|
|
+
|
|
|
+ if (!capable(CAP_SYS_ADMIN))
|
|
|
+ return -EPERM;
|
|
|
+
|
|
|
+ p = memdup_user(arg, sizeof(*p));
|
|
|
+ if (IS_ERR(p))
|
|
|
+ return PTR_ERR(p);
|
|
|
+
|
|
|
+ switch (p->cmd) {
|
|
|
+ case BTRFS_IOCTL_DEV_REPLACE_CMD_START:
|
|
|
+ if (atomic_xchg(
|
|
|
+ &root->fs_info->mutually_exclusive_operation_running,
|
|
|
+ 1)) {
|
|
|
+ pr_info("btrfs: dev add/delete/balance/replace/resize operation in progress\n");
|
|
|
+ ret = -EINPROGRESS;
|
|
|
+ } else {
|
|
|
+ ret = btrfs_dev_replace_start(root, p);
|
|
|
+ atomic_set(
|
|
|
+ &root->fs_info->mutually_exclusive_operation_running,
|
|
|
+ 0);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case BTRFS_IOCTL_DEV_REPLACE_CMD_STATUS:
|
|
|
+ btrfs_dev_replace_status(root->fs_info, p);
|
|
|
+ ret = 0;
|
|
|
+ break;
|
|
|
+ case BTRFS_IOCTL_DEV_REPLACE_CMD_CANCEL:
|
|
|
+ ret = btrfs_dev_replace_cancel(root->fs_info, p);
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ ret = -EINVAL;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (copy_to_user(arg, p, sizeof(*p)))
|
|
|
+ ret = -EFAULT;
|
|
|
+
|
|
|
+ kfree(p);
|
|
|
+ return ret;
|
|
|
+}
|
|
|
+
|
|
|
static long btrfs_ioctl_ino_to_path(struct btrfs_root *root, void __user *arg)
|
|
|
{
|
|
|
int ret = 0;
|
|
@@ -3826,6 +3872,8 @@ long btrfs_ioctl(struct file *file, unsigned int
|
|
|
return btrfs_ioctl_qgroup_create(root, argp);
|
|
|
case BTRFS_IOC_QGROUP_LIMIT:
|
|
|
return btrfs_ioctl_qgroup_limit(root, argp);
|
|
|
+ case BTRFS_IOC_DEV_REPLACE:
|
|
|
+ return btrfs_ioctl_dev_replace(root, argp);
|
|
|
}
|
|
|
|
|
|
return -ENOTTY;
|