diff options
author | Qu Wenruo <quwenruo@cn.fujitsu.com> | 2015-04-16 02:54:50 -0400 |
---|---|---|
committer | Chris Mason <clm@fb.com> | 2015-06-10 12:25:45 -0400 |
commit | 21633fc6037f8ceb2bb927dacc3f9ef46ccae891 (patch) | |
tree | d031ae663b36cba46e061d03c8161e2418442b74 /fs/btrfs/backref.c | |
parent | 3b7d00f99c60b31e1cff0efc6b9178eea3696e27 (diff) |
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>
Diffstat (limited to 'fs/btrfs/backref.c')
-rw-r--r-- | fs/btrfs/backref.c | 35 |
1 files changed, 29 insertions, 6 deletions
diff --git a/fs/btrfs/backref.c b/fs/btrfs/backref.c index 49bc5a41c1f8..802fabb30e15 100644 --- a/fs/btrfs/backref.c +++ b/fs/btrfs/backref.c | |||
@@ -250,8 +250,12 @@ static int add_all_parents(struct btrfs_root *root, struct btrfs_path *path, | |||
250 | * the first item to check. But sometimes, we may enter it with | 250 | * the first item to check. But sometimes, we may enter it with |
251 | * slot==nritems. In that case, go to the next leaf before we continue. | 251 | * slot==nritems. In that case, go to the next leaf before we continue. |
252 | */ | 252 | */ |
253 | if (path->slots[0] >= btrfs_header_nritems(path->nodes[0])) | 253 | if (path->slots[0] >= btrfs_header_nritems(path->nodes[0])) { |
254 | ret = btrfs_next_old_leaf(root, path, time_seq); | 254 | if (time_seq == (u64)-1) |
255 | ret = btrfs_next_leaf(root, path); | ||
256 | else | ||
257 | ret = btrfs_next_old_leaf(root, path, time_seq); | ||
258 | } | ||
255 | 259 | ||
256 | while (!ret && count < total_refs) { | 260 | while (!ret && count < total_refs) { |
257 | eb = path->nodes[0]; | 261 | eb = path->nodes[0]; |
@@ -291,7 +295,10 @@ static int add_all_parents(struct btrfs_root *root, struct btrfs_path *path, | |||
291 | eie = NULL; | 295 | eie = NULL; |
292 | } | 296 | } |
293 | next: | 297 | next: |
294 | ret = btrfs_next_old_item(root, path, time_seq); | 298 | if (time_seq == (u64)-1) |
299 | ret = btrfs_next_item(root, path); | ||
300 | else | ||
301 | ret = btrfs_next_old_item(root, path, time_seq); | ||
295 | } | 302 | } |
296 | 303 | ||
297 | if (ret > 0) | 304 | if (ret > 0) |
@@ -334,6 +341,8 @@ static int __resolve_indirect_ref(struct btrfs_fs_info *fs_info, | |||
334 | 341 | ||
335 | if (path->search_commit_root) | 342 | if (path->search_commit_root) |
336 | root_level = btrfs_header_level(root->commit_root); | 343 | root_level = btrfs_header_level(root->commit_root); |
344 | else if (time_seq == (u64)-1) | ||
345 | root_level = btrfs_header_level(root->node); | ||
337 | else | 346 | else |
338 | root_level = btrfs_old_root_level(root, time_seq); | 347 | root_level = btrfs_old_root_level(root, time_seq); |
339 | 348 | ||
@@ -343,7 +352,12 @@ static int __resolve_indirect_ref(struct btrfs_fs_info *fs_info, | |||
343 | } | 352 | } |
344 | 353 | ||
345 | path->lowest_level = level; | 354 | path->lowest_level = level; |
346 | ret = btrfs_search_old_slot(root, &ref->key_for_search, path, time_seq); | 355 | if (time_seq == (u64)-1) |
356 | ret = btrfs_search_slot(NULL, root, &ref->key_for_search, path, | ||
357 | 0, 0); | ||
358 | else | ||
359 | ret = btrfs_search_old_slot(root, &ref->key_for_search, path, | ||
360 | time_seq); | ||
347 | 361 | ||
348 | /* root node has been locked, we can release @subvol_srcu safely here */ | 362 | /* root node has been locked, we can release @subvol_srcu safely here */ |
349 | srcu_read_unlock(&fs_info->subvol_srcu, index); | 363 | srcu_read_unlock(&fs_info->subvol_srcu, index); |
@@ -879,6 +893,11 @@ static int __add_keyed_refs(struct btrfs_fs_info *fs_info, | |||
879 | * | 893 | * |
880 | * NOTE: This can return values > 0 | 894 | * NOTE: This can return values > 0 |
881 | * | 895 | * |
896 | * If time_seq is set to (u64)-1, it will not search delayed_refs, and behave | ||
897 | * much like trans == NULL case, the difference only lies in it will not | ||
898 | * commit root. | ||
899 | * The special case is for qgroup to search roots in commit_transaction(). | ||
900 | * | ||
882 | * FIXME some caching might speed things up | 901 | * FIXME some caching might speed things up |
883 | */ | 902 | */ |
884 | static int find_parent_nodes(struct btrfs_trans_handle *trans, | 903 | static int find_parent_nodes(struct btrfs_trans_handle *trans, |
@@ -917,6 +936,9 @@ static int find_parent_nodes(struct btrfs_trans_handle *trans, | |||
917 | path->skip_locking = 1; | 936 | path->skip_locking = 1; |
918 | } | 937 | } |
919 | 938 | ||
939 | if (time_seq == (u64)-1) | ||
940 | path->skip_locking = 1; | ||
941 | |||
920 | /* | 942 | /* |
921 | * grab both a lock on the path and a lock on the delayed ref head. | 943 | * grab both a lock on the path and a lock on the delayed ref head. |
922 | * We need both to get a consistent picture of how the refs look | 944 | * We need both to get a consistent picture of how the refs look |
@@ -931,9 +953,10 @@ again: | |||
931 | BUG_ON(ret == 0); | 953 | BUG_ON(ret == 0); |
932 | 954 | ||
933 | #ifdef CONFIG_BTRFS_FS_RUN_SANITY_TESTS | 955 | #ifdef CONFIG_BTRFS_FS_RUN_SANITY_TESTS |
934 | if (trans && likely(trans->type != __TRANS_DUMMY)) { | 956 | if (trans && likely(trans->type != __TRANS_DUMMY) && |
957 | time_seq != (u64)-1) { | ||
935 | #else | 958 | #else |
936 | if (trans) { | 959 | if (trans && time_seq != (u64)-1) { |
937 | #endif | 960 | #endif |
938 | /* | 961 | /* |
939 | * look if there are updates for this ref queued and lock the | 962 | * look if there are updates for this ref queued and lock the |