Skip to content

Commit

Permalink
Btrfs: run chunk allocations while we do delayed refs
Browse files Browse the repository at this point in the history
Btrfs tries to batch extent allocation tree changes to improve performance
and reduce metadata trashing.  But it doesn't allocate new metadata chunks
while it is doing allocations for the extent allocation tree.

This commit changes the delayed refence code to do chunk allocations if we're
getting low on room.  It prevents crashes and improves performance.

Signed-off-by: Chris Mason <chris.mason@oracle.com>
  • Loading branch information
Chris Mason committed Jan 6, 2012
1 parent c1111b1 commit 203bf28
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 12 deletions.
14 changes: 10 additions & 4 deletions fs/btrfs/extent-tree.c
Original file line number Diff line number Diff line change
Expand Up @@ -2267,9 +2267,7 @@ static noinline int run_clustered_refs(struct btrfs_trans_handle *trans,
BUG_ON(ret);
kfree(extent_op);

cond_resched();
spin_lock(&delayed_refs->lock);
continue;
goto next;
}

list_del_init(&locked_ref->cluster);
Expand All @@ -2289,7 +2287,11 @@ static noinline int run_clustered_refs(struct btrfs_trans_handle *trans,
btrfs_put_delayed_ref(ref);
kfree(extent_op);
count++;

next:
do_chunk_alloc(trans, root->fs_info->extent_root,
2 * 1024 * 1024,
btrfs_get_alloc_profile(root, 0),
CHUNK_ALLOC_NO_FORCE);
cond_resched();
spin_lock(&delayed_refs->lock);
}
Expand Down Expand Up @@ -2317,6 +2319,10 @@ int btrfs_run_delayed_refs(struct btrfs_trans_handle *trans,
if (root == root->fs_info->extent_root)
root = root->fs_info->tree_root;

do_chunk_alloc(trans, root->fs_info->extent_root,
2 * 1024 * 1024, btrfs_get_alloc_profile(root, 0),
CHUNK_ALLOC_NO_FORCE);

delayed_refs = &trans->transaction->delayed_refs;
INIT_LIST_HEAD(&cluster);
again:
Expand Down
9 changes: 1 addition & 8 deletions fs/btrfs/transaction.c
Original file line number Diff line number Diff line change
Expand Up @@ -467,19 +467,12 @@ static int __btrfs_end_transaction(struct btrfs_trans_handle *trans,

btrfs_trans_release_metadata(trans, root);
trans->block_rsv = NULL;
while (count < 4) {
while (count < 2) {
unsigned long cur = trans->delayed_ref_updates;
trans->delayed_ref_updates = 0;
if (cur &&
trans->transaction->delayed_refs.num_heads_ready > 64) {
trans->delayed_ref_updates = 0;

/*
* do a full flush if the transaction is trying
* to close
*/
if (trans->transaction->delayed_refs.flushing)
cur = 0;
btrfs_run_delayed_refs(trans, root, cur);
} else {
break;
Expand Down

0 comments on commit 203bf28

Please sign in to comment.