Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

btrfs: tree-checker: add remap-tree checks to check_block_group_item()

Add some write-time checks for block group items relating to the remap
tree.

Here we're checking:

* That the REMAPPED or METADATA_REMAP flags aren't set unless the
REMAP_TREE incompat flag is also set
* That `remap_bytes` isn't more than the size of the block group
* That `identity_remap_count` isn't more than the number of sectors in
the block group

Signed-off-by: Mark Harmstone <mark@harmstone.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>

authored by

Mark Harmstone and committed by
David Sterba
b753612b e3799e65

+41
+41
fs/btrfs/tree-checker.c
··· 777 777 BTRFS_BLOCK_GROUP_METADATA | BTRFS_BLOCK_GROUP_DATA); 778 778 return -EUCLEAN; 779 779 } 780 + 781 + if (unlikely(!btrfs_fs_incompat(fs_info, REMAP_TREE) && 782 + type == BTRFS_BLOCK_GROUP_METADATA_REMAP)) { 783 + block_group_err(leaf, slot, 784 + "invalid type, METADATA_REMAP set but REMAP_TREE incompat flag not set"); 785 + return -EUCLEAN; 786 + } 787 + 788 + if (unlikely(!btrfs_fs_incompat(fs_info, REMAP_TREE) && 789 + flags & BTRFS_BLOCK_GROUP_REMAPPED)) { 790 + block_group_err(leaf, slot, 791 + "invalid flags, REMAPPED set but REMAP_TREE incompat flag not set"); 792 + return -EUCLEAN; 793 + } 794 + 795 + if (item_size == sizeof(struct btrfs_block_group_item_v2)) { 796 + struct btrfs_block_group_item_v2 *bgi2; 797 + u64 remap_bytes; 798 + u32 identity_remap_count; 799 + 800 + bgi2 = btrfs_item_ptr(leaf, slot, struct btrfs_block_group_item_v2); 801 + remap_bytes = btrfs_block_group_v2_remap_bytes(leaf, bgi2); 802 + 803 + if (unlikely(remap_bytes > key->offset)) { 804 + block_group_err(leaf, slot, 805 + "invalid remap_bytes, have %llu expect [0, %llu]", 806 + remap_bytes, key->offset); 807 + return -EUCLEAN; 808 + } 809 + 810 + identity_remap_count = btrfs_block_group_v2_identity_remap_count(leaf, bgi2); 811 + if (unlikely((u64)identity_remap_count > 812 + key->offset >> fs_info->sectorsize_bits)) { 813 + block_group_err(leaf, slot, 814 + "invalid identity_remap_count, have %u expect [0, %llu]", 815 + identity_remap_count, 816 + key->offset >> fs_info->sectorsize_bits); 817 + return -EUCLEAN; 818 + } 819 + } 820 + 780 821 return 0; 781 822 } 782 823