Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 203bf287 authored by Chris Mason's avatar Chris Mason
Browse files

Btrfs: run chunk allocations while we do delayed refs



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: default avatarChris Mason <chris.mason@oracle.com>
parent c1111b1f
Loading
Loading
Loading
Loading
+10 −4
Original line number Original line Diff line number Diff line
@@ -2267,9 +2267,7 @@ static noinline int run_clustered_refs(struct btrfs_trans_handle *trans,
				BUG_ON(ret);
				BUG_ON(ret);
				kfree(extent_op);
				kfree(extent_op);


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


			list_del_init(&locked_ref->cluster);
			list_del_init(&locked_ref->cluster);
@@ -2289,7 +2287,11 @@ static noinline int run_clustered_refs(struct btrfs_trans_handle *trans,
		btrfs_put_delayed_ref(ref);
		btrfs_put_delayed_ref(ref);
		kfree(extent_op);
		kfree(extent_op);
		count++;
		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();
		cond_resched();
		spin_lock(&delayed_refs->lock);
		spin_lock(&delayed_refs->lock);
	}
	}
@@ -2317,6 +2319,10 @@ int btrfs_run_delayed_refs(struct btrfs_trans_handle *trans,
	if (root == root->fs_info->extent_root)
	if (root == root->fs_info->extent_root)
		root = root->fs_info->tree_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;
	delayed_refs = &trans->transaction->delayed_refs;
	INIT_LIST_HEAD(&cluster);
	INIT_LIST_HEAD(&cluster);
again:
again:
+1 −8
Original line number Original line Diff line number Diff line
@@ -467,19 +467,12 @@ static int __btrfs_end_transaction(struct btrfs_trans_handle *trans,


	btrfs_trans_release_metadata(trans, root);
	btrfs_trans_release_metadata(trans, root);
	trans->block_rsv = NULL;
	trans->block_rsv = NULL;
	while (count < 4) {
	while (count < 2) {
		unsigned long cur = trans->delayed_ref_updates;
		unsigned long cur = trans->delayed_ref_updates;
		trans->delayed_ref_updates = 0;
		trans->delayed_ref_updates = 0;
		if (cur &&
		if (cur &&
		    trans->transaction->delayed_refs.num_heads_ready > 64) {
		    trans->transaction->delayed_refs.num_heads_ready > 64) {
			trans->delayed_ref_updates = 0;
			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);
			btrfs_run_delayed_refs(trans, root, cur);
		} else {
		} else {
			break;
			break;