[PATCH 3/4] libfuse: wire up FUSE_SYNCFS to the low level library

Darrick J. Wong
2025-09-16T00:47:31Z

Create hooks in the lowlevel library for syncfs.

Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
---
include/fuse_lowlevel.h | 16 ++++++++++++++++
lib/fuse_lowlevel.c | 19 +++++++++++++++++++
2 files changed, 35 insertions(+)

diff --git a/include/fuse_lowlevel.h b/include/fuse_lowlevel.h
index 687e14b8fea64f..9de93392d6df67 100644
--- a/include/fuse_lowlevel.h
+++ b/include/fuse_lowlevel.h
@@ -1422,6 +1422,22 @@ struct fuse_lowlevel_ops {
*/
void (*iomap_config) (fuse_req_t req, uint64_t flags,
uint64_t maxbytes);
+
+ /**
+ * Flush the entire filesystem to disk.
+ *
+ * If this request is answered with an error code of ENOSYS, this is
+ * treated as a permanent failure, i.e. all future syncfs() requests
+ * will fail with the same error code without being sent to the
+ * filesystem process.
+ *
+ * Valid replies:
+ * fuse_reply_err
+ *
+ * @param req request handle
+ * @param ino the inode number
+ */
+ void (*syncfs) (fuse_req_t req, fuse_ino_t ino);
};

/**
diff --git a/lib/fuse_lowlevel.c b/lib/fuse_lowlevel.c
index a6294c5c065cd2..668645dd1c2e08 100644
--- a/lib/fuse_lowlevel.c
+++ b/lib/fuse_lowlevel.c
@@ -2783,6 +2783,23 @@ static void do_iomap_config(fuse_req_t req, const fuse_ino_t nodeid,
_do_iomap_config(req, nodeid, inarg, NULL);
}

+static void _do_syncfs(fuse_req_t req, const fuse_ino_t nodeid,
+ const void *op_in, const void *in_payload)
+{
+ (void)op_in;
+ (void)in_payload;
+
+ if (req->se->op.syncfs)
+ req->se->op.syncfs(req, nodeid);
+ else
+ fuse_reply_err(req, ENOSYS);
+}
+
+static void do_syncfs(fuse_req_t req, const fuse_ino_t nodeid, const void *inarg)
+{
+ _do_syncfs(req, nodeid, inarg, NULL);
+}
+
static bool want_flags_valid(uint64_t capable, uint64_t want)
{
uint64_t unknown_flags = want & (~capable);
@@ -3704,6 +3721,7 @@ static struct {
[FUSE_COPY_FILE_RANGE] = { do_copy_file_range, "COPY_FILE_RANGE" },
[FUSE_LSEEK] = { do_lseek, "LSEEK" },
[FUSE_STATX] = { do_statx, "STATX" },
+ [FUSE_SYNCFS] = { do_syncfs, "SYNCFS" },
[FUSE_IOMAP_CONFIG]= { do_iomap_config, "IOMAP_CONFIG" },
[FUSE_IOMAP_BEGIN] = { do_iomap_begin, "IOMAP_BEGIN" },
[FUSE_IOMAP_END] = { do_iomap_end, "IOMAP_END" },
@@ -3763,6 +3781,7 @@ static struct {
[FUSE_COPY_FILE_RANGE] = { _do_copy_file_range, "COPY_FILE_RANGE" },
[FUSE_LSEEK] = { _do_lseek, "LSEEK" },
[FUSE_STATX] = { _do_statx, "STATX" },
+ [FUSE_SYNCFS] = { _do_syncfs, "SYNCFS" },
[FUSE_IOMAP_CONFIG] = { _do_iomap_config, "IOMAP_CONFIG" },
[FUSE_IOMAP_BEGIN] = { _do_iomap_begin, "IOMAP_BEGIN" },
[FUSE_IOMAP_END] = { _do_iomap_end, "IOMAP_END" },