From: Qu Wenruo <wqu@suse.com>
To: linux-btrfs@vger.kernel.org
Subject: Re: [PATCH v3 0/2] btrfs: remove the tailing zeros from compressed inline extents
Date: Mon, 21 Sep 2026 10:36:21 +0930 [thread overview]
Message-ID: <2f777aa2-bebb-4b21-9027-6a64371711ed@suse.com> (raw)
In-Reply-To: <cover.1789951424.git.wqu@suse.com>
在 2026/9/21 10:14, Qu Wenruo 写道:
> [CHANGELOG]
> v3:
> - Introduce an early i_size >= blocksize rejection to prevent race
> Previously we allow inline extents for i_size == blocksize case, as
> long as the compressed data can still be inlined.
>
> But that introduce a race with setsize(), which is masked by using
> blocksize for compression.
>
> When reverting back to using i_size for compression, we can get a much
> larger i_size than expectation.
>
> Close the race window by always requireing i_size < blocksize, which
> makes btrfs_setsize() to always wait for the folio held by us before
> updating the i_size.
>
> This unfortunately introduce a behavior change, so all the fixes tags
> are dropped.
Please drop the whole series.
Filipe's merged v3 fix is good enough, and the extra i_size related race
is very tricky to handle correctly.
The existing blocksize based compression so far is the safest solution,
the saved a dozen of bytes are not worthy for the extra races.
Thanks,
Qu
>
> This is exposed by Sashiko during review of v1 and v2 patchsets, and
> reproduced once during fstests runs, resulting the following
> warning without the new rejection:
>
> [ 497.553473] BTRFS info (device dm-2 state M): use lzo compression, level 1
> [ 497.599454] BTRFS info (device dm-2 state M): use zstd compression, level 3
> [ 497.661405] ------------[ cut here ]------------
> [ 497.661414] WARNING: zstd.c:41 at zstd_compress_bio+0x120a/0x1fb0 [btrfs], CPU#1: kworker/u47:5/3431
> [ 497.666534] Modules linked in: dm_flakey btrfs(OE) nls_ascii nls_cp437 vfat fat i2c_i801 joydev psmouse pcspkr iTCO_wdt i2c_smbus mousedev xor raid6_pq loop vsock_loopback vmw_vsock_virtio_transport_common vmw_vsock_vmci_transport vsock vmw_vmci qemu_fw_cfg ext4 crc16 mbcache jbd2 dm_mod virtio_net net_failover serio_raw virtio_rng virtio_balloon virtio_gpu virtio_scsi failover virtio_dma_buf lpc_ich virtio_blk [last unloaded: btrfs]
> [ 497.677435] CPU: 1 UID: 0 PID: 3431 Comm: kworker/u47:5 Tainted: G OE 7.3.0-rc3-custom+ #464 PREEMPT(full) 8f6fa45f5906dd4b1abb78057674460bd6af91c9
> [ 497.681556] Tainted: [O]=OOT_MODULE, [E]=UNSIGNED_MODULE
> [ 497.683051] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS unknown 02/02/2022
> [ 497.685450] Workqueue: writeback wb_workfn (flush-btrfs-222)
> [ 497.687235] RIP: 0010:zstd_compress_bio+0x120a/0x1fb0 [btrfs]
> [ 497.689061] Code: fd ff ff 48 89 ef e8 85 65 00 00 e9 db fd ff ff 48 89 df e8 38 e0 4b c2 e9 57 fe ff ff 48 89 d7 e8 2b e0 4b c2 e9 6f fa ff ff <0f> 0b e9 2c f0 ff ff e8 0a c5 ec c1 49 8d bf b8 01 00 00 48 b8 00
> [ 497.694043] RSP: 0018:ffff88810a17ece8 EFLAGS: 00010202
> [ 497.695504] RAX: 0000000000000011 RBX: ffff888102615e28 RCX: 0000001000000015
> [ 497.697482] RDX: 0000000100000011 RSI: 0000000000000002 RDI: ffff88810a17ec58
> [ 497.699455] RBP: 0000000000000011 R08: ffffffff846ca856 R09: ffff88810a17ec50
> [ 497.701424] R10: ffffed102142fd8b R11: 0000000000000010 R12: 0000000000000003
> [ 497.703444] R13: ffff888112695a00 R14: 000000000048f5e9 R15: ffff88819f5b0000
> [ 497.705410] FS: 0000000000000000(0000) GS:ffff8882aed9b000(0000) knlGS:0000000000000000
> [ 497.707610] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> [ 497.709251] CR2: 000055967f60f000 CR3: 0000000111372000 CR4: 0000000000f50ef0
> [ 497.711388] PKRU: 55555554
> [ 497.712204] Call Trace:
> [ 497.712923] <TASK>
> [ 497.713575] ? _raw_spin_unlock_bh+0xe/0x20
> [ 497.714781] ? zstd_find_workspace.isra.0+0x283/0x8b0 [btrfs 1621afd7f58f5561128c1bbfbe7eb177867269dc]
> [ 497.717434] ? kmem_cache_alloc_noprof+0x194/0x420
> [ 497.718798] ? zstd_get_workspace+0xde/0x2c0 [btrfs 1621afd7f58f5561128c1bbfbe7eb177867269dc]
> [ 497.721241] ? zstd_get_workspace+0x2c0/0x2c0 [btrfs 1621afd7f58f5561128c1bbfbe7eb177867269dc]
> [ 497.723730] ? __asan_memset+0x27/0x50
> [ 497.724907] ? btrfs_free_compr_folio+0x2c0/0x2c0 [btrfs 1621afd7f58f5561128c1bbfbe7eb177867269dc]
> [ 497.727535] btrfs_compress_bio+0x683/0xb90 [btrfs 1621afd7f58f5561128c1bbfbe7eb177867269dc]
> [ 497.729989] btrfs_run_delalloc_range+0x12d9/0x1ba0 [btrfs 1621afd7f58f5561128c1bbfbe7eb177867269dc]
> [ 497.732712] ? extent_writepage_io+0xe40/0xe40 [btrfs 1621afd7f58f5561128c1bbfbe7eb177867269dc]
> [ 497.735231] ? btrfs_copy_subpage_dirty_bitmap+0x98/0x620 [btrfs 1621afd7f58f5561128c1bbfbe7eb177867269dc]
> [ 497.737989] ? submit_uncompressed_range+0x260/0x260 [btrfs 1621afd7f58f5561128c1bbfbe7eb177867269dc]
> [ 497.740665] ? btrfs_folio_set_lock+0x15c/0x420 [btrfs 1621afd7f58f5561128c1bbfbe7eb177867269dc]
> [ 497.743162] writepage_delalloc+0x7d8/0x1270 [btrfs 1621afd7f58f5561128c1bbfbe7eb177867269dc]
> [ 497.745646] ? find_lock_delalloc_range+0x7b0/0x7b0 [btrfs 1621afd7f58f5561128c1bbfbe7eb177867269dc]
> [ 497.748277] ? tag_pages_for_writeback+0x205/0x2d0
> [ 497.749653] ? folio_mkclean+0x163/0x3a0
> [ 497.750784] ? __traceiter_remove_migration_pte+0xb0/0xb0
> [ 497.752297] ? folio_wait_writeback+0xa8/0x200
> [ 497.753574] extent_write_cache_pages+0xb59/0x1e30 [btrfs 1621afd7f58f5561128c1bbfbe7eb177867269dc]
> [ 497.756187] ? btrfs_do_readpage+0x2600/0x2600 [btrfs 1621afd7f58f5561128c1bbfbe7eb177867269dc]
> [ 497.758797] btrfs_writepages+0x1c2/0x4a0 [btrfs 1621afd7f58f5561128c1bbfbe7eb177867269dc]
> [ 497.761179] ? virtqueue_add_inbuf_ctx+0x2820/0x2820
> [ 497.762655] ? extent_write_locked_range+0x8f0/0x8f0 [btrfs 1621afd7f58f5561128c1bbfbe7eb177867269dc]
> [ 497.765264] ? blk_mq_tag_update_sched_shared_tags+0xf0/0xf0
> [ 497.766854] ? sg_init_table+0x19/0x60
> [ 497.767967] do_writepages+0x212/0x550
> [ 497.769062] ? _raw_spin_lock+0x84/0xe0
> [ 497.770185] ? writeback_set_ratelimit+0x120/0x120
> [ 497.771574] __writeback_single_inode+0xeb/0xba0
> [ 497.772902] ? _raw_spin_lock+0x84/0xe0
> [ 497.774015] ? sync_lazytime+0x330/0x330
> [ 497.775167] ? _raw_spin_unlock+0xe/0x20
> [ 497.776288] ? wbc_attach_and_unlock_inode+0x346/0x610
> [ 497.777741] writeback_sb_inodes+0x5a3/0xff0
> [ 497.779007] ? asm_common_interrupt+0x26/0x40
> [ 497.780399] ? __writeback_single_inode+0xba0/0xba0
> [ 497.781862] ? queue_io+0x2a3/0x480
> [ 497.782957] ? wb_update_bandwidth+0xd0/0xd0
> [ 497.784258] wb_writeback+0x1d9/0x780
> [ 497.785338] ? writeback_inodes_wb.constprop.0+0x1d0/0x1d0
> [ 497.786935] ? _raw_write_lock_irq+0xe0/0xe0
> [ 497.788340] ? psi_group_change+0x38d/0x750
> [ 497.789711] wb_workfn+0x1f6/0xc10
> [ 497.790877] ? _raw_spin_unlock+0xe/0x20
> [ 497.792082] ? sync_inode_metadata+0xd0/0xd0
> [ 497.793392] ? __schedule+0xe8d/0x5ec0
> [ 497.794549] ? max_active_store+0x100/0x100
> [ 497.795838] ? _raw_spin_lock_irq+0x8a/0xe0
> [ 497.797113] process_one_work+0x721/0x10b0
> [ 497.798376] ? io_schedule_timeout+0x130/0x130
> [ 497.799801] ? pwq_dec_nr_in_flight+0xfd0/0xfd0
> [ 497.801092] ? _raw_spin_lock_irq+0x8a/0xe0
> [ 497.802271] ? _raw_write_lock_irq+0xe0/0xe0
> [ 497.803477] worker_thread+0x536/0xda0
> [ 497.804548] ? rescuer_thread+0x1480/0x1480
> [ 497.805905] kthread+0x352/0x450
> [ 497.806874] ? recalc_sigpending+0x15c/0x200
> [ 497.808114] ? kthread_affine_node+0x300/0x300
> [ 497.809389] ret_from_fork+0x473/0x710
> [ 497.810484] ? exit_thread+0x70/0x70
> [ 497.811537] ? __switch_to+0x3ab/0xcf0
> [ 497.812645] ? kthread_affine_node+0x300/0x300
> [ 497.813930] ret_from_fork_asm+0x11/0x20
> [ 497.815060] </TASK>
> [ 497.815718] ---[ end trace 0000000000000000 ]---
> [ 497.817260] BTRFS warning (device dm-2): zstd compression level 3 failed, error 64 root 263 inode 264 offset 0
> [ 497.840873] BTRFS info (device dm-2 state M): use no compression
>
> v2:
> - Remove the block based space saving checks completely from lzo
> Zlib and ZSTD do not have block based space saving in the first place.
> It's the caller's responsibility to check, and inlined and regular
> extents have different requirements.
>
> This simplify the first patch a lot.
>
> - Update the cover letter
> Filipe's v3 fix is already merged, so we can not force push a fix but
> to co-operate the v3 fix.
>
> Commit 3eaf5f082c4c ("btrfs: extract inlined creation into a dedicated
> delalloc helper") changed the compression input from [0, i_size) to [0,
> blocksize), which caused two problems:
>
> - Other tools unable to decompress the inlined extent
> U-boot and btrfs-restore are affected, as they only allocated a buffer
> which is @ram_bytes sized.
> That buffer is too small to contain the decompressed data, which is
> @sectorsize.
>
> Those projects are fixed to have a more robust decompression routine
> which can handle both cases now.
>
> - Worse ratio for those compressed inline extent.
>
> For the same 3K 0xcd filled range, the results are small but
> observable, 48 vs 61 bytes.
>
> Filipe's v1 fix is very close to a proper fix, but btrfs will unable to
> create inlined extents for lzo.
> It turns out to be another bug in the copy_compressed_data_to_bio()
> function.
>
> Which is doing a premature block size based space saving checks,
> meanwhile all other algorithms do not have block sized based checks, but
> only a simple "@compressed >= @input" check.
> Zlib and Zstd all rely on the caller to do proper space saving checks,
> as regular and inlined extents have different requirements.
>
> So this series is to properly fix the bug, firstly fix the lzo
> regression which prevents inlined extent creation, then restore the old
> i_size based inline extent creation.
>
> To prevent i_size being updated during writeback, add a new i_size <
> blocksize requirement, so btrfs_setsize() will always wait for us before
> updating the i_size during expansion.
>
> However this introduces a new behavior change, that we can no longer
> create block sized (ram_bytes) inlined extents.
>
>
> Qu Wenruo (2):
> btrfs: lzo: fix space saving checks
> btrfs: remove the trailing zeros from compressed inline extent
>
> fs/btrfs/inode.c | 28 ++++++++++++++++++++++------
> fs/btrfs/lzo.c | 5 +++--
> 2 files changed, 25 insertions(+), 8 deletions(-)
>
prev parent reply other threads:[~2026-09-21 1:06 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-21 0:44 [PATCH v3 0/2] btrfs: remove the tailing zeros from compressed inline extents Qu Wenruo
2026-09-21 0:44 ` [PATCH v3 1/2] btrfs: lzo: fix space saving checks Qu Wenruo
2026-09-21 0:44 ` [PATCH v3 2/2] btrfs: remove the trailing zeros from compressed inline extent Qu Wenruo
2026-09-21 1:06 ` Qu Wenruo [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=2f777aa2-bebb-4b21-9027-6a64371711ed@suse.com \
--to=wqu@suse.com \
--cc=linux-btrfs@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox