Re: [PATCH v2 3/7] exfat: validate cached iomaps during buffered writes
From: Chi Zhiling
Date: Wed Oct 14 2026 - 03:12:35 EST
On 10/14/2026 9:19 AM, Namjae Jeon wrote:
+static bool exfat_iomap_valid(struct inode *inode, const struct iomap *iomap)exfat_write_iomap_begin() reads valid_size before
+{
+ struct folio *folio = iomap->private;
+ loff_t old_valid_size = iomap->validity_cookie;
+ loff_t valid_size = exfat_get_valid_size(EXFAT_I(inode));
+
+ if (valid_size == old_valid_size)
__exfat_iomap_begin() records the validity cookie. concurrent mmap
fault can advance valid_size between those reads, allowing the stale
value to zero mmap data before iomap_valid() is called:
buffered write [0,128) mmap fault
Reads valid_size = 256
Raises valid_size to 4096
Stores 'X' at offset 400
Records cookie = 4096
Zeroes [256,512), erasing 'X'
iomap_valid() sees cookie = 4096 and accepts
The validation runs too late to prevent this data loss. Could we
recheck or serialize valid_size before zeroing?
Sorry, I forgot to address this issue, even though I had it in mind:
https://lore.kernel.org/exfat/7250425f-8626-4e8d-ab5a-32d9d4588ba9@xxxxxxx/
This is because the valid_size read in exfat_write_iomap_begin() can become stale.
I spent quite a while looking into this today and realized that I had oversimplified the problem. Moving the zeroing logic from exfat_write_iomap_begin() to ->put_folio won't solve it, because the folio has already been marked uptodate before ->put_folio is called.
I'll fix this in the next version, and hopefully the fix won't require more extensive changes.
Thanks!
+ return true;
+
+ if (!folio)
+ return false;
+
+ /* Still valid for this folio. */
+ if (old_valid_size >= folio_next_pos(folio))
+ return true;
+
+ if (valid_size <= folio_pos(folio))
+ return true;
+
+ return false;
+}
+