From: Darrick J. Wong <djwong@xxxxxxxxxx> Make it so that fuse servers can ask the kernel fuse driver to use iomap to support buffered IO. Signed-off-by: "Darrick J. Wong" <djwong@xxxxxxxxxx> --- include/fuse_common.h | 5 +++++ include/fuse_kernel.h | 3 +++ lib/fuse_lowlevel.c | 8 +++++++- 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/include/fuse_common.h b/include/fuse_common.h index f7bc03427d12e4..a102e450944f4a 100644 --- a/include/fuse_common.h +++ b/include/fuse_common.h @@ -530,6 +530,11 @@ struct fuse_loop_config_v1 { */ #define FUSE_CAP_IOMAP_DIRECTIO (1ULL << 33) +/* + * Client supports using iomap for pagecache I/O file operations + */ +#define FUSE_CAP_IOMAP_PAGECACHE (1ULL << 34) + /** * Ioctl flags * diff --git a/include/fuse_kernel.h b/include/fuse_kernel.h index a2c044b5957169..93ecb98a0bc20f 100644 --- a/include/fuse_kernel.h +++ b/include/fuse_kernel.h @@ -235,6 +235,7 @@ * SEEK_{DATA,HOLE} support * - add FUSE_NOTIFY_ADD_IOMAP_DEVICE for multi-device filesystems * - add FUSE_IOMAP_DIRECTIO for direct I/O support + * - add FUSE_IOMAP_PAGECACHE for pagecache I/O support */ #ifndef _LINUX_FUSE_H @@ -444,6 +445,7 @@ struct fuse_file_lock { * FUSE_IOMAP: Client supports iomap for FIEMAP and SEEK_{DATA,HOLE} file * operations. * FUSE_IOMAP_DIRECTIO: Client supports iomap for direct I/O operations. + * FUSE_IOMAP_PAGECACHE: Client supports iomap for pagecache I/O operations. */ #define FUSE_ASYNC_READ (1 << 0) #define FUSE_POSIX_LOCKS (1 << 1) @@ -493,6 +495,7 @@ struct fuse_file_lock { #define FUSE_OVER_IO_URING (1ULL << 41) #define FUSE_IOMAP (1ULL << 43) #define FUSE_IOMAP_DIRECTIO (1ULL << 44) +#define FUSE_IOMAP_PAGECACHE (1ULL << 45) /** * CUSE INIT request/reply flags diff --git a/lib/fuse_lowlevel.c b/lib/fuse_lowlevel.c index 9d07743fe522c6..fd12daf509cebf 100644 --- a/lib/fuse_lowlevel.c +++ b/lib/fuse_lowlevel.c @@ -2639,7 +2639,8 @@ _do_init(fuse_req_t req, const fuse_ino_t nodeid, const void *op_in, se->conn.capable_ext |= FUSE_CAP_IOMAP; if (inargflags & FUSE_IOMAP_DIRECTIO) se->conn.capable_ext |= FUSE_CAP_IOMAP_DIRECTIO; - + if (inargflags & FUSE_IOMAP_PAGECACHE) + se->conn.capable_ext |= FUSE_CAP_IOMAP_PAGECACHE; } else { se->conn.max_readahead = 0; } @@ -2688,6 +2689,7 @@ _do_init(fuse_req_t req, const fuse_ino_t nodeid, const void *op_in, /* servers need to opt-in to iomap explicitly */ LL_SET_DEFAULT(0, FUSE_CAP_IOMAP); LL_SET_DEFAULT(0, FUSE_CAP_IOMAP_DIRECTIO); + LL_SET_DEFAULT(0, FUSE_CAP_IOMAP_PAGECACHE); /* This could safely become default, but libfuse needs an API extension * to support it @@ -2816,6 +2818,8 @@ _do_init(fuse_req_t req, const fuse_ino_t nodeid, const void *op_in, outargflags |= FUSE_IOMAP; if (se->conn.want_ext & FUSE_CAP_IOMAP_DIRECTIO) outargflags |= FUSE_IOMAP_DIRECTIO; + if (se->conn.want_ext & FUSE_CAP_IOMAP_PAGECACHE) + outargflags |= FUSE_IOMAP_PAGECACHE; if (inargflags & FUSE_INIT_EXT) { outargflags |= FUSE_INIT_EXT; @@ -2861,6 +2865,8 @@ _do_init(fuse_req_t req, const fuse_ino_t nodeid, const void *op_in, fuse_log(FUSE_LOG_DEBUG, " iomap=1\n"); if (se->conn.want_ext & FUSE_CAP_IOMAP_DIRECTIO) fuse_log(FUSE_LOG_DEBUG, " iomap_directio=1\n"); + if (se->conn.want_ext & FUSE_CAP_IOMAP_PAGECACHE) + fuse_log(FUSE_LOG_DEBUG, " iomap_pagecache=1\n"); } if (arg->minor < 5) outargsize = FUSE_COMPAT_INIT_OUT_SIZE;