diff options
author | Qu Wenruo <quwenruo@cn.fujitsu.com> | 2015-11-19 14:42:39 +0800 |
---|---|---|
committer | David Sterba <dsterba@suse.com> | 2015-11-19 18:34:30 +0100 |
commit | a99d13dccee11d29da3d045c2c2fc69d47eff770 (patch) | |
tree | 88ed49e670647477b8c8c90856638fa062628df7 | |
parent | b7a69afe6947d913fed4ad64eca6471c6059a1ec (diff) | |
download | btrfs-progs-a99d13dccee11d29da3d045c2c2fc69d47eff770.tar.gz |
btrfs-progs: chunk-recovery: Fix a float point error
Fix a zero division causing chunk-recovery fail.
Also fix a typo "strpie_length" -> "stripe_length".
Reported-by: Scotty Edmonds <scotty@scottyedmonds.com>
Signed-off-by: Qu Wenruo <quwenruo@cn.fujitsu.com>
Signed-off-by: David Sterba <dsterba@suse.com>
-rw-r--r-- | btrfsck.h | 17 | ||||
-rw-r--r-- | chunk-recover.c | 9 |
2 files changed, 23 insertions, 3 deletions
@@ -142,6 +142,23 @@ static inline unsigned long btrfs_chunk_record_size(int num_stripes) } void free_chunk_cache_tree(struct cache_tree *chunk_cache); +/* + * Function to check validation for num_stripes, or it can call + * float point error for 0 division + * return < 0 for invalid combination + * return 0 for valid combination + */ +static inline int check_num_stripes(u64 type, int num_stripes) +{ + if (num_stripes == 0) + return -1; + if (type & BTRFS_BLOCK_GROUP_RAID5 && num_stripes <= 1) + return -1; + if (type & BTRFS_BLOCK_GROUP_RAID6 && num_stripes <= 2) + return -1; + return 0; +} + u64 calc_stripe_length(u64 type, u64 length, int num_stripes); /* For block group tree */ static inline void block_group_tree_init(struct block_group_tree *tree) diff --git a/chunk-recover.c b/chunk-recover.c index 0d4c8ffa..85dc1bca 100644 --- a/chunk-recover.c +++ b/chunk-recover.c @@ -1607,16 +1607,19 @@ static int btrfs_verify_device_extents(struct block_group_record *bg, struct list_head *devexts, int ndevexts) { struct device_extent_record *devext; - u64 strpie_length; + u64 stripe_length; int expected_num_stripes; expected_num_stripes = calc_num_stripes(bg->flags); if (expected_num_stripes && expected_num_stripes != ndevexts) return 1; - strpie_length = calc_stripe_length(bg->flags, bg->offset, ndevexts); + if (check_num_stripes(bg->flags, ndevexts) < 0) + return 1; + + stripe_length = calc_stripe_length(bg->flags, bg->offset, ndevexts); list_for_each_entry(devext, devexts, chunk_list) { - if (devext->length != strpie_length) + if (devext->length != stripe_length) return 1; } return 0; |