mode_t umask;
};
+#if (defined(LIBFUSE_BUILT_WITH_VERSIONED_SYMBOLS))
+/**
+ * The real main function
+ *
+ * Do not call this directly, use fuse_main()
+ */
+int fuse_main_real(int argc, char *argv[], const struct fuse_operations *op,
+ size_t op_size, struct libfuse_version *version,
+ void *user_data);
+#else
+int fuse_main_real_317(int argc, char *argv[], const struct fuse_operations *op,
+ size_t op_size, struct libfuse_version *version, void *user_data);
+#define fuse_main_real(argc, argv, op, op_size, version, user_data) \
+ fuse_main_real_317(argc, argv, op, op_size, version, user_data);
+#endif
+
/**
* Main function of FUSE.
*
*
* Example usage, see hello.c
*/
-/*
- int fuse_main(int argc, char *argv[], const struct fuse_operations *op,
- void *private_data);
-*/
-#define fuse_main(argc, argv, op, private_data) \
- fuse_main_real(argc, argv, op, sizeof(*(op)), private_data)
+static inline int
+fuse_main(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_main_real(argc, argv, op, sizeof(*(op)), &version,
+ user_data);
+}
/* ----------------------------------------------------------- *
* More detailed API *
*/
void fuse_lib_help(struct fuse_args *args);
+struct fuse *_fuse_new(struct fuse_args *args,
+ const struct fuse_operations *op,
+ size_t op_size, struct libfuse_version *version,
+ void *user_data);
+
/**
* Create a new FUSE filesystem.
*
* @return the created FUSE handle
*/
#if FUSE_USE_VERSION == 30
-struct fuse *fuse_new_30(struct fuse_args *args, const struct fuse_operations *op,
- size_t op_size, void *private_data);
-#define fuse_new(args, op, size, data) fuse_new_30(args, op, size, data)
+struct fuse *_fuse_new_30(struct fuse_args *args,
+ const struct fuse_operations *op,
+ size_t op_size, void *user_data);
+static inline struct fuse *
+fuse_new(struct fuse_args *args,
+ const struct fuse_operations *op, size_t op_size,
+ void *user_data)
+{
+ struct libfuse_version version = {
+ .major = FUSE_MAJOR_VERSION,
+ .minor = FUSE_MINOR_VERSION,
+ .hotfix = FUSE_HOTFIX_VERSION,
+ .padding = 0
+ };
+
+ return _fuse_new_30(args, op, op_size, &version, user_data);
+}
#else
#if (defined(LIBFUSE_BUILT_WITH_VERSIONED_SYMBOLS))
-struct fuse *fuse_new(struct fuse_args *args, const struct fuse_operations *op,
- size_t op_size, void *private_data);
+static inline struct fuse *
+fuse_new(struct fuse_args *args,
+ const struct fuse_operations *op, size_t op_size,
+ void *user_data)
+{
+ struct libfuse_version version = {
+ .major = FUSE_MAJOR_VERSION,
+ .minor = FUSE_MINOR_VERSION,
+ .hotfix = FUSE_HOTFIX_VERSION,
+ .padding = 0
+ };
+
+ return _fuse_new(args, op, op_size, &version, user_data);
+}
#else /* LIBFUSE_BUILT_WITH_VERSIONED_SYMBOLS */
-struct fuse *fuse_new_31(struct fuse_args *args,
- const struct fuse_operations *op,
- size_t op_size, void *private_data);
-#define fuse_new(args, op, size, data) fuse_new_31(args, op, size, data)
+struct fuse *_fuse_new_317(struct fuse_args *args,
+ const struct fuse_operations *op, size_t op_size,
+ struct libfuse_version *version,
+ void *private_data);
+#define _fuse_new(args, op, size, version, data) \
+ _fuse_new_317(args, op, size, version, data)
+static inline struct fuse *
+fuse_new(struct fuse_args *args,
+ const struct fuse_operations *op, size_t op_size,
+ void *user_data)
+{
+ struct libfuse_version version = {
+ .major = FUSE_MAJOR_VERSION,
+ .minor = FUSE_MINOR_VERSION,
+ .hotfix = FUSE_HOTFIX_VERSION,
+ .padding = 0
+ };
+
+ return _fuse_new(args, op, op_size, &version, user_data);
+}
#endif /* LIBFUSE_BUILT_WITH_VERSIONED_SYMBOLS */
#endif
*/
int fuse_invalidate_path(struct fuse *f, const char *path);
-/**
- * The real main function
- *
- * Do not call this directly, use fuse_main()
- */
-int fuse_main_real(int argc, char *argv[], const struct fuse_operations *op,
- size_t op_size, void *private_data);
-
/**
* Start the cleanup thread when using option "remember".
*
struct fuse_buf buf[1];
};
+/**
+ * libfuse version a file system was compiled with. Should be filled in from
+ * defines in 'libfuse_config.h'
+ */
+struct libfuse_version
+{
+ int major;
+ int minor;
+ int hotfix;
+ int padding;
+};
+
/* Initialize bufvec with a single buffer of given size */
#define FUSE_BUFVEC_INIT(size__) \
((struct fuse_bufvec) { \
#endif
#endif
+/*
+ * This should mostly not be called directly, but instead the fuse_session_new()
+ * macro should be used, which fills in the libfuse version compilation
+ * is done against automatically.
+ */
+struct fuse_session *_fuse_session_new_317(struct fuse_args *args,
+ const struct fuse_lowlevel_ops *op,
+ size_t op_size,
+ struct libfuse_version *version,
+ void *userdata);
+
+/* Do not call this directly, but only through fuse_session_new() */
+#if (defined(LIBFUSE_BUILT_WITH_VERSIONED_SYMBOLS))
+struct fuse_session *
+_fuse_session_new(struct fuse_args *args,
+ const struct fuse_lowlevel_ops *op,
+ size_t op_size,
+ struct libfuse_version *version,
+ void *userdata);
+#else
+struct fuse_session *
+_fuse_session_new_317(struct fuse_args *args,
+ const struct fuse_lowlevel_ops *op,
+ size_t op_size,
+ struct libfuse_version *version,
+ void *userdata);
+#define _fuse_session_new(args, op, op_size, version, userdata) \
+ _fuse_session_new_317(args, op, op_size, version, userdata)
+#endif
+
/**
* Create a low level session.
*
* @param args argument vector
* @param op the (low-level) filesystem operations
* @param op_size sizeof(struct fuse_lowlevel_ops)
+ * @param version the libfuse version a file system server was compiled against
* @param userdata user data
- *
* @return the fuse session on success, NULL on failure
**/
-struct fuse_session *fuse_session_new(struct fuse_args *args,
- const struct fuse_lowlevel_ops *op,
- size_t op_size, void *userdata);
+static inline struct fuse_session *
+fuse_session_new(struct fuse_args *args,
+ const struct fuse_lowlevel_ops *op,
+ size_t op_size,
+ void *userdata)
+{
+ struct libfuse_version version = {
+ .major = FUSE_MAJOR_VERSION,
+ .minor = FUSE_MINOR_VERSION,
+ .hotfix = FUSE_HOTFIX_VERSION,
+ .padding = 0
+ };
+
+ return _fuse_session_new(args, op, op_size, &version, userdata);
+}
/**
* Set a file descriptor for the session.
}
}
-
-FUSE_SYMVER("fuse_new_31", "fuse_new@@FUSE_3.1")
-struct fuse *fuse_new_31(struct fuse_args *args,
- const struct fuse_operations *op,
- size_t op_size, void *user_data)
+/*
+ * Not supposed to be called directly, but supposed to be called
+ * through the fuse_new macro
+ */
+struct fuse *_fuse_new_317(struct fuse_args *args,
+ const struct fuse_operations *op,
+ size_t op_size, struct libfuse_version *version,
+ void *user_data);
+FUSE_SYMVER("_fuse_new_317", "_fuse_new@@FUSE_3.17")
+struct fuse *_fuse_new_317(struct fuse_args *args,
+ const struct fuse_operations *op,
+ size_t op_size, struct libfuse_version *version,
+ void *user_data)
{
struct fuse *f;
struct node *root;
f->conf.readdir_ino = 1;
#endif
- f->se = fuse_session_new(args, &llop, sizeof(llop), f);
+ f->se = _fuse_session_new(args, &llop, sizeof(llop), version, f);
if (f->se == NULL)
goto out_free_fs;
}
/* Emulates 3.0-style fuse_new(), which processes --help */
+struct fuse *_fuse_new_30(struct fuse_args *args, const struct fuse_operations *op,
+ size_t op_size,
+ struct libfuse_version *version,
+ void *user_data);
+FUSE_SYMVER("_fuse_new_30", "_fuse_new@FUSE_3.0")
+struct fuse *_fuse_new_30(struct fuse_args *args,
+ const struct fuse_operations *op,
+ size_t op_size,
+ struct libfuse_version *version,
+ void *user_data)
+{
+ struct fuse_config conf = {0};
+
+ const struct fuse_opt opts[] = {
+ FUSE_LIB_OPT("-h", show_help, 1),
+ FUSE_LIB_OPT("--help", show_help, 1),
+ FUSE_OPT_END
+ };
+
+ if (fuse_opt_parse(args, &conf, opts,
+ fuse_lib_opt_proc) == -1)
+ return NULL;
+
+ if (conf.show_help) {
+ fuse_lib_help(args);
+ return NULL;
+ } else
+ return _fuse_new_317(args, op, op_size, version, user_data);
+}
+
+/* ABI compat version */
+struct fuse *fuse_new_31(struct fuse_args *args, const struct fuse_operations *op,
+ size_t op_size, void *user_data);
+FUSE_SYMVER("fuse_new_31", "fuse_new@FUSE_3.1")
+struct fuse *fuse_new_31(struct fuse_args *args,
+ const struct fuse_operations *op,
+ size_t op_size, void *user_data)
+{
+ /* unknown version */
+ struct libfuse_version version = { 0 };
+
+ return _fuse_new_317(args, op, op_size, &version, user_data);
+}
+
+/*
+ * ABI compat version
+ * Emulates 3.0-style fuse_new(), which processes --help
+ */
struct fuse *fuse_new_30(struct fuse_args *args, const struct fuse_operations *op,
- size_t op_size, void *private_data);
+ size_t op_size, void *user_data);
FUSE_SYMVER("fuse_new_30", "fuse_new@FUSE_3.0")
struct fuse *fuse_new_30(struct fuse_args *args,
const struct fuse_operations *op,
size_t op_size, void *user_data)
{
- struct fuse_config conf;
-
- memset(&conf, 0, sizeof(conf));
+ struct fuse_config conf = {0};
const struct fuse_opt opts[] = {
FUSE_LIB_OPT("-h", show_help, 1),
return fuse_new_31(args, op, op_size, user_data);
}
+
void fuse_destroy(struct fuse *f)
{
size_t i;
struct fuse_notify_req notify_list;
size_t bufsize;
int error;
+
+ /* This is useful if any kind of ABI incompatibility is found at
+ * a later version, to 'fix' it at run time.
+ */
+ struct libfuse_version version;
};
struct fuse_chan {
return res;
}
-struct fuse_session *fuse_session_new(struct fuse_args *args,
- const struct fuse_lowlevel_ops *op,
- size_t op_size, void *userdata)
+FUSE_SYMVER("_fuse_session_new_317", "_fuse_session_new@@FUSE_3.17")
+struct fuse_session *_fuse_session_new_317(struct fuse_args *args,
+ const struct fuse_lowlevel_ops *op,
+ size_t op_size,
+ struct libfuse_version *version,
+ void *userdata)
{
int err;
struct fuse_session *se;
se->userdata = userdata;
se->mo = mo;
+
+ /* Fuse server application should pass the version it was compiled
+ * against and pass it. If a libfuse version accidentally introduces an
+ * ABI incompatibility, it might be possible to 'fix' that at run time,
+ * by checking the version numbers.
+ */
+ se->version = *version;
+
return se;
out5:
return NULL;
}
+struct fuse_session *fuse_session_new_30(struct fuse_args *args,
+ const struct fuse_lowlevel_ops *op,
+ size_t op_size,
+ void *userdata);
+FUSE_SYMVER("fuse_session_new_30", "fuse_session_new@FUSE_3.0")
+struct fuse_session *fuse_session_new_30(struct fuse_args *args,
+ const struct fuse_lowlevel_ops *op,
+ size_t op_size,
+ void *userdata)
+{
+ /* unknown version */
+ struct libfuse_version version = { 0 };
+
+ 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_lowlevel_notify_expire_entry;
} FUSE_3.4;
+FUSE_3.17 {
+ global:
+ _fuse_session_new_317;
+ _fuse_new;
+ _fuse_new_30;
+ _fuse_new_317;
+ fuse_main_real_317;
+} FUSE_3.12;
+
# Local Variables:
# indent-tabs-mode: t
# End:
return 0;
}
-int fuse_main_real(int argc, char *argv[], const struct fuse_operations *op,
- size_t op_size, void *user_data)
+int fuse_main_real_317(int argc, char *argv[], const struct fuse_operations *op,
+ size_t op_size, struct libfuse_version *version, void *user_data);
+FUSE_SYMVER("fuse_main_real_317", "fuse_main_real@@FUSE_3.17")
+int fuse_main_real_317(int argc, char *argv[], const struct fuse_operations *op,
+ size_t op_size, struct libfuse_version *version, void *user_data)
{
struct fuse_args args = FUSE_ARGS_INIT(argc, argv);
struct fuse *fuse;
goto out1;
}
-
- fuse = fuse_new_31(&args, op, op_size, user_data);
+ fuse = _fuse_new(&args, op, op_size, version, user_data);
if (fuse == NULL) {
res = 3;
goto out1;
return res;
}
+int fuse_main_real_30(int argc, char *argv[], const struct fuse_operations *op,
+ size_t op_size, void *user_data);
+FUSE_SYMVER("fuse_main_real_30", "fuse_main_real@FUSE_3.0")
+int fuse_main_real_30(int argc, char *argv[], const struct fuse_operations *op,
+ size_t op_size, void *user_data)
+{
+ struct libfuse_version version = { 0 };
+
+ return fuse_main_real_317(argc, argv, op, op_size, &version, user_data);
+}
void fuse_apply_conn_info_opts(struct fuse_conn_info_opts *opts,
struct fuse_conn_info *conn)