aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/ioctl.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs/ioctl.c')
-rw-r--r--fs/btrfs/ioctl.c28
1 files changed, 27 insertions, 1 deletions
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index 29b3a94933f0..f572c53dda4f 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -3072,6 +3072,11 @@ void update_ioctl_balance_args(struct btrfs_fs_info *fs_info,
3072 3072
3073 bargs->flags = bctl->flags; 3073 bargs->flags = bctl->flags;
3074 3074
3075 if (atomic_read(&fs_info->balance_running))
3076 bargs->state |= BTRFS_BALANCE_STATE_RUNNING;
3077 if (atomic_read(&fs_info->balance_pause_req))
3078 bargs->state |= BTRFS_BALANCE_STATE_PAUSE_REQ;
3079
3075 memcpy(&bargs->data, &bctl->data, sizeof(bargs->data)); 3080 memcpy(&bargs->data, &bctl->data, sizeof(bargs->data));
3076 memcpy(&bargs->meta, &bctl->meta, sizeof(bargs->meta)); 3081 memcpy(&bargs->meta, &bctl->meta, sizeof(bargs->meta));
3077 memcpy(&bargs->sys, &bctl->sys, sizeof(bargs->sys)); 3082 memcpy(&bargs->sys, &bctl->sys, sizeof(bargs->sys));
@@ -3103,6 +3108,11 @@ static long btrfs_ioctl_balance(struct btrfs_root *root, void __user *arg)
3103 bargs = NULL; 3108 bargs = NULL;
3104 } 3109 }
3105 3110
3111 if (fs_info->balance_ctl) {
3112 ret = -EINPROGRESS;
3113 goto out_bargs;
3114 }
3115
3106 bctl = kzalloc(sizeof(*bctl), GFP_NOFS); 3116 bctl = kzalloc(sizeof(*bctl), GFP_NOFS);
3107 if (!bctl) { 3117 if (!bctl) {
3108 ret = -ENOMEM; 3118 ret = -ENOMEM;
@@ -3123,7 +3133,8 @@ static long btrfs_ioctl_balance(struct btrfs_root *root, void __user *arg)
3123 3133
3124 ret = btrfs_balance(bctl, bargs); 3134 ret = btrfs_balance(bctl, bargs);
3125 /* 3135 /*
3126 * bctl is freed in __cancel_balance 3136 * bctl is freed in __cancel_balance or in free_fs_info if
3137 * restriper was paused all the way until unmount
3127 */ 3138 */
3128 if (arg) { 3139 if (arg) {
3129 if (copy_to_user(arg, bargs, sizeof(*bargs))) 3140 if (copy_to_user(arg, bargs, sizeof(*bargs)))
@@ -3138,6 +3149,19 @@ out:
3138 return ret; 3149 return ret;
3139} 3150}
3140 3151
3152static long btrfs_ioctl_balance_ctl(struct btrfs_root *root, int cmd)
3153{
3154 if (!capable(CAP_SYS_ADMIN))
3155 return -EPERM;
3156
3157 switch (cmd) {
3158 case BTRFS_BALANCE_CTL_PAUSE:
3159 return btrfs_pause_balance(root->fs_info);
3160 }
3161
3162 return -EINVAL;
3163}
3164
3141long btrfs_ioctl(struct file *file, unsigned int 3165long btrfs_ioctl(struct file *file, unsigned int
3142 cmd, unsigned long arg) 3166 cmd, unsigned long arg)
3143{ 3167{
@@ -3216,6 +3240,8 @@ long btrfs_ioctl(struct file *file, unsigned int
3216 return btrfs_ioctl_scrub_progress(root, argp); 3240 return btrfs_ioctl_scrub_progress(root, argp);
3217 case BTRFS_IOC_BALANCE_V2: 3241 case BTRFS_IOC_BALANCE_V2:
3218 return btrfs_ioctl_balance(root, argp); 3242 return btrfs_ioctl_balance(root, argp);
3243 case BTRFS_IOC_BALANCE_CTL:
3244 return btrfs_ioctl_balance_ctl(root, arg);
3219 } 3245 }
3220 3246
3221 return -ENOTTY; 3247 return -ENOTTY;