diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Makefile.am | 4 | ||||
-rw-r--r-- | lib/cuse_lowlevel.c | 3 | ||||
-rw-r--r-- | lib/fuse.c | 462 | ||||
-rw-r--r-- | lib/fuse_i.h | 31 | ||||
-rw-r--r-- | lib/fuse_lowlevel.c | 286 | ||||
-rw-r--r-- | lib/fuse_misc.h | 11 | ||||
-rw-r--r-- | lib/fuse_mt.c | 100 | ||||
-rw-r--r-- | lib/fuse_opt.c | 14 | ||||
-rw-r--r-- | lib/fuse_session.c | 40 | ||||
-rw-r--r-- | lib/fuse_versionscript | 73 | ||||
-rw-r--r-- | lib/helper.c | 178 | ||||
-rw-r--r-- | lib/modules/iconv.c | 3 | ||||
-rw-r--r-- | lib/modules/subdir.c | 3 | ||||
-rw-r--r-- | lib/mount.c | 28 | ||||
-rw-r--r-- | lib/mount_bsd.c | 2 |
15 files changed, 210 insertions, 1028 deletions
diff --git a/lib/Makefile.am b/lib/Makefile.am index 3ec2401..8ec234a 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -1,7 +1,7 @@ ## Process this file with automake to produce Makefile.in AM_CPPFLAGS = -I$(top_srcdir)/include -DFUSERMOUNT_DIR=\"$(bindir)\" \ - -D_FILE_OFFSET_BITS=64 -D_REENTRANT -DFUSE_USE_VERSION=26 + -D_FILE_OFFSET_BITS=64 -D_REENTRANT -DFUSE_USE_VERSION=30 lib_LTLIBRARIES = libfuse.la libulockmgr.la @@ -36,7 +36,7 @@ libfuse_la_SOURCES = \ $(iconv_source) \ $(mount_source) -libfuse_la_LDFLAGS = -pthread @libfuse_libs@ -version-number 2:9:2 \ +libfuse_la_LDFLAGS = -pthread @libfuse_libs@ -version-number 3:0:0 \ -Wl,--version-script,$(srcdir)/fuse_versionscript if NETBSD diff --git a/lib/cuse_lowlevel.c b/lib/cuse_lowlevel.c index 402cf4b..c51a78e 100644 --- a/lib/cuse_lowlevel.c +++ b/lib/cuse_lowlevel.c @@ -11,7 +11,6 @@ #include "fuse_kernel.h" #include "fuse_i.h" #include "fuse_opt.h" -#include "fuse_misc.h" #include <stdio.h> #include <string.h> @@ -170,7 +169,7 @@ struct fuse_session *cuse_lowlevel_new(struct fuse_args *args, lop.ioctl = clop->ioctl ? cuse_fll_ioctl : NULL; lop.poll = clop->poll ? cuse_fll_poll : NULL; - se = fuse_lowlevel_new_common(args, &lop, sizeof(lop), userdata); + se = fuse_lowlevel_new(args, &lop, sizeof(lop), userdata); if (!se) { free(cd); return NULL; @@ -15,8 +15,6 @@ #include "fuse_lowlevel.h" #include "fuse_opt.h" #include "fuse_misc.h" -#include "fuse_common_compat.h" -#include "fuse_compat.h" #include "fuse_kernel.h" #include <stdio.h> @@ -82,7 +80,6 @@ struct fuse_fs { struct fuse_operations op; struct fuse_module *m; void *user_data; - int compat; int debug; }; @@ -145,8 +142,6 @@ struct fuse { struct fuse_config conf; int intr_installed; struct fuse_fs *fs; - int nullpath_ok; - int utime_omit_ok; struct lock_queue_element *lockq; int pagesize; struct list_head partial_slabs; @@ -207,12 +202,6 @@ struct fuse_dh { fuse_ino_t nodeid; }; -/* old dir handle */ -struct fuse_dirhandle { - fuse_fill_dir_t filler; - void *buf; -}; - struct fuse_context_i { struct fuse_context ctx; fuse_req_t req; @@ -1103,10 +1092,13 @@ static void debug_path(struct fuse *f, const char *msg, fuse_ino_t nodeid, if (wr) wnode = lookup_node(f, nodeid, name); - if (wnode) - fprintf(stderr, "%s %li (w)\n", msg, wnode->nodeid); - else - fprintf(stderr, "%s %li\n", msg, nodeid); + if (wnode) { + fprintf(stderr, "%s %llu (w)\n", + msg, (unsigned long long) wnode->nodeid); + } else { + fprintf(stderr, "%s %llu\n", + msg, (unsigned long long) nodeid); + } } } @@ -1181,7 +1173,7 @@ static int get_path_nullok(struct fuse *f, fuse_ino_t nodeid, char **path) *path = NULL; } else { err = get_path_common(f, nodeid, NULL, path, NULL); - if (err == -ENOENT && f->nullpath_ok) + if (err == -ENOENT) err = 0; } @@ -1463,129 +1455,6 @@ static inline void fuse_prepare_interrupt(struct fuse *f, fuse_req_t req, fuse_do_prepare_interrupt(req, d); } -#if !defined(__FreeBSD__) && !defined(__NetBSD__) - -static int fuse_compat_open(struct fuse_fs *fs, const char *path, - struct fuse_file_info *fi) -{ - int err; - if (!fs->compat || fs->compat >= 25) - err = fs->op.open(path, fi); - else if (fs->compat == 22) { - struct fuse_file_info_compat tmp; - memcpy(&tmp, fi, sizeof(tmp)); - err = ((struct fuse_operations_compat22 *) &fs->op)->open(path, - &tmp); - memcpy(fi, &tmp, sizeof(tmp)); - fi->fh = tmp.fh; - } else - err = ((struct fuse_operations_compat2 *) &fs->op) - ->open(path, fi->flags); - return err; -} - -static int fuse_compat_release(struct fuse_fs *fs, const char *path, - struct fuse_file_info *fi) -{ - if (!fs->compat || fs->compat >= 22) - return fs->op.release(path, fi); - else - return ((struct fuse_operations_compat2 *) &fs->op) - ->release(path, fi->flags); -} - -static int fuse_compat_opendir(struct fuse_fs *fs, const char *path, - struct fuse_file_info *fi) -{ - if (!fs->compat || fs->compat >= 25) - return fs->op.opendir(path, fi); - else { - int err; - struct fuse_file_info_compat tmp; - memcpy(&tmp, fi, sizeof(tmp)); - err = ((struct fuse_operations_compat22 *) &fs->op) - ->opendir(path, &tmp); - memcpy(fi, &tmp, sizeof(tmp)); - fi->fh = tmp.fh; - return err; - } -} - -static void convert_statfs_compat(struct fuse_statfs_compat1 *compatbuf, - struct statvfs *stbuf) -{ - stbuf->f_bsize = compatbuf->block_size; - stbuf->f_blocks = compatbuf->blocks; - stbuf->f_bfree = compatbuf->blocks_free; - stbuf->f_bavail = compatbuf->blocks_free; - stbuf->f_files = compatbuf->files; - stbuf->f_ffree = compatbuf->files_free; - stbuf->f_namemax = compatbuf->namelen; -} - -static void convert_statfs_old(struct statfs *oldbuf, struct statvfs *stbuf) -{ - stbuf->f_bsize = oldbuf->f_bsize; - stbuf->f_blocks = oldbuf->f_blocks; - stbuf->f_bfree = oldbuf->f_bfree; - stbuf->f_bavail = oldbuf->f_bavail; - stbuf->f_files = oldbuf->f_files; - stbuf->f_ffree = oldbuf->f_ffree; - stbuf->f_namemax = oldbuf->f_namelen; -} - -static int fuse_compat_statfs(struct fuse_fs *fs, const char *path, - struct statvfs *buf) -{ - int err; - - if (!fs->compat || fs->compat >= 25) { - err = fs->op.statfs(fs->compat == 25 ? "/" : path, buf); - } else if (fs->compat > 11) { - struct statfs oldbuf; - err = ((struct fuse_operations_compat22 *) &fs->op) - ->statfs("/", &oldbuf); - if (!err) - convert_statfs_old(&oldbuf, buf); - } else { - struct fuse_statfs_compat1 compatbuf; - memset(&compatbuf, 0, sizeof(struct fuse_statfs_compat1)); - err = ((struct fuse_operations_compat1 *) &fs->op) - ->statfs(&compatbuf); - if (!err) - convert_statfs_compat(&compatbuf, buf); - } - return err; -} - -#else /* __FreeBSD__ || __NetBSD__ */ - -static inline int fuse_compat_open(struct fuse_fs *fs, char *path, - struct fuse_file_info *fi) -{ - return fs->op.open(path, fi); -} - -static inline int fuse_compat_release(struct fuse_fs *fs, const char *path, - struct fuse_file_info *fi) -{ - return fs->op.release(path, fi); -} - -static inline int fuse_compat_opendir(struct fuse_fs *fs, const char *path, - struct fuse_file_info *fi) -{ - return fs->op.opendir(path, fi); -} - -static inline int fuse_compat_statfs(struct fuse_fs *fs, const char *path, - struct statvfs *buf) -{ - return fs->op.statfs(fs->compat == 25 ? "/" : path, buf); -} - -#endif /* __FreeBSD__ || __NetBSD__ */ - int fuse_fs_getattr(struct fuse_fs *fs, const char *path, struct stat *buf) { fuse_get_context()->private_data = fs->user_data; @@ -1695,7 +1564,7 @@ int fuse_fs_release(struct fuse_fs *fs, const char *path, fi->flush ? "+flush" : "", (unsigned long long) fi->fh, fi->flags); - return fuse_compat_release(fs, path, fi); + return fs->op.release(path, fi); } else { return 0; } @@ -1712,10 +1581,10 @@ int fuse_fs_opendir(struct fuse_fs *fs, const char *path, fprintf(stderr, "opendir flags: 0x%x %s\n", fi->flags, path); - err = fuse_compat_opendir(fs, path, fi); + err = fs->op.opendir(path, fi); if (fs->debug && !err) - fprintf(stderr, " opendir[%lli] flags: 0x%x %s\n", + fprintf(stderr, " opendir[%llu] flags: 0x%x %s\n", (unsigned long long) fi->fh, fi->flags, path); return err; @@ -1735,10 +1604,10 @@ int fuse_fs_open(struct fuse_fs *fs, const char *path, fprintf(stderr, "open flags: 0x%x %s\n", fi->flags, path); - err = fuse_compat_open(fs, path, fi); + err = fs->op.open(path, fi); if (fs->debug && !err) - fprintf(stderr, " open[%lli] flags: 0x%x %s\n", + fprintf(stderr, " open[%llu] flags: 0x%x %s\n", (unsigned long long) fi->fh, fi->flags, path); return err; @@ -1957,7 +1826,7 @@ int fuse_fs_statfs(struct fuse_fs *fs, const char *path, struct statvfs *buf) if (fs->debug) fprintf(stderr, "statfs %s\n", path); - return fuse_compat_statfs(fs, path, buf); + return fs->op.statfs(path, buf); } else { buf->f_namemax = 255; buf->f_bsize = 512; @@ -1980,20 +1849,6 @@ int fuse_fs_releasedir(struct fuse_fs *fs, const char *path, } } -static int fill_dir_old(struct fuse_dirhandle *dh, const char *name, int type, - ino_t ino) -{ - int res; - struct stat stbuf; - - memset(&stbuf, 0, sizeof(stbuf)); - stbuf.st_mode = type << 12; - stbuf.st_ino = ino; - - res = dh->filler(dh->buf, name, &stbuf, 0); - return res ? -ENOMEM : 0; -} - int fuse_fs_readdir(struct fuse_fs *fs, const char *path, void *buf, fuse_fill_dir_t filler, off_t off, struct fuse_file_info *fi) @@ -2006,16 +1861,6 @@ int fuse_fs_readdir(struct fuse_fs *fs, const char *path, void *buf, (unsigned long long) off); return fs->op.readdir(path, buf, filler, off, fi); - } else if (fs->op.getdir) { - struct fuse_dirhandle dh; - - if (fs->debug) - fprintf(stderr, "getdir[%llu]\n", - (unsigned long long) fi->fh); - - dh.filler = filler; - dh.buf = buf; - return fs->op.getdir(path, &dh, fill_dir_old); } else { return -ENOSYS; } @@ -2153,16 +1998,6 @@ int fuse_fs_utimens(struct fuse_fs *fs, const char *path, tv[1].tv_sec, tv[1].tv_nsec); return fs->op.utimens(path, tv); - } else if(fs->op.utime) { - struct utimbuf buf; - - if (fs->debug) - fprintf(stderr, "utime %s %li %li\n", path, - tv[0].tv_sec, tv[1].tv_sec); - - buf.actime = tv[0].tv_sec; - buf.modtime = tv[1].tv_sec; - return fs->op.utime(path, &buf); } else { return -ENOSYS; } @@ -2323,8 +2158,9 @@ int fuse_fs_poll(struct fuse_fs *fs, const char *path, int res; if (fs->debug) - fprintf(stderr, "poll[%llu] ph: %p\n", - (unsigned long long) fi->fh, ph); + fprintf(stderr, "poll[%llu] ph: %p, events 0x%x\n", + (unsigned long long) fi->fh, ph, + fi->poll_events); res = fs->op.poll(path, fi, ph, reventsp); @@ -2486,8 +2322,8 @@ static int lookup_path(struct fuse *f, fuse_ino_t nodeid, } set_stat(f, e->ino, &e->attr); if (f->conf.debug) - fprintf(stderr, " NODEID: %lu\n", - (unsigned long) e->ino); + fprintf(stderr, " NODEID: %llu\n", + (unsigned long long) e->ino); } } return res; @@ -2495,9 +2331,12 @@ static int lookup_path(struct fuse *f, fuse_ino_t nodeid, static struct fuse_context_i *fuse_get_context_internal(void) { - struct fuse_context_i *c; + return (struct fuse_context_i *) pthread_getspecific(fuse_context_key); +} - c = (struct fuse_context_i *) pthread_getspecific(fuse_context_key); +static struct fuse_context_i *fuse_create_context(struct fuse *f) +{ + struct fuse_context_i *c = fuse_get_context_internal(); if (c == NULL) { c = (struct fuse_context_i *) calloc(1, sizeof(struct fuse_context_i)); @@ -2510,7 +2349,11 @@ static struct fuse_context_i *fuse_get_context_internal(void) abort(); } pthread_setspecific(fuse_context_key, c); + } else { + memset(c, 0, sizeof(*c)); } + c->ctx.fuse = f; + return c; } @@ -2550,10 +2393,9 @@ static void fuse_delete_context_key(void) static struct fuse *req_fuse_prepare(fuse_req_t req) { - struct fuse_context_i *c = fuse_get_context_internal(); + struct fuse_context_i *c = fuse_create_context(req_fuse(req)); const struct fuse_ctx *ctx = fuse_req_ctx(req); c->req = req; - c->ctx.fuse = req_fuse(req); c->ctx.uid = ctx->uid; c->ctx.gid = ctx->gid; c->ctx.pid = ctx->pid; @@ -2597,10 +2439,8 @@ void fuse_fs_init(struct fuse_fs *fs, struct fuse_conn_info *conn) static void fuse_lib_init(void *data, struct fuse_conn_info *conn) { struct fuse *f = (struct fuse *) data; - struct fuse_context_i *c = fuse_get_context_internal(); - memset(c, 0, sizeof(*c)); - c->ctx.fuse = f; + fuse_create_context(f); conn->want |= FUSE_CAP_EXPORT_SUPPORT; fuse_fs_init(f->fs, conn); } @@ -2618,10 +2458,8 @@ void fuse_fs_destroy(struct fuse_fs *fs) static void fuse_lib_destroy(void *data) { struct fuse *f = (struct fuse *) data; - struct fuse_context_i *c = fuse_get_context_internal(); - memset(c, 0, sizeof(*c)); - c->ctx.fuse = f; + fuse_create_context(f); fuse_fs_destroy(f->fs); f->fs = NULL; } @@ -2795,7 +2633,7 @@ static void fuse_lib_setattr(fuse_req_t req, fuse_ino_t ino, struct stat *attr, attr->st_size); } #ifdef HAVE_UTIMENSAT - if (!err && f->utime_omit_ok && + if (!err && (valid & (FUSE_SET_ATTR_ATIME | FUSE_SET_ATTR_MTIME))) { struct timespec tv[2]; @@ -3078,14 +2916,8 @@ static void fuse_do_release(struct fuse *f, fuse_ino_t ino, const char *path, { struct node *node; int unlink_hidden = 0; - const char *compatpath; - - if (path != NULL || f->nullpath_ok || f->conf.nopath) - compatpath = path; - else - compatpath = "-"; - fuse_fs_release(f->fs, compatpath, fi); + fuse_fs_release(f->fs, path, fi); pthread_mutex_lock(&f->lock); node = get_node(f, ino); @@ -3516,16 +3348,11 @@ static void fuse_lib_releasedir(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info fi; struct fuse_dh *dh = get_dirhandle(llfi, &fi); char *path; - const char *compatpath; get_path_nullok(f, ino, &path); - if (path != NULL || f->nullpath_ok || f->conf.nopath) - compatpath = path; - else - compatpath = "-"; fuse_prepare_interrupt(f, req, &d); - fuse_fs_releasedir(f->fs, compatpath, &fi); + fuse_fs_releasedir(f->fs, path, &fi); fuse_finish_interrupt(f, req, &d); free_path(f, ino, path); @@ -4183,63 +4010,11 @@ int fuse_notify_poll(struct fuse_pollhandle *ph) return fuse_lowlevel_notify_poll(ph); } -static void free_cmd(struct fuse_cmd *cmd) -{ - free(cmd->buf); - free(cmd); -} - -void fuse_process_cmd(struct fuse *f, struct fuse_cmd *cmd) -{ - fuse_session_process(f->se, cmd->buf, cmd->buflen, cmd->ch); - free_cmd(cmd); -} - -int fuse_exited(struct fuse *f) -{ - return fuse_session_exited(f->se); -} - struct fuse_session *fuse_get_session(struct fuse *f) { return f->se; } -static struct fuse_cmd *fuse_alloc_cmd(size_t bufsize) -{ - struct fuse_cmd *cmd = (struct fuse_cmd *) malloc(sizeof(*cmd)); - if (cmd == NULL) { - fprintf(stderr, "fuse: failed to allocate cmd\n"); - return NULL; - } - cmd->buf = (char *) malloc(bufsize); - if (cmd->buf == NULL) { - fprintf(stderr, "fuse: failed to allocate read buffer\n"); - free(cmd); - return NULL; - } - return cmd; -} - -struct fuse_cmd *fuse_read_cmd(struct fuse *f) -{ - struct fuse_chan *ch = fuse_session_next_chan(f->se, NULL); - size_t bufsize = fuse_chan_bufsize(ch); - struct fuse_cmd *cmd = fuse_alloc_cmd(bufsize); - if (cmd != NULL) { - int res = fuse_chan_recv(&ch, cmd->buf, bufsize); - if (res <= 0) { - free_cmd(cmd); - if (res < 0 && res != -EINTR && res != -EAGAIN) - fuse_exit(f); - return NULL; - } - cmd->buflen = res; - cmd->ch = ch; - } - return cmd; -} - static int fuse_session_loop_remember(struct fuse *f) { struct fuse_session *se = f->se; @@ -4313,13 +4088,6 @@ int fuse_loop(struct fuse *f) return fuse_session_loop(f->se); } -int fuse_invalidate(struct fuse *f, const char *path) -{ - (void) f; - (void) path; - return -EINVAL; -} - void fuse_exit(struct fuse *f) { fuse_session_exit(f->se); @@ -4327,36 +4095,31 @@ void fuse_exit(struct fuse *f) struct fuse_context *fuse_get_context(void) { - return &fuse_get_context_internal()->ctx; -} + struct fuse_context_i *c = fuse_get_context_internal(); -/* - * The size of fuse_context got extended, so need to be careful about - * incompatibility (i.e. a new binary cannot work with an old - * library). - */ -struct fuse_context *fuse_get_context_compat22(void); -struct fuse_context *fuse_get_context_compat22(void) -{ - return &fuse_get_context_internal()->ctx; + if (c) + return &c->ctx; + else + return NULL; } -FUSE_SYMVER(".symver fuse_get_context_compat22,fuse_get_context@FUSE_2.2"); int fuse_getgroups(int size, gid_t list[]) { - fuse_req_t req = fuse_get_context_internal()->req; - return fuse_req_getgroups(req, size, list); + struct fuse_context_i *c = fuse_get_context_internal(); + if (!c) + return -EINVAL; + + return fuse_req_getgroups(c->req, size, list); } int fuse_interrupted(void) { - return fuse_req_interrupted(fuse_get_context_internal()->req); -} + struct fuse_context_i *c = fuse_get_context_internal(); -void fuse_set_getcontext_func(struct fuse_context *(*func)(void)) -{ - (void) func; - /* no-op */ + if (c) + return fuse_req_interrupted(c->req); + else + return 0; } enum { @@ -4458,12 +4221,6 @@ static int fuse_lib_opt_proc(void *data, const char *arg, int key, return 1; } -int fuse_is_lib_option(const char *opt) -{ - return fuse_lowlevel_is_lib_option(opt) || - fuse_opt_match(fuse_lib_opts, opt); -} - static int fuse_init_intr_signal(int signum, int *installed) { struct sigaction old_sa; @@ -4516,9 +4273,7 @@ static int fuse_push_module(struct fuse *f, const char *module, } newfs->m = m; f->fs = newfs; - f->nullpath_ok = newfs->op.flag_nullpath_ok && f->nullpath_ok; f->conf.nopath = newfs->op.flag_nopath && f->conf.nopath; - f->utime_omit_ok = newfs->op.flag_utime_omit_ok && f->utime_omit_ok; return 0; } @@ -4588,9 +4343,9 @@ void fuse_stop_cleanup_thread(struct fuse *f) } } -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, int compat) +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; @@ -4610,11 +4365,8 @@ struct fuse *fuse_new_common(struct fuse_chan *ch, struct fuse_args *args, if (!fs) goto out_free; - fs->compat = compat; f->fs = fs; - f->nullpath_ok = fs->op.flag_nullpath_ok; f->conf.nopath = fs->op.flag_nopath; - f->utime_omit_ok = fs->op.flag_utime_omit_ok; /* Oh f**k, this is ugly! */ if (!fs->op.lock) { @@ -4662,12 +4414,7 @@ struct fuse *fuse_new_common(struct fuse_chan *ch, struct fuse_args *args, f->conf.readdir_ino = 1; #endif - if (compat && compat <= 25) { - if (fuse_sync_compat_args(args) == -1) - goto out_free_fs; - } - - 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) { if (f->conf.help) fuse_lib_help_modules(); @@ -4677,9 +4424,7 @@ struct fuse *fuse_new_common(struct fuse_chan *ch, struct fuse_args *args, fuse_session_add_chan(f->se, ch); if (f->conf.debug) { - fprintf(stderr, "nullpath_ok: %i\n", f->nullpath_ok); fprintf(stderr, "nopath: %i\n", f->conf.nopath); - fprintf(stderr, "utime_omit_ok: %i\n", f->utime_omit_ok); } /* Trace topmost layer by default */ @@ -4728,10 +4473,9 @@ out_free_name_table: out_free_session: fuse_session_destroy(f->se); out_free_fs: - /* Horrible compatibility hack to stop the destructor from being - called on the filesystem without init being called first */ - fs->op.destroy = NULL; - fuse_fs_destroy(f->fs); + if (f->fs->m) + fuse_put_module(f->fs->m); + free(f->fs); free(f->conf.modules); out_free: free(f); @@ -4741,13 +4485,6 @@ out: 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, 0); -} - void fuse_destroy(struct fuse *f) { size_t i; @@ -4756,10 +4493,7 @@ void fuse_destroy(struct fuse *f) fuse_restore_intr_signal(f->conf.intr_signal); if (f->fs) { - struct fuse_context_i *c = fuse_get_context_internal(); - - memset(c, 0, sizeof(*c)); - c->ctx.fuse = f; + fuse_create_context(f); for (i = 0; i < f->id_table.size; i++) { struct node *node; @@ -4798,19 +4532,6 @@ void fuse_destroy(struct fuse *f) fuse_delete_context_key(); } -static struct fuse *fuse_new_common_compat25(int fd, struct fuse_args *args, - const struct fuse_operations *op, - size_t op_size, int compat) -{ - struct fuse *f = NULL; - struct fuse_chan *ch = fuse_kern_chan_new(fd); - - if (ch) - f = fuse_new_common(ch, args, op, op_size, NULL, compat); - - return f; -} - /* called with fuse_context_lock held or during initialization (before main() has been called) */ void fuse_register_module(struct fuse_module *mod) @@ -4822,72 +4543,3 @@ void fuse_register_module(struct fuse_module *mod) mod->next = fuse_modules; fuse_modules = mod; } - -#if !defined(__FreeBSD__) && !defined(__NetBSD__) - -static struct fuse *fuse_new_common_compat(int fd, const char *opts, - const struct fuse_operations *op, - size_t op_size, int compat) -{ - struct fuse *f; - struct fuse_args args = FUSE_ARGS_INIT(0, NULL); - - if (fuse_opt_add_arg(&args, "") == -1) - return NULL; - if (opts && - (fuse_opt_add_arg(&args, "-o") == -1 || - fuse_opt_add_arg(&args, opts) == -1)) { - fuse_opt_free_args(&args); - return NULL; - } - f = fuse_new_common_compat25(fd, &args, op, op_size, compat); - fuse_opt_free_args(&args); - - return f; -} - -struct fuse *fuse_new_compat22(int fd, const char *opts, - const struct fuse_operations_compat22 *op, - size_t op_size) -{ - return fuse_new_common_compat(fd, opts, (struct fuse_operations *) op, - op_size, 22); -} - -struct fuse *fuse_new_compat2(int fd, const char *opts, - const struct fuse_operations_compat2 *op) -{ - return fuse_new_common_compat(fd, opts, (struct fuse_operations *) op, - sizeof(struct fuse_operations_compat2), - 21); -} - -struct fuse *fuse_new_compat1(int fd, int flags, - const struct fuse_operations_compat1 *op) -{ - const char *opts = NULL; - if (flags & FUSE_DEBUG_COMPAT1) - opts = "debug"; - return fuse_new_common_compat(fd, opts, (struct fuse_operations *) op, - sizeof(struct fuse_operations_compat1), - 11); -} - -FUSE_SYMVER(".symver fuse_exited,__fuse_exited@"); -FUSE_SYMVER(".symver fuse_process_cmd,__fuse_process_cmd@"); -FUSE_SYMVER(".symver fuse_read_cmd,__fuse_read_cmd@"); -FUSE_SYMVER(".symver fuse_set_getcontext_func,__fuse_set_getcontext_func@"); -FUSE_SYMVER(".symver fuse_new_compat2,fuse_new@"); -FUSE_SYMVER(".symver fuse_new_compat22,fuse_new@FUSE_2.2"); - -#endif /* __FreeBSD__ || __NetBSD__ */ - -struct fuse *fuse_new_compat25(int fd, struct fuse_args *args, - const struct fuse_operations_compat25 *op, - size_t op_size) -{ - return fuse_new_common_compat25(fd, args, (struct fuse_operations *) op, - op_size, 25); -} - -FUSE_SYMVER(".symver fuse_new_compat25,fuse_new@FUSE_2.5"); diff --git a/lib/fuse_i.h b/lib/fuse_i.h index 78f1467..ffcf062 100644 --- a/lib/fuse_i.h +++ b/lib/fuse_i.h @@ -71,6 +71,10 @@ struct fuse_ll { 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; struct fuse_lowlevel_ops op; int got_init; struct cuse_data *cuse_data; @@ -87,25 +91,8 @@ struct fuse_ll { struct fuse_notify_req notify_list; }; -struct fuse_cmd { - char *buf; - size_t buflen; - 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, int compat); - -int fuse_sync_compat_args(struct fuse_args *args); - 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); - -void fuse_kern_unmount_compat22(const char *mountpoint); void fuse_kern_unmount(const char *mountpoint, int fd); int fuse_kern_mount(const char *mountpoint, struct fuse_args *args); @@ -113,16 +100,6 @@ int fuse_send_reply_iov_nofree(fuse_req_t req, int error, struct iovec *iov, int count); void fuse_free_req(fuse_req_t req); - -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, - int compat); - void cuse_lowlevel_init(fuse_req_t req, fuse_ino_t nodeide, const void *inarg); int fuse_start_thread(pthread_t *thread_id, void *(*func)(void *), void *arg); diff --git a/lib/fuse_lowlevel.c b/lib/fuse_lowlevel.c index 01efc6a..45cd5f3 100644 --- a/lib/fuse_lowlevel.c +++ b/lib/fuse_lowlevel.c @@ -13,8 +13,6 @@ #include "fuse_kernel.h" #include "fuse_opt.h" #include "fuse_misc.h" -#include "fuse_common_compat.h" -#include "fuse_lowlevel_compat.h" #include <stdio.h> #include <stdlib.h> @@ -241,13 +239,13 @@ int fuse_reply_iov(fuse_req_t req, const struct iovec *iov, int count) return res; } -size_t fuse_dirent_size(size_t namelen) +static size_t fuse_dirent_size(size_t namelen) { return FUSE_DIRENT_ALIGN(FUSE_NAME_OFFSET + namelen); } -char *fuse_add_dirent(char *buf, const char *name, const struct stat *stbuf, - off_t off) +static char *fuse_add_dirent(char *buf, const char *name, + const struct stat *stbuf, off_t off) { unsigned namelen = strlen(name); unsigned entlen = FUSE_NAME_OFFSET + namelen; @@ -341,6 +339,25 @@ static void fill_entry(struct fuse_entry_out *arg, convert_stat(&e->attr, &arg->attr); } +size_t fuse_add_direntry_plus(fuse_req_t req, char *buf, size_t bufsize, + const char *name, + const struct fuse_entry_param *e, off_t off) +{ + struct fuse_entry_out *argp; + size_t entsize; + + (void) req; + entsize = FUSE_DIRENT_ALIGN(FUSE_NAME_OFFSET_DIRENTPLUS + + fuse_dirent_size(strlen(name))); + if (entsize <= bufsize && buf){ + argp = (struct fuse_entry_out *)buf; + memset(argp, 0, sizeof(*argp)); + fill_entry(argp, e); + fuse_add_dirent(buf + sizeof(*argp), name, &(e->attr), off); + } + return entsize; +} + static void fill_open(struct fuse_open_out *arg, const struct fuse_file_info *f) { @@ -485,6 +502,31 @@ static void fuse_ll_pipe_free(struct fuse_ll_pipe *llp) } #ifdef HAVE_SPLICE +#if !defined(HAVE_PIPE2) || !defined(O_CLOEXEC) +static int fuse_pipe(int fds[2]) +{ + int rv = pipe(fds); + + if (rv == -1) + return rv; + + if (fcntl(fds[0], F_SETFL, O_NONBLOCK) == -1 || + fcntl(fds[1], F_SETFL, O_NONBLOCK) == -1 || + fcntl(fds[0], F_SETFD, FD_CLOEXEC) == -1 || + fcntl(fds[1], F_SETFD, FD_CLOEXEC) == -1) { + close(fds[0]); + close(fds[1]); + rv = -1; + } + return rv; +} +#else +static int fuse_pipe(int fds[2]) +{ + return pipe2(fds, O_CLOEXEC | O_NONBLOCK); +} +#endif + static struct fuse_ll_pipe *fuse_ll_get_pipe(struct fuse_ll *f) { struct fuse_ll_pipe *llp = pthread_getspecific(f->pipe_key); @@ -495,20 +537,12 @@ static struct fuse_ll_pipe *fuse_ll_get_pipe(struct fuse_ll *f) if (llp == NULL) return NULL; - res = pipe(llp->pipe); + res = fuse_pipe(llp->pipe); if (res == -1) { free(llp); return NULL; } - if (fcntl(llp->pipe[0], F_SETFL, O_NONBLOCK) == -1 || - fcntl(llp->pipe[1], F_SETFL, O_NONBLOCK) == -1) { - close(llp->pipe[0]); - close(llp->pipe[1]); - free(llp); - return NULL; - } - /* *the default size is 16 pages on linux */ @@ -1391,6 +1425,21 @@ static void do_readdir(fuse_req_t req, fuse_ino_t nodeid, const void *inarg) fuse_reply_err(req, ENOSYS); } +static void do_readdirplus(fuse_req_t req, fuse_ino_t nodeid, const void *inarg) +{ + struct fuse_read_in *arg = (struct fuse_read_in *) inarg; + struct fuse_file_info fi; + + memset(&fi, 0, sizeof(fi)); + fi.fh = arg->fh; + fi.fh_old = fi.fh; + + if (req->f->op.readdirplus) + req->f->op.readdirplus(req, nodeid, arg->size, arg->offset, &fi); + else + fuse_reply_err(req, ENOSYS); +} + static void do_releasedir(fuse_req_t req, fuse_ino_t nodeid, const void *inarg) { struct fuse_release_in *arg = (struct fuse_release_in *) inarg; @@ -1697,6 +1746,7 @@ static void do_poll(fuse_req_t req, fuse_ino_t nodeid, const void *inarg) memset(&fi, 0, sizeof(fi)); fi.fh = arg->fh; fi.fh_old = fi.fh; + fi.poll_events = arg->events; if (req->f->op.poll) { struct fuse_pollhandle *ph = NULL; @@ -1789,6 +1839,12 @@ static void do_init(fuse_req_t req, fuse_ino_t nodeid, const void *inarg) f->conn.capable |= FUSE_CAP_DONT_MASK; if (arg->flags & FUSE_FLOCK_LOCKS) f->conn.capable |= FUSE_CAP_FLOCK_LOCKS; + if (arg->flags & FUSE_AUTO_INVAL_DATA) + f->conn.capable |= FUSE_CAP_AUTO_INVAL_DATA; + if (arg->flags & FUSE_DO_READDIRPLUS) + f->conn.capable |= FUSE_CAP_READDIRPLUS; + if (arg->flags & FUSE_READDIRPLUS_AUTO) + f->conn.capable |= FUSE_CAP_READDIRPLUS_AUTO; } else { f->conn.async_read = 0; f->conn.max_readahead = 0; @@ -1819,6 +1875,13 @@ static void do_init(fuse_req_t req, fuse_ino_t nodeid, const void *inarg) f->conn.want |= FUSE_CAP_FLOCK_LOCKS; if (f->big_writes) f->conn.want |= FUSE_CAP_BIG_WRITES; + if (f->auto_inval_data) + f->conn.want |= FUSE_CAP_AUTO_INVAL_DATA; + if (f->op.readdirplus && !f->no_readdirplus) { + f->conn.want |= FUSE_CAP_READDIRPLUS; + if (!f->no_readdirplus_auto) + f->conn.want |= FUSE_CAP_READDIRPLUS_AUTO; + } if (bufsize < FUSE_MIN_READ_BUFFER) { fprintf(stderr, "fuse: warning: buffer size too small: %zu\n", @@ -1840,7 +1903,12 @@ static void do_init(fuse_req_t req, fuse_ino_t nodeid, const void *inarg) f->conn.want &= ~FUSE_CAP_SPLICE_WRITE; if (f->no_splice_move) f->conn.want &= ~FUSE_CAP_SPLICE_MOVE; - + if (f->no_auto_inval_data) + f->conn.want &= ~FUSE_CAP_AUTO_INVAL_DATA; + if (f->no_readdirplus) + f->conn.want &= ~FUSE_CAP_READDIRPLUS; + if (f->no_readdirplus_auto) + f->conn.want &= ~FUSE_CAP_READDIRPLUS_AUTO; if (f->conn.async_read || (f->conn.want & FUSE_CAP_ASYNC_READ)) outarg.flags |= FUSE_ASYNC_READ; if (f->conn.want & FUSE_CAP_POSIX_LOCKS) @@ -1855,6 +1923,12 @@ static void do_init(fuse_req_t req, fuse_ino_t nodeid, const void *inarg) outarg.flags |= FUSE_DONT_MASK; if (f->conn.want & FUSE_CAP_FLOCK_LOCKS) outarg.flags |= FUSE_FLOCK_LOCKS; + if (f->conn.want & FUSE_CAP_AUTO_INVAL_DATA) + outarg.flags |= FUSE_AUTO_INVAL_DATA; + if (f->conn.want & FUSE_CAP_READDIRPLUS) + outarg.flags |= FUSE_DO_READDIRPLUS; + if (f->conn.want & FUSE_CAP_READDIRPLUS_AUTO) + outarg.flags |= FUSE_READDIRPLUS_AUTO; outarg.max_readahead = f->conn.max_readahead; outarg.max_write = f->conn.max_write; if (f->conn.proto_minor >= 13) { @@ -2202,21 +2276,6 @@ const struct fuse_ctx *fuse_req_ctx(fuse_req_t req) return &req->ctx; } -/* - * The size of fuse_ctx got extended, so need to be careful about - * incompatibility (i.e. a new binary cannot work with an old - * library). - */ -const struct fuse_ctx *fuse_req_ctx_compat24(fuse_req_t req); -const struct fuse_ctx *fuse_req_ctx_compat24(fuse_req_t req) -{ - return fuse_req_ctx(req); -} -#ifndef __NetBSD__ -FUSE_SYMVER(".symver fuse_req_ctx_compat24,fuse_req_ctx@FUSE_2.4"); -#endif - - void fuse_req_interrupt_func(fuse_req_t req, fuse_interrupt_func_t func, void *data) { @@ -2286,6 +2345,7 @@ static struct { [FUSE_DESTROY] = { do_destroy, "DESTROY" }, [FUSE_NOTIFY_REPLY] = { (void *) 1, "NOTIFY_REPLY" }, [FUSE_BATCH_FORGET] = { do_batch_forget, "BATCH_FORGET" }, + [FUSE_READDIRPLUS] = { do_readdirplus, "READDIRPLUS"}, [CUSE_INIT] = { cuse_lowlevel_init, "CUSE_INIT" }, }; @@ -2351,10 +2411,10 @@ static void fuse_ll_process_buf(void *data, const struct fuse_buf *buf, if (f->debug) { fprintf(stderr, - "unique: %llu, opcode: %s (%i), nodeid: %lu, insize: %zu, pid: %u\n", + "unique: %llu, opcode: %s (%i), nodeid: %llu, insize: %zu, pid: %u\n", (unsigned long long) in->unique, opname((enum fuse_opcode) in->opcode), in->opcode, - (unsigned long) in->nodeid, buf->size, in->pid); + (unsigned long long) in->nodeid, buf->size, in->pid); } req = fuse_ll_alloc_req(f); @@ -2394,7 +2454,8 @@ static void fuse_ll_process_buf(void *data, const struct fuse_buf *buf, in->opcode != FUSE_WRITE && in->opcode != FUSE_FSYNC && in->opcode != FUSE_RELEASE && in->opcode != FUSE_READDIR && in->opcode != FUSE_FSYNCDIR && in->opcode != FUSE_RELEASEDIR && - in->opcode != FUSE_NOTIFY_REPLY) + in->opcode != FUSE_NOTIFY_REPLY && + in->opcode != FUSE_READDIRPLUS) goto reply_err; err = ENOSYS; @@ -2491,6 +2552,13 @@ static const struct fuse_opt fuse_ll_opts[] = { { "no_splice_move", offsetof(struct fuse_ll, no_splice_move), 1}, { "splice_read", offsetof(struct fuse_ll, splice_read), 1}, { "no_splice_read", offsetof(struct fuse_ll, no_splice_read), 1}, + { "auto_inval_data", offsetof(struct fuse_ll, auto_inval_data), 1}, + { "no_auto_inval_data", offsetof(struct fuse_ll, no_auto_inval_data), 1}, + { "readdirplus=no", offsetof(struct fuse_ll, no_readdirplus), 1}, + { "readdirplus=yes", offsetof(struct fuse_ll, no_readdirplus), 0}, + { "readdirplus=yes", offsetof(struct fuse_ll, no_readdirplus_auto), 1}, + { "readdirplus=auto", offsetof(struct fuse_ll, no_readdirplus), 0}, + { "readdirplus=auto", offsetof(struct fuse_ll, no_readdirplus_auto), 0}, FUSE_OPT_KEY("max_read=", FUSE_OPT_KEY_DISCARD), FUSE_OPT_KEY("-h", KEY_HELP), FUSE_OPT_KEY("--help", KEY_HELP), @@ -2522,6 +2590,8 @@ static void fuse_ll_help(void) " -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" ); } @@ -2546,11 +2616,6 @@ static int fuse_ll_opt_proc(void *data, const char *arg, int key, return -1; } -int fuse_lowlevel_is_lib_option(const char *opt) -{ - return fuse_opt_match(fuse_ll_opts, opt); -} - static void fuse_ll_destroy(void *data) { struct fuse_ll *f = (struct fuse_ll *) data; @@ -2690,14 +2755,9 @@ static int fuse_ll_receive_buf(struct fuse_session *se, struct fuse_buf *buf, #endif -/* - * 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, - 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) { int err; struct fuse_ll *f; @@ -2763,14 +2823,6 @@ out: 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); -} - #ifdef linux int fuse_req_getgroups(fuse_req_t req, int size, gid_t list[]) { @@ -2839,129 +2891,3 @@ int fuse_req_getgroups(fuse_req_t req, int size, gid_t list[]) return -ENOSYS; } #endif - -#if !defined(__FreeBSD__) && !defined(__NetBSD__) - -static void fill_open_compat(struct fuse_open_out *arg, - const struct fuse_file_info_compat *f) -{ - arg->fh = f->fh; - if (f->direct_io) - arg->open_flags |= FOPEN_DIRECT_IO; - if (f->keep_cache) - arg->open_flags |= FOPEN_KEEP_CACHE; -} - -static void convert_statfs_compat(const struct statfs *compatbuf, - struct statvfs *buf) -{ - buf->f_bsize = compatbuf->f_bsize; - buf->f_blocks = compatbuf->f_blocks; - buf->f_bfree = compatbuf->f_bfree; - buf->f_bavail = compatbuf->f_bavail; - buf->f_files = compatbuf->f_files; - buf->f_ffree = compatbuf->f_ffree; - buf->f_namemax = compatbuf->f_namelen; -} - -int fuse_reply_open_compat(fuse_req_t req, - const struct fuse_file_info_compat *f) -{ - struct fuse_open_out arg; - - memset(&arg, 0, sizeof(arg)); - fill_open_compat(&arg, f); - return send_reply_ok(req, &arg, sizeof(arg)); -} - -int fuse_reply_statfs_compat(fuse_req_t req, const struct statfs *stbuf) -{ - struct statvfs newbuf; - - memset(&newbuf, 0, sizeof(newbuf)); - convert_statfs_compat(stbuf, &newbuf); - - return fuse_reply_statfs(req, &newbuf); -} - -struct fuse_session *fuse_lowlevel_new_compat(const char *opts, - const struct fuse_lowlevel_ops_compat *op, - size_t op_size, void *userdata) -{ - struct fuse_session *se; - struct fuse_args args = FUSE_ARGS_INIT(0, NULL); - - if (opts && - (fuse_opt_add_arg(&args, "") == -1 || - fuse_opt_add_arg(&args, "-o") == -1 || - fuse_opt_add_arg(&args, opts) == -1)) { - fuse_opt_free_args(&args); - return NULL; - } - se = fuse_lowlevel_new(&args, (const struct fuse_lowlevel_ops *) op, - op_size, userdata); - fuse_opt_free_args(&args); - - return se; -} - -struct fuse_ll_compat_conf { - unsigned max_read; - int set_max_read; -}; - -static const struct fuse_opt fuse_ll_opts_compat[] = { - { "max_read=", offsetof(struct fuse_ll_compat_conf, set_max_read), 1 }, - { "max_read=%u", offsetof(struct fuse_ll_compat_conf, max_read), 0 }, - FUSE_OPT_KEY("max_read=", FUSE_OPT_KEY_KEEP), - FUSE_OPT_END -}; - -int fuse_sync_compat_args(struct fuse_args *args) -{ - struct fuse_ll_compat_conf conf; - - memset(&conf, 0, sizeof(conf)); - if (fuse_opt_parse(args, &conf, fuse_ll_opts_compat, NULL) == -1) - return -1; - - if (fuse_opt_insert_arg(args, 1, "-osync_read")) - return -1; - - if (conf.set_max_read) { - char tmpbuf[64]; - - sprintf(tmpbuf, "-omax_readahead=%u", conf.max_read); - if (fuse_opt_insert_arg(args, 1, tmpbuf) == -1) - return -1; - } - return 0; -} - -FUSE_SYMVER(".symver fuse_reply_statfs_compat,fuse_reply_statfs@FUSE_2.4"); -FUSE_SYMVER(".symver fuse_reply_open_compat,fuse_reply_open@FUSE_2.4"); -FUSE_SYMVER(".symver fuse_lowlevel_new_compat,fuse_lowlevel_new@FUSE_2.4"); - -#else /* __FreeBSD__ || __NetBSD__ */ - -int fuse_sync_compat_args(struct fuse_args *args) -{ - (void) args; - return 0; -} - -#endif /* __FreeBSD__ || __NetBSD__ */ - -struct fuse_session *fuse_lowlevel_new_compat25(struct fuse_args *args, - const struct fuse_lowlevel_ops_compat25 *op, - size_t op_size, void *userdata) -{ - if (fuse_sync_compat_args(args) == -1) - return NULL; - - return fuse_lowlevel_new_common(args, - (const struct fuse_lowlevel_ops *) op, - op_size, userdata); -} - -FUSE_SYMVER(".symver fuse_lowlevel_new_compat25,fuse_lowlevel_new@FUSE_2.5"); diff --git a/lib/fuse_misc.h b/lib/fuse_misc.h index eedf0e0..f102ba3 100644 --- a/lib/fuse_misc.h +++ b/lib/fuse_misc.h @@ -9,17 +9,6 @@ #include "config.h" #include <pthread.h> -/* - Versioned symbols cannot be used in some cases because it - - confuse the dynamic linker in uClibc - - not supported on MacOSX (in MachO binary format) -*/ -#if (!defined(__UCLIBC__) && !defined(__APPLE__)) -#define FUSE_SYMVER(x) __asm__(x) -#else -#define FUSE_SYMVER(x) -#endif - #ifndef USE_UCLIBC #define fuse_mutex_init(mut) pthread_mutex_init(mut, NULL) #else diff --git a/lib/fuse_mt.c b/lib/fuse_mt.c index f6dbe71..ee38b28 100644 --- a/lib/fuse_mt.c +++ b/lib/fuse_mt.c @@ -6,105 +6,9 @@ See the file COPYING.LIB. */ -#include "fuse_i.h" -#include "fuse_misc.h" +#include "fuse.h" #include "fuse_lowlevel.h" -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <pthread.h> -#include <assert.h> - -struct procdata { - struct fuse *f; - struct fuse_chan *prevch; - struct fuse_session *prevse; - fuse_processor_t proc; - void *data; -}; - -static void mt_session_proc(void *data, const char *buf, size_t len, - struct fuse_chan *ch) -{ - struct procdata *pd = (struct procdata *) data; - struct fuse_cmd *cmd = *(struct fuse_cmd **) buf; - - (void) len; - (void) ch; - pd->proc(pd->f, cmd, pd->data); -} - -static void mt_session_exit(void *data, int val) -{ - struct procdata *pd = (struct procdata *) data; - if (val) - fuse_session_exit(pd->prevse); - else - fuse_session_reset(pd->prevse); -} - -static int mt_session_exited(void *data) -{ - struct procdata *pd = (struct procdata *) data; - return fuse_session_exited(pd->prevse); -} - -static int mt_chan_receive(struct fuse_chan **chp, char *buf, size_t size) -{ - struct fuse_cmd *cmd; - struct procdata *pd = (struct procdata *) fuse_chan_data(*chp); - - assert(size >= sizeof(cmd)); - - cmd = fuse_read_cmd(pd->f); - if (cmd == NULL) - return 0; - - *(struct fuse_cmd **) buf = cmd; - - return sizeof(cmd); -} - -int fuse_loop_mt_proc(struct fuse *f, fuse_processor_t proc, void *data) -{ - int res; - struct procdata pd; - struct fuse_session *prevse = fuse_get_session(f); - struct fuse_session *se; - struct fuse_chan *prevch = fuse_session_next_chan(prevse, NULL); - struct fuse_chan *ch; - struct fuse_session_ops sop = { - .exit = mt_session_exit, - .exited = mt_session_exited, - .process = mt_session_proc, - }; - struct fuse_chan_ops cop = { - .receive = mt_chan_receive, - }; - - pd.f = f; - pd.prevch = prevch; - pd.prevse = prevse; - pd.proc = proc; - pd.data = data; - - se = fuse_session_new(&sop, &pd); - if (se == NULL) - return -1; - - ch = fuse_chan_new(&cop, fuse_chan_fd(prevch), - sizeof(struct fuse_cmd *), &pd); - if (ch == NULL) { - fuse_session_destroy(se); - return -1; - } - fuse_session_add_chan(se, ch); - res = fuse_session_loop_mt(se); - fuse_session_destroy(se); - return res; -} - int fuse_loop_mt(struct fuse *f) { if (f == NULL) @@ -118,5 +22,3 @@ int fuse_loop_mt(struct fuse *f) fuse_stop_cleanup_thread(f); return res; } - -FUSE_SYMVER(".symver fuse_loop_mt_proc,__fuse_loop_mt@"); diff --git a/lib/fuse_opt.c b/lib/fuse_opt.c index a2118ce..15f9e21 100644 --- a/lib/fuse_opt.c +++ b/lib/fuse_opt.c @@ -92,13 +92,6 @@ int fuse_opt_insert_arg(struct fuse_args *args, int pos, const char *arg) return fuse_opt_insert_arg_common(args, pos, arg); } -int fuse_opt_insert_arg_compat(struct fuse_args *args, int pos, - const char *arg); -int fuse_opt_insert_arg_compat(struct fuse_args *args, int pos, const char *arg) -{ - return fuse_opt_insert_arg_common(args, pos, arg); -} - static int next_arg(struct fuse_opt_context *ctx, const char *opt) { if (ctx->argctr + 1 >= ctx->argc) { @@ -211,11 +204,13 @@ static int process_opt_param(void *var, const char *format, const char *param, { assert(format[0] == '%'); if (format[1] == 's') { + char **s = var; char *copy = strdup(param); if (!copy) return alloc_failed(); - *(char **) var = copy; + free(*s); + *s = copy; } else { if (sscanf(param, format, var) != 1) { fprintf(stderr, "fuse: invalid parameter in option `%s'\n", arg); @@ -421,6 +416,3 @@ int fuse_opt_parse(struct fuse_args *args, void *data, fuse_opt_free_args(&ctx.outargs); return res; } - -/* This symbol version was mistakenly added to the version script */ -FUSE_SYMVER(".symver fuse_opt_insert_arg_compat,fuse_opt_insert_arg@FUSE_2.5"); diff --git a/lib/fuse_session.c b/lib/fuse_session.c index c55f250..ccd11c3 100644 --- a/lib/fuse_session.c +++ b/lib/fuse_session.c @@ -8,8 +8,6 @@ #include "fuse_i.h" #include "fuse_misc.h" -#include "fuse_common_compat.h" -#include "fuse_lowlevel_compat.h" #include <stdio.h> #include <stdlib.h> @@ -27,8 +25,6 @@ struct fuse_chan { size_t bufsize; void *data; - - int compat; }; struct fuse_session *fuse_session_new(struct fuse_session_ops *op, void *data) @@ -144,9 +140,8 @@ void *fuse_session_data(struct fuse_session *se) return se->data; } -static struct fuse_chan *fuse_chan_new_common(struct fuse_chan_ops *op, int fd, - size_t bufsize, void *data, - int compat) +struct fuse_chan *fuse_chan_new(struct fuse_chan_ops *op, int fd, + size_t bufsize, void *data) { struct fuse_chan *ch = (struct fuse_chan *) malloc(sizeof(*ch)); if (ch == NULL) { @@ -159,24 +154,10 @@ static struct fuse_chan *fuse_chan_new_common(struct fuse_chan_ops *op, int fd, ch->fd = fd; ch->bufsize = bufsize; ch->data = data; - ch->compat = compat; return ch; } -struct fuse_chan *fuse_chan_new(struct fuse_chan_ops *op, int fd, - size_t bufsize, void *data) -{ - return fuse_chan_new_common(op, fd, bufsize, data, 0); -} - -struct fuse_chan *fuse_chan_new_compat24(struct fuse_chan_ops_compat24 *op, - int fd, size_t bufsize, void *data) -{ - return fuse_chan_new_common((struct fuse_chan_ops *) op, fd, bufsize, - data, 24); -} - int fuse_chan_fd(struct fuse_chan *ch) { return ch->fd; @@ -200,19 +181,8 @@ struct fuse_session *fuse_chan_session(struct fuse_chan *ch) int fuse_chan_recv(struct fuse_chan **chp, char *buf, size_t size) { struct fuse_chan *ch = *chp; - if (ch->compat) - return ((struct fuse_chan_ops_compat24 *) &ch->op) - ->receive(ch, buf, size); - else - return ch->op.receive(chp, buf, size); -} -int fuse_chan_receive(struct fuse_chan *ch, char *buf, size_t size) -{ - int res; - - res = fuse_chan_recv(&ch, buf, size); - return res >= 0 ? res : (res != -EINTR && res != -EAGAIN) ? -1 : 0; + return ch->op.receive(chp, buf, size); } int fuse_chan_send(struct fuse_chan *ch, const struct iovec iov[], size_t count) @@ -227,7 +197,3 @@ void fuse_chan_destroy(struct fuse_chan *ch) ch->op.destroy(ch); free(ch); } - -#ifndef __FreeBSD__ -FUSE_SYMVER(".symver fuse_chan_new_compat24,fuse_chan_new@FUSE_2.4"); -#endif diff --git a/lib/fuse_versionscript b/lib/fuse_versionscript index 8d91887..cfff5de 100644 --- a/lib/fuse_versionscript +++ b/lib/fuse_versionscript @@ -1,38 +1,15 @@ -FUSE_2.2 { +FUSE_3.0 { global: fuse_destroy; fuse_exit; - fuse_exited; - fuse_invalidate; - fuse_is_lib_option; fuse_loop; fuse_loop_mt; - fuse_loop_mt_proc; - fuse_main; - fuse_main_compat1; - fuse_main_compat2; - fuse_mount_compat1; - fuse_new_compat1; - fuse_new_compat2; - fuse_process_cmd; - fuse_read_cmd; - fuse_set_getcontext_func; - fuse_setup_compat2; -}; - -FUSE_2.4 { - global: - fuse_add_dirent; fuse_chan_bufsize; fuse_chan_data; fuse_chan_destroy; fuse_chan_fd; - fuse_chan_receive; fuse_chan_send; fuse_chan_session; - fuse_dirent_size; - fuse_kern_chan_new; - fuse_lowlevel_is_lib_option; fuse_reply_attr; fuse_reply_buf; fuse_reply_entry; @@ -52,14 +29,6 @@ FUSE_2.4 { fuse_session_next_chan; fuse_session_process; fuse_session_reset; -} FUSE_2.2; - -FUSE_2.5 { - global: - fuse_lowlevel_new_compat; - fuse_main_real_compat22; - fuse_mount_compat22; - fuse_new_compat22; fuse_opt_parse; fuse_opt_add_opt; fuse_opt_add_arg; @@ -69,45 +38,25 @@ FUSE_2.5 { fuse_remove_signal_handlers; fuse_reply_create; fuse_reply_open; - fuse_reply_open_compat; fuse_reply_statfs; - fuse_reply_statfs_compat; - fuse_setup_compat22; fuse_set_signal_handlers; -} FUSE_2.4; - -FUSE_2.6 { - global: fuse_add_direntry; + fuse_add_direntry_plus; fuse_chan_new; - fuse_chan_new_compat24; fuse_chan_recv; fuse_daemonize; fuse_get_session; fuse_interrupted; fuse_lowlevel_new; - fuse_lowlevel_new_compat25; fuse_main_real; - fuse_main_real_compat25; fuse_mount; - fuse_mount_compat25; fuse_new; - fuse_new_compat25; fuse_opt_insert_arg; fuse_reply_lock; fuse_req_interrupt_func; fuse_req_interrupted; fuse_session_remove_chan; - fuse_setup; - fuse_setup_compat25; - fuse_teardown; - fuse_teardown_compat22; fuse_unmount; - fuse_unmount_compat22; -} FUSE_2.5; - -FUSE_2.7 { - global: fuse_fs_access; fuse_fs_bmap; fuse_fs_chmod; @@ -148,15 +97,7 @@ FUSE_2.7 { fuse_register_module; fuse_reply_iov; fuse_version; -} FUSE_2.6; - -FUSE_2.7.5 { - global: fuse_reply_bmap; -} FUSE_2.7; - -FUSE_2.8 { - global: cuse_lowlevel_new; cuse_lowlevel_main; cuse_lowlevel_setup; @@ -178,10 +119,6 @@ FUSE_2.8 { fuse_req_ctx; fuse_req_getgroups; fuse_session_data; -} FUSE_2.7.5; - -FUSE_2.9 { - global: fuse_buf_copy; fuse_buf_size; fuse_fs_read_buf; @@ -196,12 +133,8 @@ FUSE_2.9 { fuse_clean_cache; fuse_lowlevel_notify_delete; fuse_fs_flock; -} FUSE_2.8; - -FUSE_2.9.1 { - global: fuse_fs_fallocate; local: *; -} FUSE_2.9; +}; diff --git a/lib/helper.c b/lib/helper.c index ace19dd..8ee66df 100644 --- a/lib/helper.c +++ b/lib/helper.c @@ -11,7 +11,6 @@ #include "fuse_misc.h" #include "fuse_opt.h" #include "fuse_lowlevel.h" -#include "fuse_common_compat.h" #include <stdio.h> #include <stdlib.h> @@ -211,12 +210,13 @@ int fuse_daemonize(int foreground) if (nullfd > 2) close(nullfd); } + } else { + (void) chdir("/"); } 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; @@ -231,7 +231,7 @@ static struct fuse_chan *fuse_mount_common(const char *mountpoint, close(fd); } while (fd >= 0 && fd <= 2); - fd = fuse_mount_compat25(mountpoint, args); + fd = fuse_kern_mount(mountpoint, args); if (fd == -1) return NULL; @@ -242,12 +242,7 @@ 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); @@ -255,19 +250,9 @@ static void fuse_unmount_common(const char *mountpoint, struct fuse_chan *ch) fuse_chan_destroy(ch); } -void fuse_unmount(const char *mountpoint, struct fuse_chan *ch) -{ - fuse_unmount_common(mountpoint, ch); -} - -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, - int compat) +static struct fuse *fuse_setup(int argc, char *argv[], + const struct fuse_operations *op, size_t op_size, + char **mountpoint, int *multithreaded, void *user_data) { struct fuse_args args = FUSE_ARGS_INIT(argc, argv); struct fuse_chan *ch; @@ -279,13 +264,13 @@ struct fuse *fuse_setup_common(int argc, char *argv[], if (res == -1) return NULL; - ch = fuse_mount_common(*mountpoint, &args); + ch = fuse_mount(*mountpoint, &args); if (!ch) { fuse_opt_free_args(&args); goto err_free; } - fuse = fuse_new_common(ch, &args, op, op_size, user_data, compat); + fuse = fuse_new(ch, &args, op, op_size, user_data); fuse_opt_free_args(&args); if (fuse == NULL) goto err_unmount; @@ -298,13 +283,10 @@ struct fuse *fuse_setup_common(int argc, char *argv[], if (res == -1) goto err_unmount; - if (fd) - *fd = fuse_chan_fd(ch); - return fuse; err_unmount: - fuse_unmount_common(*mountpoint, ch); + fuse_unmount(*mountpoint, ch); if (fuse) fuse_destroy(fuse); err_free: @@ -312,40 +294,26 @@ err_free: return NULL; } -struct fuse *fuse_setup(int argc, char *argv[], - const struct fuse_operations *op, size_t op_size, - char **mountpoint, int *multithreaded, void *user_data) -{ - return fuse_setup_common(argc, argv, op, op_size, mountpoint, - multithreaded, NULL, user_data, 0); -} - -static void fuse_teardown_common(struct fuse *fuse, char *mountpoint) +static void fuse_teardown(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_unmount(mountpoint, ch); fuse_destroy(fuse); free(mountpoint); } -void fuse_teardown(struct fuse *fuse, char *mountpoint) -{ - fuse_teardown_common(fuse, mountpoint); -} - -static int fuse_main_common(int argc, char *argv[], - const struct fuse_operations *op, size_t op_size, - void *user_data, int compat) +int fuse_main_real(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, compat); + fuse = fuse_setup(argc, argv, op, op_size, &mountpoint, + &multithreaded, user_data); if (fuse == NULL) return 1; @@ -354,125 +322,15 @@ static int fuse_main_common(int argc, char *argv[], else res = fuse_loop(fuse); - fuse_teardown_common(fuse, mountpoint); + fuse_teardown(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, 0); -} - -#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; } -#include "fuse_compat.h" - -#if !defined(__FreeBSD__) && !defined(__NetBSD__) - -struct fuse *fuse_setup_compat22(int argc, char *argv[], - const struct fuse_operations_compat22 *op, - size_t op_size, char **mountpoint, - int *multithreaded, int *fd) -{ - return fuse_setup_common(argc, argv, (struct fuse_operations *) op, - op_size, mountpoint, multithreaded, fd, NULL, - 22); -} - -struct fuse *fuse_setup_compat2(int argc, char *argv[], - const struct fuse_operations_compat2 *op, - char **mountpoint, int *multithreaded, - int *fd) -{ - return fuse_setup_common(argc, argv, (struct fuse_operations *) op, - sizeof(struct fuse_operations_compat2), - mountpoint, multithreaded, fd, NULL, 21); -} - -int fuse_main_real_compat22(int argc, char *argv[], - const struct fuse_operations_compat22 *op, - size_t op_size) -{ - return fuse_main_common(argc, argv, (struct fuse_operations *) op, - op_size, NULL, 22); -} - -void fuse_main_compat1(int argc, char *argv[], - const struct fuse_operations_compat1 *op) -{ - fuse_main_common(argc, argv, (struct fuse_operations *) op, - sizeof(struct fuse_operations_compat1), NULL, 11); -} - -int fuse_main_compat2(int argc, char *argv[], - const struct fuse_operations_compat2 *op) -{ - return fuse_main_common(argc, argv, (struct fuse_operations *) op, - sizeof(struct fuse_operations_compat2), NULL, - 21); -} - -int fuse_mount_compat1(const char *mountpoint, const char *args[]) -{ - /* just ignore mount args for now */ - (void) args; - return fuse_mount_compat22(mountpoint, NULL); -} - -FUSE_SYMVER(".symver fuse_setup_compat2,__fuse_setup@"); -FUSE_SYMVER(".symver fuse_setup_compat22,fuse_setup@FUSE_2.2"); -FUSE_SYMVER(".symver fuse_teardown,__fuse_teardown@"); -FUSE_SYMVER(".symver fuse_main_compat2,fuse_main@"); -FUSE_SYMVER(".symver fuse_main_real_compat22,fuse_main_real@FUSE_2.2"); - -#endif /* __FreeBSD__ || __NetBSD__ */ - - -struct fuse *fuse_setup_compat25(int argc, char *argv[], - const struct fuse_operations_compat25 *op, - size_t op_size, char **mountpoint, - int *multithreaded, int *fd) -{ - return fuse_setup_common(argc, argv, (struct fuse_operations *) op, - op_size, mountpoint, multithreaded, fd, NULL, - 25); -} - -int fuse_main_real_compat25(int argc, char *argv[], - const struct fuse_operations_compat25 *op, - size_t op_size) -{ - return fuse_main_common(argc, argv, (struct fuse_operations *) op, - op_size, NULL, 25); -} - -void fuse_teardown_compat22(struct fuse *fuse, int fd, char *mountpoint) -{ - (void) fd; - fuse_teardown_common(fuse, mountpoint); -} - -int fuse_mount_compat25(const char *mountpoint, struct fuse_args *args) -{ - return fuse_kern_mount(mountpoint, args); -} - -FUSE_SYMVER(".symver fuse_setup_compat25,fuse_setup@FUSE_2.5"); -FUSE_SYMVER(".symver fuse_teardown_compat22,fuse_teardown@FUSE_2.2"); -FUSE_SYMVER(".symver fuse_main_real_compat25,fuse_main_real@FUSE_2.5"); -FUSE_SYMVER(".symver fuse_mount_compat25,fuse_mount@FUSE_2.5"); diff --git a/lib/modules/iconv.c b/lib/modules/iconv.c index 89b22e4..bc3694e 100644 --- a/lib/modules/iconv.c +++ b/lib/modules/iconv.c @@ -6,7 +6,7 @@ See the file COPYING.LIB */ -#define FUSE_USE_VERSION 26 +#define FUSE_USE_VERSION 30 #include <fuse.h> #include <stdio.h> @@ -631,7 +631,6 @@ static const struct fuse_operations iconv_oper = { .flock = iconv_flock, .bmap = iconv_bmap, - .flag_nullpath_ok = 1, .flag_nopath = 1, }; diff --git a/lib/modules/subdir.c b/lib/modules/subdir.c index 76a53fa..52b91e1 100644 --- a/lib/modules/subdir.c +++ b/lib/modules/subdir.c @@ -6,7 +6,7 @@ See the file COPYING.LIB */ -#define FUSE_USE_VERSION 26 +#define FUSE_USE_VERSION 30 #include <fuse.h> #include <stdio.h> @@ -614,7 +614,6 @@ static const struct fuse_operations subdir_oper = { .flock = subdir_flock, .bmap = subdir_bmap, - .flag_nullpath_ok = 1, .flag_nopath = 1, }; diff --git a/lib/mount.c b/lib/mount.c index 6a9da9e..4f74841 100644 --- a/lib/mount.c +++ b/lib/mount.c @@ -10,7 +10,6 @@ #include "fuse_i.h" #include "fuse_misc.h" #include "fuse_opt.h" -#include "fuse_common_compat.h" #include "mount_util.h" #include <stdio.h> @@ -98,6 +97,10 @@ static const struct fuse_opt fuse_mount_opts[] = { 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), + FUSE_OPT_KEY("fscontext=", KEY_KERN_OPT), + FUSE_OPT_KEY("defcontext=", KEY_KERN_OPT), + FUSE_OPT_KEY("rootcontext=", KEY_KERN_OPT), FUSE_OPT_KEY("max_read=", KEY_KERN_OPT), FUSE_OPT_KEY("max_read=", FUSE_OPT_KEY_KEEP), FUSE_OPT_KEY("user=", KEY_MTAB_OPT), @@ -333,11 +336,6 @@ void fuse_kern_unmount(const char *mountpoint, int fd) waitpid(pid, NULL, 0); } -void fuse_unmount_compat22(const char *mountpoint) -{ - fuse_kern_unmount(mountpoint, -1); -} - static int fuse_mount_fusermount(const char *mountpoint, struct mount_opts *mo, const char *opts, int quiet) { @@ -408,14 +406,9 @@ static int fuse_mount_fusermount(const char *mountpoint, struct mount_opts *mo, return rv; } -int fuse_mount_compat22(const char *mountpoint, const char *opts) -{ - struct mount_opts mo; - memset(&mo, 0, sizeof(mo)); - mo.flags = MS_NOSUID | MS_NODEV; - - return fuse_mount_fusermount(mountpoint, &mo, opts, 0); -} +#ifndef O_CLOEXEC +#define O_CLOEXEC 0 +#endif static int fuse_mount_sys(const char *mnt, struct mount_opts *mo, const char *mnt_opts) @@ -453,7 +446,7 @@ static int fuse_mount_sys(const char *mnt, struct mount_opts *mo, return -2; } - fd = open(devname, O_RDWR); + fd = open(devname, O_RDWR | O_CLOEXEC); if (fd == -1) { if (errno == ENODEV || errno == ENOENT) fprintf(stderr, "fuse: device not found, try 'modprobe fuse' first\n"); @@ -462,6 +455,8 @@ static int fuse_mount_sys(const char *mnt, struct mount_opts *mo, devname, strerror(errno)); return -1; } + if (!O_CLOEXEC) + fcntl(fd, F_SETFD, FD_CLOEXEC); snprintf(tmp, sizeof(tmp), "fd=%i,rootmode=%o,user_id=%i,group_id=%i", fd, stbuf.st_mode & S_IFMT, getuid(), getgid()); @@ -631,6 +626,3 @@ out: free(mo.mtab_opts); return res; } - -FUSE_SYMVER(".symver fuse_mount_compat22,fuse_mount@FUSE_2.2"); -FUSE_SYMVER(".symver fuse_unmount_compat22,fuse_unmount@FUSE_2.2"); diff --git a/lib/mount_bsd.c b/lib/mount_bsd.c index 62443ac..9ee74fb 100644 --- a/lib/mount_bsd.c +++ b/lib/mount_bsd.c @@ -384,5 +384,3 @@ out: free(mo.kernel_opts); return res; } - -FUSE_SYMVER(".symver fuse_unmount_compat22,fuse_unmount@FUSE_2.2"); |