From b4a1246298d9c0a7cbcbc05d437c5803eb6a9994 Mon Sep 17 00:00:00 2001 From: Qu Wenruo Date: Tue, 10 Mar 2026 08:49:26 +1030 Subject: [PATCH] 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 Signed-off-by: Qu Wenruo Reviewed-by: David Sterba Signed-off-by: David Sterba --- fs/btrfs/tree-checker.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/fs/btrfs/tree-checker.c b/fs/btrfs/tree-checker.c index c4826b0484e6..f4a8f1c643ed 100644 --- a/fs/btrfs/tree-checker.c +++ b/fs/btrfs/tree-checker.c @@ -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))