aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/volumes.c
diff options
context:
space:
mode:
authorIlya Dryomov <idryomov@gmail.com>2013-01-20 08:57:57 -0500
committerIlya Dryomov <idryomov@gmail.com>2013-01-20 09:21:17 -0500
commited0fb78fb6aa294a719f8f5654fdff0ec8bc00bc (patch)
tree27675574e1f79775a5ab03f84e27b81266be4e21 /fs/btrfs/volumes.c
parent3972f2603d8570effaf633cea52b12c7c2773c11 (diff)
Btrfs: bring back balance pause/resume logic
Balance pause/resume logic got broken by 5ac00add (went in into 3.8-rc1 as part of dev-replace merge). Offending commit took a stab at making mutually exclusive volume operations (add_dev, rm_dev, resize, balance, replace_dev) not block behind volume_mutex if another such operation is in progress and instead return an error right away. Balancing front-end relied on the blocking behaviour, so the fix is ugly, but short of a complete rework, it's the best we can do. Reported-by: Liu Bo <bo.li.liu@oracle.com> Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
Diffstat (limited to 'fs/btrfs/volumes.c')
-rw-r--r--fs/btrfs/volumes.c10
1 files changed, 7 insertions, 3 deletions
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index 86279c37de64..9c84dbe64f18 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -2959,6 +2959,8 @@ static void __cancel_balance(struct btrfs_fs_info *fs_info)
2959 unset_balance_control(fs_info); 2959 unset_balance_control(fs_info);
2960 ret = del_balance_item(fs_info->tree_root); 2960 ret = del_balance_item(fs_info->tree_root);
2961 BUG_ON(ret); 2961 BUG_ON(ret);
2962
2963 atomic_set(&fs_info->mutually_exclusive_operation_running, 0);
2962} 2964}
2963 2965
2964void update_ioctl_balance_args(struct btrfs_fs_info *fs_info, int lock, 2966void update_ioctl_balance_args(struct btrfs_fs_info *fs_info, int lock,
@@ -3138,8 +3140,10 @@ int btrfs_balance(struct btrfs_balance_control *bctl,
3138out: 3140out:
3139 if (bctl->flags & BTRFS_BALANCE_RESUME) 3141 if (bctl->flags & BTRFS_BALANCE_RESUME)
3140 __cancel_balance(fs_info); 3142 __cancel_balance(fs_info);
3141 else 3143 else {
3142 kfree(bctl); 3144 kfree(bctl);
3145 atomic_set(&fs_info->mutually_exclusive_operation_running, 0);
3146 }
3143 return ret; 3147 return ret;
3144} 3148}
3145 3149
@@ -3156,7 +3160,6 @@ static int balance_kthread(void *data)
3156 ret = btrfs_balance(fs_info->balance_ctl, NULL); 3160 ret = btrfs_balance(fs_info->balance_ctl, NULL);
3157 } 3161 }
3158 3162
3159 atomic_set(&fs_info->mutually_exclusive_operation_running, 0);
3160 mutex_unlock(&fs_info->balance_mutex); 3163 mutex_unlock(&fs_info->balance_mutex);
3161 mutex_unlock(&fs_info->volume_mutex); 3164 mutex_unlock(&fs_info->volume_mutex);
3162 3165
@@ -3179,7 +3182,6 @@ int btrfs_resume_balance_async(struct btrfs_fs_info *fs_info)
3179 return 0; 3182 return 0;
3180 } 3183 }
3181 3184
3182 WARN_ON(atomic_xchg(&fs_info->mutually_exclusive_operation_running, 1));
3183 tsk = kthread_run(balance_kthread, fs_info, "btrfs-balance"); 3185 tsk = kthread_run(balance_kthread, fs_info, "btrfs-balance");
3184 if (IS_ERR(tsk)) 3186 if (IS_ERR(tsk))
3185 return PTR_ERR(tsk); 3187 return PTR_ERR(tsk);
@@ -3233,6 +3235,8 @@ int btrfs_recover_balance(struct btrfs_fs_info *fs_info)
3233 btrfs_balance_sys(leaf, item, &disk_bargs); 3235 btrfs_balance_sys(leaf, item, &disk_bargs);
3234 btrfs_disk_balance_args_to_cpu(&bctl->sys, &disk_bargs); 3236 btrfs_disk_balance_args_to_cpu(&bctl->sys, &disk_bargs);
3235 3237
3238 WARN_ON(atomic_xchg(&fs_info->mutually_exclusive_operation_running, 1));
3239
3236 mutex_lock(&fs_info->volume_mutex); 3240 mutex_lock(&fs_info->volume_mutex);
3237 mutex_lock(&fs_info->balance_mutex); 3241 mutex_lock(&fs_info->balance_mutex);
3238 3242