From 646df471c37483eb31548d76a1b062775db71d60 Mon Sep 17 00:00:00 2001 From: Chi Zhiling Date: Sun, 4 Oct 2026 18:19:31 +0800 Subject: [PATCH] exfat: hold the invalidate lock while truncating truncate_setsize() ends in truncate_inode_pages(), which is documented as being "Called under (and serialised by) inode->i_rwsem and mapping->invalidate_lock". Hold invalidate_lock while executing truncate_setsize() to ensure that truncate and mmap writes are mutually exclusive. This can simplify the handling in exfat_page_mkwrite(). Fixes: 82a81a7352bc ("exfat: add iomap buffered I/O support") Cc: stable@vger.kernel.org Signed-off-by: Chi Zhiling Signed-off-by: Namjae Jeon --- fs/exfat/file.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/fs/exfat/file.c b/fs/exfat/file.c index 87afb6bffd35..871011750990 100644 --- a/fs/exfat/file.c +++ b/fs/exfat/file.c @@ -413,6 +413,7 @@ int exfat_setattr(const struct mnt_idmap *idmap, struct dentry *dentry, * about to be freed. */ inode_dio_wait(inode); + filemap_invalidate_lock(inode->i_mapping); truncate_setsize(inode, attr->ia_size); /* @@ -420,6 +421,7 @@ int exfat_setattr(const struct mnt_idmap *idmap, struct dentry *dentry, * is already written by it, so mark_inode_dirty() is unneeded. */ exfat_truncate(inode); + filemap_invalidate_unlock(inode->i_mapping); } else mark_inode_dirty(inode); @@ -784,8 +786,10 @@ static int exfat_extend_valid_size(struct inode *inode, loff_t new_valid_size) ret = exfat_zero_new_range(inode, gap_start, new_valid_size); filemap_invalidate_unlock(inode->i_mapping); if (ret) { + filemap_invalidate_lock(inode->i_mapping); truncate_setsize(inode, old_valid_size); exfat_truncate(inode); + filemap_invalidate_unlock(inode->i_mapping); return ret; }