mount_service: create high level fuse helpers

Create a fuse_main wrapper for fuse services.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Bernd Schubert <bernd@bsbernd.com>
This commit is contained in:
Darrick J. Wong
2026-03-12 10:46:42 -07:00
committed by Bernd Schubert
parent 5d8b9a39a1
commit bb9ae35f5a
3 changed files with 140 additions and 4 deletions
+34
View File
@@ -1008,6 +1008,40 @@ 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,
struct fuse_args *args,
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 and an fuse_args that has already had fuse_service_append_args
* applied to it.
*/
static inline int fuse_service_main_fn(struct fuse_service *service,
struct fuse_args *args,
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 = FUSE_USE_VERSION,
};
return fuse_service_main_real_versioned(service, args, op,
sizeof(*(op)), &version,
user_data);
}
#define fuse_service_main(s, args, op, user_data) \
fuse_service_main_fn(s, args, op, user_data)
#endif /* FUSE_USE_VERSION >= FUSE_MAKE_VERSION(3, 19) */
/* ----------------------------------------------------------- *
* More detailed API *
* ----------------------------------------------------------- */
+1
View File
@@ -240,6 +240,7 @@ FUSE_3.19 {
fuse_service_exit;
fuse_service_expect_mount_format;
fuse_service_finish_file_requests;
fuse_service_main_real_versioned;
fuse_service_parse_cmdline_opts;
fuse_service_receive_file;
fuse_service_release;
+105 -4
View File
@@ -16,6 +16,7 @@
#include "fuse_opt.h"
#include "fuse_lowlevel.h"
#include "fuse_daemonize.h"
#include "fuse_service.h"
#include "mount_util.h"
#include <stdio.h>
@@ -302,6 +303,110 @@ int fuse_parse_cmdline_30(struct fuse_args *args,
return rc;
}
struct fuse *_fuse_new_31(struct fuse_args *args,
const struct fuse_operations *op, size_t op_size,
struct libfuse_version *version,
void *user_data);
int fuse_service_main_real_versioned(struct fuse_service *service,
struct fuse_args *args,
const struct fuse_operations *op,
size_t op_size,
struct libfuse_version *version,
void *user_data)
{
struct fuse *fuse;
struct fuse_cmdline_opts opts;
struct fuse_loop_config *loop_config = NULL;
int res;
if (fuse_service_parse_cmdline_opts(args, &opts) != 0) {
res = 1;
goto out0;
}
if (opts.show_version) {
printf("FUSE library version %s\n", PACKAGE_VERSION);
fuse_lowlevel_version();
res = 0;
goto out1;
}
if (opts.show_help) {
if (args->argv[0][0] != '\0')
printf("usage: %s [options] <mountpoint>\n\n",
args->argv[0]);
printf("FUSE options:\n");
fuse_cmdline_help();
fuse_lib_help(args);
res = 0;
goto out1;
}
if (!opts.show_help &&
!opts.mountpoint) {
fuse_log(FUSE_LOG_ERR, "error: no mountpoint specified\n");
res = 2;
goto out1;
}
fuse = _fuse_new_31(args, op, op_size, version, user_data);
if (fuse == NULL) {
res = 3;
goto out1;
}
struct fuse_session *se = fuse_get_session(fuse);
if (!opts.singlethread) {
loop_config = fuse_loop_cfg_create();
if (loop_config == NULL) {
res = 7;
goto out2;
}
}
if (fuse_set_signal_handlers(se) != 0) {
res = 6;
goto out3;
}
if (fuse_service_session_mount(service, se, 0, &opts) != 0) {
res = 4;
goto out4;
}
if (opts.singlethread) {
fuse_service_send_goodbye(service, 0);
fuse_service_release(service);
res = fuse_loop(fuse);
} else {
fuse_loop_cfg_set_clone_fd(loop_config, opts.clone_fd);
fuse_loop_cfg_set_idle_threads(loop_config, opts.max_idle_threads);
fuse_loop_cfg_set_max_threads(loop_config, opts.max_threads);
fuse_service_send_goodbye(service, 0);
fuse_service_release(service);
res = fuse_loop_mt(fuse, loop_config);
}
if (res)
res = 8;
out4:
fuse_remove_signal_handlers(se);
out3:
fuse_loop_cfg_destroy(loop_config);
out2:
fuse_destroy(fuse);
out1:
free(opts.mountpoint);
out0:
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)
@@ -340,10 +445,6 @@ int fuse_main_real_versioned(int argc, char *argv[],
goto out1;
}
struct fuse *_fuse_new_31(struct fuse_args *args,
const struct fuse_operations *op, size_t op_size,
struct libfuse_version *version,
void *user_data);
fuse = _fuse_new_31(&args, op, op_size, version, user_data);
if (fuse == NULL) {
res = 3;