[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <176169814616.1428599.2864088786806186737.stgit@frogsfrogsfrogs>
Date: Tue, 28 Oct 2025 18:06:52 -0700
From: "Darrick J. Wong" <djwong@...nel.org>
To: djwong@...nel.org, bschubert@....com
Cc: linux-ext4@...r.kernel.org, linux-fsdevel@...r.kernel.org,
 bernd@...ernd.com, miklos@...redi.hu, joannelkoong@...il.com, neal@...pa.dev
Subject: [PATCH 2/3] libfuse: add upper-level iomap cache management
From: Darrick J. Wong <djwong@...nel.org>
Make it so that upper-level fuse servers can use the iomap cache too.
Signed-off-by: "Darrick J. Wong" <djwong@...nel.org>
---
 include/fuse.h         |   31 +++++++++++++++++++++++++++++++
 lib/fuse.c             |   30 ++++++++++++++++++++++++++++++
 lib/fuse_versionscript |    2 ++
 3 files changed, 63 insertions(+)
diff --git a/include/fuse.h b/include/fuse.h
index 3d36b49e1b3f67..1f03f3c3115cc1 100644
--- a/include/fuse.h
+++ b/include/fuse.h
@@ -1470,6 +1470,37 @@ bool fuse_fs_can_enable_iomap(const struct stat *statbuf);
  */
 bool fuse_fs_can_enable_iomapx(const struct statx *statxbuf);
 
+/*
+ * Upsert some file mapping information into the kernel.  This is necessary
+ * for filesystems that require coordination of mapping state changes between
+ * buffered writes and writeback, and desirable for better performance
+ * elsewhere.
+ *
+ * @param nodeid the inode number
+ * @param attr_ino inode number as told by fuse_attr::ino
+ * @param read mapping information for file reads
+ * @param write mapping information for file writes
+ * @return zero for success, -errno for failure
+ */
+int fuse_fs_iomap_upsert(uint64_t nodeid, uint64_t attr_ino,
+			 const struct fuse_file_iomap *read,
+			 const struct fuse_file_iomap *write);
+
+/**
+ * Invalidate some file mapping information in the kernel.
+ *
+ * @param nodeid the inode number
+ * @param attr_ino inode number as told by fuse_attr::ino
+ * @param read_off start of the range of read mappings to invalidate
+ * @param read_len length of the range of read mappings to invalidate
+ * @param write_off start of the range of write mappings to invalidate
+ * @param write_len length of the range of write mappings to invalidate
+ * @return zero for success, -errno for failure
+ */
+int fuse_fs_iomap_inval(uint64_t nodeid, uint64_t attr_ino, loff_t read_off,
+			uint64_t read_len, loff_t write_off,
+			uint64_t write_len);
+
 int fuse_notify_poll(struct fuse_pollhandle *ph);
 
 /**
diff --git a/lib/fuse.c b/lib/fuse.c
index d54fc9ea2004bd..553bc0cb5bc818 100644
--- a/lib/fuse.c
+++ b/lib/fuse.c
@@ -3010,6 +3010,36 @@ static int fuse_fs_syncfs(struct fuse_fs *fs, const char *path)
 	return fs->op.syncfs(path);
 }
 
+int fuse_fs_iomap_upsert(uint64_t nodeid, uint64_t attr_ino,
+			 const struct fuse_file_iomap *read,
+			 const struct fuse_file_iomap *write)
+{
+	struct fuse_context *ctxt = fuse_get_context();
+	struct fuse_session *se = fuse_get_session(ctxt->fuse);
+
+	return fuse_lowlevel_notify_iomap_upsert(se, nodeid, attr_ino,
+						 read, write);
+}
+
+int fuse_fs_iomap_inval(uint64_t nodeid, uint64_t attr_ino, loff_t read_off,
+			uint64_t read_len, loff_t write_off,
+			uint64_t write_len)
+{
+	struct fuse_context *ctxt = fuse_get_context();
+	struct fuse_session *se = fuse_get_session(ctxt->fuse);
+	struct fuse_iomap_inval read = {
+		.offset = read_off,
+		.length = read_len,
+	};
+	struct fuse_iomap_inval write = {
+		.offset = write_off,
+		.length = write_len,
+	};
+
+	return fuse_lowlevel_notify_iomap_inval(se, nodeid, attr_ino, &read,
+						&write);
+}
+
 static void fuse_lib_setattr(fuse_req_t req, fuse_ino_t ino, struct stat *attr,
 			     int valid, struct fuse_file_info *fi)
 {
diff --git a/lib/fuse_versionscript b/lib/fuse_versionscript
index 696cb77a254ccb..3bf7c0aca8f657 100644
--- a/lib/fuse_versionscript
+++ b/lib/fuse_versionscript
@@ -239,6 +239,8 @@ FUSE_3.99 {
 		fuse_loopdev_setup;
 		fuse_lowlevel_notify_iomap_upsert;
 		fuse_lowlevel_notify_iomap_inval;
+		fuse_fs_iomap_upsert;
+		fuse_fs_iomap_inval;
 } FUSE_3.18;
 
 # Local Variables:
Powered by blists - more mailing lists
 
