summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmds-check.c16
-rw-r--r--volumes.c8
-rw-r--r--volumes.h4
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) {
diff --git a/volumes.c b/volumes.c
index 9a5580ae..2d07e66a 100644
--- a/volumes.c
+++ b/volumes.c
@@ -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;
diff --git a/volumes.h b/volumes.h
index af7182b8..d7b7d3cc 100644
--- a/volumes.h
+++ b/volumes.h
@@ -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