Commit ff59f71f1c95 ("iomap: simplify writepages reclaim guard") removed the PF_KSWAPD exemption from the iomap_writepages() guard on the assumption that kswapd can no longer reach filesystem writeback now that pageout() returns PAGE_ACTIVATE for non-shmem, non-anon folios. That assumption only covers the folio reclaim path. kswapd can still reach filesystem writeback through the inode shrinkers, and syzbot reports exactly that on GFS2: WARNING: (current->flags & PF_MEMALLOC) in iomap_writepages kswapd -> balance_pgdat -> shrink_node -> shrink_slab -> super_cache_scan -> prune_icache_sb -> evict -> gfs2_evict_inode -> evict_linked_inode -> gfs2_log_flush -> gfs2_ordered_write -> filemap_fdatawrite -> do_writepages -> gfs2_writepages -> iomap_writepages Under memory pressure kswapd evicts GFS2 inodes whose glock is still dirty, and gfs2_evict_inode() -> gfs2_log_flush() -> gfs2_ordered_write() then writes back the ordered data of every inode on sd_log_ordered. This is long-standing, intentional behaviour: in the default data=ordered mode GFS2 must flush dirty data before the log commit that writes the metadata. Writeback from kswapd has been explicitly allowed since 2010, when the guard was still in XFS: commit d4f7a5cbd544 ("xfs: allow writeback from kswapd"), because the kswapd stack usage is low and it cannot deadlock on the filesystem. Beyond the noisy warning the new guard is actively harmful: it returns -EIO on every hit (WARN_ON_ONCE only limits the report), while gfs2_ordered_write() ignores the filemap_fdatawrite() return value, so the log commit proceeds with metadata even though the ordered data was never written, breaking the data-before-metadata ordering guarantee of data=ordered mode. Restore the historical semantics of the guard using the current_is_kswapd() helper that replaced the PF_KSWAPD flag: warn about and refuse writeback from direct or memcg reclaim, but allow it from kswapd, as was the case from 2010 until ff59f71f1c95. Fixes: ff59f71f1c95 ("iomap: simplify writepages reclaim guard") Reported-by: syzbot+5e659793378ad9e06387@syzkaller.appspotmail.com Closes: https://syzbot.org/bug?extid=5e659793378ad9e06387 Cc: Christian Brauner Cc: gfs2@lists.linux.dev Cc: Kefeng Wang Cc: Andrew Morton Cc: Shakeel Butt Cc: linux-xfs@vger.kernel.org Cc: linux-fsdevel@vger.kernel.org Cc: linux-kernel@vger.kernel.org Signed-off-by: Yiqing Wu --- fs/iomap/buffered-io.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/iomap/buffered-io.c b/fs/iomap/buffered-io.c index d6e2f1ded5ca..324da0f5cb29 100644 --- a/fs/iomap/buffered-io.c +++ b/fs/iomap/buffered-io.c @@ -2082,7 +2082,7 @@ iomap_writepages(struct iomap_writepage_ctx *wpc) * Writeback from reclaim context should never happen except in the case * of a VM regression so warn about it and refuse to write the data. */ - if (WARN_ON_ONCE((current->flags & PF_MEMALLOC))) + if (WARN_ON_ONCE((current->flags & PF_MEMALLOC) && !current_is_kswapd())) return -EIO; while ((folio = writeback_iter(mapping, wpc->wbc, folio, &error))) { -- 2.56.0