Re: [PATCH/RFC] btrfs: fix folio lock leak in writepage_delalloc() for folios dirtied behind btrfs' back
From: Qu Wenruo
Date: Wed Jul 22 2026 - 05:40:08 EST
在 2026/7/22 18:59, Christian Borntraeger 写道:
Am 22.07.26 um 10:59 schrieb Qu Wenruo:
So I now have an userspace O_DIRECT reproducer outside of KVM. (attached) which gave me (on an s390 system, though)
在 2026/7/22 18:05, Christian Borntraeger 写道:
Am 21.07.26 um 23:07 schrieb Qu Wenruo:
First, thank you for taking the time to look into this and trying to understand
things and trying to explain things. this is highly appreciated.
I am still trying to fully understand this myself. A question:
在 2026/7/22 04:41, Christian Borntraeger 写道:
A folio can carry the folio-level dirty flag while its btrfs subpage
dirty bitmap is empty: btrfs data mappings use filemap_dirty_folio(),
so a generic folio_mark_dirty() call sets only the folio flag and the
xarray tag, without setting any subpage dirty bit and without a
delalloc reservation. The typical source is set_page_dirty_lock() on
a GUP pin,
Shouldn't such folio got its ->page_mkwrite() callback get called first?
Isnt that called implicitely at pin time?
I have to admit, I'm not an expert on the MM part, I'm mostly a simple user of the existing MM interfaces.
AFAIK, the last time I brought this thing up, Christoph mentioned that dirtying-folio-without-notifying-fs is a bug, and fs should not and is not able to handle such situation anyway.
And that idea makes a lot of sense to me.
So adding MM list for more help.
Thanks a lot, I can also reproduce it on arm64 (64K page size).
This is super bad, as we have just removed a lot of folio ordered related code to detect such problem.
I'll also check if it's some recent btrfs changes making it worse.
Thanks,
Qu
[ 189.067731] sysrq: Show Blocked State
[ 189.067872] task:kworker/u1665:5 state:D stack:0 pid:1363 tgid:1363 ppid:2 task_flags:0x4208060 flags:0x00000000
[ 189.067877] Workqueue: writeback wb_workfn (flush-btrfs-1)
[ 189.067884] Call Trace:
[ 189.067886] [<000003a8b2e19284>] __schedule+0x374/0x900
[ 189.067891] [<000003a8b2e1984c>] schedule+0x3c/0xf0
[ 189.067894] [<000003a8b2e1996c>] io_schedule+0x2c/0x40
[ 189.067896] [<000003a8b219d158>] folio_wait_bit_common+0x198/0x3b0
[ 189.067902] [<000003a8b263e2e8>] extent_write_cache_pages+0x348/0x4d0
[ 189.067907] [<000003a8b263ea0a>] btrfs_writepages+0x6a/0xd0
[ 189.067910] [<000003a8b21ad444>] do_writepages+0xd4/0x190
[ 189.067915] [<000003a8b2324590>] __writeback_single_inode+0x50/0x310
[ 189.067917] [<000003a8b2324b1a>] writeback_sb_inodes+0x2ca/0x690
[ 189.067919] [<000003a8b2324f36>] __writeback_inodes_wb+0x56/0x140
[ 189.067921] [<000003a8b2325498>] wb_writeback+0x368/0x460
[ 189.067923] [<000003a8b23258c6>] wb_do_writeback+0x336/0x3d0
[ 189.067925] [<000003a8b2325d2a>] wb_workfn+0x5a/0x1d0
[ 189.067927] [<000003a8b1f0cee2>] process_one_work+0x1d2/0x480
[ 189.067932] [<000003a8b1f0df30>] worker_thread+0x210/0x420
[ 189.067935] [<000003a8b1f190b8>] kthread+0x148/0x170
[ 189.067939] [<000003a8b1e90358>] __ret_from_fork+0x48/0x220
[ 189.067941] [<000003a8b2e2426a>] ret_from_fork+0xa/0x30
[ 189.067994] task:oob-dirty-repro state:D stack:0 pid:8152 tgid:8151 ppid:7260 task_flags:0x400040 flags:0x00000800
[ 189.067997] Call Trace:
[ 189.067998] [<000003a8b2e19284>] __schedule+0x374/0x900
[ 189.068050] [<000003a8b2e1984c>] schedule+0x3c/0xf0
[ 189.068052] [<000003a8b2e1996c>] io_schedule+0x2c/0x40
[ 189.068054] [<000003a8b219d158>] folio_wait_bit_common+0x198/0x3b0
[ 189.068057] [<000003a8b263e2e8>] extent_write_cache_pages+0x348/0x4d0
[ 189.068061] [<000003a8b263ea0a>] btrfs_writepages+0x6a/0xd0
[ 189.068063] [<000003a8b21ad444>] do_writepages+0xd4/0x190
[ 189.068066] [<000003a8b2199dec>] filemap_writeback+0xbc/0x100
[ 189.068069] [<000003a8b2199e5a>] filemap_fdatawrite_range+0x2a/0x40
[ 189.068072] [<000003a8b2637d3c>] btrfs_start_ordered_extent_nowriteback+0x18c/0x1d0
[ 189.068074] [<000003a8b26260ce>] btrfs_page_mkwrite+0x22e/0x8d0
[ 189.068079] [<000003a8b21f89d0>] do_page_mkwrite+0x60/0xf0
[ 189.068084] [<000003a8b21ffa64>] do_wp_page+0x134/0x660
[ 189.068086] [<000003a8b2206584>] __handle_mm_fault+0x1c4/0x5a0
[ 189.068088] [<000003a8b22069f0>] handle_mm_fault+0x90/0x230
[ 189.068090] [<000003a8b1ebfbd0>] do_exception+0x190/0x560
[ 189.068094] [<000003a8b2e136c0>] __do_pgm_check+0x1b0/0x370
[ 189.068098] [<000003a8b2e243a4>] pgm_check_handler+0x114/0x160
[ 189.068101] [<000003a8b283135e>] _copy_to_iter+0x6e/0x870
[ 189.068106] [<000003a8b2831c4a>] copy_page_to_iter+0xea/0x160
[ 189.068108] [<000003a8b219ff8c>] filemap_read+0x1ec/0x400
[ 189.068109] [<000003a8b22d0a70>] vfs_read+0x210/0x370
[ 189.068112] [<000003a8b22d1694>] ksys_pread64+0xa4/0xd0
[ 189.068114] [<000003a8b2e13b7e>] __do_syscall+0x14e/0x590
[ 189.068117] [<000003a8b2e24242>] system_call+0x72/0x90
[ 189.068120] task:oob-dirty-repro state:D stack:0 pid:8153 tgid:8151 ppid:7260 task_flags:0x400040 flags:0x00000000
[ 189.068123] Call Trace:
[ 189.068124] [<000003a8b2e19284>] __schedule+0x374/0x900
[ 189.068126] [<000003a8b2e1984c>] schedule+0x3c/0xf0
[ 189.068128] [<000003a8b2e1996c>] io_schedule+0x2c/0x40
[ 189.068130] [<000003a8b219d158>] folio_wait_bit_common+0x198/0x3b0
[ 189.068133] [<000003a8b263e2e8>] extent_write_cache_pages+0x348/0x4d0
[ 189.068136] [<000003a8b263ea0a>] btrfs_writepages+0x6a/0xd0
[ 189.068138] [<000003a8b21ad444>] do_writepages+0xd4/0x190
[ 189.068141] [<000003a8b2199dec>] filemap_writeback+0xbc/0x100
[ 189.068144] [<000003a8b2199e5a>] filemap_fdatawrite_range+0x2a/0x40
[ 189.068146] [<000003a8b2637d3c>] btrfs_start_ordered_extent_nowriteback+0x18c/0x1d0
[ 189.068149] [<000003a8b26260ce>] btrfs_page_mkwrite+0x22e/0x8d0
[ 189.068152] [<000003a8b21f89d0>] do_page_mkwrite+0x60/0xf0
[ 189.068154] [<000003a8b21ffa64>] do_wp_page+0x134/0x660
[ 189.068156] [<000003a8b2206584>] __handle_mm_fault+0x1c4/0x5a0
[ 189.068158] [<000003a8b22069f0>] handle_mm_fault+0x90/0x230
[ 189.068160] [<000003a8b1ebfbd0>] do_exception+0x190/0x560
[ 189.068163] [<000003a8b2e136c0>] __do_pgm_check+0x1b0/0x370
[ 189.068165] [<000003a8b2e243a4>] pgm_check_handler+0x114/0x160
[ 189.068168] [<000003a8b283135e>] _copy_to_iter+0x6e/0x870
[ 189.068170] [<000003a8b2831c4a>] copy_page_to_iter+0xea/0x160
[ 189.068172] [<000003a8b219ff8c>] filemap_read+0x1ec/0x400
[ 189.068174] [<000003a8b22d0a70>] vfs_read+0x210/0x370
[ 189.068176] [<000003a8b22d1694>] ksys_pread64+0xa4/0xd0
[ 189.068178] [<000003a8b2e13b7e>] __do_syscall+0x14e/0x590
[ 189.068181] [<000003a8b2e24242>] system_call+0x72/0x90
[ 189.068184] task:oob-dirty-repro state:D stack:0 pid:8154 tgid:8151 ppid:7260 task_flags:0x400040 flags:0x00000000
[ 189.068187] Call Trace:
[ 189.068188] [<000003a8b2e19284>] __schedule+0x374/0x900
[ 189.068190] [<000003a8b2e1984c>] schedule+0x3c/0xf0
[ 189.068192] [<000003a8b2e1996c>] io_schedule+0x2c/0x40
[ 189.068193] [<000003a8b219d158>] folio_wait_bit_common+0x198/0x3b0
[ 189.068196] [<000003a8b26260fc>] btrfs_page_mkwrite+0x25c/0x8d0
[ 189.068199] [<000003a8b21f89d0>] do_page_mkwrite+0x60/0xf0
[ 189.068202] [<000003a8b21ffa64>] do_wp_page+0x134/0x660
[ 189.068203] [<000003a8b2206584>] __handle_mm_fault+0x1c4/0x5a0
[ 189.068206] [<000003a8b22069f0>] handle_mm_fault+0x90/0x230
[ 189.068208] [<000003a8b1ebfbd0>] do_exception+0x190/0x560
[ 189.068210] [<000003a8b2e136c0>] __do_pgm_check+0x1b0/0x370
[ 189.068213] [<000003a8b2e243a4>] pgm_check_handler+0x114/0x160
[ 189.068215] [<000003a8b283135e>] _copy_to_iter+0x6e/0x870
[ 189.068218] [<000003a8b2831c4a>] copy_page_to_iter+0xea/0x160
[ 189.068219] [<000003a8b219ff8c>] filemap_read+0x1ec/0x400
[ 189.068221] [<000003a8b22d0a70>] vfs_read+0x210/0x370
[ 189.068223] [<000003a8b22d1694>] ksys_pread64+0xa4/0xd0
[ 189.068225] [<000003a8b2e13b7e>] __do_syscall+0x14e/0x590
[ 189.068228] [<000003a8b2e24242>] system_call+0x72/0x90
[ 189.068231] task:oob-dirty-repro state:D stack:0 pid:8155 tgid:8151 ppid:7260 task_flags:0x400040 flags:0x00000000
[ 189.068234] Call Trace:
[ 189.068235] [<000003a8b2e19284>] __schedule+0x374/0x900
[ 189.068237] [<000003a8b2e1984c>] schedule+0x3c/0xf0
[ 189.068239] [<000003a8b2e1996c>] io_schedule+0x2c/0x40
[ 189.068241] [<000003a8b219d158>] folio_wait_bit_common+0x198/0x3b0
[ 189.068244] [<000003a8b263e2e8>] extent_write_cache_pages+0x348/0x4d0
[ 189.068246] [<000003a8b263ea0a>] btrfs_writepages+0x6a/0xd0
[ 189.068249] [<000003a8b21ad444>] do_writepages+0xd4/0x190
[ 189.068252] [<000003a8b2199dec>] filemap_writeback+0xbc/0x100
[ 189.068255] [<000003a8b2199e5a>] filemap_fdatawrite_range+0x2a/0x40
[ 189.068257] [<000003a8b2637d3c>] btrfs_start_ordered_extent_nowriteback+0x18c/0x1d0
[ 189.068260] [<000003a8b26260ce>] btrfs_page_mkwrite+0x22e/0x8d0
[ 189.068263] [<000003a8b21f89d0>] do_page_mkwrite+0x60/0xf0
[ 189.068265] [<000003a8b21ffa64>] do_wp_page+0x134/0x660
[ 189.068267] [<000003a8b2206584>] __handle_mm_fault+0x1c4/0x5a0
[ 189.068269] [<000003a8b22069f0>] handle_mm_fault+0x90/0x230
[ 189.068271] [<000003a8b1ebfbd0>] do_exception+0x190/0x560
[ 189.068274] [<000003a8b2e136c0>] __do_pgm_check+0x1b0/0x370
[ 189.068277] [<000003a8b2e243a4>] pgm_check_handler+0x114/0x160
[ 189.068279] [<000003a8b283135e>] _copy_to_iter+0x6e/0x870
[ 189.068281] [<000003a8b2831c4a>] copy_page_to_iter+0xea/0x160
[ 189.068283] [<000003a8b219ff8c>] filemap_read+0x1ec/0x400
[ 189.068285] [<000003a8b22d0a70>] vfs_read+0x210/0x370
[ 189.068287] [<000003a8b22d1694>] ksys_pread64+0xa4/0xd0
[ 189.068289] [<000003a8b2e13b7e>] __do_syscall+0x14e/0x590
[ 189.068292] [<000003a8b2e24242>] system_call+0x72/0x90
[ 189.068294] task:oob-dirty-repro state:D stack:0 pid:8156 tgid:8151 ppid:7260 task_flags:0x400040 flags:0x00000000
[ 189.068297] Call Trace:
[ 189.068298] [<000003a8b2e19284>] __schedule+0x374/0x900
[ 189.068300] [<000003a8b2e1984c>] schedule+0x3c/0xf0
[ 189.068302] [<000003a8b2e1996c>] io_schedule+0x2c/0x40
[ 189.068304] [<000003a8b219d158>] folio_wait_bit_common+0x198/0x3b0
[ 189.068307] [<000003a8b263e2e8>] extent_write_cache_pages+0x348/0x4d0
[ 189.068310] [<000003a8b263ea0a>] btrfs_writepages+0x6a/0xd0
[ 189.068313] [<000003a8b21ad444>] do_writepages+0xd4/0x190
[ 189.068315] [<000003a8b2199dec>] filemap_writeback+0xbc/0x100
[ 189.068318] [<000003a8b2199e5a>] filemap_fdatawrite_range+0x2a/0x40
[ 189.068320] [<000003a8b232bbf2>] sync_file_range+0x122/0x150
[ 189.068323] [<000003a8b232bc84>] ksys_sync_file_range+0x64/0xb0
[ 189.068326] [<000003a8b232bd0a>] __s390x_sys_sync_file_range+0x3a/0x50
[ 189.068328] [<000003a8b2e13b7e>] __do_syscall+0x14e/0x590
[ 189.068331] [<000003a8b2e24242>] system_call+0x72/0x90