mirror of
https://github.com/torvalds/linux.git
synced 2026-11-07 06:17:02 +01:00
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: e1bf796284 ("mm: kick writeback flusher for IOCB_DONTCACHE with targeted dirty tracking")
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
This commit is contained in:
parent
b14fcabd34
commit
aa6439028d
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user