diff options
Diffstat (limited to 'fs/btrfs/tree-checker.c')
| -rw-r--r-- | fs/btrfs/tree-checker.c | 18 | 
1 files changed, 18 insertions, 0 deletions
| diff --git a/fs/btrfs/tree-checker.c b/fs/btrfs/tree-checker.c index f0ffd5ee77bd..8784b74f5232 100644 --- a/fs/btrfs/tree-checker.c +++ b/fs/btrfs/tree-checker.c @@ -760,18 +760,36 @@ int btrfs_check_chunk_valid(struct extent_buffer *leaf,  	u64 type;  	u64 features;  	bool mixed = false; +	int raid_index; +	int nparity; +	int ncopies;  	length = btrfs_chunk_length(leaf, chunk);  	stripe_len = btrfs_chunk_stripe_len(leaf, chunk);  	num_stripes = btrfs_chunk_num_stripes(leaf, chunk);  	sub_stripes = btrfs_chunk_sub_stripes(leaf, chunk);  	type = btrfs_chunk_type(leaf, chunk); +	raid_index = btrfs_bg_flags_to_raid_index(type); +	ncopies = btrfs_raid_array[raid_index].ncopies; +	nparity = btrfs_raid_array[raid_index].nparity;  	if (!num_stripes) {  		chunk_err(leaf, chunk, logical,  			  "invalid chunk num_stripes, have %u", num_stripes);  		return -EUCLEAN;  	} +	if (num_stripes < ncopies) { +		chunk_err(leaf, chunk, logical, +			  "invalid chunk num_stripes < ncopies, have %u < %d", +			  num_stripes, ncopies); +		return -EUCLEAN; +	} +	if (nparity && num_stripes == nparity) { +		chunk_err(leaf, chunk, logical, +			  "invalid chunk num_stripes == nparity, have %u == %d", +			  num_stripes, nparity); +		return -EUCLEAN; +	}  	if (!IS_ALIGNED(logical, fs_info->sectorsize)) {  		chunk_err(leaf, chunk, logical,  		"invalid chunk logical, have %llu should aligned to %u", |