aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs
diff options
context:
space:
mode:
authorIlya Dryomov <idryomov@gmail.com>2012-06-22 14:24:13 -0400
committerChris Mason <chris.mason@fusionio.com>2012-07-02 15:39:17 -0400
commit2b6ba629b5aac51e7099efbb43e2b403213aa7fb (patch)
tree0a36f4adb14a57fdf4ee1dafa957927b6a6f9203 /fs/btrfs
parent68310a5e42f93c2242ec1836c3b18d531e0065e2 (diff)
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: Ilya Dryomov <idryomov@gmail.com>
Diffstat (limited to 'fs/btrfs')
-rw-r--r--fs/btrfs/disk-io.c24
-rw-r--r--fs/btrfs/super.c4
-rw-r--r--fs/btrfs/volumes.c36
-rw-r--r--fs/btrfs/volumes.h1
4 files changed, 47 insertions, 18 deletions
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 3a7961ba161e..8cc47103a32e 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -2490,17 +2490,23 @@ retry_root_backup:
2490 goto fail_trans_kthread; 2490 goto fail_trans_kthread;
2491 } 2491 }
2492 2492
2493 if (!(sb->s_flags & MS_RDONLY)) { 2493 if (sb->s_flags & MS_RDONLY)
2494 down_read(&fs_info->cleanup_work_sem); 2494 return 0;
2495 err = btrfs_orphan_cleanup(fs_info->fs_root); 2495
2496 if (!err) 2496 down_read(&fs_info->cleanup_work_sem);
2497 err = btrfs_orphan_cleanup(fs_info->tree_root); 2497 if ((ret = btrfs_orphan_cleanup(fs_info->fs_root)) ||
2498 (ret = btrfs_orphan_cleanup(fs_info->tree_root))) {
2498 up_read(&fs_info->cleanup_work_sem); 2499 up_read(&fs_info->cleanup_work_sem);
2500 close_ctree(tree_root);
2501 return ret;
2502 }
2503 up_read(&fs_info->cleanup_work_sem);
2499 2504
2500 if (err) { 2505 ret = btrfs_resume_balance_async(fs_info);
2501 close_ctree(tree_root); 2506 if (ret) {
2502 return err; 2507 printk(KERN_WARNING "btrfs: failed to resume balance\n");
2503 } 2508 close_ctree(tree_root);
2509 return ret;
2504 } 2510 }
2505 2511
2506 return 0; 2512 return 0;
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
index 0eb9a4da069e..e23991574fdf 100644
--- a/fs/btrfs/super.c
+++ b/fs/btrfs/super.c
@@ -1187,6 +1187,10 @@ static int btrfs_remount(struct super_block *sb, int *flags, char *data)
1187 if (ret) 1187 if (ret)
1188 goto restore; 1188 goto restore;
1189 1189
1190 ret = btrfs_resume_balance_async(fs_info);
1191 if (ret)
1192 goto restore;
1193
1190 sb->s_flags &= ~MS_RDONLY; 1194 sb->s_flags &= ~MS_RDONLY;
1191 } 1195 }
1192 1196
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index 48943d0f861a..ecaad40e7ef4 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -2845,28 +2845,46 @@ out:
2845 2845
2846static int balance_kthread(void *data) 2846static int balance_kthread(void *data)
2847{ 2847{
2848 struct btrfs_balance_control *bctl = 2848 struct btrfs_fs_info *fs_info = data;
2849 (struct btrfs_balance_control *)data;
2850 struct btrfs_fs_info *fs_info = bctl->fs_info;
2851 int ret = 0; 2849 int ret = 0;
2852 2850
2853 mutex_lock(&fs_info->volume_mutex); 2851 mutex_lock(&fs_info->volume_mutex);
2854 mutex_lock(&fs_info->balance_mutex); 2852 mutex_lock(&fs_info->balance_mutex);
2855 2853
2856 set_balance_control(bctl); 2854 if (fs_info->balance_ctl) {
2857
2858 if (btrfs_test_opt(fs_info->tree_root, SKIP_BALANCE)) {
2859 printk(KERN_INFO "btrfs: force skipping balance\n");
2860 } else {
2861 printk(KERN_INFO "btrfs: continuing balance\n"); 2855 printk(KERN_INFO "btrfs: continuing balance\n");
2862 ret = btrfs_balance(bctl, NULL); 2856 ret = btrfs_balance(fs_info->balance_ctl, NULL);
2863 } 2857 }
2864 2858
2865 mutex_unlock(&fs_info->balance_mutex); 2859 mutex_unlock(&fs_info->balance_mutex);
2866 mutex_unlock(&fs_info->volume_mutex); 2860 mutex_unlock(&fs_info->volume_mutex);
2861
2867 return ret; 2862 return ret;
2868} 2863}
2869 2864
2865int btrfs_resume_balance_async(struct btrfs_fs_info *fs_info)
2866{
2867 struct task_struct *tsk;
2868
2869 spin_lock(&fs_info->balance_lock);
2870 if (!fs_info->balance_ctl) {
2871 spin_unlock(&fs_info->balance_lock);
2872 return 0;
2873 }
2874 spin_unlock(&fs_info->balance_lock);
2875
2876 if (btrfs_test_opt(fs_info->tree_root, SKIP_BALANCE)) {
2877 printk(KERN_INFO "btrfs: force skipping balance\n");
2878 return 0;
2879 }
2880
2881 tsk = kthread_run(balance_kthread, fs_info, "btrfs-balance");
2882 if (IS_ERR(tsk))
2883 return PTR_ERR(tsk);
2884
2885 return 0;
2886}
2887
2870int btrfs_recover_balance(struct btrfs_fs_info *fs_info) 2888int btrfs_recover_balance(struct btrfs_fs_info *fs_info)
2871{ 2889{
2872 struct btrfs_balance_control *bctl; 2890 struct btrfs_balance_control *bctl;
diff --git a/fs/btrfs/volumes.h b/fs/btrfs/volumes.h
index e1b1a649fc5a..95f6637614db 100644
--- a/fs/btrfs/volumes.h
+++ b/fs/btrfs/volumes.h
@@ -281,6 +281,7 @@ int btrfs_shrink_device(struct btrfs_device *device, u64 new_size);
281int btrfs_init_new_device(struct btrfs_root *root, char *path); 281int btrfs_init_new_device(struct btrfs_root *root, char *path);
282int btrfs_balance(struct btrfs_balance_control *bctl, 282int btrfs_balance(struct btrfs_balance_control *bctl,
283 struct btrfs_ioctl_balance_args *bargs); 283 struct btrfs_ioctl_balance_args *bargs);
284int btrfs_resume_balance_async(struct btrfs_fs_info *fs_info);
284int btrfs_recover_balance(struct btrfs_fs_info *fs_info); 285int btrfs_recover_balance(struct btrfs_fs_info *fs_info);
285int btrfs_pause_balance(struct btrfs_fs_info *fs_info); 286int btrfs_pause_balance(struct btrfs_fs_info *fs_info);
286int btrfs_cancel_balance(struct btrfs_fs_info *fs_info); 287int btrfs_cancel_balance(struct btrfs_fs_info *fs_info);