aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2009-03-16 10:59:57 -0400
committerChris Mason <chris.mason@oracle.com>2009-03-24 16:14:51 -0400
commita4b6e07d1a8a9b907e82b9acbf51a026fbb9301c (patch)
treefb93f38d01812a6f8af8dbefd4f769460afc997e /fs/btrfs
parent5d13a98f3bf5afc1113f7db184c627a44659bc29 (diff)
Btrfs: limit balancing work while flushing delayed refs
The delayed reference mechanism is responsible for all updates to the extent allocation trees, including those updates created while processing the delayed references. This commit tries to limit the amount of work that gets created during the final run of delayed refs before a commit. It avoids cowing new blocks unless it is required to finish the commit, and so it avoids new allocations that were not really required. The goal is to avoid infinite loops where we are always making more work on the final run of delayed refs. Over the long term we'll make a special log for the last delayed ref updates as well. Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs')
-rw-r--r--fs/btrfs/ctree.c12
1 files changed, 9 insertions, 3 deletions
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c
index 8686a3d2ab3a..dbb724124633 100644
--- a/fs/btrfs/ctree.c
+++ b/fs/btrfs/ctree.c
@@ -949,6 +949,10 @@ static noinline int balance_level(struct btrfs_trans_handle *trans,
949 BTRFS_NODEPTRS_PER_BLOCK(root) / 4) 949 BTRFS_NODEPTRS_PER_BLOCK(root) / 4)
950 return 0; 950 return 0;
951 951
952 if (trans->transaction->delayed_refs.flushing &&
953 btrfs_header_nritems(mid) > 2)
954 return 0;
955
952 if (btrfs_header_nritems(mid) < 2) 956 if (btrfs_header_nritems(mid) < 2)
953 err_on_enospc = 1; 957 err_on_enospc = 1;
954 958
@@ -2159,7 +2163,7 @@ static noinline int split_node(struct btrfs_trans_handle *trans,
2159 ret = insert_new_root(trans, root, path, level + 1); 2163 ret = insert_new_root(trans, root, path, level + 1);
2160 if (ret) 2164 if (ret)
2161 return ret; 2165 return ret;
2162 } else { 2166 } else if (!trans->transaction->delayed_refs.flushing) {
2163 ret = push_nodes_for_insert(trans, root, path, level); 2167 ret = push_nodes_for_insert(trans, root, path, level);
2164 c = path->nodes[level]; 2168 c = path->nodes[level];
2165 if (!ret && btrfs_header_nritems(c) < 2169 if (!ret && btrfs_header_nritems(c) <
@@ -2848,7 +2852,8 @@ static noinline int split_leaf(struct btrfs_trans_handle *trans,
2848 int num_doubles = 0; 2852 int num_doubles = 0;
2849 2853
2850 /* first try to make some room by pushing left and right */ 2854 /* first try to make some room by pushing left and right */
2851 if (data_size && ins_key->type != BTRFS_DIR_ITEM_KEY) { 2855 if (data_size && ins_key->type != BTRFS_DIR_ITEM_KEY &&
2856 !trans->transaction->delayed_refs.flushing) {
2852 wret = push_leaf_right(trans, root, path, data_size, 0); 2857 wret = push_leaf_right(trans, root, path, data_size, 0);
2853 if (wret < 0) 2858 if (wret < 0)
2854 return wret; 2859 return wret;
@@ -3786,7 +3791,8 @@ int btrfs_del_items(struct btrfs_trans_handle *trans, struct btrfs_root *root,
3786 } 3791 }
3787 3792
3788 /* delete the leaf if it is mostly empty */ 3793 /* delete the leaf if it is mostly empty */
3789 if (used < BTRFS_LEAF_DATA_SIZE(root) / 4) { 3794 if (used < BTRFS_LEAF_DATA_SIZE(root) / 4 &&
3795 !trans->transaction->delayed_refs.flushing) {
3790 /* push_leaf_left fixes the path. 3796 /* push_leaf_left fixes the path.
3791 * make sure the path still points to our leaf 3797 * make sure the path still points to our leaf
3792 * for possible call to del_ptr below 3798 * for possible call to del_ptr below