Commit 075cb3c7 authored by Qu Wenruo's avatar Qu Wenruo Committed by David Sterba

btrfs: tree-checker: Check chunk item at tree block read time

Since we have btrfs_check_chunk_valid() in tree-checker, let's do
chunk item verification in tree-checker too.

Since the tree-checker is run at endio time, if one chunk leaf fails
chunk verification, we can still retry the other copy, making btrfs more
robust to fuzzed image as we may still get a good chunk item.

Also since we have done chunk verification in tree block read time, skip
the btrfs_check_chunk_valid() call in read_one_chunk() if we're reading
chunk items from leaf.
Reviewed-by: default avatarJohannes Thumshirn <jthumshirn@suse.de>
Signed-off-by: default avatarQu Wenruo <wqu@suse.com>
Reviewed-by: default avatarDavid Sterba <dsterba@suse.com>
Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
parent bf871c3b
...@@ -608,6 +608,7 @@ static int check_leaf_item(struct btrfs_fs_info *fs_info, ...@@ -608,6 +608,7 @@ static int check_leaf_item(struct btrfs_fs_info *fs_info,
struct btrfs_key *key, int slot) struct btrfs_key *key, int slot)
{ {
int ret = 0; int ret = 0;
struct btrfs_chunk *chunk;
switch (key->type) { switch (key->type) {
case BTRFS_EXTENT_DATA_KEY: case BTRFS_EXTENT_DATA_KEY:
...@@ -624,6 +625,11 @@ static int check_leaf_item(struct btrfs_fs_info *fs_info, ...@@ -624,6 +625,11 @@ static int check_leaf_item(struct btrfs_fs_info *fs_info,
case BTRFS_BLOCK_GROUP_ITEM_KEY: case BTRFS_BLOCK_GROUP_ITEM_KEY:
ret = check_block_group_item(fs_info, leaf, key, slot); ret = check_block_group_item(fs_info, leaf, key, slot);
break; break;
case BTRFS_CHUNK_ITEM_KEY:
chunk = btrfs_item_ptr(leaf, slot, struct btrfs_chunk);
ret = btrfs_check_chunk_valid(fs_info, leaf, chunk,
key->offset);
break;
} }
return ret; return ret;
} }
......
...@@ -6745,9 +6745,15 @@ static int read_one_chunk(struct btrfs_fs_info *fs_info, struct btrfs_key *key, ...@@ -6745,9 +6745,15 @@ static int read_one_chunk(struct btrfs_fs_info *fs_info, struct btrfs_key *key,
length = btrfs_chunk_length(leaf, chunk); length = btrfs_chunk_length(leaf, chunk);
num_stripes = btrfs_chunk_num_stripes(leaf, chunk); num_stripes = btrfs_chunk_num_stripes(leaf, chunk);
ret = btrfs_check_chunk_valid(fs_info, leaf, chunk, logical); /*
if (ret) * Only need to verify chunk item if we're reading from sys chunk array,
return ret; * as chunk item in tree block is already verified by tree-checker.
*/
if (leaf->start == BTRFS_SUPER_INFO_OFFSET) {
ret = btrfs_check_chunk_valid(fs_info, leaf, chunk, logical);
if (ret)
return ret;
}
read_lock(&map_tree->map_tree.lock); read_lock(&map_tree->map_tree.lock);
em = lookup_extent_mapping(&map_tree->map_tree, logical, 1); em = lookup_extent_mapping(&map_tree->map_tree, logical, 1);
......
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