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

Commit 21633fc6 authored by Qu Wenruo's avatar Qu Wenruo Committed by Chris Mason
Browse files

btrfs: backref: Add special time_seq == (u64)-1 case for


btrfs_find_all_roots().

Allow btrfs_find_all_roots() to skip all delayed_ref_head lock and tree
lock to do tree search.

This is important for later qgroup implement which will call
find_all_roots() after fs trees are committed.

Signed-off-by: default avatarQu Wenruo <quwenruo@cn.fujitsu.com>
Signed-off-by: default avatarChris Mason <clm@fb.com>
parent 3b7d00f9
Loading
Loading
Loading
Loading
+29 −6
Original line number Diff line number Diff line
@@ -250,8 +250,12 @@ static int add_all_parents(struct btrfs_root *root, struct btrfs_path *path,
	 * the first item to check. But sometimes, we may enter it with
	 * slot==nritems. In that case, go to the next leaf before we continue.
	 */
	if (path->slots[0] >= btrfs_header_nritems(path->nodes[0]))
	if (path->slots[0] >= btrfs_header_nritems(path->nodes[0])) {
		if (time_seq == (u64)-1)
			ret = btrfs_next_leaf(root, path);
		else
			ret = btrfs_next_old_leaf(root, path, time_seq);
	}

	while (!ret && count < total_refs) {
		eb = path->nodes[0];
@@ -291,6 +295,9 @@ static int add_all_parents(struct btrfs_root *root, struct btrfs_path *path,
			eie = NULL;
		}
next:
		if (time_seq == (u64)-1)
			ret = btrfs_next_item(root, path);
		else
			ret = btrfs_next_old_item(root, path, time_seq);
	}

@@ -334,6 +341,8 @@ static int __resolve_indirect_ref(struct btrfs_fs_info *fs_info,

	if (path->search_commit_root)
		root_level = btrfs_header_level(root->commit_root);
	else if (time_seq == (u64)-1)
		root_level = btrfs_header_level(root->node);
	else
		root_level = btrfs_old_root_level(root, time_seq);

@@ -343,7 +352,12 @@ static int __resolve_indirect_ref(struct btrfs_fs_info *fs_info,
	}

	path->lowest_level = level;
	ret = btrfs_search_old_slot(root, &ref->key_for_search, path, time_seq);
	if (time_seq == (u64)-1)
		ret = btrfs_search_slot(NULL, root, &ref->key_for_search, path,
					0, 0);
	else
		ret = btrfs_search_old_slot(root, &ref->key_for_search, path,
					    time_seq);

	/* root node has been locked, we can release @subvol_srcu safely here */
	srcu_read_unlock(&fs_info->subvol_srcu, index);
@@ -879,6 +893,11 @@ static int __add_keyed_refs(struct btrfs_fs_info *fs_info,
 *
 * NOTE: This can return values > 0
 *
 * If time_seq is set to (u64)-1, it will not search delayed_refs, and behave
 * much like trans == NULL case, the difference only lies in it will not
 * commit root.
 * The special case is for qgroup to search roots in commit_transaction().
 *
 * FIXME some caching might speed things up
 */
static int find_parent_nodes(struct btrfs_trans_handle *trans,
@@ -917,6 +936,9 @@ static int find_parent_nodes(struct btrfs_trans_handle *trans,
		path->skip_locking = 1;
	}

	if (time_seq == (u64)-1)
		path->skip_locking = 1;

	/*
	 * grab both a lock on the path and a lock on the delayed ref head.
	 * We need both to get a consistent picture of how the refs look
@@ -931,9 +953,10 @@ static int find_parent_nodes(struct btrfs_trans_handle *trans,
	BUG_ON(ret == 0);

#ifdef CONFIG_BTRFS_FS_RUN_SANITY_TESTS
	if (trans && likely(trans->type != __TRANS_DUMMY)) {
	if (trans && likely(trans->type != __TRANS_DUMMY) &&
	    time_seq != (u64)-1) {
#else
	if (trans) {
	if (trans && time_seq != (u64)-1) {
#endif
		/*
		 * look if there are updates for this ref queued and lock the