]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
btrfs: fix an incorrect ASSERT() condition inside zstd_decompress_bio()
authorQu Wenruo <wqu@suse.com>
Thu, 19 Feb 2026 08:21:13 +0000 (18:51 +1030)
committerDavid Sterba <dsterba@suse.com>
Tue, 17 Mar 2026 10:43:08 +0000 (11:43 +0100)
[BUG]
When running btrfs/284 with 64K page size and 4K fs block size, it
crashes with the following ASSERT() triggered:

  assertion failed: folio_size(fi.folio) == blocksize :: 0, in fs/btrfs/zstd.c:603
  ------------[ cut here ]------------
  kernel BUG at fs/btrfs/zstd.c:603!
  Internal error: Oops - BUG: 00000000f2000800 [#1]  SMP
  CPU: 2 UID: 0 PID: 1183 Comm: kworker/u35:4 Not tainted 6.19.0-rc8-custom+ #185 PREEMPT(voluntary)
  Hardware name: QEMU KVM Virtual Machine, BIOS unknown 2/2/2022
  Workqueue: btrfs-endio simple_end_io_work [btrfs]
  pc : zstd_decompress_bio+0x4f0/0x508 [btrfs]
  lr : zstd_decompress_bio+0x4f0/0x508 [btrfs]
  Call trace:
   zstd_decompress_bio+0x4f0/0x508 [btrfs] (P)
   end_bbio_compressed_read+0x260/0x2c0 [btrfs]
   btrfs_bio_end_io+0xc4/0x258 [btrfs]
   btrfs_check_read_bio+0x424/0x7e0 [btrfs]
   simple_end_io_work+0x40/0xa8 [btrfs]
   process_one_work+0x168/0x3f0
   worker_thread+0x25c/0x398
   kthread+0x154/0x250
   ret_from_fork+0x10/0x20
  ---[ end trace 0000000000000000 ]---

[CAUSE]
Commit 1914b94231e9 ("btrfs: zstd: use folio_iter to handle
zstd_decompress_bio()") added the ASSERT() to make sure the folio size
matches the fs block size.

But the check is completely wrong, the original intention is to make
sure for bs > ps cases, we always got a large folio that covers a full fs
block.

However for bs < ps cases, a folio can never be smaller than page size,
and the ASSERT() gets triggered immediately.

[FIX]
Check the folio size against @min_folio_size instead, which will never
be smaller than PAGE_SIZE, and still cover bs > ps cases.

Fixes: 1914b94231e9 ("btrfs: zstd: use folio_iter to handle zstd_decompress_bio()")
Reviewed-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: Qu Wenruo <wqu@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
fs/btrfs/zstd.c

index 32fd7f5454d3c4102234d5c8520e8779d8fc130a..c002d18666b71d13df3816fc15224d797f42b884 100644 (file)
@@ -600,7 +600,7 @@ int zstd_decompress_bio(struct list_head *ws, struct compressed_bio *cb)
        bio_first_folio(&fi, &cb->bbio.bio, 0);
        if (unlikely(!fi.folio))
                return -EINVAL;
-       ASSERT(folio_size(fi.folio) == blocksize);
+       ASSERT(folio_size(fi.folio) == min_folio_size);
 
        stream = zstd_init_dstream(
                        ZSTD_BTRFS_MAX_INPUT, workspace->mem, workspace->size);