Re: [PATCH v2] btrfs: tree-checker: introduce checks for FREE_SPACE_BITMAP
From: David Sterba
Date: Fri Mar 13 2026 - 15:43:17 EST
On Tue, Mar 10, 2026 at 06:56:06PM +0800, ZhengYuan Huang wrote:
> Introduce checks for FREE_SPACE_BITMAP item, which include:
>
> - Key alignment check
> Same as FREE_SPACE_EXTENT, the objectid is the logical bytenr of the
> free space, and offset is the length of the free space, so both
> should be aligned to the fs block size.
>
> - Non-zero range check
> A zero key->offset would describe an empty bitmap, which is invalid.
>
> - Item size check
> The item must hold exactly DIV_ROUND_UP(key->offset >> sectorsize_bits,
> BITS_PER_BYTE) bytes. A mismatch indicates a truncated or otherwise
> corrupt bitmap item; without this check, the bitmap loading path would
> walk past the end of the leaf and trigger a NULL dereference in
> assert_eb_folio_uptodate().
>
> Signed-off-by: ZhengYuan Huang <gality369@xxxxxxxxx>
> ---
> [CHANGELOG]
> v2:
> - Move the FREE_SPACE_BITMAP item size validation from
> load_free_space_bitmaps() in free-space-tree.c into tree-checker, so
> corrupt bitmap items are rejected when the leaf is read from disk.
> - Drop the extent_buffer_test_bit() range check added in v1.
> - Rework the fix to follow Qu Wenruo's suggested tree-checker based
> validation.
> ---
> fs/btrfs/tree-checker.c | 39 +++++++++++++++++++++++++++++++++++++++
> 1 file changed, 39 insertions(+)
>
> diff --git a/fs/btrfs/tree-checker.c b/fs/btrfs/tree-checker.c
> index c10b4c242acf..0f12fe462b6c 100644
> --- a/fs/btrfs/tree-checker.c
> +++ b/fs/btrfs/tree-checker.c
> @@ -1901,6 +1901,42 @@ static int check_dev_extent_item(const struct extent_buffer *leaf,
> return 0;
> }
>
> +static int check_free_space_bitmap(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;
> + u32 expected_item_size;
> +
> + if (unlikely(!IS_ALIGNED(key->objectid, blocksize) ||
> + !IS_ALIGNED(key->offset, blocksize))) {
> + generic_err(leaf, slot,
> + "free space bitmap key range is not aligned to %u, has (%llu %u %llu)",
We have a format specifier macro for keys, KEY_FMT, I'll fix it in git.
> + blocksize, key->objectid, key->type, key->offset);