From: Darrick J. Wong <djwong@xxxxxxxxxx> Add some flags to query and request kernel support for filesystem iomap for regular files. Bump the minor API version so that the new iomap symbols don't go bleeding into old programs. Signed-off-by: "Darrick J. Wong" <djwong@xxxxxxxxxx> --- include/fuse_common.h | 5 +++++ include/fuse_kernel.h | 9 ++++++++- lib/fuse_lowlevel.c | 9 +++++++++ lib/meson.build | 2 +- 4 files changed, 23 insertions(+), 2 deletions(-) diff --git a/include/fuse_common.h b/include/fuse_common.h index b82f2c41deb30c..8f87263d78f999 100644 --- a/include/fuse_common.h +++ b/include/fuse_common.h @@ -520,6 +520,11 @@ struct fuse_loop_config_v1 { */ #define FUSE_CAP_OVER_IO_URING (1UL << 31) +/** + * Client supports using iomap for FIEMAP and SEEK_{DATA,HOLE} + */ +#define FUSE_CAP_IOMAP (1ULL << 32) + /** * Ioctl flags * diff --git a/include/fuse_kernel.h b/include/fuse_kernel.h index 122d6586e8d4da..b1e42d3cf86e81 100644 --- a/include/fuse_kernel.h +++ b/include/fuse_kernel.h @@ -235,6 +235,10 @@ * * 7.44 * - add FUSE_NOTIFY_INC_EPOCH + * + * 7.99 + * - add FUSE_IOMAP and iomap_{begin,end,ioend} handlers for FIEMAP and + * SEEK_{DATA,HOLE} support */ #ifndef _LINUX_FUSE_H @@ -270,7 +274,7 @@ #define FUSE_KERNEL_VERSION 7 /** Minor version number of this interface */ -#define FUSE_KERNEL_MINOR_VERSION 44 +#define FUSE_KERNEL_MINOR_VERSION 99 /** The node ID of the root inode */ #define FUSE_ROOT_ID 1 @@ -443,6 +447,8 @@ struct fuse_file_lock { * FUSE_OVER_IO_URING: Indicate that client supports io-uring * FUSE_REQUEST_TIMEOUT: kernel supports timing out requests. * init_out.request_timeout contains the timeout (in secs) + * FUSE_IOMAP: Client supports iomap for FIEMAP and SEEK_{DATA,HOLE} file + * operations. */ #define FUSE_ASYNC_READ (1 << 0) #define FUSE_POSIX_LOCKS (1 << 1) @@ -490,6 +496,7 @@ struct fuse_file_lock { #define FUSE_ALLOW_IDMAP (1ULL << 40) #define FUSE_OVER_IO_URING (1ULL << 41) #define FUSE_REQUEST_TIMEOUT (1ULL << 42) +#define FUSE_IOMAP (1ULL << 43) /** * CUSE INIT request/reply flags diff --git a/lib/fuse_lowlevel.c b/lib/fuse_lowlevel.c index 91f42440fca4b3..392e898a5e8ec1 100644 --- a/lib/fuse_lowlevel.c +++ b/lib/fuse_lowlevel.c @@ -2624,6 +2624,8 @@ _do_init(fuse_req_t req, const fuse_ino_t nodeid, const void *op_in, se->conn.capable_ext |= FUSE_CAP_NO_EXPORT_SUPPORT; if (inargflags & FUSE_OVER_IO_URING) se->conn.capable_ext |= FUSE_CAP_OVER_IO_URING; + if (inargflags & FUSE_IOMAP) + se->conn.capable_ext |= FUSE_CAP_IOMAP; } else { se->conn.max_readahead = 0; @@ -2670,6 +2672,9 @@ _do_init(fuse_req_t req, const fuse_ino_t nodeid, const void *op_in, FUSE_CAP_READDIRPLUS_AUTO); LL_SET_DEFAULT(1, FUSE_CAP_OVER_IO_URING); + /* servers need to opt-in to iomap explicitly */ + LL_SET_DEFAULT(0, FUSE_CAP_IOMAP); + /* This could safely become default, but libfuse needs an API extension * to support it * LL_SET_DEFAULT(1, FUSE_CAP_SETXATTR_EXT); @@ -2788,6 +2793,8 @@ _do_init(fuse_req_t req, const fuse_ino_t nodeid, const void *op_in, outargflags |= FUSE_REQUEST_TIMEOUT; outarg.request_timeout = se->conn.request_timeout; } + if (se->conn.want_ext & FUSE_CAP_IOMAP) + outargflags |= FUSE_IOMAP; if (inargflags & FUSE_INIT_EXT) { outargflags |= FUSE_INIT_EXT; @@ -2829,6 +2836,8 @@ _do_init(fuse_req_t req, const fuse_ino_t nodeid, const void *op_in, if (se->conn.want_ext & FUSE_CAP_PASSTHROUGH) fuse_log(FUSE_LOG_DEBUG, " max_stack_depth=%u\n", outarg.max_stack_depth); + if (se->conn.want_ext & FUSE_CAP_IOMAP) + fuse_log(FUSE_LOG_DEBUG, " iomap=1\n"); } if (arg->minor < 5) outargsize = FUSE_COMPAT_INIT_OUT_SIZE; diff --git a/lib/meson.build b/lib/meson.build index fcd95741c9d374..2999abe8262afd 100644 --- a/lib/meson.build +++ b/lib/meson.build @@ -49,7 +49,7 @@ libfuse = library('fuse3', dependencies: deps, install: true, link_depends: 'fuse_versionscript', - c_args: [ '-DFUSE_USE_VERSION=317', + c_args: [ '-DFUSE_USE_VERSION=318', '-DFUSERMOUNT_DIR="@0@"'.format(fusermount_path) ], link_args: ['-Wl,--version-script,' + meson.current_source_dir() + '/fuse_versionscript' ])