diff mbox series

[14/18] btrfs-progs: add a btrfs_read_extent_buffer helper

Message ID da6aef1cc75408edd38cb254b9a480cb35f1fea9.1681939316.git.josef@toxicpanda.com (mailing list archive)
State New, archived
Headers show
Series btrfs-progs: more prep work for syncing ctree.c | expand

Commit Message

Josef Bacik April 19, 2023, 9:24 p.m. UTC
This exists in the kernel to do the read on an extent buffer we may have
already looked up and initialized.  Simply create this helper by
extracting out the existing code from read_tree_block and make
read_tree_block call this helper.  This gives us the helper we need to
sync ctree.c into btrfs-progs, and keeps the code the same in
btrfs-progs.

Signed-off-by: Josef Bacik <josef@toxicpanda.com>
---
 kernel-shared/disk-io.c | 72 ++++++++++++++++++++++++-----------------
 kernel-shared/disk-io.h |  2 ++
 2 files changed, 45 insertions(+), 29 deletions(-)
diff mbox series

Patch

diff --git a/kernel-shared/disk-io.c b/kernel-shared/disk-io.c
index 29fe9027..6e810bd1 100644
--- a/kernel-shared/disk-io.c
+++ b/kernel-shared/disk-io.c
@@ -337,39 +337,18 @@  int read_whole_eb(struct btrfs_fs_info *info, struct extent_buffer *eb, int mirr
 	return 0;
 }
 
-struct extent_buffer *read_tree_block(struct btrfs_fs_info *fs_info, u64 bytenr,
-				      u64 owner_root, u64 parent_transid,
-				      int level, struct btrfs_key *first_key)
+int btrfs_read_extent_buffer(struct extent_buffer *eb, u64 parent_transid,
+			     int level, struct btrfs_key *first_key)
 {
+	struct btrfs_fs_info *fs_info = eb->fs_info;
 	int ret;
-	struct extent_buffer *eb;
 	u64 best_transid = 0;
-	u32 sectorsize = fs_info->sectorsize;
 	int mirror_num = 1;
 	int good_mirror = 0;
 	int candidate_mirror = 0;
 	int num_copies;
 	int ignore = 0;
 
-	/*
-	 * Don't even try to create tree block for unaligned tree block
-	 * bytenr.
-	 * Such unaligned tree block will free overlapping extent buffer,
-	 * causing use-after-free bugs for fuzzed images.
-	 */
-	if (bytenr < sectorsize || !IS_ALIGNED(bytenr, sectorsize)) {
-		error("tree block bytenr %llu is not aligned to sectorsize %u",
-		      bytenr, sectorsize);
-		return ERR_PTR(-EIO);
-	}
-
-	eb = btrfs_find_create_tree_block(fs_info, bytenr);
-	if (!eb)
-		return ERR_PTR(-ENOMEM);
-
-	if (btrfs_buffer_uptodate(eb, parent_transid, 0))
-		return eb;
-
 	num_copies = btrfs_num_copies(fs_info, eb->start, eb->len);
 	while (1) {
 		ret = read_whole_eb(fs_info, eb, mirror_num);
@@ -396,7 +375,7 @@  struct extent_buffer *read_tree_block(struct btrfs_fs_info *fs_info, u64 bytenr,
 				ret = btrfs_check_leaf(eb);
 			if (!ret || candidate_mirror == mirror_num) {
 				btrfs_set_buffer_uptodate(eb);
-				return eb;
+				return 0;
 			}
 			if (candidate_mirror <= 0)
 				candidate_mirror = mirror_num;
@@ -439,12 +418,47 @@  struct extent_buffer *read_tree_block(struct btrfs_fs_info *fs_info, u64 bytenr,
 			continue;
 		}
 	}
+	return ret;
+}
+
+struct extent_buffer *read_tree_block(struct btrfs_fs_info *fs_info, u64 bytenr,
+				      u64 owner_root, u64 parent_transid,
+				      int level, struct btrfs_key *first_key)
+{
+	int ret;
+	struct extent_buffer *eb;
+	u32 sectorsize = fs_info->sectorsize;
+
 	/*
-	 * We failed to read this tree block, it be should deleted right now
-	 * to avoid stale cache populate the cache.
+	 * Don't even try to create tree block for unaligned tree block
+	 * bytenr.
+	 * Such unaligned tree block will free overlapping extent buffer,
+	 * causing use-after-free bugs for fuzzed images.
 	 */
-	free_extent_buffer_nocache(eb);
-	return ERR_PTR(ret);
+	if (bytenr < sectorsize || !IS_ALIGNED(bytenr, sectorsize)) {
+		error("tree block bytenr %llu is not aligned to sectorsize %u",
+		      bytenr, sectorsize);
+		return ERR_PTR(-EIO);
+	}
+
+	eb = btrfs_find_create_tree_block(fs_info, bytenr);
+	if (!eb)
+		return ERR_PTR(-ENOMEM);
+
+	if (btrfs_buffer_uptodate(eb, parent_transid, 0))
+		return eb;
+
+	ret = btrfs_read_extent_buffer(eb, parent_transid, level, first_key);
+	if (ret) {
+		/*
+		 * We failed to read this tree block, it be should deleted right
+		 * now to avoid stale cache populate the cache.
+		 */
+		free_extent_buffer_nocache(eb);
+		return ERR_PTR(ret);
+	}
+
+	return eb;
 }
 
 int write_and_map_eb(struct btrfs_fs_info *fs_info, struct extent_buffer *eb)
diff --git a/kernel-shared/disk-io.h b/kernel-shared/disk-io.h
index ed7f9259..4c63a4a8 100644
--- a/kernel-shared/disk-io.h
+++ b/kernel-shared/disk-io.h
@@ -233,6 +233,8 @@  int btrfs_global_root_insert(struct btrfs_fs_info *fs_info,
 int btrfs_find_and_setup_root(struct btrfs_root *tree_root,
 			      struct btrfs_fs_info *fs_info,
 			      u64 objectid, struct btrfs_root *root);
+int btrfs_read_extent_buffer(struct extent_buffer *eb, u64 parent_transid,
+			     int level, struct btrfs_key *first_key);
 
 static inline struct btrfs_root *btrfs_block_group_root(
 						struct btrfs_fs_info *fs_info)