]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
exfat: reduce unnecessary writes during mmap write
authorYuling Dong <yuling-dong@qq.com>
Thu, 15 Jan 2026 05:05:23 +0000 (13:05 +0800)
committerNamjae Jeon <linkinjeon@kernel.org>
Thu, 12 Feb 2026 12:21:47 +0000 (21:21 +0900)
During mmap write, exfat_page_mkwrite() currently extends
valid_size to the end of the VMA range. For a large mapping,
this can push valid_size far beyond the page that actually
triggered the fault, resulting in unnecessary writes.

valid_size only needs to extend to the end of the page
being written.

Signed-off-by: Yuling Dong <yuling-dong@qq.com>
Reviewed-by: Yuezhang Mo <Yuezhang.Mo@sony.com>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
fs/exfat/file.c

index b60ee0e1bec9344145a6328cdd727e35b317c08a..c0a19f8716e60c088819b3d05724955d609d0ec7 100644 (file)
@@ -708,21 +708,18 @@ static ssize_t exfat_file_read_iter(struct kiocb *iocb, struct iov_iter *iter)
 static vm_fault_t exfat_page_mkwrite(struct vm_fault *vmf)
 {
        int err;
-       struct vm_area_struct *vma = vmf->vma;
-       struct file *file = vma->vm_file;
-       struct inode *inode = file_inode(file);
+       struct inode *inode = file_inode(vmf->vma->vm_file);
        struct exfat_inode_info *ei = EXFAT_I(inode);
-       loff_t start, end;
+       loff_t new_valid_size;
 
        if (!inode_trylock(inode))
                return VM_FAULT_RETRY;
 
-       start = ((loff_t)vma->vm_pgoff << PAGE_SHIFT);
-       end = min_t(loff_t, i_size_read(inode),
-                       start + vma->vm_end - vma->vm_start);
+       new_valid_size = ((loff_t)vmf->pgoff + 1) << PAGE_SHIFT;
+       new_valid_size = min(new_valid_size, i_size_read(inode));
 
-       if (ei->valid_size < end) {
-               err = exfat_extend_valid_size(inode, end);
+       if (ei->valid_size < new_valid_size) {
+               err = exfat_extend_valid_size(inode, new_valid_size);
                if (err < 0) {
                        inode_unlock(inode);
                        return vmf_fs_error(err);