From 949944ff3bde50d62f98b0cab15cef2959d40a2d Mon Sep 17 00:00:00 2001 From: legezywzh <94814730+legezywzh@users.noreply.github.com> Date: Sun, 2 Jun 2024 05:18:35 +0800 Subject: [PATCH] Fix compatibility issue around fuse_custom_io->clone_fd (#953) Fixes: 73cd124d0408 ("Add clone_fd to custom IO (#927)") Signed-off-by: Xiaoguang Wang --- include/fuse_lowlevel.h | 24 ++++++++++++++++++++++-- lib/compat.c | 13 +++++++++++++ lib/fuse_lowlevel.c | 24 ++++++++++++++++++++---- lib/fuse_versionscript | 2 ++ lib/meson.build | 2 +- util/meson.build | 2 +- 6 files changed, 59 insertions(+), 8 deletions(-) diff --git a/include/fuse_lowlevel.h b/include/fuse_lowlevel.h index cb38115..e849617 100644 --- a/include/fuse_lowlevel.h +++ b/include/fuse_lowlevel.h @@ -24,6 +24,7 @@ #include "fuse_common.h" +#include #include #include #include @@ -2092,6 +2093,13 @@ fuse_session_new(struct fuse_args *args, return _fuse_session_new(args, op, op_size, &version, userdata); } +/* + * This should mostly not be called directly, but instead the + * fuse_session_custom_io() should be used. + */ +int fuse_session_custom_io_317(struct fuse_session *se, + const struct fuse_custom_io *io, size_t op_size, int fd); + /** * Set a file descriptor for the session. * @@ -2119,8 +2127,20 @@ fuse_session_new(struct fuse_args *args, * @return -errno if failed to allocate memory to store `io` * **/ -int fuse_session_custom_io(struct fuse_session *se, - const struct fuse_custom_io *io, int fd); +#if FUSE_MAKE_VERSION(3, 17) <= FUSE_USE_VERSION +static inline int fuse_session_custom_io(struct fuse_session *se, + const struct fuse_custom_io *io, size_t op_size, int fd) +{ + return fuse_session_custom_io_317(se, io, op_size, fd); +} +#else +static inline int fuse_session_custom_io(struct fuse_session *se, + const struct fuse_custom_io *io, int fd) +{ + return fuse_session_custom_io_317(se, io, + offsetof(struct fuse_custom_io, clone_fd), fd); +} +#endif /** * Mount a FUSE file system. diff --git a/lib/compat.c b/lib/compat.c index 17febac..bab3f88 100644 --- a/lib/compat.c +++ b/lib/compat.c @@ -20,6 +20,8 @@ struct fuse_args; struct fuse_cmdline_opts; struct fuse_cmdline_opts; +struct fuse_session; +struct fuse_custom_io; /** @@ -42,6 +44,17 @@ int fuse_parse_cmdline(struct fuse_args *args, { return fuse_parse_cmdline_30(args, opts); } + +int fuse_session_custom_io_30(struct fuse_session *se, + const struct fuse_custom_io *io, int fd); +int fuse_session_custom_io(struct fuse_session *se, + const struct fuse_custom_io *io, int fd); +int fuse_session_custom_io(struct fuse_session *se, + const struct fuse_custom_io *io, int fd) + +{ + return fuse_session_custom_io_30(se, io, fd); +} #endif diff --git a/lib/fuse_lowlevel.c b/lib/fuse_lowlevel.c index 1f3a5fa..dc1b7a6 100644 --- a/lib/fuse_lowlevel.c +++ b/lib/fuse_lowlevel.c @@ -3190,9 +3190,15 @@ struct fuse_session *fuse_session_new_30(struct fuse_args *args, return _fuse_session_new_317(args, op, op_size, &version, userdata); } -int fuse_session_custom_io(struct fuse_session *se, const struct fuse_custom_io *io, - int fd) +FUSE_SYMVER("fuse_session_custom_io_317", "fuse_session_custom_io@@FUSE_3.17") +int fuse_session_custom_io_317(struct fuse_session *se, + const struct fuse_custom_io *io, size_t op_size, int fd) { + if (sizeof(struct fuse_custom_io) < op_size) { + fuse_log(FUSE_LOG_ERR, "fuse: warning: library too old, some operations may not work\n"); + op_size = sizeof(struct fuse_custom_io); + } + if (fd < 0) { fuse_log(FUSE_LOG_ERR, "Invalid file descriptor value %d passed to " "fuse_session_custom_io()\n", fd); @@ -3212,7 +3218,7 @@ int fuse_session_custom_io(struct fuse_session *se, const struct fuse_custom_io return -EINVAL; } - se->io = malloc(sizeof(struct fuse_custom_io)); + se->io = calloc(1, sizeof(struct fuse_custom_io)); if (se->io == NULL) { fuse_log(FUSE_LOG_ERR, "Failed to allocate memory for custom io. " "Error: %s\n", strerror(errno)); @@ -3220,10 +3226,20 @@ int fuse_session_custom_io(struct fuse_session *se, const struct fuse_custom_io } se->fd = fd; - *se->io = *io; + memcpy(se->io, io, op_size); return 0; } +int fuse_session_custom_io_30(struct fuse_session *se, + const struct fuse_custom_io *io, int fd); +FUSE_SYMVER("fuse_session_custom_io_30", "fuse_session_custom_io@FUSE_3.0") +int fuse_session_custom_io_30(struct fuse_session *se, + const struct fuse_custom_io *io, int fd) +{ + return fuse_session_custom_io_317(se, io, + offsetof(struct fuse_custom_io, clone_fd), fd); +} + int fuse_session_mount(struct fuse_session *se, const char *mountpoint) { int fd; diff --git a/lib/fuse_versionscript b/lib/fuse_versionscript index d0b98f6..1058372 100644 --- a/lib/fuse_versionscript +++ b/lib/fuse_versionscript @@ -196,6 +196,8 @@ FUSE_3.17 { fuse_main_real_317; fuse_passthrough_open; fuse_passthrough_close; + fuse_session_custom_io_30; + fuse_session_custom_io_317; } FUSE_3.12; # Local Variables: diff --git a/lib/meson.build b/lib/meson.build index 9044630..1822ce0 100644 --- a/lib/meson.build +++ b/lib/meson.build @@ -37,7 +37,7 @@ libfuse = library('fuse3', libfuse_sources, version: meson.project_version(), soversion: '3', include_directories: include_dirs, dependencies: deps, install: true, link_depends: 'fuse_versionscript', - c_args: [ '-DFUSE_USE_VERSION=312', + c_args: [ '-DFUSE_USE_VERSION=317', '-DFUSERMOUNT_DIR="@0@"'.format(fusermount_path) ], link_args: ['-Wl,--version-script,' + meson.current_source_dir() + '/fuse_versionscript' ]) diff --git a/util/meson.build b/util/meson.build index 47aac14..01c92f0 100644 --- a/util/meson.build +++ b/util/meson.build @@ -11,7 +11,7 @@ executable('mount.fuse3', ['mount.fuse.c'], link_with: [ libfuse ], install: true, install_dir: get_option('sbindir'), - c_args: '-DFUSE_USE_VERSION=312') + c_args: '-DFUSE_USE_VERSION=317') udevrulesdir = get_option('udevrulesdir')