summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorQu Wenruo <quwenruo@cn.fujitsu.com>2017-05-31 13:56:06 +0800
committerDavid Sterba <dsterba@suse.com>2017-07-03 13:35:11 +0200
commit383b2b9c562fc944c4c5733dcc2b0eaaea84d7b2 (patch)
treec592677639212e521524b16c88fc145e1e51c56e
parent05734124f2cf616d94d7f2640351bc0272b1a8d0 (diff)
btrfs-progs: Enhance chunk item validation check
btrfs_check_chunk_valid() doesn't check if 1) chunk flag has conflicting flags For example chunk type DATA|METADATA|RAID1|RAID10 is completely invalid, while current check_chunk_valid() can't detect it. 2) num_stripes is invalid for RAID10 Num_stripes 5 is not valid for RAID10. This patch will enhance btrfs_check_chunk_valid() to handle above cases. Signed-off-by: Qu Wenruo <quwenruo@cn.fujitsu.com> Signed-off-by: David Sterba <dsterba@suse.com>
-rw-r--r--volumes.c17
1 files changed, 16 insertions, 1 deletions
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) ||