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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox