Commit 2b6ba629 authored by Ilya Dryomov's avatar Ilya Dryomov Committed by Chris Mason

Btrfs: resume balance on rw (re)mounts properly

This introduces btrfs_resume_balance_async(), which, given that
restriper state was recovered earlier by btrfs_recover_balance(),
resumes balance in btrfs-balance kthread.
Signed-off-by: default avatarIlya Dryomov <idryomov@gmail.com>
parent 68310a5e
...@@ -2490,17 +2490,23 @@ int open_ctree(struct super_block *sb, ...@@ -2490,17 +2490,23 @@ int open_ctree(struct super_block *sb,
goto fail_trans_kthread; goto fail_trans_kthread;
} }
if (!(sb->s_flags & MS_RDONLY)) { if (sb->s_flags & MS_RDONLY)
return 0;
down_read(&fs_info->cleanup_work_sem); down_read(&fs_info->cleanup_work_sem);
err = btrfs_orphan_cleanup(fs_info->fs_root); if ((ret = btrfs_orphan_cleanup(fs_info->fs_root)) ||
if (!err) (ret = btrfs_orphan_cleanup(fs_info->tree_root))) {
err = btrfs_orphan_cleanup(fs_info->tree_root);
up_read(&fs_info->cleanup_work_sem); up_read(&fs_info->cleanup_work_sem);
if (err) {
close_ctree(tree_root); close_ctree(tree_root);
return err; return ret;
} }
up_read(&fs_info->cleanup_work_sem);
ret = btrfs_resume_balance_async(fs_info);
if (ret) {
printk(KERN_WARNING "btrfs: failed to resume balance\n");
close_ctree(tree_root);
return ret;
} }
return 0; return 0;
......
...@@ -1187,6 +1187,10 @@ static int btrfs_remount(struct super_block *sb, int *flags, char *data) ...@@ -1187,6 +1187,10 @@ static int btrfs_remount(struct super_block *sb, int *flags, char *data)
if (ret) if (ret)
goto restore; goto restore;
ret = btrfs_resume_balance_async(fs_info);
if (ret)
goto restore;
sb->s_flags &= ~MS_RDONLY; sb->s_flags &= ~MS_RDONLY;
} }
......
...@@ -2845,28 +2845,46 @@ int btrfs_balance(struct btrfs_balance_control *bctl, ...@@ -2845,28 +2845,46 @@ int btrfs_balance(struct btrfs_balance_control *bctl,
static int balance_kthread(void *data) static int balance_kthread(void *data)
{ {
struct btrfs_balance_control *bctl = struct btrfs_fs_info *fs_info = data;
(struct btrfs_balance_control *)data;
struct btrfs_fs_info *fs_info = bctl->fs_info;
int ret = 0; int ret = 0;
mutex_lock(&fs_info->volume_mutex); mutex_lock(&fs_info->volume_mutex);
mutex_lock(&fs_info->balance_mutex); mutex_lock(&fs_info->balance_mutex);
set_balance_control(bctl); if (fs_info->balance_ctl) {
if (btrfs_test_opt(fs_info->tree_root, SKIP_BALANCE)) {
printk(KERN_INFO "btrfs: force skipping balance\n");
} else {
printk(KERN_INFO "btrfs: continuing balance\n"); printk(KERN_INFO "btrfs: continuing balance\n");
ret = btrfs_balance(bctl, NULL); ret = btrfs_balance(fs_info->balance_ctl, NULL);
} }
mutex_unlock(&fs_info->balance_mutex); mutex_unlock(&fs_info->balance_mutex);
mutex_unlock(&fs_info->volume_mutex); mutex_unlock(&fs_info->volume_mutex);
return ret; return ret;
} }
int btrfs_resume_balance_async(struct btrfs_fs_info *fs_info)
{
struct task_struct *tsk;
spin_lock(&fs_info->balance_lock);
if (!fs_info->balance_ctl) {
spin_unlock(&fs_info->balance_lock);
return 0;
}
spin_unlock(&fs_info->balance_lock);
if (btrfs_test_opt(fs_info->tree_root, SKIP_BALANCE)) {
printk(KERN_INFO "btrfs: force skipping balance\n");
return 0;
}
tsk = kthread_run(balance_kthread, fs_info, "btrfs-balance");
if (IS_ERR(tsk))
return PTR_ERR(tsk);
return 0;
}
int btrfs_recover_balance(struct btrfs_fs_info *fs_info) int btrfs_recover_balance(struct btrfs_fs_info *fs_info)
{ {
struct btrfs_balance_control *bctl; struct btrfs_balance_control *bctl;
......
...@@ -281,6 +281,7 @@ int btrfs_shrink_device(struct btrfs_device *device, u64 new_size); ...@@ -281,6 +281,7 @@ int btrfs_shrink_device(struct btrfs_device *device, u64 new_size);
int btrfs_init_new_device(struct btrfs_root *root, char *path); int btrfs_init_new_device(struct btrfs_root *root, char *path);
int btrfs_balance(struct btrfs_balance_control *bctl, int btrfs_balance(struct btrfs_balance_control *bctl,
struct btrfs_ioctl_balance_args *bargs); struct btrfs_ioctl_balance_args *bargs);
int btrfs_resume_balance_async(struct btrfs_fs_info *fs_info);
int btrfs_recover_balance(struct btrfs_fs_info *fs_info); int btrfs_recover_balance(struct btrfs_fs_info *fs_info);
int btrfs_pause_balance(struct btrfs_fs_info *fs_info); int btrfs_pause_balance(struct btrfs_fs_info *fs_info);
int btrfs_cancel_balance(struct btrfs_fs_info *fs_info); int btrfs_cancel_balance(struct btrfs_fs_info *fs_info);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment