From: Qu Wenruo Date: Mon, 9 Mar 2026 22:19:26 +0000 (+1030) Subject: btrfs: tree-checker: introduce checks for FREE_SPACE_EXTENT X-Git-Tag: v7.1-rc1~231^2~53 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b4a1246298d9c0a7cbcbc05d437c5803eb6a9994;p=thirdparty%2Fkernel%2Flinux.git 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 --- diff --git a/fs/btrfs/tree-checker.c b/fs/btrfs/tree-checker.c index c4826b0484e6a..f4a8f1c643ed5 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))