diff options
author | Ilya Dryomov <idryomov@gmail.com> | 2012-06-22 14:24:12 -0400 |
---|---|---|
committer | Chris Mason <chris.mason@fusionio.com> | 2012-07-02 15:39:16 -0400 |
commit | 68310a5e42f93c2242ec1836c3b18d531e0065e2 (patch) | |
tree | cf457369274a1633ba02170fcb6aab0114906f0a /fs/btrfs/volumes.c | |
parent | c3473e830074ef04f974f2829690942dd8580619 (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.c | 39 |
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 | ||
2870 | int btrfs_recover_balance(struct btrfs_root *tree_root) | 2870 | int 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 | ||
2922 | out_bctl: | 2919 | set_balance_control(bctl); |
2923 | kfree(bctl); | 2920 | |
2921 | mutex_unlock(&fs_info->balance_mutex); | ||
2922 | mutex_unlock(&fs_info->volume_mutex); | ||
2924 | out: | 2923 | out: |
2925 | btrfs_free_path(path); | 2924 | btrfs_free_path(path); |
2926 | return ret; | 2925 | return ret; |