diff mbox series

[10/11] btrfs-progs: add a btrfs check helper for checking blocks

Message ID 4f7342dabcc239185623abebdac57a30d0db259e.1681938648.git.josef@toxicpanda.com (mailing list archive)
State New, archived
Headers show
Series btrfs-progs: prep work for syncing files into kernel-shared | expand

Commit Message

Josef Bacik April 19, 2023, 9:13 p.m. UTC
btrfs check wants to be able to record corrupted extents if it finds any
bad blocks.  This has been done directly inside of the
btrfs_check_leaf/btrfs_check_node helpers, but these are going to be
sync'ed from the kernel in the future.  Add another helper and move the
corrupt block handling into this helper and keep it inside of the check
code.

Signed-off-by: Josef Bacik <josef@toxicpanda.com>
---
 check/main.c          | 16 +++-------------
 check/mode-lowmem.c   | 11 ++++-------
 check/repair.c        | 29 +++++++++++++++++++++++++++++
 check/repair.h        |  3 ++-
 kernel-shared/ctree.c | 22 ++--------------------
 5 files changed, 40 insertions(+), 41 deletions(-)
diff mbox series

Patch

diff --git a/check/main.c b/check/main.c
index 8c3a10a1..467c8a57 100644
--- a/check/main.c
+++ b/check/main.c
@@ -1920,10 +1920,7 @@  static int walk_down_tree(struct btrfs_root *root, struct btrfs_path *path,
 			goto out;
 		}
 
