[PATCH v2 5/7] exfat: do not re-zero the valid range in exfat_page_mkwrite
From: Chi Zhiling
Date: Mon Oct 12 2026 - 23:41:52 EST
From: Chi Zhiling <chizhiling@xxxxxxxxxx>
valid_size is advanced before zeroed_size, and exfat_page_mkwrite() no
longer holds i_rwsem, so a fault can observe a zeroed_size that lags
valid_size. Zeroing the gap from zeroed_size then reads back and dirties
folios below valid_size that already hold valid data.
Start from max(valid_size, zeroed_size) instead, as
exfat_extend_valid_size() already does. The skipped range is either
already zeroed or already valid, so nothing that needs zeroing is missed.
Signed-off-by: Chi Zhiling <chizhiling@xxxxxxxxxx>
---
fs/exfat/file.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/fs/exfat/file.c b/fs/exfat/file.c
index a8c1f4757678..6209a991a118 100644
--- a/fs/exfat/file.c
+++ b/fs/exfat/file.c
@@ -965,8 +965,9 @@ static vm_fault_t exfat_page_mkwrite(struct vm_fault *vmf)
{
struct inode *inode = file_inode(vmf->vma->vm_file);
struct exfat_inode_info *ei = EXFAT_I(inode);
+ loff_t mmap_valid_size, fault_page_start;
+ loff_t old_valid_size, new_valid_size;
vm_fault_t ret;
- loff_t new_valid_size, mmap_valid_size, fault_page_start;
bool dirty = false;
sb_start_pagefault(inode->i_sb);
@@ -975,12 +976,14 @@ static vm_fault_t exfat_page_mkwrite(struct vm_fault *vmf)
mmap_valid_size = ((loff_t)vmf->pgoff + 1) << PAGE_SHIFT;
fault_page_start = ((loff_t)vmf->pgoff) << PAGE_SHIFT;
+ old_valid_size = exfat_get_valid_size(ei);
new_valid_size = min(mmap_valid_size, i_size_read(inode));
- if (exfat_get_valid_size(ei) < new_valid_size) {
+ if (old_valid_size < new_valid_size) {
loff_t zeroed_size = exfat_get_zeroed_size(ei);
if (zeroed_size < fault_page_start) {
+ loff_t gap_start = max(old_valid_size, zeroed_size);
int err;
/*
@@ -988,7 +991,7 @@ static vm_fault_t exfat_page_mkwrite(struct vm_fault *vmf)
* fault populated its folio and iomap_page_mkwrite()
* will dirty it.
*/
- err = exfat_prepare_valid_range(inode, zeroed_size,
+ err = exfat_prepare_valid_range(inode, gap_start,
fault_page_start);
if (err < 0) {
ret = vmf_fs_error(err);
--
2.53.0