btrfs-progs: kernel-shared: sync tree-checker.c
Sync from kernel 6.12 queue: - dir type range - DEV_EXTENT item checks Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
parent
158a25af0d
commit
bc2317381d
|
@ -585,9 +585,10 @@ static int check_dir_item(struct extent_buffer *leaf,
|
||||||
|
|
||||||
/* dir type check */
|
/* dir type check */
|
||||||
dir_type = btrfs_dir_ftype(leaf, di);
|
dir_type = btrfs_dir_ftype(leaf, di);
|
||||||
if (unlikely(dir_type >= BTRFS_FT_MAX)) {
|
if (unlikely(dir_type <= BTRFS_FT_UNKNOWN ||
|
||||||
|
dir_type >= BTRFS_FT_MAX)) {
|
||||||
dir_item_err(leaf, slot,
|
dir_item_err(leaf, slot,
|
||||||
"invalid dir item type, have %u expect [0, %u)",
|
"invalid dir item type, have %u expect (0, %u)",
|
||||||
dir_type, BTRFS_FT_MAX);
|
dir_type, BTRFS_FT_MAX);
|
||||||
return -EUCLEAN;
|
return -EUCLEAN;
|
||||||
}
|
}
|
||||||
|
@ -1737,6 +1738,72 @@ static int check_raid_stripe_extent(const struct extent_buffer *leaf,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int check_dev_extent_item(const struct extent_buffer *leaf,
|
||||||
|
const struct btrfs_key *key,
|
||||||
|
int slot,
|
||||||
|
struct btrfs_key *prev_key)
|
||||||
|
{
|
||||||
|
struct btrfs_dev_extent *de;
|
||||||
|
const u32 sectorsize = leaf->fs_info->sectorsize;
|
||||||
|
|
||||||
|
de = btrfs_item_ptr(leaf, slot, struct btrfs_dev_extent);
|
||||||
|
/* Basic fixed member checks. */
|
||||||
|
if (unlikely(btrfs_dev_extent_chunk_tree(leaf, de) !=
|
||||||
|
BTRFS_CHUNK_TREE_OBJECTID)) {
|
||||||
|
generic_err(leaf, slot,
|
||||||
|
"invalid dev extent chunk tree id, has %llu expect %llu",
|
||||||
|
btrfs_dev_extent_chunk_tree(leaf, de),
|
||||||
|
BTRFS_CHUNK_TREE_OBJECTID);
|
||||||
|
return -EUCLEAN;
|
||||||
|
}
|
||||||
|
if (unlikely(btrfs_dev_extent_chunk_objectid(leaf, de) !=
|
||||||
|
BTRFS_FIRST_CHUNK_TREE_OBJECTID)) {
|
||||||
|
generic_err(leaf, slot,
|
||||||
|
"invalid dev extent chunk objectid, has %llu expect %llu",
|
||||||
|
btrfs_dev_extent_chunk_objectid(leaf, de),
|
||||||
|
BTRFS_FIRST_CHUNK_TREE_OBJECTID);
|
||||||
|
return -EUCLEAN;
|
||||||
|
}
|
||||||
|
/* Alignment check. */
|
||||||
|
if (unlikely(!IS_ALIGNED(key->offset, sectorsize))) {
|
||||||
|
generic_err(leaf, slot,
|
||||||
|
"invalid dev extent key.offset, has %llu not aligned to %u",
|
||||||
|
key->offset, sectorsize);
|
||||||
|
return -EUCLEAN;
|
||||||
|
}
|
||||||
|
if (unlikely(!IS_ALIGNED(btrfs_dev_extent_chunk_offset(leaf, de),
|
||||||
|
sectorsize))) {
|
||||||
|
generic_err(leaf, slot,
|
||||||
|
"invalid dev extent chunk offset, has %llu not aligned to %u",
|
||||||
|
btrfs_dev_extent_chunk_objectid(leaf, de),
|
||||||
|
sectorsize);
|
||||||
|
return -EUCLEAN;
|
||||||
|
}
|
||||||
|
if (unlikely(!IS_ALIGNED(btrfs_dev_extent_length(leaf, de),
|
||||||
|
sectorsize))) {
|
||||||
|
generic_err(leaf, slot,
|
||||||
|
"invalid dev extent length, has %llu not aligned to %u",
|
||||||
|
btrfs_dev_extent_length(leaf, de), sectorsize);
|
||||||
|
return -EUCLEAN;
|
||||||
|
}
|
||||||
|
/* Overlap check with previous dev extent. */
|
||||||
|
if (slot && prev_key->objectid == key->objectid &&
|
||||||
|
prev_key->type == key->type) {
|
||||||
|
struct btrfs_dev_extent *prev_de;
|
||||||
|
u64 prev_len;
|
||||||
|
|
||||||
|
prev_de = btrfs_item_ptr(leaf, slot - 1, struct btrfs_dev_extent);
|
||||||
|
prev_len = btrfs_dev_extent_length(leaf, prev_de);
|
||||||
|
if (unlikely(prev_key->offset + prev_len > key->offset)) {
|
||||||
|
generic_err(leaf, slot,
|
||||||
|
"dev extent overlap, prev offset %llu len %llu current offset %llu",
|
||||||
|
prev_key->objectid, prev_len, key->offset);
|
||||||
|
return -EUCLEAN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Common point to switch the item-specific validation.
|
* Common point to switch the item-specific validation.
|
||||||
*/
|
*/
|
||||||
|
@ -1777,6 +1844,9 @@ static enum btrfs_tree_block_status check_leaf_item(struct extent_buffer *leaf,
|
||||||
case BTRFS_DEV_ITEM_KEY:
|
case BTRFS_DEV_ITEM_KEY:
|
||||||
ret = check_dev_item(leaf, key, slot);
|
ret = check_dev_item(leaf, key, slot);
|
||||||
break;
|
break;
|
||||||
|
case BTRFS_DEV_EXTENT_KEY:
|
||||||
|
ret = check_dev_extent_item(leaf, key, slot, prev_key);
|
||||||
|
break;
|
||||||
case BTRFS_INODE_ITEM_KEY:
|
case BTRFS_INODE_ITEM_KEY:
|
||||||
ret = check_inode_item(leaf, key, slot);
|
ret = check_inode_item(leaf, key, slot);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -54,6 +54,7 @@ enum btrfs_tree_block_status {
|
||||||
BTRFS_TREE_BLOCK_INVALID_BLOCKPTR,
|
BTRFS_TREE_BLOCK_INVALID_BLOCKPTR,
|
||||||
BTRFS_TREE_BLOCK_INVALID_ITEM,
|
BTRFS_TREE_BLOCK_INVALID_ITEM,
|
||||||
BTRFS_TREE_BLOCK_INVALID_OWNER,
|
BTRFS_TREE_BLOCK_INVALID_OWNER,
|
||||||
|
BTRFS_TREE_BLOCK_WRITTEN_NOT_SET,
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Reference in New Issue