mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-11 12:28:41 +08:00
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>
This commit is contained in:
parent
5d13a98f3b
commit
a4b6e07d1a
@ -949,6 +949,10 @@ static noinline int balance_level(struct btrfs_trans_handle *trans,
|
||||
BTRFS_NODEPTRS_PER_BLOCK(root) / 4)
|
||||
return 0;
|
||||
|
||||
if (trans->transaction->delayed_refs.flushing &&
|
||||
btrfs_header_nritems(mid) > 2)
|
||||
return 0;
|
||||
|
||||
if (btrfs_header_nritems(mid) < 2)
|
||||
err_on_enospc = 1;
|
||||
|
||||
@ -2159,7 +2163,7 @@ static noinline int split_node(struct btrfs_trans_handle *trans,
|
||||
ret = insert_new_root(trans, root, path, level + 1);
|
||||
if (ret)
|
||||
return ret;
|
||||
} else {
|
||||
} else if (!trans->transaction->delayed_refs.flushing) {
|
||||
ret = push_nodes_for_insert(trans, root, path, level);
|
||||
c = path->nodes[level];
|
||||
if (!ret && btrfs_header_nritems(c) <
|
||||
@ -2848,7 +2852,8 @@ static noinline int split_leaf(struct btrfs_trans_handle *trans,
|
||||
int num_doubles = 0;
|
||||
|
||||
/* first try to make some room by pushing left and right */
|
||||
if (data_size && ins_key->type != BTRFS_DIR_ITEM_KEY) {
|
||||
if (data_size && ins_key->type != BTRFS_DIR_ITEM_KEY &&
|
||||
!trans->transaction->delayed_refs.flushing) {
|
||||
wret = push_leaf_right(trans, root, path, data_size, 0);
|
||||
if (wret < 0)
|
||||
return wret;
|
||||
@ -3786,7 +3791,8 @@ int btrfs_del_items(struct btrfs_trans_handle *trans, struct btrfs_root *root,
|
||||
}
|
||||
|
||||
/* delete the leaf if it is mostly empty */
|
||||
if (used < BTRFS_LEAF_DATA_SIZE(root) / 4) {
|
||||
if (used < BTRFS_LEAF_DATA_SIZE(root) / 4 &&
|
||||
!trans->transaction->delayed_refs.flushing) {
|
||||
/* push_leaf_left fixes the path.
|
||||
* make sure the path still points to our leaf
|
||||
* for possible call to del_ptr below
|
||||
|
Loading…
Reference in New Issue
Block a user