* Re: [PATCH] netfs: fix ENOMEM handling in netfs_writepages() to drain all dirty folios
2026-07-07 5:25 [PATCH] netfs: fix ENOMEM handling in netfs_writepages() to drain all dirty folios Yun Zhou
@ 2026-07-07 6:13 ` Zhou, Yun
2026-07-19 12:32 ` Zhou, Yun
` (2 subsequent siblings)
3 siblings, 0 replies; 7+ messages in thread
From: Zhou, Yun @ 2026-07-07 6:13 UTC (permalink / raw)
To: dhowells, pc; +Cc: netfs, linux-fsdevel, linux-kernel
Tested-by: syzbot+0da43efa72f88bd3a8af@syzkaller.appspotmail.com
https://lore.kernel.org/all/6a4c9787.a1ad617e.25832.0006.GAE@google.com/
On 7/7/26 13:25, Yun Zhou wrote:
> When netfs_create_write_req() fails with -ENOMEM in netfs_writepages(),
> the couldnt_start error path redirties and unlocks the first folio, then
> calls writeback_iter() expecting it to return NULL. However, if the
> mapping contains multiple dirty folios, writeback_iter() returns the
> next one, triggering WARN_ON_ONCE(folio != NULL).
>
> This can be reproduced via 9p (cache=loose) with shared mmap writes and
> fault injection (fail_nth), where v9fs_mmap_vm_close() triggers
> writeback on a mapping with multiple dirty folios during mmap overlap.
>
> Fix this by looping over all remaining dirty folios in the ENOMEM path,
> redirtying and unlocking each one. This ensures all folios taken by the
> writeback iterator are properly released, and they will be retried on
> the next writeback cycle when memory is available.
>
> Reported-by: syzbot+0da43efa72f88bd3a8af@syzkaller.appspotmail.com
> Closes: https://syzkaller.appspot.com/bug?extid=0da43efa72f88bd3a8af
> Fixes: ac5f95ac5d6d ("netfs: Fix writeback error handling")
> Signed-off-by: Yun Zhou <yun.zhou@windriver.com>
> ---
> fs/netfs/write_issue.c | 9 +++++----
> 1 file changed, 5 insertions(+), 4 deletions(-)
>
> diff --git a/fs/netfs/write_issue.c b/fs/netfs/write_issue.c
> index f2761c99795a..5aa47128f7e7 100644
> --- a/fs/netfs/write_issue.c
> +++ b/fs/netfs/write_issue.c
> @@ -597,10 +597,11 @@ int netfs_writepages(struct address_space *mapping,
>
> couldnt_start:
> if (error == -ENOMEM) {
> - folio_redirty_for_writepage(wbc, folio);
> - folio_unlock(folio);
> - folio = writeback_iter(mapping, wbc, folio, &error);
> - WARN_ON_ONCE(folio != NULL);
> + /* Redirty all dirty folios and let writeback retry later. */
> + do {
> + folio_redirty_for_writepage(wbc, folio);
> + folio_unlock(folio);
> + } while ((folio = writeback_iter(mapping, wbc, folio, &error)));
> } else {
> netfs_kill_dirty_pages(mapping, wbc, folio);
> }
^ permalink raw reply [flat|nested] 7+ messages in thread* Re: [PATCH] netfs: fix ENOMEM handling in netfs_writepages() to drain all dirty folios
2026-07-07 5:25 [PATCH] netfs: fix ENOMEM handling in netfs_writepages() to drain all dirty folios Yun Zhou
2026-07-07 6:13 ` Zhou, Yun
@ 2026-07-19 12:32 ` Zhou, Yun
2026-07-22 14:04 ` Is writeback_iter() missing some error handling? -- was " David Howells
2026-07-23 4:59 ` Christoph Hellwig
3 siblings, 0 replies; 7+ messages in thread
From: Zhou, Yun @ 2026-07-19 12:32 UTC (permalink / raw)
To: dhowells, pc; +Cc: netfs, linux-fsdevel, linux-kernel, yun.zhou
Friendly ping.
On 7/7/2026 1:25 PM, Yun Zhou wrote:
> When netfs_create_write_req() fails with -ENOMEM in netfs_writepages(),
> the couldnt_start error path redirties and unlocks the first folio, then
> calls writeback_iter() expecting it to return NULL. However, if the
> mapping contains multiple dirty folios, writeback_iter() returns the
> next one, triggering WARN_ON_ONCE(folio != NULL).
>
> This can be reproduced via 9p (cache=loose) with shared mmap writes and
> fault injection (fail_nth), where v9fs_mmap_vm_close() triggers
> writeback on a mapping with multiple dirty folios during mmap overlap.
>
> Fix this by looping over all remaining dirty folios in the ENOMEM path,
> redirtying and unlocking each one. This ensures all folios taken by the
> writeback iterator are properly released, and they will be retried on
> the next writeback cycle when memory is available.
>
> Reported-by: syzbot+0da43efa72f88bd3a8af@syzkaller.appspotmail.com
> Closes: https://syzkaller.appspot.com/bug?extid=0da43efa72f88bd3a8af
> Fixes: ac5f95ac5d6d ("netfs: Fix writeback error handling")
> Signed-off-by: Yun Zhou <yun.zhou@windriver.com>
> ---
> fs/netfs/write_issue.c | 9 +++++----
> 1 file changed, 5 insertions(+), 4 deletions(-)
>
> diff --git a/fs/netfs/write_issue.c b/fs/netfs/write_issue.c
> index f2761c99795a..5aa47128f7e7 100644
> --- a/fs/netfs/write_issue.c
> +++ b/fs/netfs/write_issue.c
> @@ -597,10 +597,11 @@ int netfs_writepages(struct address_space *mapping,
>
> couldnt_start:
> if (error == -ENOMEM) {
> - folio_redirty_for_writepage(wbc, folio);
> - folio_unlock(folio);
> - folio = writeback_iter(mapping, wbc, folio, &error);
> - WARN_ON_ONCE(folio != NULL);
> + /* Redirty all dirty folios and let writeback retry later. */
> + do {
> + folio_redirty_for_writepage(wbc, folio);
> + folio_unlock(folio);
> + } while ((folio = writeback_iter(mapping, wbc, folio, &error)));
> } else {
> netfs_kill_dirty_pages(mapping, wbc, folio);
> }
^ permalink raw reply [flat|nested] 7+ messages in thread* Is writeback_iter() missing some error handling? -- was Re: [PATCH] netfs: fix ENOMEM handling in netfs_writepages() to drain all dirty folios
2026-07-07 5:25 [PATCH] netfs: fix ENOMEM handling in netfs_writepages() to drain all dirty folios Yun Zhou
2026-07-07 6:13 ` Zhou, Yun
2026-07-19 12:32 ` Zhou, Yun
@ 2026-07-22 14:04 ` David Howells
2026-07-23 3:43 ` Zhou, Yun
2026-07-23 4:59 ` Christoph Hellwig
3 siblings, 1 reply; 7+ messages in thread
From: David Howells @ 2026-07-22 14:04 UTC (permalink / raw)
To: Yun Zhou, Matthew Wilcox, Christoph Hellwig, Christian Brauner
Cc: dhowells, pc, netfs, linux-fsdevel, linux-kernel
Yun Zhou <yun.zhou@windriver.com> wrote:
> When netfs_create_write_req() fails with -ENOMEM in netfs_writepages(),
> the couldnt_start error path redirties and unlocks the first folio, then
> calls writeback_iter() expecting it to return NULL. However, if the
> mapping contains multiple dirty folios, writeback_iter() returns the
> next one, triggering WARN_ON_ONCE(folio != NULL).
>
> This can be reproduced via 9p (cache=loose) with shared mmap writes and
> fault injection (fail_nth), where v9fs_mmap_vm_close() triggers
> writeback on a mapping with multiple dirty folios during mmap overlap.
>
> Fix this by looping over all remaining dirty folios in the ENOMEM path,
> redirtying and unlocking each one. This ensures all folios taken by the
> writeback iterator are properly released, and they will be retried on
> the next writeback cycle when memory is available.
>
> ...
> --- a/fs/netfs/write_issue.c
> +++ b/fs/netfs/write_issue.c
> @@ -597,10 +597,11 @@ int netfs_writepages(struct address_space *mapping,
>
> couldnt_start:
> if (error == -ENOMEM) {
> - folio_redirty_for_writepage(wbc, folio);
> - folio_unlock(folio);
> - folio = writeback_iter(mapping, wbc, folio, &error);
> - WARN_ON_ONCE(folio != NULL);
> + /* Redirty all dirty folios and let writeback retry later. */
> + do {
> + folio_redirty_for_writepage(wbc, folio);
> + folio_unlock(folio);
> + } while ((folio = writeback_iter(mapping, wbc, folio, &error)));
> } else {
> netfs_kill_dirty_pages(mapping, wbc, folio);
> }
This seems like the wrong thing to do - or, at least, a bug in the
writeback_iter() API. Getting something like ENOMEM would seem to indicate
that all subsequent writeback_iter() calls in this loop are pointless as it
looks like the sequence will just go { lock, undirty, dirty, unlock } for each
folio.
David
^ permalink raw reply [flat|nested] 7+ messages in thread* Re: Is writeback_iter() missing some error handling? -- was Re: [PATCH] netfs: fix ENOMEM handling in netfs_writepages() to drain all dirty folios
2026-07-22 14:04 ` Is writeback_iter() missing some error handling? -- was " David Howells
@ 2026-07-23 3:43 ` Zhou, Yun
0 siblings, 0 replies; 7+ messages in thread
From: Zhou, Yun @ 2026-07-23 3:43 UTC (permalink / raw)
To: David Howells, Matthew Wilcox, Christoph Hellwig,
Christian Brauner
Cc: pc, netfs, linux-fsdevel, linux-kernel
On 7/22/26 22:04, David Howells wrote:
> Yun Zhou <yun.zhou@windriver.com> wrote:
>
>> couldnt_start:
>> if (error == -ENOMEM) {
>> - folio_redirty_for_writepage(wbc, folio);
>> - folio_unlock(folio);
>> - folio = writeback_iter(mapping, wbc, folio, &error);
>> - WARN_ON_ONCE(folio != NULL);
>> + /* Redirty all dirty folios and let writeback retry later. */
>> + do {
>> + folio_redirty_for_writepage(wbc, folio);
>> + folio_unlock(folio);
>> + } while ((folio = writeback_iter(mapping, wbc, folio, &error)));
>> } else {
>> netfs_kill_dirty_pages(mapping, wbc, folio);
>> }
>
> This seems like the wrong thing to do - or, at least, a bug in the
> writeback_iter() API. Getting something like ENOMEM would seem to indicate
> that all subsequent writeback_iter() calls in this loop are pointless as it
> looks like the sequence will just go { lock, undirty, dirty, unlock } for each
> folio.
>
Thanks for the feedback. I understand the concern — the loop is indeed
doing mechanical { redirty, unlock } work that ideally writeback_iter()
could handle internally when the caller has nothing meaningful to do
with the folios.
However, given the current writeback_iter() API contract ("callers must
keep calling until it returns NULL"), I'm not sure there's a cleaner way
to handle this without a VFS/mm level change. And in the meantime,
syzbot is hitting this — the WARN fires and any folio returned beyond
the first is left locked.
Would it be acceptable to keep this as a minimal stopgap fix for the
immediate bug, with the understanding that it can be cleaned up later if
writeback_iter() gains an early-abort mechanism? Happy to adjust the
approach if you have something else in mind.
BR,
Yun
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] netfs: fix ENOMEM handling in netfs_writepages() to drain all dirty folios
2026-07-07 5:25 [PATCH] netfs: fix ENOMEM handling in netfs_writepages() to drain all dirty folios Yun Zhou
` (2 preceding siblings ...)
2026-07-22 14:04 ` Is writeback_iter() missing some error handling? -- was " David Howells
@ 2026-07-23 4:59 ` Christoph Hellwig
2026-07-23 7:25 ` Zhou, Yun
3 siblings, 1 reply; 7+ messages in thread
From: Christoph Hellwig @ 2026-07-23 4:59 UTC (permalink / raw)
To: Yun Zhou; +Cc: dhowells, pc, netfs, linux-fsdevel, linux-kernel
On Tue, Jul 07, 2026 at 01:25:55PM +0800, Yun Zhou wrote:
> When netfs_create_write_req() fails with -ENOMEM in netfs_writepages(),
> the couldnt_start error path redirties and unlocks the first folio,
writeback must use mempools to back resoures, or __GFP_NOFAIL if it
can't for some reason. -ENOMEM must not happend in writeback paths
or your toast. So please fix the cause of this error and not the
symptoms.
^ permalink raw reply [flat|nested] 7+ messages in thread* Re: [PATCH] netfs: fix ENOMEM handling in netfs_writepages() to drain all dirty folios
2026-07-23 4:59 ` Christoph Hellwig
@ 2026-07-23 7:25 ` Zhou, Yun
0 siblings, 0 replies; 7+ messages in thread
From: Zhou, Yun @ 2026-07-23 7:25 UTC (permalink / raw)
To: Christoph Hellwig; +Cc: dhowells, pc, netfs, linux-fsdevel, linux-kernel
On 7/23/26 12:59, Christoph Hellwig wrote:
> On Tue, Jul 07, 2026 at 01:25:55PM +0800, Yun Zhou wrote:
>> When netfs_create_write_req() fails with -ENOMEM in netfs_writepages(),
>> the couldnt_start error path redirties and unlocks the first folio,
>
> writeback must use mempools to back resoures, or __GFP_NOFAIL if it
> can't for some reason. -ENOMEM must not happend in writeback paths
> or your toast. So please fix the cause of this error and not the
> symptoms.
>
Thanks for the review. You're right - writeback should not fail with ENOMEM.
I'll follow your suggestion and use __GFP_NOFAIL for the allocation in
the writeback path. The ENOMEM here comes from rolling_buffer_init()
which uses plain GFP_NOFS for its folio_queue allocation.
Using mempools would be the more robust approach, but it requires adding
a new mempool, modifying the rolling_buffer_init() signature and all its
callers, plus the init/destroy lifecycle - a much larger change.
__GFP_NOFAIL is a minimal fix that achieves the same goal for the
writeback path.
Will send v2 shortly.
^ permalink raw reply [flat|nested] 7+ messages in thread