aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosef Bacik <jbacik@fb.com>2015-03-02 16:37:31 -0500
committerJosef Bacik <jbacik@fb.com>2015-03-17 10:56:55 -0400
commitdcdf7f6ddba006f3482ebee73dfa6b75aec5f07b (patch)
treea91a5105b64f8d0c6ea5f653ea0000b295050b2a
parentea526d18990018f224e5734748975bea1824545f (diff)
Btrfs: prepare block group cache before writing
Writing the block group cache will modify the extent tree quite a bit because it truncates the old space cache and pre-allocates new stuff. To try and cut down on the churn lets do the setup dance first, then later on hopefully we can avoid looping with newly dirtied roots. Thanks, Signed-off-by: Josef Bacik <jbacik@fb.com>
-rw-r--r--fs/btrfs/ctree.h2
-rw-r--r--fs/btrfs/extent-tree.c26
-rw-r--r--fs/btrfs/transaction.c5
3 files changed, 32 insertions, 1 deletions
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index b3dd55f52f71..a0c90a324f53 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -3386,6 +3386,8 @@ int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans,
3386 3386
3387int btrfs_write_dirty_block_groups(struct btrfs_trans_handle *trans, 3387int btrfs_write_dirty_block_groups(struct btrfs_trans_handle *trans,
3388 struct btrfs_root *root); 3388 struct btrfs_root *root);
3389int btrfs_setup_space_cache(struct btrfs_trans_handle *trans,
3390 struct btrfs_root *root);
3389int btrfs_extent_readonly(struct btrfs_root *root, u64 bytenr); 3391int btrfs_extent_readonly(struct btrfs_root *root, u64 bytenr);
3390int btrfs_free_block_groups(struct btrfs_fs_info *info); 3392int btrfs_free_block_groups(struct btrfs_fs_info *info);
3391int btrfs_read_block_groups(struct btrfs_root *root); 3393int btrfs_read_block_groups(struct btrfs_root *root);
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 96c613bfe157..3ac3fefb1625 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -3325,6 +3325,32 @@ out:
3325 return ret; 3325 return ret;
3326} 3326}
3327 3327
3328int btrfs_setup_space_cache(struct btrfs_trans_handle *trans,
3329 struct btrfs_root *root)
3330{
3331 struct btrfs_block_group_cache *cache, *tmp;
3332 struct btrfs_transaction *cur_trans = trans->transaction;
3333 struct btrfs_path *path;
3334
3335 if (list_empty(&cur_trans->dirty_bgs) ||
3336 !btrfs_test_opt(root, SPACE_CACHE))
3337 return 0;
3338
3339 path = btrfs_alloc_path();
3340 if (!path)
3341 return -ENOMEM;
3342
3343 /* Could add new block groups, use _safe just in case */
3344 list_for_each_entry_safe(cache, tmp, &cur_trans->dirty_bgs,
3345 dirty_list) {
3346 if (cache->disk_cache_state == BTRFS_DC_CLEAR)
3347 cache_save_setup(cache, trans, path);
3348 }
3349
3350 btrfs_free_path(path);
3351 return 0;
3352}
3353
3328int btrfs_write_dirty_block_groups(struct btrfs_trans_handle *trans, 3354int btrfs_write_dirty_block_groups(struct btrfs_trans_handle *trans,
3329 struct btrfs_root *root) 3355 struct btrfs_root *root)
3330{ 3356{
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
index 2fe3ef5e9de3..932709af5163 100644
--- a/fs/btrfs/transaction.c
+++ b/fs/btrfs/transaction.c
@@ -1025,7 +1025,6 @@ static int update_cowonly_root(struct btrfs_trans_handle *trans,
1025 struct btrfs_root *tree_root = root->fs_info->tree_root; 1025 struct btrfs_root *tree_root = root->fs_info->tree_root;
1026 1026
1027 old_root_used = btrfs_root_used(&root->root_item); 1027 old_root_used = btrfs_root_used(&root->root_item);
1028 btrfs_write_dirty_block_groups(trans, root);
1029 1028
1030 while (1) { 1029 while (1) {
1031 old_root_bytenr = btrfs_root_bytenr(&root->root_item); 1030 old_root_bytenr = btrfs_root_bytenr(&root->root_item);
@@ -1085,6 +1084,10 @@ static noinline int commit_cowonly_roots(struct btrfs_trans_handle *trans,
1085 if (ret) 1084 if (ret)
1086 return ret; 1085 return ret;
1087 1086
1087 ret = btrfs_setup_space_cache(trans, root);
1088 if (ret)
1089 return ret;
1090
1088 /* run_qgroups might have added some more refs */ 1091 /* run_qgroups might have added some more refs */
1089 ret = btrfs_run_delayed_refs(trans, root, (unsigned long)-1); 1092 ret = btrfs_run_delayed_refs(trans, root, (unsigned long)-1);
1090 if (ret) 1093 if (ret)