diff --git a/include/fuse-lite/fuse.h b/include/fuse-lite/fuse.h index 8ea787a0..2b58bcd3 100644 --- a/include/fuse-lite/fuse.h +++ b/include/fuse-lite/fuse.h @@ -426,36 +426,6 @@ struct fuse_context { void *private_data; }; -/** - * Main function of FUSE. - * - * This is for the lazy. This is all that has to be called from the - * main() function. - * - * This function does the following: - * - parses command line options (-d -s and -h) - * - passes relevant mount options to the fuse_mount() - * - installs signal handlers for INT, HUP, TERM and PIPE - * - registers an exit handler to unmount the filesystem on program exit - * - creates a fuse handle - * - registers the operations - * - calls either the single-threaded or the multi-threaded event loop - * - * Note: this is currently implemented as a macro. - * - * @param argc the argument counter passed to the main() function - * @param argv the argument vector passed to the main() function - * @param op the file system operation - * @param user_data user data supplied in the context during the init() method - * @return 0 on success, nonzero on failure - */ -/* -int fuse_main(int argc, char *argv[], const struct fuse_operations *op, - void *user_data); -*/ -#define fuse_main(argc, argv, op, user_data) \ - fuse_main_real(argc, argv, op, sizeof(*(op)), user_data) - /* ----------------------------------------------------------- * * More detailed API * * ----------------------------------------------------------- */ @@ -504,21 +474,6 @@ int fuse_loop(struct fuse *f); */ void fuse_exit(struct fuse *f); -/** - * FUSE event loop with multiple threads - * - * Requests from the kernel are processed, and the appropriate - * operations are called. Request are processed in parallel by - * distributing them between multiple threads. - * - * Calling this function requires the pthreads library to be linked to - * the application. - * - * @param f the FUSE handle - * @return 0 if no error occurred, -1 otherwise - */ -int fuse_loop_mt(struct fuse *f); - /** * Get the current context * @@ -537,14 +492,6 @@ struct fuse_context *fuse_get_context(void); */ int fuse_interrupted(void); -/** - * 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 *user_data); - /* * Stacking API */ diff --git a/include/fuse-lite/fuse_common.h b/include/fuse-lite/fuse_common.h index ddc9ce30..20868cf8 100644 --- a/include/fuse-lite/fuse_common.h +++ b/include/fuse-lite/fuse_common.h @@ -133,38 +133,6 @@ struct fuse_chan *fuse_mount(const char *mountpoint, struct fuse_args *args); */ void fuse_unmount(const char *mountpoint, struct fuse_chan *ch); -/** - * Parse common options - * - * The following options are parsed: - * - * '-f' foreground - * '-d' '-odebug' foreground, but keep the debug option - * '-s' single threaded - * '-h' '--help' help - * '-ho' help without header - * '-ofsname=..' file system name, if not present, then set to the program - * name - * - * All parameters may be NULL - * - * @param args argument vector - * @param mountpoint the returned mountpoint, should be freed after use - * @param multithreaded set to 1 unless the '-s' option is present - * @param foreground set to 1 if one of the relevant options is present - * @return 0 on success, -1 on failure - */ -int fuse_parse_cmdline(struct fuse_args *args, char **mountpoint, - int *multithreaded, int *foreground); - -/** - * Go into the background - * - * @param foreground if true, stay in the foreground - * @return 0 on success, -1 on failure - */ -int fuse_daemonize(int foreground); - /** * Get the version of the library * diff --git a/libfuse-lite/Makefile.am b/libfuse-lite/Makefile.am index baac0bb3..c09e8d7d 100644 --- a/libfuse-lite/Makefile.am +++ b/libfuse-lite/Makefile.am @@ -16,10 +16,8 @@ libfuse_lite_la_SOURCES = \ fuse_i.h \ fuse_kern_chan.c \ fuse_loop.c \ - fuse_loop_mt.c \ fuse_lowlevel.c \ fuse_misc.h \ - fuse_mt.c \ fuse_opt.c \ fuse_session.c \ fuse_signals.c \ diff --git a/libfuse-lite/fuse.c b/libfuse-lite/fuse.c index 808cd315..5de1ffec 100644 --- a/libfuse-lite/fuse.c +++ b/libfuse-lite/fuse.c @@ -2677,9 +2677,9 @@ struct fuse_fs *fuse_fs_new(const struct fuse_operations *op, size_t op_size, return fs; } -struct fuse *fuse_new_common(struct fuse_chan *ch, struct fuse_args *args, - const struct fuse_operations *op, - size_t op_size, void *user_data) +struct fuse *fuse_new(struct fuse_chan *ch, struct fuse_args *args, + const struct fuse_operations *op, size_t op_size, + void *user_data) { struct fuse *f; struct node *root; @@ -2726,7 +2726,7 @@ struct fuse *fuse_new_common(struct fuse_chan *ch, struct fuse_args *args, f->conf.readdir_ino = 1; #endif - f->se = fuse_lowlevel_new_common(args, &llop, sizeof(llop), f); + f->se = fuse_lowlevel_new(args, &llop, sizeof(llop), f); if (f->se == NULL) { goto out_free_fs; } @@ -2803,13 +2803,6 @@ struct fuse *fuse_new_common(struct fuse_chan *ch, struct fuse_args *args, return NULL; } -struct fuse *fuse_new(struct fuse_chan *ch, struct fuse_args *args, - const struct fuse_operations *op, size_t op_size, - void *user_data) -{ - return fuse_new_common(ch, args, op, op_size, user_data); -} - void fuse_destroy(struct fuse *f) { size_t i; diff --git a/libfuse-lite/fuse_i.h b/libfuse-lite/fuse_i.h index 6c1027db..9101fb58 100644 --- a/libfuse-lite/fuse_i.h +++ b/libfuse-lite/fuse_i.h @@ -19,15 +19,11 @@ struct fuse_cmd { struct fuse_chan *ch; }; -struct fuse *fuse_new_common(struct fuse_chan *ch, struct fuse_args *args, - const struct fuse_operations *op, - size_t op_size, void *user_data); - struct fuse_chan *fuse_kern_chan_new(int fd); -struct fuse_session *fuse_lowlevel_new_common(struct fuse_args *args, - const struct fuse_lowlevel_ops *op, - size_t op_size, void *userdata); +struct fuse_session *fuse_lowlevel_new(struct fuse_args *args, + const struct fuse_lowlevel_ops *op, + size_t op_size, void *userdata); void fuse_kern_unmount(const char *mountpoint, int fd); int fuse_kern_mount(const char *mountpoint, struct fuse_args *args); diff --git a/libfuse-lite/fuse_loop_mt.c b/libfuse-lite/fuse_loop_mt.c deleted file mode 100644 index f5082fd3..00000000 --- a/libfuse-lite/fuse_loop_mt.c +++ /dev/null @@ -1,222 +0,0 @@ -/* - FUSE: Filesystem in Userspace - Copyright (C) 2001-2007 Miklos Szeredi - - This program can be distributed under the terms of the GNU LGPLv2. - See the file COPYING.LIB. -*/ - -#include "config.h" -#include "fuse_lowlevel.h" -#include "fuse_misc.h" -#include "fuse_kernel.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -struct fuse_worker { - struct fuse_worker *prev; - struct fuse_worker *next; - pthread_t thread_id; - size_t bufsize; - char *buf; - struct fuse_mt *mt; -}; - -struct fuse_mt { - pthread_mutex_t lock; - int numworker; - int numavail; - struct fuse_session *se; - struct fuse_chan *prevch; - struct fuse_worker main; - sem_t finish; - int exit; - int error; -}; - -static void list_add_worker(struct fuse_worker *w, struct fuse_worker *next) -{ - struct fuse_worker *prev = next->prev; - w->next = next; - w->prev = prev; - prev->next = w; - next->prev = w; -} - -static void list_del_worker(struct fuse_worker *w) -{ - struct fuse_worker *prev = w->prev; - struct fuse_worker *next = w->next; - prev->next = next; - next->prev = prev; -} - -static int fuse_start_thread(struct fuse_mt *mt); - -static void *fuse_do_work(void *data) -{ - struct fuse_worker *w = (struct fuse_worker *) data; - struct fuse_mt *mt = w->mt; - - while (!fuse_session_exited(mt->se)) { - int isforget = 0; - struct fuse_chan *ch = mt->prevch; - int res = fuse_chan_recv(&ch, w->buf, w->bufsize); - if (res == -EINTR) - continue; - if (res <= 0) { - if (res < 0) { - fuse_session_exit(mt->se); - mt->error = -1; - } - break; - } - - pthread_mutex_lock(&mt->lock); - if (mt->exit) { - pthread_mutex_unlock(&mt->lock); - return NULL; - } - - /* - * This disgusting hack is needed so that zillions of threads - * are not created on a burst of FORGET messages - */ - if (((struct fuse_in_header *) w->buf)->opcode == FUSE_FORGET) - isforget = 1; - - if (!isforget) - mt->numavail--; - if (mt->numavail == 0) - fuse_start_thread(mt); - pthread_mutex_unlock(&mt->lock); - - fuse_session_process(mt->se, w->buf, res, ch); - - pthread_mutex_lock(&mt->lock); - if (!isforget) - mt->numavail++; - if (mt->numavail > 10) { - if (mt->exit) { - pthread_mutex_unlock(&mt->lock); - return NULL; - } - list_del_worker(w); - mt->numavail--; - mt->numworker--; - pthread_mutex_unlock(&mt->lock); - - pthread_detach(w->thread_id); - free(w->buf); - free(w); - return NULL; - } - pthread_mutex_unlock(&mt->lock); - } - - sem_post(&mt->finish); - pause(); - - return NULL; -} - -static int fuse_start_thread(struct fuse_mt *mt) -{ - sigset_t oldset; - sigset_t newset; - int res; - struct fuse_worker *w = malloc(sizeof(struct fuse_worker)); - if (!w) { - fprintf(stderr, "fuse: failed to allocate worker structure\n"); - return -1; - } - memset(w, 0, sizeof(struct fuse_worker)); - w->bufsize = fuse_chan_bufsize(mt->prevch); - w->buf = malloc(w->bufsize); - w->mt = mt; - if (!w->buf) { - fprintf(stderr, "fuse: failed to allocate read buffer\n"); - free(w); - return -1; - } - - /* Disallow signal reception in worker threads */ - sigemptyset(&newset); - sigaddset(&newset, SIGTERM); - sigaddset(&newset, SIGINT); - sigaddset(&newset, SIGHUP); - sigaddset(&newset, SIGQUIT); - pthread_sigmask(SIG_BLOCK, &newset, &oldset); - res = pthread_create(&w->thread_id, NULL, fuse_do_work, w); - pthread_sigmask(SIG_SETMASK, &oldset, NULL); - if (res != 0) { - fprintf(stderr, "fuse: error creating thread: %s\n", strerror(res)); - free(w->buf); - free(w); - return -1; - } - list_add_worker(w, &mt->main); - mt->numavail ++; - mt->numworker ++; - - return 0; -} - -static void fuse_join_worker(struct fuse_mt *mt, struct fuse_worker *w) -{ - pthread_join(w->thread_id, NULL); - pthread_mutex_lock(&mt->lock); - list_del_worker(w); - pthread_mutex_unlock(&mt->lock); - free(w->buf); - free(w); -} - -int fuse_session_loop_mt(struct fuse_session *se) -{ - int err; - struct fuse_mt mt; - struct fuse_worker *w; - - memset(&mt, 0, sizeof(struct fuse_mt)); - mt.se = se; - mt.prevch = fuse_session_next_chan(se, NULL); - mt.error = 0; - mt.numworker = 0; - mt.numavail = 0; - mt.main.thread_id = pthread_self(); - mt.main.prev = mt.main.next = &mt.main; - sem_init(&mt.finish, 0, 0); - fuse_mutex_init(&mt.lock); - - pthread_mutex_lock(&mt.lock); - err = fuse_start_thread(&mt); - pthread_mutex_unlock(&mt.lock); - if (!err) { - /* sem_wait() is interruptible */ - while (!fuse_session_exited(se)) - sem_wait(&mt.finish); - - for (w = mt.main.next; w != &mt.main; w = w->next) - pthread_cancel(w->thread_id); - mt.exit = 1; - pthread_mutex_unlock(&mt.lock); - - while (mt.main.next != &mt.main) - fuse_join_worker(&mt, mt.main.next); - - err = mt.error; - } - - pthread_mutex_destroy(&mt.lock); - sem_destroy(&mt.finish); - fuse_session_reset(se); - return err; -} diff --git a/libfuse-lite/fuse_lowlevel.c b/libfuse-lite/fuse_lowlevel.c index 3df9d265..42387073 100644 --- a/libfuse-lite/fuse_lowlevel.c +++ b/libfuse-lite/fuse_lowlevel.c @@ -1244,13 +1244,8 @@ static void fuse_ll_destroy(void *data) free(f); } -/* - * always call fuse_lowlevel_new_common() internally, to work around a - * misfeature in the FreeBSD runtime linker, which links the old - * version of a symbol to internal references. - */ -struct fuse_session *fuse_lowlevel_new_common(struct fuse_args *args, - const struct fuse_lowlevel_ops *op, +struct fuse_session *fuse_lowlevel_new(struct fuse_args *args, + const struct fuse_lowlevel_ops *op, size_t op_size, void *userdata) { struct fuse_ll *f; @@ -1297,11 +1292,3 @@ struct fuse_session *fuse_lowlevel_new_common(struct fuse_args *args, return NULL; } - -struct fuse_session *fuse_lowlevel_new(struct fuse_args *args, - const struct fuse_lowlevel_ops *op, - size_t op_size, void *userdata) -{ - return fuse_lowlevel_new_common(args, op, op_size, userdata); -} - diff --git a/libfuse-lite/fuse_mt.c b/libfuse-lite/fuse_mt.c deleted file mode 100644 index 1b850c62..00000000 --- a/libfuse-lite/fuse_mt.c +++ /dev/null @@ -1,25 +0,0 @@ -/* - FUSE: Filesystem in Userspace - Copyright (C) 2001-2007 Miklos Szeredi - - This program can be distributed under the terms of the GNU LGPLv2. - See the file COPYING.LIB. -*/ - -#include "config.h" -#include "fuse_i.h" -#include "fuse_lowlevel.h" - -#include -#include -#include -#include -#include - -int fuse_loop_mt(struct fuse *f) -{ - if (f == NULL) - return -1; - - return fuse_session_loop_mt(fuse_get_session(f)); -} diff --git a/libfuse-lite/helper.c b/libfuse-lite/helper.c index 2827cf71..6c640aec 100644 --- a/libfuse-lite/helper.c +++ b/libfuse-lite/helper.c @@ -8,154 +8,9 @@ #include "config.h" #include "fuse_i.h" -#include "fuse_opt.h" #include "fuse_lowlevel.h" -#include -#include -#include -#include -#include -#include -#include -#include - -enum { - KEY_HELP, - KEY_HELP_NOHEADER, - KEY_VERSION, -}; - -struct helper_opts { - int singlethread; - int foreground; - int nodefault_subtype; - char *mountpoint; -}; - -#define FUSE_HELPER_OPT(t, p) { t, offsetof(struct helper_opts, p), 1 } - -static const struct fuse_opt fuse_helper_opts[] = { - FUSE_HELPER_OPT("-d", foreground), - FUSE_HELPER_OPT("debug", foreground), - FUSE_HELPER_OPT("-f", foreground), - FUSE_HELPER_OPT("-s", singlethread), - FUSE_HELPER_OPT("fsname=", nodefault_subtype), - - FUSE_OPT_KEY("-h", KEY_HELP), - FUSE_OPT_KEY("--help", KEY_HELP), - FUSE_OPT_KEY("-ho", KEY_HELP_NOHEADER), - FUSE_OPT_KEY("-V", KEY_VERSION), - FUSE_OPT_KEY("--version", KEY_VERSION), - FUSE_OPT_KEY("-d", FUSE_OPT_KEY_KEEP), - FUSE_OPT_KEY("debug", FUSE_OPT_KEY_KEEP), - FUSE_OPT_KEY("fsname=", FUSE_OPT_KEY_KEEP), - FUSE_OPT_END -}; - -static void usage(const char *progname) -{ - fprintf(stderr, - "usage: %s mountpoint [options]\n\n", progname); - fprintf(stderr, - "general options:\n" - " -o opt,[opt...] mount options\n" - " -h --help print help\n" - " -V --version print version\n" - "\n"); -} - -static void helper_help(void) -{ - fprintf(stderr, - "FUSE options:\n" - " -d -o debug enable debug output (implies -f)\n" - " -f foreground operation\n" - " -s disable multi-threaded operation\n" - "\n" - ); -} - -static void helper_version(void) -{ - fprintf(stderr, "FUSE library version: %s\n", PACKAGE_VERSION); -} - -static int fuse_helper_opt_proc(void *data, const char *arg, int key, - struct fuse_args *outargs) -{ - struct helper_opts *hopts = data; - - switch (key) { - case KEY_HELP: - usage(outargs->argv[0]); - /* fall through */ - - case KEY_HELP_NOHEADER: - helper_help(); - return fuse_opt_add_arg(outargs, "-h"); - - case KEY_VERSION: - helper_version(); - return 1; - - case FUSE_OPT_KEY_NONOPT: - if (!hopts->mountpoint) { - char mountpoint[PATH_MAX]; - if (realpath(arg, mountpoint) == NULL) { - fprintf(stderr, "fuse: bad mount point `%s': %s\n", arg, strerror(errno)); - return -1; - } - return fuse_opt_add_opt(&hopts->mountpoint, mountpoint); - } else { - fprintf(stderr, "fuse: invalid argument `%s'\n", arg); - return -1; - } - - default: - return 1; - } -} - -int fuse_parse_cmdline(struct fuse_args *args, char **mountpoint, - int *multithreaded, int *foreground) -{ - int res; - struct helper_opts hopts; - - memset(&hopts, 0, sizeof(hopts)); - res = fuse_opt_parse(args, &hopts, fuse_helper_opts, fuse_helper_opt_proc); - if (res == -1) - return -1; - - if (mountpoint) - *mountpoint = hopts.mountpoint; - else - free(hopts.mountpoint); - - if (multithreaded) - *multithreaded = !hopts.singlethread; - if (foreground) - *foreground = hopts.foreground; - return 0; -} - -int fuse_daemonize(int foreground) -{ - int res; - - if (!foreground) { - res = daemon(0, 0); - if (res == -1) { - perror("fuse: failed to daemonize program\n"); - return -1; - } - } - return 0; -} - -static struct fuse_chan *fuse_mount_common(const char *mountpoint, - struct fuse_args *args) +struct fuse_chan *fuse_mount(const char *mountpoint, struct fuse_args *args) { struct fuse_chan *ch; int fd; @@ -171,124 +26,13 @@ static struct fuse_chan *fuse_mount_common(const char *mountpoint, return ch; } -struct fuse_chan *fuse_mount(const char *mountpoint, struct fuse_args *args) -{ - return fuse_mount_common(mountpoint, args); -} - -static void fuse_unmount_common(const char *mountpoint, struct fuse_chan *ch) +void fuse_unmount(const char *mountpoint, struct fuse_chan *ch) { int fd = ch ? fuse_chan_fd(ch) : -1; fuse_kern_unmount(mountpoint, fd); fuse_chan_destroy(ch); } -void fuse_unmount(const char *mountpoint, struct fuse_chan *ch) -{ - fuse_unmount_common(mountpoint, ch); -} - -static struct fuse *fuse_setup_common(int argc, char *argv[], - const struct fuse_operations *op, - size_t op_size, - char **mountpoint, - int *multithreaded, - int *fd, - void *user_data) -{ - struct fuse_args args = FUSE_ARGS_INIT(argc, argv); - struct fuse_chan *ch; - struct fuse *fuse; - int foreground; - int res; - - res = fuse_parse_cmdline(&args, mountpoint, multithreaded, &foreground); - if (res == -1) - return NULL; - - ch = fuse_mount_common(*mountpoint, &args); - if (!ch) { - fuse_opt_free_args(&args); - goto err_free; - } - - fuse = fuse_new_common(ch, &args, op, op_size, user_data); - fuse_opt_free_args(&args); - if (fuse == NULL) - goto err_unmount; - - res = fuse_daemonize(foreground); - if (res == -1) - goto err_unmount; - - res = fuse_set_signal_handlers(fuse_get_session(fuse)); - if (res == -1) - goto err_unmount; - - if (fd) - *fd = fuse_chan_fd(ch); - - return fuse; - - err_unmount: - fuse_unmount_common(*mountpoint, ch); - if (fuse) - fuse_destroy(fuse); - err_free: - free(*mountpoint); - return NULL; -} - -static void fuse_teardown_common(struct fuse *fuse, char *mountpoint) -{ - struct fuse_session *se = fuse_get_session(fuse); - struct fuse_chan *ch = fuse_session_next_chan(se, NULL); - fuse_remove_signal_handlers(se); - fuse_unmount_common(mountpoint, ch); - fuse_destroy(fuse); - free(mountpoint); -} - -static int fuse_main_common(int argc, char *argv[], - const struct fuse_operations *op, size_t op_size, - void *user_data) -{ - struct fuse *fuse; - char *mountpoint; - int multithreaded; - int res; - - fuse = fuse_setup_common(argc, argv, op, op_size, &mountpoint, - &multithreaded, NULL, user_data); - if (fuse == NULL) - return 1; - - if (multithreaded) - res = fuse_loop_mt(fuse); - else - res = fuse_loop(fuse); - - fuse_teardown_common(fuse, mountpoint); - if (res == -1) - return 1; - - return 0; -} - -int fuse_main_real(int argc, char *argv[], const struct fuse_operations *op, - size_t op_size, void *user_data) -{ - return fuse_main_common(argc, argv, op, op_size, user_data); -} - -#undef fuse_main -int fuse_main(void); -int fuse_main(void) -{ - fprintf(stderr, "fuse_main(): This function does not exist\n"); - return -1; -} - int fuse_version(void) { return FUSE_VERSION;