Re: [PATCH v2 4/7] exfat: drop i_rwsem from exfat_page_mkwrite
From: Namjae Jeon
Date: Tue Oct 13 2026 - 21:20:51 EST
> @@ -969,8 +969,9 @@ static vm_fault_t exfat_page_mkwrite(struct vm_fault *vmf)
> loff_t new_valid_size, mmap_valid_size, fault_page_start;
> bool dirty = false;
>
> - if (!inode_trylock(inode))
> - return VM_FAULT_RETRY;
exfat_page_mkwrite() reads the file size before iomap_page_mkwrite()
locks the page. Because inode_trylock was removed, another thread can
grow the file in between. exfat_cont_expand() does not take
invalidate_lock, so the shared lock does not stop it.
mmap write fault ftruncate/fallocate
Snapshot i_size = 1000
new_valid_size = 1000
dirty = false
Extend i_size to 3000
valid_size stays 1000
iomap_page_mkwrite() locks folio
Checks the current i_size (3000) and succeeds
dirty is still false, so VDL is not advanced
MM makes the page writable
Store at offset 2000, no new page_mkwrite()
The data at offset 2000 is beyond valid_size, so it can later be read
as zero. Could you check and fix this race?
+ sb_start_pagefault(inode->i_sb);
+ file_update_time(vmf->vma->vm_file);
+ filemap_invalidate_lock_shared(inode->i_mapping);
With i_size = 12 KB and valid_size = 0, DIO write to [0, 4 KiB can
race with an mmap write fault at offset 8 KB. The fault zeroes and
dirties the gap [0, 8 KiB), then advances valid_size.
DIO write [0,4 KiB) mmap fault at 8 KiB
Starts writing data
Reads the gap as zero
Dirties pages 0 and 1
Advances valid_size
Completes
Post-DIO invalidation cannot remove
the dirty page
Writeback can overwrite DIO data with zeros
Removing inode_trylock() from exfat_page_mkwrite() can introduce
several racy issues. Could you check that the affected paths are
properly synchronized?
Thanks.