From cdd00958e4463465f2781252e86c76fb32a699ce Mon Sep 17 00:00:00 2001 From: Qu Wenruo Date: Wed, 5 Sep 2018 14:08:21 +0800 Subject: btrfs-progs: Introduce function to find next sibling tree block Introduce a new function, btrfs_next_sibling_tree_block(), which could find any sibling tree blocks at path->lowest_level, unlike level 0 limited btrfs_next_leaf(). Since this function is more generic than btrfs_next_leaf(), also make btrfs_next_leaf() a wrapper of btrfs_next_sibling_tree_block(), to keep the interface the same as kernel. This would provide the basis for later breadth-first search print-tree. Reviewed-by: Nikolay Borisov Signed-off-by: Qu Wenruo Signed-off-by: David Sterba --- ctree.c | 14 +++++++++----- ctree.h | 17 ++++++++++++++++- 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/ctree.c b/ctree.c index e875f9f8..46e2cced 100644 --- a/ctree.c +++ b/ctree.c @@ -2950,18 +2950,22 @@ int btrfs_prev_leaf(struct btrfs_root *root, struct btrfs_path *path) } /* - * walk up the tree as far as required to find the next leaf. + * Walk up the tree as far as necessary to find the next sibling tree block. + * More generic version of btrfs_next_leaf(), as it could find sibling nodes + * if @path->lowest_level is not 0. + * * returns 0 if it found something or 1 if there are no greater leaves. * returns < 0 on io errors. */ -int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path) +int btrfs_next_sibling_tree_block(struct btrfs_fs_info *fs_info, + struct btrfs_path *path) { int slot; - int level = 1; + int level = path->lowest_level + 1; struct extent_buffer *c; struct extent_buffer *next = NULL; - struct btrfs_fs_info *fs_info = root->fs_info; + BUG_ON(path->lowest_level + 1 >= BTRFS_MAX_LEVEL); while(level < BTRFS_MAX_LEVEL) { if (!path->nodes[level]) return 1; @@ -2990,7 +2994,7 @@ int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path) free_extent_buffer(c); path->nodes[level] = next; path->slots[level] = 0; - if (!level) + if (level == path->lowest_level) break; if (path->reada) reada_for_search(fs_info, path, level, 0, 0); diff --git a/ctree.h b/ctree.h index 0a95352b..5d9ba3c5 100644 --- a/ctree.h +++ b/ctree.h @@ -2647,7 +2647,22 @@ static inline int btrfs_insert_empty_item(struct btrfs_trans_handle *trans, return btrfs_insert_empty_items(trans, root, path, key, &data_size, 1); } -int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path); +int btrfs_next_sibling_tree_block(struct btrfs_fs_info *fs_info, + struct btrfs_path *path); + +/* + * Walk up the tree as far as necessary to find the next leaf. + * + * returns 0 if it found something or 1 if there are no greater leaves. + * returns < 0 on io errors. + */ +static inline int btrfs_next_leaf(struct btrfs_root *root, + struct btrfs_path *path) +{ + path->lowest_level = 0; + return btrfs_next_sibling_tree_block(root->fs_info, path); +} + static inline int btrfs_next_item(struct btrfs_root *root, struct btrfs_path *p) { -- cgit v1.2.3