aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/volumes.c
diff options
context:
space:
mode:
authorIlya Dryomov <idryomov@gmail.com>2012-06-22 14:24:12 -0400
committerChris Mason <chris.mason@fusionio.com>2012-07-02 15:39:16 -0400
commit68310a5e42f93c2242ec1836c3b18d531e0065e2 (patch)
treecf457369274a1633ba02170fcb6aab0114906f0a /fs/btrfs/volumes.c
parentc3473e830074ef04f974f2829690942dd8580619 (diff)
Btrfs: restore restriper state on all mounts
Fix a bug that triggered asserts in btrfs_balance() in both normal and resume modes -- restriper state was not properly restored on read-only mounts. This factors out resuming code from btrfs_restore_balance(), which is now also called earlier in the mount sequence to avoid the problem of some early writes getting the old profile. Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
Diffstat (limited to 'fs/btrfs/volumes.c')
-rw-r--r--fs/btrfs/volumes.c39
1 files changed, 19 insertions, 20 deletions
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index 3f292cf693a7..48943d0f861a 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -2867,9 +2867,8 @@ static int balance_kthread(void *data)
2867 return ret; 2867 return ret;
2868} 2868}
2869 2869
2870int btrfs_recover_balance(struct btrfs_root *tree_root) 2870int btrfs_recover_balance(struct btrfs_fs_info *fs_info)
2871{ 2871{
2872 struct task_struct *tsk;
2873 struct btrfs_balance_control *bctl; 2872 struct btrfs_balance_control *bctl;
2874 struct btrfs_balance_item *item; 2873 struct btrfs_balance_item *item;
2875 struct btrfs_disk_balance_args disk_bargs; 2874 struct btrfs_disk_balance_args disk_bargs;
@@ -2882,29 +2881,30 @@ int btrfs_recover_balance(struct btrfs_root *tree_root)
2882 if (!path) 2881 if (!path)
2883 return -ENOMEM; 2882 return -ENOMEM;
2884 2883
2885 bctl = kzalloc(sizeof(*bctl), GFP_NOFS);
2886 if (!bctl) {
2887 ret = -ENOMEM;
2888 goto out;
2889 }
2890
2891 key.objectid = BTRFS_BALANCE_OBJECTID; 2884 key.objectid = BTRFS_BALANCE_OBJECTID;
2892 key.type = BTRFS_BALANCE_ITEM_KEY; 2885 key.type = BTRFS_BALANCE_ITEM_KEY;
2893 key.offset = 0; 2886 key.offset = 0;
2894 2887
2895 ret = btrfs_search_slot(NULL, tree_root, &key, path, 0, 0); 2888 ret = btrfs_search_slot(NULL, fs_info->tree_root, &key, path, 0, 0);
2896 if (ret < 0) 2889 if (ret < 0)
2897 goto out_bctl; 2890 goto out;
2898 if (ret > 0) { /* ret = -ENOENT; */ 2891 if (ret > 0) { /* ret = -ENOENT; */
2899 ret = 0; 2892 ret = 0;
2900 goto out_bctl; 2893 goto out;
2894 }
2895
2896 bctl = kzalloc(sizeof(*bctl), GFP_NOFS);
2897 if (!bctl) {
2898 ret = -ENOMEM;
2899 goto out;
2901 } 2900 }
2902 2901
2903 leaf = path->nodes[0]; 2902 leaf = path->nodes[0];
2904 item = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_balance_item); 2903 item = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_balance_item);
2905 2904
2906 bctl->fs_info = tree_root->fs_info; 2905 bctl->fs_info = fs_info;
2907 bctl->flags = btrfs_balance_flags(leaf, item) | BTRFS_BALANCE_RESUME; 2906 bctl->flags = btrfs_balance_flags(leaf, item);
2907 bctl->flags |= BTRFS_BALANCE_RESUME;
2908 2908
2909 btrfs_balance_data(leaf, item, &disk_bargs); 2909 btrfs_balance_data(leaf, item, &disk_bargs);
2910 btrfs_disk_balance_args_to_cpu(&bctl->data, &disk_bargs); 2910 btrfs_disk_balance_args_to_cpu(&bctl->data, &disk_bargs);
@@ -2913,14 +2913,13 @@ int btrfs_recover_balance(struct btrfs_root *tree_root)
2913 btrfs_balance_sys(leaf, item, &disk_bargs); 2913 btrfs_balance_sys(leaf, item, &disk_bargs);
2914 btrfs_disk_balance_args_to_cpu(&bctl->sys, &disk_bargs); 2914 btrfs_disk_balance_args_to_cpu(&bctl->sys, &disk_bargs);
2915 2915
2916 tsk = kthread_run(balance_kthread, bctl, "btrfs-balance"); 2916 mutex_lock(&fs_info->volume_mutex);
2917 if (IS_ERR(tsk)) 2917 mutex_lock(&fs_info->balance_mutex);
2918 ret = PTR_ERR(tsk);
2919 else
2920 goto out;
2921 2918
2922out_bctl: 2919 set_balance_control(bctl);
2923 kfree(bctl); 2920
2921 mutex_unlock(&fs_info->balance_mutex);
2922 mutex_unlock(&fs_info->volume_mutex);
2924out: 2923out:
2925 btrfs_free_path(path); 2924 btrfs_free_path(path);
2926 return ret; 2925 return ret;