diff options
-rw-r--r-- | cmds-check.c | 16 | ||||
-rw-r--r-- | volumes.c | 8 | ||||
-rw-r--r-- | volumes.h | 4 |
3 files changed, 24 insertions, 4 deletions
diff --git a/cmds-check.c b/cmds-check.c index 617b867f..1e1f7c9d 100644 --- a/cmds-check.c +++ b/cmds-check.c @@ -5220,8 +5220,24 @@ static int process_chunk_item(struct cache_tree *chunk_cache, int slot) { struct chunk_record *rec; + struct btrfs_chunk *chunk; int ret = 0; + chunk = btrfs_item_ptr(eb, slot, struct btrfs_chunk); + /* + * Do extra check for this chunk item, + * + * It's still possible one can craft a leaf with CHUNK_ITEM, with + * wrong onwer(3) out of chunk tree, to pass both chunk tree check + * and owner<->key_type check. + */ + ret = btrfs_check_chunk_valid(global_info->tree_root, eb, chunk, slot, + key->offset); + if (ret < 0) { + error("chunk(%llu, %llu) is not valid, ignore it", + key->offset, btrfs_chunk_length(eb, chunk)); + return 0; + } rec = btrfs_new_chunk_record(eb, key, slot); ret = insert_cache_extent(chunk_cache, &rec->cache); if (ret) { @@ -1614,10 +1614,10 @@ static struct btrfs_device *fill_missing_device(u64 devid) * slot == -1: SYSTEM chunk * return -EIO on error, otherwise return 0 */ -static int btrfs_check_chunk_valid(struct btrfs_root *root, - struct extent_buffer *leaf, - struct btrfs_chunk *chunk, - int slot, u64 logical) +int btrfs_check_chunk_valid(struct btrfs_root *root, + struct extent_buffer *leaf, + struct btrfs_chunk *chunk, + int slot, u64 logical) { u64 length; u64 stripe_len; @@ -226,4 +226,8 @@ int write_raid56_with_parity(struct btrfs_fs_info *info, struct extent_buffer *eb, struct btrfs_multi_bio *multi, u64 stripe_len, u64 *raid_map); +int btrfs_check_chunk_valid(struct btrfs_root *root, + struct extent_buffer *leaf, + struct btrfs_chunk *chunk, + int slot, u64 logical); #endif |