[RFC PATCH 5/5] xfs: track mmap dirty state per block

From: Kiryl Shutsemau

Date: Thu Sep 03 2026 - 14:57:16 EST


From: "Kiryl Shutsemau (Meta)" <kas@xxxxxxxxxx>

With a_ops->dirty_folio_range() wired up, a store through a shared
mapping writes back only the block it touched instead of the whole
folio.

a_ops->dirty_folio() goes away with it. folio_mark_dirty() reaches
a_ops->dirty_folio_range() with a range covering the folio, which is
what iomap_dirty_folio() does.

On a 512M file held in 2M page cache folios, storing one byte per folio
and then calling msync() wrote 512M of the file before this series and
writes 1M after it. Minor fault counts are the same either way, in both
the PTE-mapped and the batch-mapped case.

A PMD-mapped folio still writes back whole. A PMD carries one dirty bit
for the 2M it maps, so there is no per-block state to recover.

Assisted-by: Claude:claude-opus-5
Signed-off-by: Kiryl Shutsemau (Meta) <kas@xxxxxxxxxx>
---
fs/xfs/xfs_aops.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c
index 74a6089abadf..600e7de2e599 100644
--- a/fs/xfs/xfs_aops.c
+++ b/fs/xfs/xfs_aops.c
@@ -863,7 +863,7 @@ const struct address_space_operations xfs_address_space_operations = {
.read_folio = xfs_vm_read_folio,
.readahead = xfs_vm_readahead,
.writepages = xfs_vm_writepages,
- .dirty_folio = iomap_dirty_folio,
+ .dirty_folio_range = iomap_dirty_folio_range,
.release_folio = iomap_release_folio,
.invalidate_folio = iomap_invalidate_folio,
.bmap = xfs_vm_bmap,
--
2.54.0