mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-01-10 07:10:27 +00:00
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: Qu Wenruo <quwenruo@cn.fujitsu.com> Signed-off-by: Chris Mason <clm@fb.com>
This commit is contained in:
parent
3b7d00f99c
commit
21633fc603
@ -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
|
* 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.
|
* 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])) {
|
||||||
ret = btrfs_next_old_leaf(root, path, time_seq);
|
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) {
|
while (!ret && count < total_refs) {
|
||||||
eb = path->nodes[0];
|
eb = path->nodes[0];
|
||||||
@ -291,7 +295,10 @@ static int add_all_parents(struct btrfs_root *root, struct btrfs_path *path,
|
|||||||
eie = NULL;
|
eie = NULL;
|
||||||
}
|
}
|
||||||
next:
|
next:
|
||||||
ret = btrfs_next_old_item(root, path, time_seq);
|
if (time_seq == (u64)-1)
|
||||||
|
ret = btrfs_next_item(root, path);
|
||||||
|
else
|
||||||
|
ret = btrfs_next_old_item(root, path, time_seq);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret > 0)
|
if (ret > 0)
|
||||||
@ -334,6 +341,8 @@ static int __resolve_indirect_ref(struct btrfs_fs_info *fs_info,
|
|||||||
|
|
||||||
if (path->search_commit_root)
|
if (path->search_commit_root)
|
||||||
root_level = btrfs_header_level(root->commit_root);
|
root_level = btrfs_header_level(root->commit_root);
|
||||||
|
else if (time_seq == (u64)-1)
|
||||||
|
root_level = btrfs_header_level(root->node);
|
||||||
else
|
else
|
||||||
root_level = btrfs_old_root_level(root, time_seq);
|
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;
|
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 */
|
/* root node has been locked, we can release @subvol_srcu safely here */
|
||||||
srcu_read_unlock(&fs_info->subvol_srcu, index);
|
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
|
* 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
|
* FIXME some caching might speed things up
|
||||||
*/
|
*/
|
||||||
static int find_parent_nodes(struct btrfs_trans_handle *trans,
|
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;
|
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.
|
* 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
|
* We need both to get a consistent picture of how the refs look
|
||||||
@ -931,9 +953,10 @@ again:
|
|||||||
BUG_ON(ret == 0);
|
BUG_ON(ret == 0);
|
||||||
|
|
||||||
#ifdef CONFIG_BTRFS_FS_RUN_SANITY_TESTS
|
#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
|
#else
|
||||||
if (trans) {
|
if (trans && time_seq != (u64)-1) {
|
||||||
#endif
|
#endif
|
||||||
/*
|
/*
|
||||||
* look if there are updates for this ref queued and lock the
|
* look if there are updates for this ref queued and lock the
|
||||||
|
Loading…
x
Reference in New Issue
Block a user