]> git.hungrycats.org Git - linux/commitdiff
Btrfs: prepare block group cache before writing
authorJosef Bacik <jbacik@fb.com>
Mon, 2 Mar 2015 21:37:31 +0000 (16:37 -0500)
committerZygo Blaxell <zblaxell@serenity.furryterror.org>
Fri, 27 Mar 2015 01:22:10 +0000 (21:22 -0400)
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>
(cherry picked from commit aa4661f6a7aee90423d1c77ee4d492e7b1a99883)

fs/btrfs/ctree.h
fs/btrfs/extent-tree.c
fs/btrfs/transaction.c

index 303fcdc7320fee51c1141e177919c9634a239a42..e5431e308c0b0d31c27d5010a9ceb3c9cf81addd 100644 (file)
@@ -3320,6 +3320,8 @@ int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans,
 
 int btrfs_write_dirty_block_groups(struct btrfs_trans_handle *trans,
                                    struct btrfs_root *root);
+int btrfs_setup_space_cache(struct btrfs_trans_handle *trans,
+                           struct btrfs_root *root);
 int btrfs_extent_readonly(struct btrfs_root *root, u64 bytenr);
 int btrfs_free_block_groups(struct btrfs_fs_info *info);
 int btrfs_read_block_groups(struct btrfs_root *root);
index 234bf208c605d8bbf39b36b7c8b453b352a4f111..e432bc09843b2145329072b1044da9c3743794e0 100644 (file)
@@ -3311,6 +3311,32 @@ out:
        return ret;
 }
 
+int btrfs_setup_space_cache(struct btrfs_trans_handle *trans,
+                           struct btrfs_root *root)
+{
+       struct btrfs_block_group_cache *cache, *tmp;
+       struct btrfs_transaction *cur_trans = trans->transaction;
+       struct btrfs_path *path;
+
+       if (list_empty(&cur_trans->dirty_bgs) ||
+           !btrfs_test_opt(root, SPACE_CACHE))
+               return 0;
+
+       path = btrfs_alloc_path();
+       if (!path)
+               return -ENOMEM;
+
+       /* Could add new block groups, use _safe just in case */
+       list_for_each_entry_safe(cache, tmp, &cur_trans->dirty_bgs,
+                                dirty_list) {
+               if (cache->disk_cache_state == BTRFS_DC_CLEAR)
+                       cache_save_setup(cache, trans, path);
+       }
+
+       btrfs_free_path(path);
+       return 0;
+}
+
 int btrfs_write_dirty_block_groups(struct btrfs_trans_handle *trans,
                                   struct btrfs_root *root)
 {
index 74e3a642175baa5935a152f16417e6d321392baf..5f5617898c8e5af1382dbce1df5540ae7d4fabad 100644 (file)
@@ -960,7 +960,6 @@ static int update_cowonly_root(struct btrfs_trans_handle *trans,
        struct btrfs_root *tree_root = root->fs_info->tree_root;
 
        old_root_used = btrfs_root_used(&root->root_item);
-       btrfs_write_dirty_block_groups(trans, root);
 
        while (1) {
                old_root_bytenr = btrfs_root_bytenr(&root->root_item);
@@ -1024,6 +1023,10 @@ static noinline int commit_cowonly_roots(struct btrfs_trans_handle *trans,
        if (ret)
                return ret;
 
+       ret = btrfs_setup_space_cache(trans, root);
+       if (ret)
+               return ret;
+
        /* run_qgroups might have added some more refs */
        ret = btrfs_run_delayed_refs(trans, root, (unsigned long)-1);
        if (ret)