|
@@ -6211,6 +6211,7 @@ static int read_one_chunk(struct btrfs_root *root, struct btrfs_key *key,
|
|
struct extent_map *em;
|
|
struct extent_map *em;
|
|
u64 logical;
|
|
u64 logical;
|
|
u64 length;
|
|
u64 length;
|
|
|
|
+ u64 stripe_len;
|
|
u64 devid;
|
|
u64 devid;
|
|
u8 uuid[BTRFS_UUID_SIZE];
|
|
u8 uuid[BTRFS_UUID_SIZE];
|
|
int num_stripes;
|
|
int num_stripes;
|
|
@@ -6219,6 +6220,37 @@ static int read_one_chunk(struct btrfs_root *root, struct btrfs_key *key,
|
|
|
|
|
|
logical = key->offset;
|
|
logical = key->offset;
|
|
length = btrfs_chunk_length(leaf, chunk);
|
|
length = btrfs_chunk_length(leaf, chunk);
|
|
|
|
+ stripe_len = btrfs_chunk_stripe_len(leaf, chunk);
|
|
|
|
+ num_stripes = btrfs_chunk_num_stripes(leaf, chunk);
|
|
|
|
+ /* Validation check */
|
|
|
|
+ if (!num_stripes) {
|
|
|
|
+ btrfs_err(root->fs_info, "invalid chunk num_stripes: %u",
|
|
|
|
+ num_stripes);
|
|
|
|
+ return -EIO;
|
|
|
|
+ }
|
|
|
|
+ if (!IS_ALIGNED(logical, root->sectorsize)) {
|
|
|
|
+ btrfs_err(root->fs_info,
|
|
|
|
+ "invalid chunk logical %llu", logical);
|
|
|
|
+ return -EIO;
|
|
|
|
+ }
|
|
|
|
+ if (!length || !IS_ALIGNED(length, root->sectorsize)) {
|
|
|
|
+ btrfs_err(root->fs_info,
|
|
|
|
+ "invalid chunk length %llu", length);
|
|
|
|
+ return -EIO;
|
|
|
|
+ }
|
|
|
|
+ if (!is_power_of_2(stripe_len)) {
|
|
|
|
+ btrfs_err(root->fs_info, "invalid chunk stripe length: %llu",
|
|
|
|
+ stripe_len);
|
|
|
|
+ return -EIO;
|
|
|
|
+ }
|
|
|
|
+ if (~(BTRFS_BLOCK_GROUP_TYPE_MASK | BTRFS_BLOCK_GROUP_PROFILE_MASK) &
|
|
|
|
+ btrfs_chunk_type(leaf, chunk)) {
|
|
|
|
+ btrfs_err(root->fs_info, "unrecognized chunk type: %llu",
|
|
|
|
+ ~(BTRFS_BLOCK_GROUP_TYPE_MASK |
|
|
|
|
+ BTRFS_BLOCK_GROUP_PROFILE_MASK) &
|
|
|
|
+ btrfs_chunk_type(leaf, chunk));
|
|
|
|
+ return -EIO;
|
|
|
|
+ }
|
|
|
|
|
|
read_lock(&map_tree->map_tree.lock);
|
|
read_lock(&map_tree->map_tree.lock);
|
|
em = lookup_extent_mapping(&map_tree->map_tree, logical, 1);
|
|
em = lookup_extent_mapping(&map_tree->map_tree, logical, 1);
|
|
@@ -6235,7 +6267,6 @@ static int read_one_chunk(struct btrfs_root *root, struct btrfs_key *key,
|
|
em = alloc_extent_map();
|
|
em = alloc_extent_map();
|
|
if (!em)
|
|
if (!em)
|
|
return -ENOMEM;
|
|
return -ENOMEM;
|
|
- num_stripes = btrfs_chunk_num_stripes(leaf, chunk);
|
|
|
|
map = kmalloc(map_lookup_size(num_stripes), GFP_NOFS);
|
|
map = kmalloc(map_lookup_size(num_stripes), GFP_NOFS);
|
|
if (!map) {
|
|
if (!map) {
|
|
free_extent_map(em);
|
|
free_extent_map(em);
|