From aa6439028dc39230e62917ba0a7dafdc103564cf Mon Sep 17 00:00:00 2001 From: Josef Bacik Date: Sun, 4 Oct 2026 20:33:45 +0000 Subject: [PATCH] writeback: don't kick a missing wb for dontcache writes With CONFIG_CGROUP_WRITEBACK, inode->i_wb stays NULL until the inode is dirtied for the first time (folio_account_dirtied(), __mark_inode_dirty() or wbc_attach_fdatawrite_inode() attach it). generic_write_sync() calls filemap_dontcache_kick_writeback() for every IOCB_DONTCACHE write, including O_DIRECT ones, which never dirty the page cache. The function then passes the NULL returned by unlocked_inode_to_wb_begin() to wb_has_dirty_io(): fd = open("/dev/ram0", O_WRONLY | O_DIRECT); pwritev2(fd, &iov, 1, 0, RWF_DONTCACHE); BUG: KASAN: null-ptr-deref in filemap_dontcache_kick_writeback+0xec Oops: general protection fault, probably for non-canonical address RIP: 0010:filemap_dontcache_kick_writeback+0xfd/0x7a0 The task dies inside rcu_read_lock(). blkdev_write_iter() gets there for any block device whose page cache has not been dirtied yet. nfs_file_direct_write() calls generic_write_sync() the same way. An inode without a wb has never had dirty pages, so there is nothing to flush: skip the kick. Fixes: e1bf79628453 ("mm: kick writeback flusher for IOCB_DONTCACHE with targeted dirty tracking") Signed-off-by: Josef Bacik Signed-off-by: Christian Brauner (Amutable) --- fs/fs-writeback.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c index ac612c02ced9..15260cf2a29b 100644 --- a/fs/fs-writeback.c +++ b/fs/fs-writeback.c @@ -2579,8 +2579,9 @@ void filemap_dontcache_kick_writeback(struct address_space *mapping) struct wb_lock_cookie cookie = {}; bool need_wakeup = false; + /* An inode which was never dirtied has no wb and nothing to flush. */ wb = unlocked_inode_to_wb_begin(inode, &cookie); - if (wb_has_dirty_io(wb) && + if (wb && wb_has_dirty_io(wb) && !test_bit(WB_start_dontcache, &wb->state) && !test_and_set_bit(WB_start_dontcache, &wb->state)) { wb_get(wb);