Commit 85d8a826 authored by Josef Bacik's avatar Josef Bacik Committed by David Sterba

btrfs: simplify btrfs_check_leaf_* helpers into a single helper

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: default avatarJohannes Thumshirn <johannes.thumshirn@wdc.com>
Signed-off-by: default avatarJosef Bacik <josef@toxicpanda.com>
Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
parent 4aec05fa
...@@ -326,7 +326,7 @@ static int csum_one_extent_buffer(struct extent_buffer *eb) ...@@ -326,7 +326,7 @@ static int csum_one_extent_buffer(struct extent_buffer *eb)
if (btrfs_header_level(eb)) if (btrfs_header_level(eb))
ret = btrfs_check_node(eb); ret = btrfs_check_node(eb);
else else
ret = btrfs_check_leaf_full(eb); ret = btrfs_check_leaf(eb);
if (ret < 0) if (ret < 0)
goto error; goto error;
...@@ -583,7 +583,7 @@ static int validate_extent_buffer(struct extent_buffer *eb, ...@@ -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 * that we don't try and read the other copies of this block, just
* return -EIO. * 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); set_bit(EXTENT_BUFFER_CORRUPT, &eb->bflags);
ret = -EIO; ret = -EIO;
} }
...@@ -4701,12 +4701,10 @@ void btrfs_mark_buffer_dirty(struct extent_buffer *buf) ...@@ -4701,12 +4701,10 @@ void btrfs_mark_buffer_dirty(struct extent_buffer *buf)
fs_info->dirty_metadata_batch); fs_info->dirty_metadata_batch);
#ifdef CONFIG_BTRFS_FS_CHECK_INTEGRITY #ifdef CONFIG_BTRFS_FS_CHECK_INTEGRITY
/* /*
* Since btrfs_mark_buffer_dirty() can be called with item pointer set * btrfs_check_leaf() won't check item data if we don't have WRITTEN
* but item data not updated. * set, so this will only validate the basic structure of the items.
* So here we should only check item pointers, not item data.
*/ */
if (btrfs_header_level(buf) == 0 && if (btrfs_header_level(buf) == 0 && btrfs_check_leaf(buf)) {
btrfs_check_leaf_relaxed(buf)) {
btrfs_print_leaf(buf); btrfs_print_leaf(buf);
ASSERT(0); ASSERT(0);
} }
......
...@@ -1674,7 +1674,7 @@ static int check_leaf_item(struct extent_buffer *leaf, ...@@ -1674,7 +1674,7 @@ static int check_leaf_item(struct extent_buffer *leaf,
return ret; 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; struct btrfs_fs_info *fs_info = leaf->fs_info;
/* No valid key type is 0, so all key should be larger than this key */ /* 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) ...@@ -1807,7 +1807,11 @@ static int check_leaf(struct extent_buffer *leaf, bool check_item_data)
return -EUCLEAN; 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 * Check if the item size and content meet other
* criteria * criteria
...@@ -1824,17 +1828,7 @@ static int check_leaf(struct extent_buffer *leaf, bool check_item_data) ...@@ -1824,17 +1828,7 @@ static int check_leaf(struct extent_buffer *leaf, bool check_item_data)
return 0; return 0;
} }
ALLOW_ERROR_INJECTION(btrfs_check_leaf, ERRNO);
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);
}
int btrfs_check_node(struct extent_buffer *node) int btrfs_check_node(struct extent_buffer *node)
{ {
......
...@@ -40,18 +40,7 @@ struct btrfs_tree_parent_check { ...@@ -40,18 +40,7 @@ struct btrfs_tree_parent_check {
u8 level; u8 level;
}; };
/* int btrfs_check_leaf(struct extent_buffer *leaf);
* 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_node(struct extent_buffer *node); int btrfs_check_node(struct extent_buffer *node);
int btrfs_check_chunk_valid(struct extent_buffer *leaf, int btrfs_check_chunk_valid(struct extent_buffer *leaf,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment