diff options
author | Ilya Dryomov <idryomov@gmail.com> | 2013-01-20 08:57:57 -0500 |
---|---|---|
committer | Ilya Dryomov <idryomov@gmail.com> | 2013-01-20 09:21:17 -0500 |
commit | ed0fb78fb6aa294a719f8f5654fdff0ec8bc00bc (patch) | |
tree | 27675574e1f79775a5ab03f84e27b81266be4e21 /fs/btrfs/volumes.c | |
parent | 3972f2603d8570effaf633cea52b12c7c2773c11 (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.c | 10 |
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 | ||
2964 | void update_ioctl_balance_args(struct btrfs_fs_info *fs_info, int lock, | 2966 | void update_ioctl_balance_args(struct btrfs_fs_info *fs_info, int lock, |
@@ -3138,8 +3140,10 @@ int btrfs_balance(struct btrfs_balance_control *bctl, | |||
3138 | out: | 3140 | out: |
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 | ||