btrfs: tree-checker: introduce checks for FREE_SPACE_EXTENT

Introduce FREE_SPACE_EXTENT checks, which include:

- The key alignment check
  The objectid is the logical bytenr of the free space, and offset is the
  length of the free space, thus they should all be aligned to the fs
  block size.

- The item size check
  The FREE_SPACE_EXTENT item should have a size of zero.

Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Signed-off-by: Qu Wenruo <wqu@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
Qu Wenruo 2026-03-10 08:49:26 +10:30 committed by David Sterba
parent 52e71eb95c
commit b4a1246298

View File

@ -1992,6 +1992,32 @@ static int check_free_space_info(struct extent_buffer *leaf, struct btrfs_key *k
return 0;
}
static int check_free_space_extent(struct extent_buffer *leaf, struct btrfs_key *key, int slot)
{
struct btrfs_fs_info *fs_info = leaf->fs_info;
const u32 blocksize = fs_info->sectorsize;
if (unlikely(!IS_ALIGNED(key->objectid, blocksize))) {
generic_err(leaf, slot,
"free space extent key objectid is not aligned to %u, has " BTRFS_KEY_FMT,
blocksize, BTRFS_KEY_FMT_VALUE(key));
return -EUCLEAN;
}
if (unlikely(!IS_ALIGNED(key->offset, blocksize))) {
generic_err(leaf, slot,
"free space extent key offset is not aligned to %u, has " BTRFS_KEY_FMT,
blocksize, BTRFS_KEY_FMT_VALUE(key));
return -EUCLEAN;
}
if (unlikely(btrfs_item_size(leaf, slot) != 0)) {
generic_err(leaf, slot,
"invalid item size for free space info, has %u expect 0",
btrfs_item_size(leaf, slot));
return -EUCLEAN;
}
return 0;
}
/*
* Common point to switch the item-specific validation.
*/
@ -2058,6 +2084,9 @@ static enum btrfs_tree_block_status check_leaf_item(struct extent_buffer *leaf,
case BTRFS_FREE_SPACE_INFO_KEY:
ret = check_free_space_info(leaf, key, slot);
break;
case BTRFS_FREE_SPACE_EXTENT_KEY:
ret = check_free_space_extent(leaf, key, slot);
break;
}
if (unlikely(ret))