-		if (btrfs_is_leaf(next))
-			status = btrfs_check_leaf(NULL, next);
-		else
-			status = btrfs_check_node(NULL, next);
+		status = btrfs_check_block_for_repair(next, NULL);
 		if (status != BTRFS_TREE_BLOCK_CLEAN) {
 			free_extent_buffer(next);
 			err = -EIO;
@@ -3701,10 +3698,7 @@  static int check_fs_root(struct btrfs_root *root,
 	wc->root_level = level;
 
 	/* We may not have checked the root block, lets do that now */
-	if (btrfs_is_leaf(root->node))
-		status = btrfs_check_leaf(NULL, root->node);
-	else
-		status = btrfs_check_node(NULL, root->node);
+	status = btrfs_check_block_for_repair(root->node, NULL);
 	if (status != BTRFS_TREE_BLOCK_CLEAN)
 		return -EIO;
 
@@ -4607,11 +4601,7 @@  static int check_block(struct btrfs_root *root,
 	}
 	rec->info_level = level;
 
-	if (btrfs_is_leaf(buf))
-		status = btrfs_check_leaf(&rec->parent_key, buf);
-	else
-		status = btrfs_check_node(&rec->parent_key, buf);
-
+	status = btrfs_check_block_for_repair(buf, &rec->parent_key);
 	if (status != BTRFS_TREE_BLOCK_CLEAN) {
 		if (opt_check_repair)
 			status = try_to_fix_bad_block(root, buf, status);
diff --git a/check/mode-lowmem.c b/check/mode-lowmem.c
index 1672da26..3cf8d97f 100644
--- a/check/mode-lowmem.c
+++ b/check/mode-lowmem.c
@@ -2695,7 +2695,7 @@  static int check_inode_item(struct btrfs_root *root, struct btrfs_path *path)
 		 * we need to bail otherwise we could end up stuck.
 		 */
 		if (path->slots[0] == 0 &&
-		    btrfs_check_leaf(NULL, path->nodes[0]))
+		    btrfs_check_block_for_repair(path->nodes[0], NULL))
 			ret = -EIO;
 
 		if (ret < 0) {
@@ -5001,7 +5001,7 @@  static int walk_down_tree(struct btrfs_root *root, struct btrfs_path *path,
 		if (*level == 0) {
 			/* skip duplicate check */
 			if (check || !check_all) {
-				ret = btrfs_check_leaf(NULL, cur);
+				ret = btrfs_check_block_for_repair(cur, NULL);
 				if (ret != BTRFS_TREE_BLOCK_CLEAN) {
 					err |= -EIO;
 					break;
@@ -5018,7 +5018,7 @@  static int walk_down_tree(struct btrfs_root *root, struct btrfs_path *path,
 			break;
 		}
 		if (check || !check_all) {
-			ret = btrfs_check_node(NULL, cur);
+			ret = btrfs_check_block_for_repair(cur, NULL);
 			if (ret != BTRFS_TREE_BLOCK_CLEAN) {
 				err |= -EIO;
 				break;
@@ -5065,10 +5065,7 @@  static int walk_down_tree(struct btrfs_root *root, struct btrfs_path *path,
 		if (ret < 0)
 			break;
 
-		if (btrfs_is_leaf(next))
-			status = btrfs_check_leaf(NULL, next);
-		else
-			status = btrfs_check_node(NULL, next);
+		status = btrfs_check_block_for_repair(next, NULL);
 		if (status != BTRFS_TREE_BLOCK_CLEAN) {
 			free_extent_buffer(next);
 			err |= -EIO;
diff --git a/check/repair.c b/check/repair.c
index f84df9cf..71b2a277 100644
--- a/check/repair.c
+++ b/check/repair.c
@@ -299,3 +299,32 @@  out:
 	extent_io_tree_cleanup(&used);
 	return ret;
 }
+
+enum btrfs_tree_block_status btrfs_check_block_for_repair(struct extent_buffer *eb,
+							  struct btrfs_key *first_key)
+{
+	struct btrfs_fs_info *fs_info = eb->fs_info;
+	enum btrfs_tree_block_status status;
+
+	if (btrfs_is_leaf(eb))
+		status = btrfs_check_leaf(first_key, eb);
+	else
+		status = btrfs_check_node(first_key, eb);
+
+	if (status == BTRFS_TREE_BLOCK_CLEAN)
+		return status;
+
+	if (btrfs_header_owner(eb) == BTRFS_EXTENT_TREE_OBJECTID) {
+		struct btrfs_key key;
+
+		if (first_key)
+			memcpy(&key, first_key, sizeof(struct btrfs_key));
+		else
+			btrfs_node_key_to_cpu(eb, &key, 0);
+		btrfs_add_corrupt_extent_record(fs_info, &key,
+						eb->start, eb->len,
+						btrfs_header_level(eb));
+	}
+	return status;
+
+}
diff --git a/check/repair.h b/check/repair.h
index 3e6ffcf6..d4222600 100644
--- a/check/repair.h
+++ b/check/repair.h
@@ -43,5 +43,6 @@  int btrfs_mark_used_tree_blocks(struct btrfs_fs_info *fs_info,
 				struct extent_io_tree *tree);
 int btrfs_mark_used_blocks(struct btrfs_fs_info *fs_info,
 			   struct extent_io_tree *tree);
-
+enum btrfs_tree_block_status btrfs_check_block_for_repair(struct extent_buffer *eb,
+							  struct btrfs_key *first_key);
 #endif
diff --git a/kernel-shared/ctree.c b/kernel-shared/ctree.c
index fb56a863..c1c2059b 100644
--- a/kernel-shared/ctree.c
+++ b/kernel-shared/ctree.c
@@ -668,17 +668,8 @@  btrfs_check_node(struct btrfs_key *parent_key, struct extent_buffer *node)
 			goto fail;
 		}
 	}
-	return BTRFS_TREE_BLOCK_CLEAN;
+	ret = BTRFS_TREE_BLOCK_CLEAN;
 fail:
-	if (btrfs_header_owner(node) == BTRFS_EXTENT_TREE_OBJECTID) {
-		if (parent_key)
-			memcpy(&key, parent_key, sizeof(struct btrfs_key));
-		else
-			btrfs_node_key_to_cpu(node, &key, 0);
-		btrfs_add_corrupt_extent_record(fs_info, &key,
-						node->start, node->len,
-						btrfs_header_level(node));
-	}
 	return ret;
 }
 
@@ -782,17 +773,8 @@  btrfs_check_leaf(struct btrfs_key *parent_key, struct extent_buffer *leaf)
 		prev_key.offset = key.offset;
 	}
 
-	return BTRFS_TREE_BLOCK_CLEAN;
+	ret = BTRFS_TREE_BLOCK_CLEAN;
 fail:
-	if (btrfs_header_owner(leaf) == BTRFS_EXTENT_TREE_OBJECTID) {
-		if (parent_key)
-			memcpy(&key, parent_key, sizeof(struct btrfs_key));
-		else
-			btrfs_item_key_to_cpu(leaf, &key, 0);
-
-		btrfs_add_corrupt_extent_record(fs_info, &key,
-						leaf->start, leaf->len, 0);
-	}
 	return ret;
 }