Signed-off-by: Gao Xiang <[email protected]> --- fuse/main.c | 240 +++++++++++++++++++++++++--------------------------- 1 file changed, 113 insertions(+), 127 deletions(-)
diff --git a/fuse/main.c b/fuse/main.c index 236d54635acb..7beaba8a9bc2 100644 --- a/fuse/main.c +++ b/fuse/main.c @@ -4,125 +4,28 @@ * * Created by Li Guifu <[email protected]> */ -#include <stdio.h> #include <stdlib.h> #include <string.h> #include <execinfo.h> #include <signal.h> -#include <stddef.h> - +#include <libgen.h> #include <fuse.h> #include <fuse_opt.h> +#include "erofs/config.h" #include "erofs/print.h" #include "erofs/io.h" int erofsfuse_readdir(const char *path, void *buffer, fuse_fill_dir_t filler, off_t offset, struct fuse_file_info *fi); -/* XXX: after liberofs is linked in, it should be removed */ -struct erofs_configure cfg; - -enum { - EROFS_OPT_HELP, - EROFS_OPT_VER, -}; - -struct options { - const char *disk; - const char *mount; - const char *logfile; - unsigned int debug_lvl; -}; -static struct options fusecfg; - -#define OPTION(t, p) { t, offsetof(struct options, p), 1 } - -static const struct fuse_opt option_spec[] = { - OPTION("--log=%s", logfile), - OPTION("--dbg=%u", debug_lvl), - FUSE_OPT_KEY("-h", EROFS_OPT_HELP), - FUSE_OPT_KEY("-v", EROFS_OPT_VER), - FUSE_OPT_END -}; - -static void usage(void) -{ - fprintf(stderr, "\terofsfuse [options] <image> <mountpoint>\n"); - fprintf(stderr, "\t --log=<file> output log file\n"); - fprintf(stderr, "\t --dbg=<level> log debug level 0 ~ 7\n"); - fprintf(stderr, "\t -h show help\n"); - fprintf(stderr, "\t -v show version\n"); - exit(1); -} - -static void dump_cfg(void) -{ - fprintf(stderr, "\tdisk :%s\n", fusecfg.disk); - fprintf(stderr, "\tmount:%s\n", fusecfg.mount); - fprintf(stderr, "\tdebug_lvl:%u\n", fusecfg.debug_lvl); - fprintf(stderr, "\tlogfile :%s\n", fusecfg.logfile); -} - -static int optional_opt_func(void *data, const char *arg, int key, - struct fuse_args *outargs) -{ - UNUSED(data); - UNUSED(outargs); - - switch (key) { - case FUSE_OPT_KEY_OPT: - return 1; - - case FUSE_OPT_KEY_NONOPT: - if (!fusecfg.disk) { - fusecfg.disk = strdup(arg); - return 0; - } else if (!fusecfg.mount) - fusecfg.mount = strdup(arg); - - return 1; - case EROFS_OPT_HELP: - usage(); - break; - - case EROFS_OPT_VER: - fprintf(stderr, "EROFS FUSE VERSION v 1.0.0\n"); - exit(0); - } - - return 1; -} - -static void signal_handle_sigsegv(int signal) -{ - void *array[10]; - size_t nptrs; - char **strings; - size_t i; - - UNUSED(signal); - erofs_dbg("========================================"); - erofs_dbg("Segmentation Fault. Starting backtrace:"); - nptrs = backtrace(array, 10); - strings = backtrace_symbols(array, nptrs); - if (strings) { - for (i = 0; i < nptrs; i++) - erofs_dbg("%s", strings[i]); - free(strings); - } - erofs_dbg("========================================"); - - abort(); -} - -void *erofs_init(struct fuse_conn_info *info) +static void *erofsfuse_init(struct fuse_conn_info *info) { erofs_info("Using FUSE protocol %d.%d", info->proto_major, info->proto_minor); return NULL; } -int erofs_open(const char *path, struct fuse_file_info *fi) +static int erofsfuse_open(const char *path, struct fuse_file_info *fi) { erofs_info("open path=%s", path); @@ -132,7 +35,7 @@ int erofs_open(const char *path, struct fuse_file_info *fi) return 0; } -int erofs_getattr(const char *path, struct stat *stbuf) +static int erofsfuse_getattr(const char *path, struct stat *stbuf) { struct erofs_inode v = { 0 }; int ret; @@ -186,51 +89,134 @@ static int erofsfuse_readlink(const char *path, char *buffer, size_t size) static struct fuse_operations erofs_ops = { .readlink = erofsfuse_readlink, - .getattr = erofs_getattr, + .getattr = erofsfuse_getattr, .readdir = erofsfuse_readdir, - .open = erofs_open, + .open = erofsfuse_open, .read = erofsfuse_read, - .init = erofs_init, + .init = erofsfuse_init, }; +static struct options { + const char *disk; + const char *mount; + unsigned int debug_lvl; + bool show_help; +} fusecfg; + +#define OPTION(t, p) \ + { t, offsetof(struct options, p), 1 } +static const struct fuse_opt option_spec[] = { + OPTION("-d %u", debug_lvl), + OPTION("-h", show_help), + OPTION("--help", show_help), + FUSE_OPT_END +}; + +#define OPTION(t, p) { t, offsetof(struct options, p), 1 } + +static void usage(void) +{ + fprintf(stderr, "\terofsfuse [options] <image> <mountpoint>\n"); + fprintf(stderr, "\t --log=<file> output log file\n"); + fprintf(stderr, "\t --dbg=<level> log debug level 0 ~ 7\n"); + fprintf(stderr, "\t -h show help\n"); + fprintf(stderr, "\t -v show version\n"); + exit(EXIT_FAILURE); +} + +static void erofsfuse_dumpcfg(void) +{ + erofs_info("disk: %s", fusecfg.disk); + erofs_info("mountpoint: %s", fusecfg.mount); + erofs_info("debug level: %u", cfg.c_dbg_lvl); +} + +static int optional_opt_func(void *data, const char *arg, int key, + struct fuse_args *outargs) +{ + switch (key) { + case FUSE_OPT_KEY_NONOPT: + if (!fusecfg.disk) { + fusecfg.disk = strdup(arg); + return 0; + } + if (!fusecfg.mount) + fusecfg.mount = strdup(arg); + case FUSE_OPT_KEY_OPT: + break; + default: + DBG_BUGON(1); + break; + } + return 1; +} + +static void signal_handle_sigsegv(int signal) +{ + void *array[10]; + size_t nptrs; + char **strings; + size_t i; + + UNUSED(signal); + erofs_dbg("========================================"); + erofs_dbg("Segmentation Fault. Starting backtrace:"); + nptrs = backtrace(array, 10); + strings = backtrace_symbols(array, nptrs); + if (strings) { + for (i = 0; i < nptrs; i++) + erofs_dbg("%s", strings[i]); + free(strings); + } + erofs_dbg("========================================"); + + abort(); +} + + int main(int argc, char *argv[]) { - int ret = EXIT_FAILURE; + int ret; struct fuse_args args = FUSE_ARGS_INIT(argc, argv); + erofs_init_configure(); + fprintf(stderr, "%s %s\n", basename(argv[0]), cfg.c_version); + if (signal(SIGSEGV, signal_handle_sigsegv) == SIG_ERR) { - fprintf(stderr, "Failed to initialize signals\n"); - return EXIT_FAILURE; + fprintf(stderr, "failed to initialize signals\n"); + ret = -errno; + goto err; } - /* Parse options */ - if (fuse_opt_parse(&args, &fusecfg, option_spec, optional_opt_func) < 0) - return 1; - - dump_cfg(); + /* parse options */ + ret = fuse_opt_parse(&args, &fusecfg, option_spec, optional_opt_func); + if (ret) + goto err; + if (fusecfg.show_help) + usage(); cfg.c_dbg_lvl = fusecfg.debug_lvl; - if (dev_open_ro(fusecfg.disk) < 0) { - fprintf(stderr, "Failed to open disk:%s\n", fusecfg.disk); - goto exit; + erofsfuse_dumpcfg(); + ret = dev_open_ro(fusecfg.disk); + if (ret) { + fprintf(stderr, "failed to open: %s\n", fusecfg.disk); + goto err_fuse_free_args; } - if (erofs_read_superblock()) { - fprintf(stderr, "Failed to read erofs super block\n"); - goto exit_dev; + ret = erofs_read_superblock(); + if (ret) { + fprintf(stderr, "failed to read erofs super block\n"); + goto err_dev_close; } - erofs_info("fuse start"); - ret = fuse_main(args.argc, args.argv, &erofs_ops, NULL); - - erofs_info("fuse done ret=%d", ret); - -exit_dev: +err_dev_close: dev_close(); -exit: +err_fuse_free_args: fuse_opt_free_args(&args); - return ret; +err: + erofs_exit_configure(); + return ret ? EXIT_FAILURE : EXIT_SUCCESS; } -- 2.24.0
