diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/fuse.c | 132 | ||||
-rw-r--r-- | lib/fuse_i.h | 25 | ||||
-rw-r--r-- | lib/fuse_lowlevel.c | 98 | ||||
-rw-r--r-- | lib/fuse_versionscript | 4 | ||||
-rw-r--r-- | lib/helper.c | 134 | ||||
-rw-r--r-- | lib/modules/iconv.c | 51 | ||||
-rw-r--r-- | lib/modules/subdir.c | 53 | ||||
-rw-r--r-- | lib/mount.c | 26 | ||||
-rw-r--r-- | lib/mount_bsd.c | 11 | ||||
-rw-r--r-- | lib/mount_util.c | 33 | ||||
-rw-r--r-- | lib/mount_util.h | 2 |
11 files changed, 205 insertions, 364 deletions
@@ -1537,34 +1537,15 @@ static inline void fuse_prepare_interrupt(struct fuse *f, fuse_req_t req, fuse_do_prepare_interrupt(req, d); } -int fuse_fs_getattr(struct fuse_fs *fs, const char *path, struct stat *buf) +int fuse_fs_getattr(struct fuse_fs *fs, const char *path, struct stat *buf, + struct fuse_file_info *fi) { fuse_get_context()->private_data = fs->user_data; if (fs->op.getattr) { if (fs->debug) - fprintf(stderr, "getattr %s\n", path); - - return fs->op.getattr(path, buf); - } else { - return -ENOSYS; - } -} - -int fuse_fs_fgetattr(struct fuse_fs *fs, const char *path, struct stat *buf, - struct fuse_file_info *fi) -{ - fuse_get_context()->private_data = fs->user_data; - if (fs->op.fgetattr) { - if (fs->debug) - fprintf(stderr, "fgetattr[%llu] %s\n", + fprintf(stderr, "getattr[%llu] %s\n", (unsigned long long) fi->fh, path); - - return fs->op.fgetattr(path, buf, fi); - } else if (path && fs->op.getattr) { - if (fs->debug) - fprintf(stderr, "getattr %s\n", path); - - return fs->op.getattr(path, buf); + return fs->op.getattr(path, buf, fi); } else { return -ENOSYS; } @@ -2023,67 +2004,50 @@ int fuse_fs_flock(struct fuse_fs *fs, const char *path, } } -int fuse_fs_chown(struct fuse_fs *fs, const char *path, uid_t uid, gid_t gid) +int fuse_fs_chown(struct fuse_fs *fs, const char *path, uid_t uid, + gid_t gid, struct fuse_file_info *fi) { fuse_get_context()->private_data = fs->user_data; if (fs->op.chown) { if (fs->debug) - fprintf(stderr, "chown %s %lu %lu\n", path, + fprintf(stderr, "chown[%llu] %s %lu %lu\n", + (unsigned long long) fi->fh, path, (unsigned long) uid, (unsigned long) gid); - return fs->op.chown(path, uid, gid); - } else { - return -ENOSYS; - } -} - -int fuse_fs_truncate(struct fuse_fs *fs, const char *path, off_t size) -{ - fuse_get_context()->private_data = fs->user_data; - if (fs->op.truncate) { - if (fs->debug) - fprintf(stderr, "truncate %s %llu\n", path, - (unsigned long long) size); - - return fs->op.truncate(path, size); + return fs->op.chown(path, uid, gid, fi); } else { return -ENOSYS; } } -int fuse_fs_ftruncate(struct fuse_fs *fs, const char *path, off_t size, +int fuse_fs_truncate(struct fuse_fs *fs, const char *path, off_t size, struct fuse_file_info *fi) { fuse_get_context()->private_data = fs->user_data; - if (fs->op.ftruncate) { + if (fs->op.truncate) { if (fs->debug) - fprintf(stderr, "ftruncate[%llu] %llu\n", + fprintf(stderr, "truncate[%llu] %llu\n", (unsigned long long) fi->fh, (unsigned long long) size); - return fs->op.ftruncate(path, size, fi); - } else if (path && fs->op.truncate) { - if (fs->debug) - fprintf(stderr, "truncate %s %llu\n", path, - (unsigned long long) size); - - return fs->op.truncate(path, size); + return fs->op.truncate(path, size, fi); } else { return -ENOSYS; } } int fuse_fs_utimens(struct fuse_fs *fs, const char *path, - const struct timespec tv[2]) + const struct timespec tv[2], struct fuse_file_info *fi) { fuse_get_context()->private_data = fs->user_data; if (fs->op.utimens) { if (fs->debug) - fprintf(stderr, "utimens %s %li.%09lu %li.%09lu\n", - path, tv[0].tv_sec, tv[0].tv_nsec, + fprintf(stderr, "utimens[%llu] %s %li.%09lu %li.%09lu\n", + (unsigned long long) fi->fh, path, + tv[0].tv_sec, tv[0].tv_nsec, tv[1].tv_sec, tv[1].tv_nsec); - return fs->op.utimens(path, tv); + return fs->op.utimens(path, tv, fi); } else { return -ENOSYS; } @@ -2318,7 +2282,7 @@ static char *hidden_name(struct fuse *f, fuse_ino_t dir, const char *oldname, break; memset(&buf, 0, sizeof(buf)); - res = fuse_fs_getattr(f->fs, newpath, &buf); + res = fuse_fs_getattr(f->fs, newpath, &buf, NULL); if (res == -ENOENT) break; free(newpath); @@ -2409,10 +2373,7 @@ static int lookup_path(struct fuse *f, fuse_ino_t nodeid, int res; memset(e, 0, sizeof(struct fuse_entry_param)); - if (fi) - res = fuse_fs_fgetattr(f->fs, path, &e->attr, fi); - else - res = fuse_fs_getattr(f->fs, path, &e->attr); + res = fuse_fs_getattr(f->fs, path, &e->attr, fi); if (res == 0) { res = do_lookup(f, nodeid, name, e); if (res == 0 && f->conf.debug) { @@ -2652,17 +2613,14 @@ static void fuse_lib_getattr(fuse_req_t req, fuse_ino_t ino, memset(&buf, 0, sizeof(buf)); - if (fi != NULL && f->fs->op.fgetattr) + if (fi != NULL) err = get_path_nullok(f, ino, &path); else err = get_path(f, ino, &path); if (!err) { struct fuse_intr_data d; fuse_prepare_interrupt(f, req, &d); - if (fi) - err = fuse_fs_fgetattr(f->fs, path, &buf, fi); - else - err = fuse_fs_getattr(f->fs, path, &buf); + err = fuse_fs_getattr(f->fs, path, &buf, fi); fuse_finish_interrupt(f, req, &d); free_path(f, ino, path); } @@ -2682,11 +2640,12 @@ static void fuse_lib_getattr(fuse_req_t req, fuse_ino_t ino, reply_err(req, err); } -int fuse_fs_chmod(struct fuse_fs *fs, const char *path, mode_t mode) +int fuse_fs_chmod(struct fuse_fs *fs, const char *path, mode_t mode, + struct fuse_file_info *fi) { fuse_get_context()->private_data = fs->user_data; if (fs->op.chmod) - return fs->op.chmod(path, mode); + return fs->op.chmod(path, mode, fi); else return -ENOSYS; } @@ -2700,8 +2659,7 @@ static void fuse_lib_setattr(fuse_req_t req, fuse_ino_t ino, struct stat *attr, int err; memset(&buf, 0, sizeof(buf)); - if (valid == FUSE_SET_ATTR_SIZE && fi != NULL && - f->fs->op.ftruncate && f->fs->op.fgetattr) + if (fi != NULL) err = get_path_nullok(f, ino, &path); else err = get_path(f, ino, &path); @@ -2710,21 +2668,17 @@ static void fuse_lib_setattr(fuse_req_t req, fuse_ino_t ino, struct stat *attr, fuse_prepare_interrupt(f, req, &d); err = 0; if (!err && (valid & FUSE_SET_ATTR_MODE)) - err = fuse_fs_chmod(f->fs, path, attr->st_mode); + err = fuse_fs_chmod(f->fs, path, attr->st_mode, fi); if (!err && (valid & (FUSE_SET_ATTR_UID | FUSE_SET_ATTR_GID))) { uid_t uid = (valid & FUSE_SET_ATTR_UID) ? attr->st_uid : (uid_t) -1; gid_t gid = (valid & FUSE_SET_ATTR_GID) ? attr->st_gid : (gid_t) -1; - err = fuse_fs_chown(f->fs, path, uid, gid); + err = fuse_fs_chown(f->fs, path, uid, gid, fi); } if (!err && (valid & FUSE_SET_ATTR_SIZE)) { - if (fi) - err = fuse_fs_ftruncate(f->fs, path, - attr->st_size, fi); - else - err = fuse_fs_truncate(f->fs, path, - attr->st_size); + err = fuse_fs_truncate(f->fs, path, + attr->st_size, fi); } #ifdef HAVE_UTIMENSAT if (!err && @@ -2746,7 +2700,7 @@ static void fuse_lib_setattr(fuse_req_t req, fuse_ino_t ino, struct stat *attr, else if (valid & FUSE_SET_ATTR_MTIME) tv[1] = attr->st_mtim; - err = fuse_fs_utimens(f->fs, path, tv); + err = fuse_fs_utimens(f->fs, path, tv, fi); } else #endif if (!err && @@ -2757,13 +2711,10 @@ static void fuse_lib_setattr(fuse_req_t req, fuse_ino_t ino, struct stat *attr, tv[0].tv_nsec = ST_ATIM_NSEC(attr); tv[1].tv_sec = attr->st_mtime; tv[1].tv_nsec = ST_MTIM_NSEC(attr); - err = fuse_fs_utimens(f->fs, path, tv); + err = fuse_fs_utimens(f->fs, path, tv, fi); } if (!err) { - if (fi) - err = fuse_fs_fgetattr(f->fs, path, &buf, fi); - else - err = fuse_fs_getattr(f->fs, path, &buf); + err = fuse_fs_getattr(f->fs, path, &buf, fi); } fuse_finish_interrupt(f, req, &d); free_path(f, ino, path); @@ -3116,7 +3067,7 @@ static void open_auto_cache(struct fuse *f, fuse_ino_t ino, const char *path, struct stat stbuf; int err; pthread_mutex_unlock(&f->lock); - err = fuse_fs_fgetattr(f->fs, path, &stbuf, fi); + err = fuse_fs_getattr(f->fs, path, &stbuf, fi); pthread_mutex_lock(&f->lock); if (!err) update_stat(node, &stbuf); @@ -4455,7 +4406,6 @@ static const struct fuse_opt fuse_lib_opts[] = { FUSE_LIB_OPT("negative_timeout=%lf", negative_timeout, 0), FUSE_LIB_OPT("noforget", remember, -1), FUSE_LIB_OPT("remember=%u", remember, 0), - FUSE_LIB_OPT("nopath", nopath, 1), FUSE_LIB_OPT("intr", intr, 1), FUSE_LIB_OPT("intr_signal=%d", intr_signal, 0), FUSE_LIB_OPT("modules=%s", modules, 0), @@ -4464,12 +4414,9 @@ static const struct fuse_opt fuse_lib_opts[] = { static void fuse_lib_help(void) { + /* These are not all options, but only the ones that + may be of interest to an end-user */ printf( -"High-level options\n" -" -o hard_remove immediate removal (don't hide files)\n" -" -o use_ino let filesystem set inode numbers\n" -" -o readdir_ino try to fill in d_ino in readdir\n" -" -o direct_io use direct I/O\n" " -o kernel_cache cache files in kernel\n" " -o [no]auto_cache enable caching based on modification times (off)\n" " -o umask=M set file permissions (octal)\n" @@ -4481,11 +4428,7 @@ static void fuse_lib_help(void) " -o ac_attr_timeout=T auto cache timeout for attributes (attr_timeout)\n" " -o noforget never forget cached inodes\n" " -o remember=T remember cached inodes for T seconds (0s)\n" -" -o nopath don't supply path if not necessary\n" -" -o intr allow requests to be interrupted\n" -" -o intr_signal=NUM signal to send on interrupt (%i)\n" -" -o modules=M1[:M2...] names of modules to push onto filesystem stack\n\n", - FUSE_DEFAULT_INTR_SIGNAL); +" -o modules=M1[:M2...] names of modules to push onto filesystem stack\n"); } static void fuse_lib_help_modules(void) @@ -4662,7 +4605,6 @@ struct fuse *fuse_new(struct fuse_args *args, if (f->conf.show_help) { fuse_lib_help(); fuse_lowlevel_help(); - fuse_mount_help(); /* Defer printing module help until modules have been loaded */ } diff --git a/lib/fuse_i.h b/lib/fuse_i.h index 5ed23c7..50962e3 100644 --- a/lib/fuse_i.h +++ b/lib/fuse_i.h @@ -41,34 +41,11 @@ struct fuse_notify_req { struct fuse_notify_req *prev; }; -struct session_opts { - int atomic_o_trunc; - int no_remote_posix_lock; - int no_remote_flock; - int splice_write; - int splice_move; - int splice_read; - int no_splice_write; - int no_splice_move; - int no_splice_read; - int auto_inval_data; - int no_auto_inval_data; - int no_readdirplus; - int no_readdirplus_auto; - int async_dio; - int no_async_dio; - int writeback_cache; - int no_writeback_cache; - int async_read; - int sync_read; -}; - struct fuse_session { char *mountpoint; volatile int exited; int fd; struct mount_opts *mo; - struct session_opts opts; int debug; int allow_root; struct fuse_lowlevel_ops op; @@ -130,9 +107,7 @@ void fuse_chan_put(struct fuse_chan *ch); struct mount_opts *parse_mount_opts(struct fuse_args *args); void destroy_mount_opts(struct mount_opts *mo); -void fuse_mount_help(void); void fuse_mount_version(void); - void fuse_kern_unmount(const char *mountpoint, int fd); int fuse_kern_mount(const char *mountpoint, struct mount_opts *mo); diff --git a/lib/fuse_lowlevel.c b/lib/fuse_lowlevel.c index 33e0ae5..1dbe6ed 100644 --- a/lib/fuse_lowlevel.c +++ b/lib/fuse_lowlevel.c @@ -1809,39 +1809,6 @@ static void do_fallocate(fuse_req_t req, fuse_ino_t nodeid, const void *inarg) fuse_reply_err(req, ENOSYS); } -static void apply_want_options(struct session_opts *opts, - struct fuse_conn_info *conn) -{ -#define LL_ENABLE(cond,cap) \ - if (cond) conn->want |= (cap) -#define LL_DISABLE(cond,cap) \ - if (cond) conn->want &= ~(cap) - - LL_ENABLE(opts->splice_read, FUSE_CAP_SPLICE_READ); - LL_DISABLE(opts->no_splice_read, FUSE_CAP_SPLICE_READ); - - LL_ENABLE(opts->splice_write, FUSE_CAP_SPLICE_WRITE); - LL_DISABLE(opts->no_splice_write, FUSE_CAP_SPLICE_WRITE); - - LL_ENABLE(opts->splice_move, FUSE_CAP_SPLICE_MOVE); - LL_DISABLE(opts->no_splice_move, FUSE_CAP_SPLICE_MOVE); - - LL_ENABLE(opts->auto_inval_data, FUSE_CAP_AUTO_INVAL_DATA); - LL_DISABLE(opts->no_auto_inval_data, FUSE_CAP_AUTO_INVAL_DATA); - - LL_DISABLE(opts->no_readdirplus, FUSE_CAP_READDIRPLUS); - LL_DISABLE(opts->no_readdirplus_auto, FUSE_CAP_READDIRPLUS_AUTO); - - LL_ENABLE(opts->async_dio, FUSE_CAP_ASYNC_DIO); - LL_DISABLE(opts->no_async_dio, FUSE_CAP_ASYNC_DIO); - - LL_ENABLE(opts->writeback_cache, FUSE_CAP_WRITEBACK_CACHE); - LL_DISABLE(opts->no_writeback_cache, FUSE_CAP_WRITEBACK_CACHE); - - LL_ENABLE(opts->async_read, FUSE_CAP_ASYNC_READ); - LL_DISABLE(opts->sync_read, FUSE_CAP_ASYNC_READ); -} - static void do_init(fuse_req_t req, fuse_ino_t nodeid, const void *inarg) { struct fuse_init_in *arg = (struct fuse_init_in *) inarg; @@ -1946,19 +1913,9 @@ static void do_init(fuse_req_t req, fuse_ino_t nodeid, const void *inarg) f->conn.max_write = bufsize; f->got_init = 1; - - /* Apply command-line options (so that init() handler has - an idea about user preferences */ - apply_want_options(&f->opts, &f->conn); - - /* Allow file-system to overwrite defaults */ if (f->op.init) f->op.init(f->userdata, &f->conn); - /* Now explicitly overwrite file-system's decision - with command-line options */ - apply_want_options(&f->opts, &f->conn); - /* Always enable big writes, this is superseded by the max_write option */ outarg.flags |= FUSE_BIG_WRITES; @@ -2566,36 +2523,8 @@ clear_pipe: static const struct fuse_opt fuse_ll_opts[] = { LL_OPTION("debug", debug, 1), LL_OPTION("-d", debug, 1), + LL_OPTION("--debug", debug, 1), LL_OPTION("allow_root", allow_root, 1), - LL_OPTION("max_write=%u", conn.max_write, 0), - LL_OPTION("max_readahead=%u", conn.max_readahead, 0), - LL_OPTION("max_background=%u", conn.max_background, 0), - LL_OPTION("congestion_threshold=%u", conn.congestion_threshold, 0), - LL_OPTION("sync_read", opts.sync_read, 1), - LL_OPTION("async_read", opts.async_read, 1), - LL_OPTION("atomic_o_trunc", opts.atomic_o_trunc, 1), - LL_OPTION("no_remote_lock", opts.no_remote_posix_lock, 1), - LL_OPTION("no_remote_lock", opts.no_remote_flock, 1), - LL_OPTION("no_remote_flock", opts.no_remote_flock, 1), - LL_OPTION("no_remote_posix_lock", opts.no_remote_posix_lock, 1), - LL_OPTION("splice_write", opts.splice_write, 1), - LL_OPTION("no_splice_write", opts.no_splice_write, 1), - LL_OPTION("splice_move", opts.splice_move, 1), - LL_OPTION("no_splice_move", opts.no_splice_move, 1), - LL_OPTION("splice_read", opts.splice_read, 1), - LL_OPTION("no_splice_read", opts.no_splice_read, 1), - LL_OPTION("auto_inval_data", opts.auto_inval_data, 1), - LL_OPTION("no_auto_inval_data", opts.no_auto_inval_data, 1), - LL_OPTION("readdirplus=no", opts.no_readdirplus, 1), - LL_OPTION("readdirplus=yes", opts.no_readdirplus, 0), - LL_OPTION("readdirplus=yes", opts.no_readdirplus_auto, 1), - LL_OPTION("readdirplus=auto", opts.no_readdirplus, 0), - LL_OPTION("readdirplus=auto", opts.no_readdirplus_auto, 0), - LL_OPTION("async_dio", opts.async_dio, 1), - LL_OPTION("no_async_dio", opts.no_async_dio, 1), - LL_OPTION("writeback_cache", opts.writeback_cache, 1), - LL_OPTION("no_writeback_cache", opts.no_writeback_cache, 1), - LL_OPTION("time_gran=%u", conn.time_gran, 0), FUSE_OPT_END }; @@ -2603,30 +2532,17 @@ void fuse_lowlevel_version(void) { printf("using FUSE kernel interface version %i.%i\n", FUSE_KERNEL_VERSION, FUSE_KERNEL_MINOR_VERSION); + fuse_mount_version(); } void fuse_lowlevel_help(void) { + /* These are not all options, but the ones that are + potentially of interest to an end-user */ printf( -"Low-level options\n" -" -o max_write=N set maximum size of write requests\n" -" -o max_readahead=N set maximum readahead\n" -" -o max_background=N set number of maximum background requests\n" -" -o congestion_threshold=N set kernel's congestion threshold\n" -" -o async_read perform reads asynchronously (default)\n" -" -o sync_read perform reads synchronously\n" -" -o atomic_o_trunc enable atomic open+truncate support\n" -" -o no_remote_lock disable remote file locking\n" -" -o no_remote_flock disable remote file locking (BSD)\n" -" -o no_remote_posix_lock disable remote file locking (POSIX)\n" -" -o [no_]splice_write use splice to write to the fuse device\n" -" -o [no_]splice_move move data while splicing to the fuse device\n" -" -o [no_]splice_read use splice to read from the fuse device\n" -" -o [no_]auto_inval_data use automatic kernel cache invalidation logic\n" -" -o readdirplus=S control readdirplus use (yes|no|auto)\n" -" -o [no_]async_dio asynchronous direct I/O\n" -" -o [no_]writeback_cache asynchronous, buffered writes\n" -" -o time_gran=N time granularity in nsec\n\n"); +" -o allow_other allow access to other users\n" +" -o allow_root allow access to root\n" +" -o auto_unmount auto unmount on process termination\n"); } void fuse_session_destroy(struct fuse_session *se) diff --git a/lib/fuse_versionscript b/lib/fuse_versionscript index 3301b12..1edaf5e 100644 --- a/lib/fuse_versionscript +++ b/lib/fuse_versionscript @@ -126,9 +126,9 @@ FUSE_3.0 { fuse_fs_fallocate; fuse_lowlevel_help; fuse_lowlevel_version; - fuse_mount_help; fuse_cmdline_help; - fuse_mount_version; + fuse_apply_conn_info_opts; + fuse_parse_conn_info_opts; local: *; diff --git a/lib/helper.c b/lib/helper.c index 5663fa9..a76c19d 100644 --- a/lib/helper.c +++ b/lib/helper.c @@ -49,16 +49,78 @@ static const struct fuse_opt fuse_helper_opts[] = { FUSE_OPT_END }; +struct fuse_conn_info_opts { + int atomic_o_trunc; + int no_remote_posix_lock; + int no_remote_flock; + int splice_write; + int splice_move; + int splice_read; + int no_splice_write; + int no_splice_move; + int no_splice_read; + int auto_inval_data; + int no_auto_inval_data; + int no_readdirplus; + int no_readdirplus_auto; + int async_dio; + int no_async_dio; + int writeback_cache; + int no_writeback_cache; + int async_read; + int sync_read; + unsigned max_write; + unsigned max_readahead; + unsigned max_background; + unsigned congestion_threshold; + unsigned time_gran; +}; + +#define CONN_OPTION(t, p, v) \ + { t, offsetof(struct fuse_conn_info_opts, p), v } +static const struct fuse_opt conn_info_opt_spec[] = { + CONN_OPTION("max_write=%u", max_write, 0), + CONN_OPTION("max_readahead=%u", max_readahead, 0), + CONN_OPTION("max_background=%u", max_background, 0), + CONN_OPTION("congestion_threshold=%u", congestion_threshold, 0), + CONN_OPTION("sync_read", sync_read, 1), + CONN_OPTION("async_read", async_read, 1), + CONN_OPTION("atomic_o_trunc", atomic_o_trunc, 1), + CONN_OPTION("no_remote_lock", no_remote_posix_lock, 1), + CONN_OPTION("no_remote_lock", no_remote_flock, 1), + CONN_OPTION("no_remote_flock", no_remote_flock, 1), + CONN_OPTION("no_remote_posix_lock", no_remote_posix_lock, 1), + CONN_OPTION("splice_write", splice_write, 1), + CONN_OPTION("no_splice_write", no_splice_write, 1), + CONN_OPTION("splice_move", splice_move, 1), + CONN_OPTION("no_splice_move", no_splice_move, 1), + CONN_OPTION("splice_read", splice_read, 1), + CONN_OPTION("no_splice_read", no_splice_read, 1), + CONN_OPTION("auto_inval_data", auto_inval_data, 1), + CONN_OPTION("no_auto_inval_data", no_auto_inval_data, 1), + CONN_OPTION("readdirplus=no", no_readdirplus, 1), + CONN_OPTION("readdirplus=yes", no_readdirplus, 0), + CONN_OPTION("readdirplus=yes", no_readdirplus_auto, 1), + CONN_OPTION("readdirplus=auto", no_readdirplus, 0), + CONN_OPTION("readdirplus=auto", no_readdirplus_auto, 0), + CONN_OPTION("async_dio", async_dio, 1), + CONN_OPTION("no_async_dio", no_async_dio, 1), + CONN_OPTION("writeback_cache", writeback_cache, 1), + CONN_OPTION("no_writeback_cache", no_writeback_cache, 1), + CONN_OPTION("time_gran=%u", time_gran, 0), + FUSE_OPT_END +}; + + void fuse_cmdline_help(void) { - printf("General options:\n" - " -h --help print help\n" + printf(" -h --help print help\n" " -V --version print version\n" " -d -o debug enable debug output (implies -f)\n" " -f foreground operation\n" " -s disable multi-threaded operation\n" " -o clone_fd use separate fuse device fd for each thread\n" - "\n"); + " (may improve performance)\n"); } static int fuse_helper_opt_proc(void *data, const char *arg, int key, @@ -196,7 +258,6 @@ int fuse_main_real(int argc, char *argv[], const struct fuse_operations *op, if (opts.show_version) { printf("FUSE library version %s\n", PACKAGE_VERSION); fuse_lowlevel_version(); - fuse_mount_version(); res = 0; goto out1; } @@ -207,6 +268,7 @@ int fuse_main_real(int argc, char *argv[], const struct fuse_operations *op, if(args.argv[0] != '\0') printf("usage: %s [options] <mountpoint>\n\n", args.argv[0]); + printf("FUSE options:\n"); fuse_cmdline_help(); if (fuse_opt_add_arg(&args, "--help") == -1) { res = 1; @@ -262,3 +324,67 @@ out1: fuse_opt_free_args(&args); return res; } + + +void fuse_apply_conn_info_opts(struct fuse_conn_info_opts *opts, + struct fuse_conn_info *conn) +{ + if(opts->max_write) + conn->max_write = opts->max_write; + if(opts->max_background) + conn->max_background = opts->max_background; + if(opts->congestion_threshold) + conn->congestion_threshold = opts->congestion_threshold; + if(opts->time_gran) + conn->time_gran = opts->time_gran; + if(opts->max_readahead) + conn->max_readahead = opts->max_readahead; + +#define LL_ENABLE(cond,cap) \ + if (cond) conn->want |= (cap) +#define LL_DISABLE(cond,cap) \ + if (cond) conn->want &= ~(cap) + + LL_ENABLE(opts->splice_read, FUSE_CAP_SPLICE_READ); + LL_DISABLE(opts->no_splice_read, FUSE_CAP_SPLICE_READ); + + LL_ENABLE(opts->splice_write, FUSE_CAP_SPLICE_WRITE); + LL_DISABLE(opts->no_splice_write, FUSE_CAP_SPLICE_WRITE); + + LL_ENABLE(opts->splice_move, FUSE_CAP_SPLICE_MOVE); + LL_DISABLE(opts->no_splice_move, FUSE_CAP_SPLICE_MOVE); + + LL_ENABLE(opts->auto_inval_data, FUSE_CAP_AUTO_INVAL_DATA); + LL_DISABLE(opts->no_auto_inval_data, FUSE_CAP_AUTO_INVAL_DATA); + + LL_DISABLE(opts->no_readdirplus, FUSE_CAP_READDIRPLUS); + LL_DISABLE(opts->no_readdirplus_auto, FUSE_CAP_READDIRPLUS_AUTO); + + LL_ENABLE(opts->async_dio, FUSE_CAP_ASYNC_DIO); + LL_DISABLE(opts->no_async_dio, FUSE_CAP_ASYNC_DIO); + + LL_ENABLE(opts->writeback_cache, FUSE_CAP_WRITEBACK_CACHE); + LL_DISABLE(opts->no_writeback_cache, FUSE_CAP_WRITEBACK_CACHE); + + LL_ENABLE(opts->async_read, FUSE_CAP_ASYNC_READ); + LL_DISABLE(opts->sync_read, FUSE_CAP_ASYNC_READ); + + LL_DISABLE(opts->no_remote_posix_lock, FUSE_CAP_POSIX_LOCKS); + LL_DISABLE(opts->no_remote_flock, FUSE_CAP_FLOCK_LOCKS); +} + +struct fuse_conn_info_opts* fuse_parse_conn_info_opts(struct fuse_args *args) +{ + struct fuse_conn_info_opts *opts; + + opts = calloc(1, sizeof(struct fuse_conn_info_opts)); + if(opts == NULL) { + fprintf(stderr, "calloc failed\n"); + return NULL; + } + if(fuse_opt_parse(args, opts, conn_info_opt_spec, NULL) == -1) { + free(opts); + return NULL; + } + return opts; +} diff --git a/lib/modules/iconv.c b/lib/modules/iconv.c index 174e2b9..41a072c 100644 --- a/lib/modules/iconv.c +++ b/lib/modules/iconv.c @@ -101,26 +101,14 @@ err: return err; } -static int iconv_getattr(const char *path, struct stat *stbuf) +static int iconv_getattr(const char *path, struct stat *stbuf, + struct fuse_file_info *fi) { struct iconv *ic = iconv_get(); char *newpath; int err = iconv_convpath(ic, path, &newpath, 0); if (!err) { - err = fuse_fs_getattr(ic->next, newpath, stbuf); - free(newpath); - } - return err; -} - -static int iconv_fgetattr(const char *path, struct stat *stbuf, - struct fuse_file_info *fi) -{ - struct iconv *ic = iconv_get(); - char *newpath; - int err = iconv_convpath(ic, path, &newpath, 0); - if (!err) { - err = fuse_fs_fgetattr(ic->next, newpath, stbuf, fi); + err = fuse_fs_getattr(ic->next, newpath, stbuf, fi); free(newpath); } return err; @@ -315,62 +303,53 @@ static int iconv_link(const char *from, const char *to) return err; } -static int iconv_chmod(const char *path, mode_t mode) -{ - struct iconv *ic = iconv_get(); - char *newpath; - int err = iconv_convpath(ic, path, &newpath, 0); - if (!err) { - err = fuse_fs_chmod(ic->next, newpath, mode); - free(newpath); - } - return err; -} - -static int iconv_chown(const char *path, uid_t uid, gid_t gid) +static int iconv_chmod(const char *path, mode_t mode, + struct fuse_file_info *fi) { struct iconv *ic = iconv_get(); char *newpath; int err = iconv_convpath(ic, path, &newpath, 0); if (!err) { - err = fuse_fs_chown(ic->next, newpath, uid, gid); + err = fuse_fs_chmod(ic->next, newpath, mode, fi); free(newpath); } return err; } -static int iconv_truncate(const char *path, off_t size) +static int iconv_chown(const char *path, uid_t uid, gid_t gid, + struct fuse_file_info *fi) { struct iconv *ic = iconv_get(); char *newpath; int err = iconv_convpath(ic, path, &newpath, 0); if (!err) { - err = fuse_fs_truncate(ic->next, newpath, size); + err = fuse_fs_chown(ic->next, newpath, uid, gid, fi); free(newpath); } return err; } -static int iconv_ftruncate(const char *path, off_t size, +static int iconv_truncate(const char *path, off_t size, struct fuse_file_info *fi) { struct iconv *ic = iconv_get(); char *newpath; int err = iconv_convpath(ic, path, &newpath, 0); if (!err) { - err = fuse_fs_ftruncate(ic->next, newpath, size, fi); + err = fuse_fs_truncate(ic->next, newpath, size, fi); free(newpath); } return err; } -static int iconv_utimens(const char *path, const struct timespec ts[2]) +static int iconv_utimens(const char *path, const struct timespec ts[2], + struct fuse_file_info *fi) { struct iconv *ic = iconv_get(); char *newpath; int err = iconv_convpath(ic, path, &newpath, 0); if (!err) { - err = fuse_fs_utimens(ic->next, newpath, ts); + err = fuse_fs_utimens(ic->next, newpath, ts, fi); free(newpath); } return err; @@ -600,7 +579,6 @@ static const struct fuse_operations iconv_oper = { .destroy = iconv_destroy, .init = iconv_init, .getattr = iconv_getattr, - .fgetattr = iconv_fgetattr, .access = iconv_access, .readlink = iconv_readlink, .opendir = iconv_opendir, @@ -616,7 +594,6 @@ static const struct fuse_operations iconv_oper = { .chmod = iconv_chmod, .chown = iconv_chown, .truncate = iconv_truncate, - .ftruncate = iconv_ftruncate, .utimens = iconv_utimens, .create = iconv_create, .open = iconv_open_file, diff --git a/lib/modules/subdir.c b/lib/modules/subdir.c index a039b3c..c264fb4 100644 --- a/lib/modules/subdir.c +++ b/lib/modules/subdir.c @@ -52,26 +52,14 @@ static int subdir_addpath(struct subdir *d, const char *path, char **newpathp) return 0; } -static int subdir_getattr(const char *path, struct stat *stbuf) +static int subdir_getattr(const char *path, struct stat *stbuf, + struct fuse_file_info *fi) { struct subdir *d = subdir_get(); char *newpath; int err = subdir_addpath(d, path, &newpath); if (!err) { - err = fuse_fs_getattr(d->next, newpath, stbuf); - free(newpath); - } - return err; -} - -static int subdir_fgetattr(const char *path, struct stat *stbuf, - struct fuse_file_info *fi) -{ - struct subdir *d = subdir_get(); - char *newpath; - int err = subdir_addpath(d, path, &newpath); - if (!err) { - err = fuse_fs_fgetattr(d->next, newpath, stbuf, fi); + err = fuse_fs_getattr(d->next, newpath, stbuf, fi); free(newpath); } return err; @@ -301,62 +289,53 @@ static int subdir_link(const char *from, const char *to) return err; } -static int subdir_chmod(const char *path, mode_t mode) -{ - struct subdir *d = subdir_get(); - char *newpath; - int err = subdir_addpath(d, path, &newpath); - if (!err) { - err = fuse_fs_chmod(d->next, newpath, mode); - free(newpath); - } - return err; -} - -static int subdir_chown(const char *path, uid_t uid, gid_t gid) +static int subdir_chmod(const char *path, mode_t mode, + struct fuse_file_info *fi) { struct subdir *d = subdir_get(); char *newpath; int err = subdir_addpath(d, path, &newpath); if (!err) { - err = fuse_fs_chown(d->next, newpath, uid, gid); + err = fuse_fs_chmod(d->next, newpath, mode, fi); free(newpath); } return err; } -static int subdir_truncate(const char *path, off_t size) +static int subdir_chown(const char *path, uid_t uid, gid_t gid, + struct fuse_file_info *fi) { struct subdir *d = subdir_get(); char *newpath; int err = subdir_addpath(d, path, &newpath); if (!err) { - err = fuse_fs_truncate(d->next, newpath, size); + err = fuse_fs_chown(d->next, newpath, uid, gid, fi); free(newpath); } return err; } -static int subdir_ftruncate(const char *path, off_t size, - struct fuse_file_info *fi) +static int subdir_truncate(const char *path, off_t size, + struct fuse_file_info *fi) { struct subdir *d = subdir_get(); char *newpath; int err = subdir_addpath(d, path, &newpath); if (!err) { - err = fuse_fs_ftruncate(d->next, newpath, size, fi); + err = fuse_fs_truncate(d->next, newpath, size, fi); free(newpath); } return err; } -static int subdir_utimens(const char *path, const struct timespec ts[2]) +static int subdir_utimens(const char *path, const struct timespec ts[2], + struct fuse_file_info *fi) { struct subdir *d = subdir_get(); char *newpath; int err = subdir_addpath(d, path, &newpath); if (!err) { - err = fuse_fs_utimens(d->next, newpath, ts); + err = fuse_fs_utimens(d->next, newpath, ts, fi); free(newpath); } return err; @@ -582,7 +561,6 @@ static const struct fuse_operations subdir_oper = { .destroy = subdir_destroy, .init = subdir_init, .getattr = subdir_getattr, - .fgetattr = subdir_fgetattr, .access = subdir_access, .readlink = subdir_readlink, .opendir = subdir_opendir, @@ -598,7 +576,6 @@ static const struct fuse_operations subdir_oper = { .chmod = subdir_chmod, .chown = subdir_chown, .truncate = subdir_truncate, - .ftruncate = subdir_ftruncate, .utimens = subdir_utimens, .create = subdir_create, .open = subdir_open, diff --git a/lib/mount.c b/lib/mount.c index 386260c..051b424 100644 --- a/lib/mount.c +++ b/lib/mount.c @@ -65,7 +65,6 @@ struct mount_opts { int allow_other; int allow_root; int flags; - int nonempty; int auto_unmount; int blkdev; char *fsname; @@ -81,19 +80,16 @@ struct mount_opts { static const struct fuse_opt fuse_mount_opts[] = { FUSE_MOUNT_OPT("allow_other", allow_other), FUSE_MOUNT_OPT("allow_root", allow_root), - FUSE_MOUNT_OPT("nonempty", nonempty), FUSE_MOUNT_OPT("blkdev", blkdev), FUSE_MOUNT_OPT("auto_unmount", auto_unmount), FUSE_MOUNT_OPT("fsname=%s", fsname), FUSE_MOUNT_OPT("subtype=%s", subtype), FUSE_OPT_KEY("allow_other", KEY_KERN_OPT), FUSE_OPT_KEY("allow_root", KEY_ALLOW_ROOT), - FUSE_OPT_KEY("nonempty", KEY_FUSERMOUNT_OPT), FUSE_OPT_KEY("auto_unmount", KEY_FUSERMOUNT_OPT), FUSE_OPT_KEY("blkdev", KEY_FUSERMOUNT_OPT), FUSE_OPT_KEY("fsname=", KEY_FUSERMOUNT_OPT), FUSE_OPT_KEY("subtype=", KEY_SUBTYPE_OPT), - FUSE_OPT_KEY("large_read", KEY_KERN_OPT), FUSE_OPT_KEY("blksize=", KEY_KERN_OPT), FUSE_OPT_KEY("default_permissions", KEY_KERN_OPT), FUSE_OPT_KEY("context=", KEY_KERN_OPT), @@ -119,21 +115,6 @@ static const struct fuse_opt fuse_mount_opts[] = { FUSE_OPT_END }; -void fuse_mount_help(void) -{ - printf( -"FUSE-specific mount options:\n" -" -o allow_other allow access to other users\n" -" -o allow_root allow access to root\n" -" -o auto_unmount auto unmount on process termination\n" -" -o nonempty allow mounts over non-empty file/dir\n" -" -o default_permissions enable permission checking by kernel\n" -" -o fsname=NAME set filesystem name\n" -" -o subtype=NAME set filesystem type\n" -" -o large_read issue large read requests (2.4 only)\n" -" -o max_read=N set maximum size of read requests\n\n"); -} - static void exec_fusermount(const char *argv[]) { execv(FUSERMOUNT_DIR "/" FUSERMOUNT_PROG, (char **) argv); @@ -423,13 +404,6 @@ static int fuse_mount_sys(const char *mnt, struct mount_opts *mo, return -1; } - if (!mo->nonempty) { - res = fuse_mnt_check_empty("fuse", mnt, stbuf.st_mode, - stbuf.st_size); - if (res == -1) - return -1; - } - if (mo->auto_unmount) { /* Tell the caller to fallback to fusermount because auto-unmount does not work otherwise. */ diff --git a/lib/mount_bsd.c b/lib/mount_bsd.c index bc3ed89..9cf9dfa 100644 --- a/lib/mount_bsd.c +++ b/lib/mount_bsd.c @@ -90,20 +90,9 @@ static const struct fuse_opt fuse_mount_opts[] = { * handle them */ FUSE_OPT_KEY("fsname=", KEY_KERN), - FUSE_OPT_KEY("nonempty", KEY_KERN), - FUSE_OPT_KEY("large_read", KEY_KERN), FUSE_OPT_END }; -void fuse_mount_help(void) -{ - printf( -"FUSE-specific mount options:\n" -" -o allow_root allow access to root\n"); - system(FUSERMOUNT_PROG " --help"); - fputc('\n', stderr); -} - void fuse_mount_version(void) { system(FUSERMOUNT_PROG " --version"); diff --git a/lib/mount_util.c b/lib/mount_util.c index a23ab0b..8b64ca2 100644 --- a/lib/mount_util.c +++ b/lib/mount_util.c @@ -333,39 +333,6 @@ char *fuse_mnt_resolve_path(const char *progname, const char *orig) return dst; } -int fuse_mnt_check_empty(const char *progname, const char *mnt, - mode_t rootmode, off_t rootsize) -{ - int isempty = 1; - - if (S_ISDIR(rootmode)) { - struct dirent *ent; - DIR *dp = opendir(mnt); - if (dp == NULL) { - fprintf(stderr, - "%s: failed to open mountpoint for reading: %s\n", - progname, strerror(errno)); - return -1; - } - while ((ent = readdir(dp)) != NULL) { - if (strcmp(ent->d_name, ".") != 0 && - strcmp(ent->d_name, "..") != 0) { - isempty = 0; - break; - } - } - closedir(dp); - } else if (rootsize) - isempty = 0; - - if (!isempty) { - fprintf(stderr, "%s: mountpoint is not empty\n", progname); - fprintf(stderr, "%s: if you are sure this is safe, use the 'nonempty' mount option\n", progname); - return -1; - } - return 0; -} - int fuse_mnt_check_fuseblk(void) { char buf[256]; diff --git a/lib/mount_util.h b/lib/mount_util.h index dc5c916..55c6c5e 100644 --- a/lib/mount_util.h +++ b/lib/mount_util.h @@ -14,6 +14,4 @@ int fuse_mnt_remove_mount(const char *progname, const char *mnt); int fuse_mnt_umount(const char *progname, const char *abs_mnt, const char *rel_mnt, int lazy); char *fuse_mnt_resolve_path(const char *progname, const char *orig); -int fuse_mnt_check_empty(const char *progname, const char *mnt, - mode_t rootmode, off_t rootsize); int fuse_mnt_check_fuseblk(void); |