public inbox for linux-fsdevel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] fuse: when copying a folio delay the mark dirty until the end
@ 2026-03-16 15:16 Horst Birthelmer
  2026-03-16 17:29 ` Joanne Koong
  2026-03-26  6:35 ` kernel test robot
  0 siblings, 2 replies; 14+ messages in thread
From: Horst Birthelmer @ 2026-03-16 15:16 UTC (permalink / raw)
  To: Miklos Szeredi, Joanne Koong
  Cc: Bernd Schubert, linux-fsdevel, linux-kernel, Horst Birthelmer

From: Horst Birthelmer <hbirthelmer@ddn.com>

Doing set_page_dirty_lock() for every page is inefficient
for large folios.
When copying a folio (and with large folios enabled,
this can be many pages) we can delay the marking dirty
and flush_dcache_page() until the whole folio is handled
and do it once per folio instead of once per page.

Signed-off-by: Horst Birthelmer <hbirthelmer@ddn.com>
---
Currently when doing a folio copy 
flush_dcache_page(cs->pg) and set_page_dirty_lock(cs->pg)
are called for every page.

We can do this at the end for the whole folio.
---
 fs/fuse/dev.c        | 9 +++++++--
 fs/fuse/fuse_dev_i.h | 1 +
 2 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c
index 0b0241f47170d4640f0b8f3cae8be1f78944a456..ae96a48f898e883b4e96147f3b27398261c5e844 100644
--- a/fs/fuse/dev.c
+++ b/fs/fuse/dev.c
@@ -855,7 +855,7 @@ void fuse_copy_finish(struct fuse_copy_state *cs)
 			buf->len = PAGE_SIZE - cs->len;
 		cs->currbuf = NULL;
 	} else if (cs->pg) {
-		if (cs->write) {
+		if (cs->write && !cs->copy_folio) {
 			flush_dcache_page(cs->pg);
 			set_page_dirty_lock(cs->pg);
 		}
@@ -1126,6 +1126,7 @@ static int fuse_copy_folio(struct fuse_copy_state *cs, struct folio **foliop,
 			folio_zero_range(folio, 0, size);
 	}
 
+	cs->copy_folio = true;
 	while (count) {
 		if (cs->write && cs->pipebufs && folio) {
 			/*
@@ -1167,8 +1168,12 @@ static int fuse_copy_folio(struct fuse_copy_state *cs, struct folio **foliop,
 		} else
 			offset += fuse_copy_do(cs, NULL, &count);
 	}
-	if (folio && !cs->write)
+	if (folio) {
 		flush_dcache_folio(folio);
+		if (cs->write)
+			folio_mark_dirty_lock(folio);
+	}
+	cs->copy_folio = false;
 	return 0;
 }
 
diff --git a/fs/fuse/fuse_dev_i.h b/fs/fuse/fuse_dev_i.h
index 134bf44aff0d39ae8d5d47cf1518efcf2f1cfc23..4a433d902266d573ad1c19adbdd573440e2a77b2 100644
--- a/fs/fuse/fuse_dev_i.h
+++ b/fs/fuse/fuse_dev_i.h
@@ -33,6 +33,7 @@ struct fuse_copy_state {
 	unsigned int offset;
 	bool write:1;
 	bool move_folios:1;
+	bool copy_folio:1;
 	bool is_uring:1;
 	struct {
 		unsigned int copied_sz; /* copied size into the user buffer */

---
base-commit: f338e77383789c0cae23ca3d48adcc5e9e137e3c
change-id: 20260316-mark-dirty-per-folio-be87b6b4bf56

Best regards,
-- 
Horst Birthelmer <hbirthelmer@ddn.com>


^ permalink raw reply related	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2026-03-26 15:05 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-16 15:16 [PATCH] fuse: when copying a folio delay the mark dirty until the end Horst Birthelmer
2026-03-16 17:29 ` Joanne Koong
2026-03-16 20:02   ` Horst Birthelmer
2026-03-16 22:06     ` Joanne Koong
2026-03-18 14:03       ` Horst Birthelmer
2026-03-18 21:19         ` Joanne Koong
2026-03-18 21:52           ` Bernd Schubert
2026-03-19  1:32             ` Joanne Koong
2026-03-19  4:27               ` Darrick J. Wong
2026-03-20 17:24                 ` Joanne Koong
2026-03-19  8:32               ` Horst Birthelmer
2026-03-20 17:18                 ` Joanne Koong
2026-03-26  6:35 ` kernel test robot
2026-03-26 15:05   ` [LTP] " Cyril Hrubis

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox