summaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorQu Wenruo <wqu@suse.com>2019-03-20 01:42:33 -0400
committerDavid Sterba <dsterba@suse.com>2019-04-29 13:02:32 -0400
commit075cb3c78fe7976c9f29ca1fa23f9728634ecefc (patch)
tree15961e83f25f21a2b9ab09d629b3b5d3f7dce7c0 /fs
parentbf871c3b43b1dcc3f2a076ff39a8f1ce7959d958 (diff)
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: 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>
Diffstat (limited to 'fs')
-rw-r--r--fs/btrfs/tree-checker.c6
-rw-r--r--fs/btrfs/volumes.c12
2 files changed, 15 insertions, 3 deletions
diff --git a/fs/btrfs/tree-checker.c b/fs/btrfs/tree-checker.c
index 75cc9e1d61bb..33d04fc4d280 100644
--- a/fs/btrfs/tree-checker.c
+++ b/fs/btrfs/tree-checker.c
@@ -608,6 +608,7 @@ static int check_leaf_item(struct btrfs_fs_info *fs_info,
608 struct btrfs_key *key, int slot) 608 struct btrfs_key *key, int slot)
609{ 609{
610 int ret = 0; 610 int ret = 0;
611 struct btrfs_chunk *chunk;
611 612
612 switch (key->type) { 613 switch (key->type) {
613 case BTRFS_EXTENT_DATA_KEY: 614 case BTRFS_EXTENT_DATA_KEY:
@@ -624,6 +625,11 @@ static int check_leaf_item(struct btrfs_fs_info *fs_info,
624 case BTRFS_BLOCK_GROUP_ITEM_KEY: 625 case BTRFS_BLOCK_GROUP_ITEM_KEY:
625 ret = check_block_group_item(fs_info, leaf, key, slot); 626 ret = check_block_group_item(fs_info, leaf, key, slot);
626 break; 627 break;
628 case BTRFS_CHUNK_ITEM_KEY:
629 chunk = btrfs_item_ptr(leaf, slot, struct btrfs_chunk);
630 ret = btrfs_check_chunk_valid(fs_info, leaf, chunk,
631 key->offset);
632 break;
627 } 633 }
628 return ret; 634 return ret;
629} 635}
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index 5f39d86d41ec..97dbd7f37674 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -6745,9 +6745,15 @@ static int read_one_chunk(struct btrfs_fs_info *fs_info, struct btrfs_key *key,
6745 length = btrfs_chunk_length(leaf, chunk); 6745 length = btrfs_chunk_length(leaf, chunk);
6746 num_stripes = btrfs_chunk_num_stripes(leaf, chunk); 6746 num_stripes = btrfs_chunk_num_stripes(leaf, chunk);
6747 6747
6748 ret = btrfs_check_chunk_valid(fs_info, leaf, chunk, logical); 6748 /*
6749 if (ret) 6749 * Only need to verify chunk item if we're reading from sys chunk array,
6750 return ret; 6750 * as chunk item in tree block is already verified by tree-checker.
6751 */
6752 if (leaf->start == BTRFS_SUPER_INFO_OFFSET) {
6753 ret = btrfs_check_chunk_valid(fs_info, leaf, chunk, logical);
6754 if (ret)
6755 return ret;
6756 }
6751 6757
6752 read_lock(&map_tree->map_tree.lock); 6758 read_lock(&map_tree->map_tree.lock);
6753 em = lookup_extent_mapping(&map_tree->map_tree, logical, 1); 6759 em = lookup_extent_mapping(&map_tree->map_tree, logical, 1);