diff --git a/volumes.c b/volumes.c index af7e7892..fdc3a94a 100644 --- a/volumes.c +++ b/volumes.c @@ -1727,6 +1727,20 @@ int btrfs_check_chunk_valid(struct btrfs_root *root, BTRFS_BLOCK_GROUP_PROFILE_MASK) & type); return -EIO; } + if (!(type & BTRFS_BLOCK_GROUP_TYPE_MASK)) { + error("missing chunk type flag: %llu", type); + return -EIO; + } + if (!(is_power_of_2(type & BTRFS_BLOCK_GROUP_PROFILE_MASK) || + (type & BTRFS_BLOCK_GROUP_PROFILE_MASK) == 0)) { + error("conflicting chunk type detected: %llu", type); + return -EIO; + } + if ((type & BTRFS_BLOCK_GROUP_PROFILE_MASK) && + !is_power_of_2(type & BTRFS_BLOCK_GROUP_PROFILE_MASK)) { + error("conflicting chunk profile detected: %llu", type); + return -EIO; + } chunk_ondisk_size = btrfs_chunk_item_size(num_stripes); /* @@ -1743,7 +1757,8 @@ int btrfs_check_chunk_valid(struct btrfs_root *root, /* * Device number check against profile */ - if ((type & BTRFS_BLOCK_GROUP_RAID10 && sub_stripes == 0) || + if ((type & BTRFS_BLOCK_GROUP_RAID10 && (sub_stripes != 2 || + !IS_ALIGNED(num_stripes, sub_stripes))) || (type & BTRFS_BLOCK_GROUP_RAID1 && num_stripes < 1) || (type & BTRFS_BLOCK_GROUP_RAID5 && num_stripes < 2) || (type & BTRFS_BLOCK_GROUP_RAID6 && num_stripes < 3) ||