Skip to content

Commit

Permalink
btrfs: tree-checker: Check chunk item at tree block read time
Browse files Browse the repository at this point in the history
commit 075cb3c upstream.

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: Johannes Thumshirn <jthumshirn@suse.de>
Signed-off-by: Qu Wenruo <wqu@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
Signed-off-by: Ben Hutchings <ben.hutchings@codethink.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
adam900710 authored and gregkh committed Nov 10, 2020
1 parent 782aa87 commit 3c06c86
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 3 deletions.
6 changes: 6 additions & 0 deletions fs/btrfs/tree-checker.c
Original file line number Diff line number Diff line change
Expand Up @@ -608,6 +608,7 @@ static int check_leaf_item(struct btrfs_fs_info *fs_info,
struct btrfs_key *key, int slot)
{
int ret = 0;
struct btrfs_chunk *chunk;

switch (key->type) {
case BTRFS_EXTENT_DATA_KEY:
Expand All @@ -624,6 +625,11 @@ static int check_leaf_item(struct btrfs_fs_info *fs_info,
case BTRFS_BLOCK_GROUP_ITEM_KEY:
ret = check_block_group_item(fs_info, leaf, key, slot);
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;
}
Expand Down
12 changes: 9 additions & 3 deletions fs/btrfs/volumes.c
Original file line number Diff line number Diff line change
Expand Up @@ -6401,9 +6401,15 @@ static int read_one_chunk(struct btrfs_fs_info *fs_info, struct btrfs_key *key,
length = btrfs_chunk_length(leaf, chunk);
num_stripes = btrfs_chunk_num_stripes(leaf, chunk);

ret = btrfs_check_chunk_valid(fs_info, leaf, chunk, logical);
if (ret)
return ret;
/*
* Only need to verify chunk item if we're reading from sys chunk array,
* 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);
em = lookup_extent_mapping(&map_tree->map_tree, logical, 1);
Expand Down

0 comments on commit 3c06c86

Please sign in to comment.