btrfs: simplify btrfs_check_leaf_* helpers into a single helper
authorJosef Bacik <josef@toxicpanda.com>
Sat, 29 Apr 2023 20:07:12 +0000 (16:07 -0400)
committerDavid Sterba <dsterba@suse.com>
Mon, 19 Jun 2023 11:59:24 +0000 (13:59 +0200)
We have two helpers for checking leaves, because we have an extra check
for debugging in btrfs_mark_buffer_dirty(), and at that stage we may
have item data that isn't consistent yet.  However we can handle this
case internally in the helper, if BTRFS_HEADER_FLAG_WRITTEN is set we
know the buffer should be internally consistent, otherwise we need to
skip checking the item data.

Simplify this helper down a single helper and handle the item data
checking logic internally to the helper.

Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Signed-off-by: David Sterba <dsterba@suse.com>
fs/btrfs/disk-io.c
fs/btrfs/tree-checker.c
fs/btrfs/tree-checker.h

index f4adda2b431763d1842bcf0fc6a080e2ea4fff4b..922755926ee9a6f3f98c7e682bf588f34299d63a 100644 (file)
@@ -326,7 +326,7 @@ static int csum_one_extent_buffer(struct extent_buffer *eb)
        if (btrfs_header_level(eb))
                ret = btrfs_check_node(eb);
        else
-               ret = btrfs_check_leaf_full(eb);
+               ret = btrfs_check_leaf(eb);
 
        if (ret < 0)
                goto error;
@@ -583,7 +583,7 @@ static int validate_extent_buffer(struct extent_buffer *eb,
         * that we don't try and read the other copies of this block, just
         * return -EIO.
         */
-       if (found_level == 0 && btrfs_check_leaf_full(eb)) {
+       if (found_level == 0 && btrfs_check_leaf(eb)) {
                set_bit(EXTENT_BUFFER_CORRUPT, &eb->bflags);
                ret = -EIO;
        }
@@ -4701,12 +4701,10 @@ void btrfs_mark_buffer_dirty(struct extent_buffer *buf)
                                         fs_info->dirty_metadata_batch);
 #ifdef CONFIG_BTRFS_FS_CHECK_INTEGRITY
        /*
-        * Since btrfs_mark_buffer_dirty() can be called with item pointer set
-        * but item data not updated.
-        * So here we should only check item pointers, not item data.
+        * btrfs_check_leaf() won't check item data if we don't have WRITTEN
+        * set, so this will only validate the basic structure of the items.
         */
-       if (btrfs_header_level(buf) == 0 &&
-           btrfs_check_leaf_relaxed(buf)) {
+       if (btrfs_header_level(buf) == 0 && btrfs_check_leaf(buf)) {
                btrfs_print_leaf(buf);
                ASSERT(0);
        }
index e2b54793bf0c248a9031ed445c4209fdadc4601f..2eff4e2f2c47e4e321090bcd59325b2b4ba9e65d 100644 (file)
@@ -1674,7 +1674,7 @@ static int check_leaf_item(struct extent_buffer *leaf,
        return ret;
 }
 
-static int check_leaf(struct extent_buffer *leaf, bool check_item_data)
+int btrfs_check_leaf(struct extent_buffer *leaf)
 {
        struct btrfs_fs_info *fs_info = leaf->fs_info;
        /* No valid key type is 0, so all key should be larger than this key */
@@ -1807,7 +1807,11 @@ static int check_leaf(struct extent_buffer *leaf, bool check_item_data)
                        return -EUCLEAN;
                }
 
-               if (check_item_data) {
+               /*
+                * We only want to do this if WRITTEN is set, otherwise the leaf
+                * may be in some intermediate state and won't appear valid.
+                */
+               if (btrfs_header_flag(leaf, BTRFS_HEADER_FLAG_WRITTEN)) {
                        /*
                         * Check if the item size and content meet other
                         * criteria
@@ -1824,17 +1828,7 @@ static int check_leaf(struct extent_buffer *leaf, bool check_item_data)
 
        return 0;
 }
-
-int btrfs_check_leaf_full(struct extent_buffer *leaf)
-{
-       return check_leaf(leaf, true);
-}
-ALLOW_ERROR_INJECTION(btrfs_check_leaf_full, ERRNO);
-
-int btrfs_check_leaf_relaxed(struct extent_buffer *leaf)
-{
-       return check_leaf(leaf, false);
-}
+ALLOW_ERROR_INJECTION(btrfs_check_leaf, ERRNO);
 
 int btrfs_check_node(struct extent_buffer *node)
 {
index bfb5efa4e01f9bed647f936e809752021e67ce64..48321e8d91bb02ee479a3662142489a383912f0d 100644 (file)
@@ -40,18 +40,7 @@ struct btrfs_tree_parent_check {
        u8 level;
 };
 
-/*
- * Comprehensive leaf checker.
- * Will check not only the item pointers, but also every possible member
- * in item data.
- */
-int btrfs_check_leaf_full(struct extent_buffer *leaf);
-
-/*
- * Less strict leaf checker.
- * Will only check item pointers, not reading item data.
- */
-int btrfs_check_leaf_relaxed(struct extent_buffer *leaf);
+int btrfs_check_leaf(struct extent_buffer *leaf);
 int btrfs_check_node(struct extent_buffer *node);
 
 int btrfs_check_chunk_valid(struct extent_buffer *leaf,