From: "Darrick J. Wong" <djwong@kernel.org>
To: Bernd Schubert <bernd@bsbernd.com>
Cc: bschubert@ddn.com, linux-fsdevel@vger.kernel.org,
miklos@szeredi.hu, neal@gompa.dev, joannelkoong@gmail.com
Subject: Re: [PATCH 03/17] mount_service: create high level fuse helpers
Date: Mon, 30 Mar 2026 13:30:07 -0700 [thread overview]
Message-ID: <20260330203007.GJ6254@frogsfrogsfrogs> (raw)
In-Reply-To: <d7e830f2-fb3f-4782-a6bc-9b850ebdcc36@bsbernd.com>
On Mon, Mar 30, 2026 at 09:37:18PM +0200, Bernd Schubert wrote:
> Hi Darrick,
>
> On 3/27/26 02:25, Darrick J. Wong wrote:
> > From: Darrick J. Wong <djwong@kernel.org>
> >
> > Create a fuse_main wrapper for fuse services.
> >
> > Signed-off-by: Darrick J. Wong <djwong@kernel.org>
> > ---
> > include/fuse.h | 33 ++++++++++++++++++++++++++++
> > lib/fuse_versionscript | 1 +
> > lib/helper.c | 57 +++++++++++++++++++++++++++++++++++++++++-------
> > 3 files changed, 83 insertions(+), 8 deletions(-)
> >
> >
> > diff --git a/include/fuse.h b/include/fuse.h
> > index 595cac07f2be36..c7dae040857aca 100644
> > --- a/include/fuse.h
> > +++ b/include/fuse.h
> > @@ -1008,6 +1008,39 @@ static inline int fuse_main_fn(int argc, char *argv[],
> > #define fuse_main(argc, argv, op, user_data) \
> > fuse_main_fn(argc, argv, op, user_data)
> >
> > +#if FUSE_MAKE_VERSION(3, 19) <= FUSE_USE_VERSION
> > +struct fuse_service;
> > +int fuse_service_main_real_versioned(struct fuse_service *service,
> > + int argc, char *argv[],
> > + const struct fuse_operations *op,
> > + size_t op_size,
> > + struct libfuse_version *version,
> > + void *user_data);
> > +
> > +/**
> > + * Same as fuse_service_main_fn, but takes its information from the mount
> > + * service context.
> > + */
> > +static inline int fuse_service_main_fn(struct fuse_service *service,
> > + int argc, char *argv[],
> > + const struct fuse_operations *op,
> > + void *user_data)
> > +{
> > + struct libfuse_version version = {
> > + .major = FUSE_MAJOR_VERSION,
> > + .minor = FUSE_MINOR_VERSION,
> > + .hotfix = FUSE_HOTFIX_VERSION,
> > + .padding = 0
> > + };
> > +
> > + return fuse_service_main_real_versioned(service, argc, argv, op,
> > + sizeof(*(op)), &version,
> > + user_data);
> > +}
> > +#define fuse_service_main(s, argc, argv, op, user_data) \
> > + fuse_service_main_fn(s, argc, argv, op, user_data)
> > +#endif /* FUSE_USE_VERSION >= FUSE_MAKE_VERSION(3, 19) */
>
> sorry, this is not exactly what I meant. Could you take a look here? I
OH, you want the program to pass in both the version of libfuse that the
program was built against (struct libfuse_version) and the version of
libfuse that the program asked for (FUSE_USE_VERSION). Not just header
guards.
> just pushed the unfinished patch I made in December. It got complicated
> in the high level API and I didn't have time to finish it yet.
Yes, that does make sense for setting defaults based on the version of
the libfuse API that the fuse server expects.
> https://github.com/libfuse/libfuse/pull/1382/changes/24836ded18e9736eb4691600600ff1d7cf581e29
>
> Basically I would like to add the API version to the functions, in order
> to set defaults flags. The topic came up about FUSE_CAP_AUTO_INVAL_DATA,
> because it can cause data corruption, but there is also a risk to cause
> regressions. So would be good to set that based on the API version
> (assuming people read the rather new doc/ChangeLog-API.rst).
>
> Anyway your function should basically be
>
> int fuse_service_main_real_versioned(struct fuse_service *service,
> int argc, char *argv[],
> const struct fuse_operations *op,
> size_t op_size,
> unsigned int user_apiabi_version,
> struct libfuse_version *version,
> void *user_data);
>
>
> I.e. adding in 'user_apiabi_version'. Although while looking into this
> again, maybe we should mis-use 'padding' and rename it 'api version. It
> would definitely simplify things.
>
>
> While you look into all these things, what is your opinion? ;)
I like the idea of encoding the FUSE_USE_VERSION as the padding value.
I wonder if there's a danger of a client setting the fields manually:
struct libfuse_version version;
version.major = FUSE_MAJOR_VERSION;
version.minor = FUSE_MINOR_VERSION;
version.hotfix = FUSE_HOTFIX_VERSION;
fuse_main_real_versioned(..., &version...);
such that version.padding is now set to stack garbage? The wrapper
functions in fuse.h use struct initialization so the .padding value will
be zero, but fuse_session_new_versioned doesn't appear to require zero,
which makes such a change a bit risky.
Debian codesearch seems to think there aren't any direct callers of
fuse_session_new_versioned or fuse_main_real_versioned outside of fuse,
so this might not be a big risk.
If the risk is acceptable, it would reduce the amount of code changes to
add the FUSE_USE_VERSION number and force programs to #define it before
#include'ing fuse.h.
The existing functions that take a struct libfuse_version could just
ignore values like 0 or values that arent't in the range 30-39 or
310-319. That might be enough to avoid complaints.
--D
>
> Thanks,
> Bernd
>
> > +
> > /* ----------------------------------------------------------- *
> > * More detailed API *
> > * ----------------------------------------------------------- */
> > diff --git a/lib/fuse_versionscript b/lib/fuse_versionscript
> > index 1fc73f417f90a0..43f8bf11b64548 100644
> > --- a/lib/fuse_versionscript
> > +++ b/lib/fuse_versionscript
> > @@ -236,6 +236,7 @@ FUSE_3.19 {
> > fuse_service_exit;
> > fuse_service_expect_mount_mode;
> > fuse_service_finish_file_requests;
> > + fuse_service_main_real_versioned;
> > fuse_service_parse_cmdline_opts;
> > fuse_service_receive_file;
> > fuse_service_release;
> > diff --git a/lib/helper.c b/lib/helper.c
> > index 533526273207d5..3509f1aa0c8f79 100644
> > --- a/lib/helper.c
> > +++ b/lib/helper.c
> > @@ -15,6 +15,7 @@
> > #include "fuse_misc.h"
> > #include "fuse_opt.h"
> > #include "fuse_lowlevel.h"
> > +#include "fuse_service.h"
> > #include "mount_util.h"
> >
> > #include <stdio.h>
> > @@ -357,7 +358,8 @@ int fuse_daemonize(int foreground)
> > return 0;
> > }
> >
> > -int fuse_main_real_versioned(int argc, char *argv[],
> > +int fuse_service_main_real_versioned(struct fuse_service *service,
> > + int argc, char *argv[],
> > const struct fuse_operations *op, size_t op_size,
> > struct libfuse_version *version, void *user_data)
> > {
> > @@ -367,8 +369,15 @@ int fuse_main_real_versioned(int argc, char *argv[],
> > int res;
> > struct fuse_loop_config *loop_config = NULL;
> >
> > - if (fuse_parse_cmdline(&args, &opts) != 0)
> > - return 1;
> > + if (service) {
> > + if (fuse_service_parse_cmdline_opts(&args, &opts) != 0) {
> > + res = 1;
> > + goto out0;
> > + }
> > + } else {
> > + if (fuse_parse_cmdline(&args, &opts) != 0)
> > + return 1;
> > + }
> >
> > if (opts.show_version) {
> > printf("FUSE library version %s\n", PACKAGE_VERSION);
> > @@ -405,9 +414,17 @@ int fuse_main_real_versioned(int argc, char *argv[],
> > goto out1;
> > }
> >
> > - if (fuse_mount(fuse,opts.mountpoint) != 0) {
> > - res = 4;
> > - goto out2;
> > + if (service) {
> > + if (fuse_service_session_mount(service, fuse_get_session(fuse),
> > + 0, &opts) != 0) {
> > + res = 4;
> > + goto out2;
> > + }
> > + } else {
> > + if (fuse_mount(fuse, opts.mountpoint) != 0) {
> > + res = 4;
> > + goto out2;
> > + }
> > }
> >
> > if (fuse_daemonize(opts.foreground) != 0) {
> > @@ -421,9 +438,14 @@ int fuse_main_real_versioned(int argc, char *argv[],
> > goto out3;
> > }
> >
> > - if (opts.singlethread)
> > + if (opts.singlethread) {
> > + if (service) {
> > + fuse_service_send_goodbye(service, 0);
> > + fuse_service_release(service);
> > + }
> > +
> > res = fuse_loop(fuse);
> > - else {
> > + } else {
> > loop_config = fuse_loop_cfg_create();
> > if (loop_config == NULL) {
> > res = 7;
> > @@ -434,6 +456,12 @@ int fuse_main_real_versioned(int argc, char *argv[],
> >
> > fuse_loop_cfg_set_idle_threads(loop_config, opts.max_idle_threads);
> > fuse_loop_cfg_set_max_threads(loop_config, opts.max_threads);
> > +
> > + if (service) {
> > + fuse_service_send_goodbye(service, 0);
> > + fuse_service_release(service);
> > + }
> > +
> > res = fuse_loop_mt(fuse, loop_config);
> > }
> > if (res)
> > @@ -448,9 +476,22 @@ int fuse_main_real_versioned(int argc, char *argv[],
> > fuse_loop_cfg_destroy(loop_config);
> > free(opts.mountpoint);
> > fuse_opt_free_args(&args);
> > +out0:
> > + if (service) {
> > + fuse_service_send_goodbye(service, res);
> > + fuse_service_release(service);
> > + }
> > return res;
> > }
> >
> > +int fuse_main_real_versioned(int argc, char *argv[],
> > + const struct fuse_operations *op, size_t op_size,
> > + struct libfuse_version *version, void *user_data)
> > +{
> > + return fuse_service_main_real_versioned(NULL, argc, argv, op, op_size,
> > + version, user_data);
> > +}
> > +
> > /* Not symboled, as not part of the official API */
> > int fuse_main_real_30(int argc, char *argv[], const struct fuse_operations *op,
> > size_t op_size, void *user_data);
> >
> >
>
next prev parent reply other threads:[~2026-03-30 20:30 UTC|newest]
Thread overview: 35+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-03-27 1:24 [PATCHSET v3] libfuse: run fuse servers as a contained service Darrick J. Wong
2026-03-27 1:25 ` [PATCH 01/17] Refactor mount code / move common functions to mount_util.c Darrick J. Wong
2026-03-27 1:25 ` [PATCH 02/17] mount_service: add systemd/inetd socket service mounting helper Darrick J. Wong
2026-03-30 20:44 ` Bernd Schubert
2026-03-30 21:37 ` Darrick J. Wong
2026-04-07 23:39 ` Darrick J. Wong
2026-03-27 1:25 ` [PATCH 03/17] mount_service: create high level fuse helpers Darrick J. Wong
2026-03-30 19:37 ` Bernd Schubert
2026-03-30 20:30 ` Darrick J. Wong [this message]
2026-03-30 20:51 ` Bernd Schubert
2026-03-30 21:09 ` Darrick J. Wong
2026-03-27 1:25 ` [PATCH 04/17] mount_service: use the new mount api for the mount service Darrick J. Wong
2026-03-30 21:06 ` Bernd Schubert
2026-03-30 21:18 ` Darrick J. Wong
2026-03-30 21:40 ` Bernd Schubert
2026-03-30 21:47 ` Darrick J. Wong
2026-03-27 1:26 ` [PATCH 05/17] mount_service: update mtab after a successful mount Darrick J. Wong
2026-04-07 23:42 ` Darrick J. Wong
2026-03-27 1:26 ` [PATCH 06/17] util: hoist the fuse.conf parsing code Darrick J. Wong
2026-04-07 23:40 ` Darrick J. Wong
2026-03-27 1:26 ` [PATCH 07/17] util: fix checkpatch complaints in fuser_conf.[ch] Darrick J. Wong
2026-03-27 1:26 ` [PATCH 08/17] mount_service: read fuse.conf to enable allow_other for unprivileged mounts Darrick J. Wong
2026-03-27 1:27 ` [PATCH 09/17] util: hoist the other non-root user limits Darrick J. Wong
2026-03-27 1:27 ` [PATCH 10/17] util: fix more checkpatch complaints in fuser_conf.[ch] Darrick J. Wong
2026-03-27 1:27 ` [PATCH 11/17] mount_service: use over the other non-root user checks Darrick J. Wong
2026-04-07 23:47 ` Darrick J. Wong
2026-03-27 1:27 ` [PATCH 12/17] mount.fuse3: integrate systemd service startup Darrick J. Wong
2026-04-07 23:56 ` Darrick J. Wong
2026-03-27 1:28 ` [PATCH 13/17] mount_service: allow installation as a setuid program Darrick J. Wong
2026-03-27 1:28 ` [PATCH 14/17] example/service_ll: create a sample systemd service fuse server Darrick J. Wong
2026-04-08 0:09 ` Darrick J. Wong
2026-03-27 1:28 ` [PATCH 15/17] example/service: create a sample systemd service for a high-level " Darrick J. Wong
2026-03-27 1:28 ` [PATCH 16/17] example/hello_ll: port to single-file common code Darrick J. Wong
2026-03-27 1:29 ` [PATCH 17/17] nullfs: support fuse systemd service mode Darrick J. Wong
2026-04-08 0:11 ` Darrick J. Wong
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260330203007.GJ6254@frogsfrogsfrogs \
--to=djwong@kernel.org \
--cc=bernd@bsbernd.com \
--cc=bschubert@ddn.com \
--cc=joannelkoong@gmail.com \
--cc=linux-fsdevel@vger.kernel.org \
--cc=miklos@szeredi.hu \
--cc=neal@gompa.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.