diff mbox series

[16/38] btrfs-progs: make a local copy of btrfs_next_sibling_block in print-tree.c

Message ID f40179778e3d772f3c3ef1b33f59f86284e9d34a.1692800904.git.josef@toxicpanda.com (mailing list archive)
State New, archived
Headers show
Series btrfs-progs: sync ctree.c into btrfs-progs | expand

Commit Message

Josef Bacik Aug. 23, 2023, 2:32 p.m. UTC
We use this in print-tree to do BFS tree printing, but there are no
other users and it doesn't exist upstream.  Copy the current code and
clean it up so it can exist in print-tree.c and use the local copy
there.  This will allow us to remove the function call when ctree.c is
synced.

Signed-off-by: Josef Bacik <josef@toxicpanda.com>
---
 kernel-shared/print-tree.c | 53 +++++++++++++++++++++++++++++++++++++-
 1 file changed, 52 insertions(+), 1 deletion(-)
diff mbox series

Patch

diff --git a/kernel-shared/print-tree.c b/kernel-shared/print-tree.c
index a32c9a2a..9796085d 100644
--- a/kernel-shared/print-tree.c
+++ b/kernel-shared/print-tree.c
@@ -1505,6 +1505,57 @@  out:
 	return ret;
 }
 
+/*
+ * 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.
+ */
+static int next_sibling_tree_block(struct btrfs_fs_info *fs_info,
+				   struct btrfs_path *path)
+{
+	int slot;
+	int level = path->lowest_level + 1;
+	struct extent_buffer *c;
+	struct extent_buffer *next = NULL;
+
+	BUG_ON(path->lowest_level + 1 >= BTRFS_MAX_LEVEL);
+	do {
+		if (!path->nodes[level])
+			return 1;
+
+		slot = path->slots[level] + 1;
+		c = path->nodes[level];
+		if (slot >= btrfs_header_nritems(c)) {
+			level++;
+			if (level == BTRFS_MAX_LEVEL)
+				return 1;
+			continue;
+		}
+
+		next = btrfs_read_node_slot(c, slot);
+		if (!extent_buffer_uptodate(next))
+			return -EIO;
+		break;
+	} while (level < BTRFS_MAX_LEVEL);
+	path->slots[level] = slot;
+	while(1) {
+		level--;
+		c = path->nodes[level];
+		free_extent_buffer(c);
+		path->nodes[level] = next;
+		path->slots[level] = 0;
+		if (level == path->lowest_level)
+			break;
+		next = btrfs_read_node_slot(next, 0);
+		if (!extent_buffer_uptodate(next))
+			return -EIO;
+	}
+	return 0;
+}
+
 static void bfs_print_children(struct extent_buffer *root_eb, unsigned int mode)
 {
 	struct btrfs_fs_info *fs_info = root_eb->fs_info;
@@ -1535,7 +1586,7 @@  static void bfs_print_children(struct extent_buffer *root_eb, unsigned int mode)
 		/* Print all sibling tree blocks */
 		while (1) {
 			btrfs_print_tree(path.nodes[cur_level], mode);
-			ret = btrfs_next_sibling_tree_block(fs_info, &path);
+			ret = next_sibling_tree_block(fs_info, &path);
 			if (ret < 0)
 				goto out;
 			if (ret > 0) {