diff options
Diffstat (limited to 'lib/fuse_lowlevel.c')
-rw-r--r-- | lib/fuse_lowlevel.c | 450 |
1 files changed, 270 insertions, 180 deletions
diff --git a/lib/fuse_lowlevel.c b/lib/fuse_lowlevel.c index f14aeeb..495eb1d 100644 --- a/lib/fuse_lowlevel.c +++ b/lib/fuse_lowlevel.c @@ -6,10 +6,8 @@ See the file COPYING.LIB */ -#include "fuse_i.h" -#include "fuse_compat.h" +#include "fuse_lowlevel.h" #include "fuse_kernel.h" -#include "fuse_kernel_compat5.h" #include <stdio.h> #include <string.h> @@ -28,7 +26,7 @@ struct fuse_ll { unsigned int debug : 1; unsigned int allow_root : 1; int fd; - struct fuse_lowlevel_operations op; + struct fuse_ll_operations op; volatile int exited; int got_init; void *user_data; @@ -42,6 +40,14 @@ struct fuse_cmd { size_t buflen; }; +struct fuse_req { + struct fuse_ll *f; + uint64_t unique; + uid_t uid; + gid_t gid; + pid_t pid; +}; + static const char *opname(enum fuse_opcode opcode) { switch (opcode) { @@ -77,7 +83,7 @@ static const char *opname(enum fuse_opcode opcode) } } -static void convert_stat(struct stat *stbuf, struct fuse_attr *attr) +static void convert_stat(const struct stat *stbuf, struct fuse_attr *attr) { attr->ino = stbuf->st_ino; attr->mode = stbuf->st_mode; @@ -97,6 +103,22 @@ static void convert_stat(struct stat *stbuf, struct fuse_attr *attr) #endif } +static void convert_attr(const struct fuse_attr *attr, struct stat *stbuf) +{ + stbuf->st_mode = attr->mode; + stbuf->st_uid = attr->uid; + stbuf->st_gid = attr->gid; + stbuf->st_size = attr->size; + stbuf->st_atime = attr->atime; + stbuf->st_mtime = attr->mtime; + stbuf->st_ctime = attr->ctime; +#ifdef HAVE_STRUCT_STAT_ST_ATIM + stbuf->st_atim.tv_nsec = attr->atimensec; + stbuf->st_mtim.tv_nsec = attr->mtimensec; + stbuf->st_ctim.tv_nsec = attr->ctimensec; +#endif +} + static size_t iov_length(const struct iovec *iov, size_t count) { size_t seg; @@ -115,17 +137,12 @@ static int send_reply_raw(struct fuse_ll *f, const struct iovec iov[], struct fuse_out_header *out = (struct fuse_out_header *) iov[0].iov_base; out->len = outsize; - if ((f->flags & FUSE_DEBUG)) { + if (f->debug) { printf(" unique: %llu, error: %i (%s), outsize: %i\n", out->unique, out->error, strerror(-out->error), outsize); fflush(stdout); } - /* This needs to be done before the reply, otherwise the scheduler - could play tricks with us, and only let the counter be - increased long after the operation is done */ - fuse_inc_avail(f); - res = writev(f->fd, iov, count); if (res == -1) { /* ENOENT means the operation was interrupted */ @@ -136,8 +153,8 @@ static int send_reply_raw(struct fuse_ll *f, const struct iovec iov[], return 0; } -static int send_reply(struct fuse_ll *f, struct fuse_in_header *in, int error, - void *arg, size_t argsize) +static int send_reply(struct fuse_ll *f, uint64_t unique, int error, + const void *arg, size_t argsize) { struct fuse_out_header out; struct iovec iov[2]; @@ -148,14 +165,14 @@ static int send_reply(struct fuse_ll *f, struct fuse_in_header *in, int error, error = -ERANGE; } - out.unique = in->unique; + out.unique = unique; out.error = error; count = 1; iov[0].iov_base = &out; iov[0].iov_len = sizeof(struct fuse_out_header); if (argsize && !error) { count++; - iov[1].iov_base = arg; + iov[1].iov_base = (void *) arg; iov[1].iov_len = argsize; } return send_reply_raw(f, iov, count); @@ -166,8 +183,8 @@ size_t fuse_dirent_size(size_t namelen) return FUSE_DIRENT_ALIGN(FUSE_NAME_OFFSET + namelen); } -void fuse_add_dirent(char *buf, const char *name, const struct stat *stat, - off_t off) +char *fuse_add_dirent(char *buf, const char *name, const struct stat *stat, + off_t off) { unsigned namelen = strlen(name); unsigned entlen = FUSE_NAME_OFFSET + namelen; @@ -183,10 +200,11 @@ void fuse_add_dirent(char *buf, const char *name, const struct stat *stat, if (padlen) memset(buf + entlen, 0, padlen); - return 0; + return buf + entsize; } -static void convert_statfs(struct statfs *statfs, struct fuse_kstatfs *kstatfs) +static void convert_statfs(const struct statfs *statfs, + struct fuse_kstatfs *kstatfs) { kstatfs->bsize = statfs->f_bsize; kstatfs->blocks = statfs->f_blocks; @@ -197,6 +215,131 @@ static void convert_statfs(struct statfs *statfs, struct fuse_kstatfs *kstatfs) kstatfs->namelen = statfs->f_namelen; } +static void free_req(fuse_req_t req) +{ + free(req); +} + +static int send_reply_req(fuse_req_t req, const void *arg, size_t argsize) +{ + int res = send_reply(req->f, req->unique, 0, arg, argsize); + free_req(req); + return res; +} + +int fuse_reply_err(fuse_req_t req, int err) +{ + int res = send_reply(req->f, req->unique, -err, NULL, 0); + free_req(req); + return res; +} + +int fuse_reply_none(fuse_req_t req) +{ + free_req(req); + return 0; +} + +static unsigned long calc_timeout_sec(double t) +{ + if (t > (double) ULONG_MAX) + return ULONG_MAX; + else if (t < 0.0) + return 0; + else + return (unsigned long) t; +} + +static unsigned int calc_timeout_nsec(double t) +{ + double f = t - (double) calc_timeout_sec(t); + if (f < 0.0) + return 0; + else if (f >= 0.999999999) + return 999999999; + else + return (unsigned int) (f * 1.0e9); +} + +int fuse_reply_entry(fuse_req_t req, const struct fuse_entry_param *e) +{ + struct fuse_entry_out arg; + + memset(&arg, 0, sizeof(arg)); + arg.nodeid = e->ino; + arg.generation = e->generation; + arg.entry_valid = calc_timeout_sec(e->entry_timeout); + arg.entry_valid_nsec = calc_timeout_nsec(e->entry_timeout); + arg.attr_valid = calc_timeout_sec(e->attr_timeout); + arg.attr_valid_nsec = calc_timeout_nsec(e->attr_timeout); + convert_stat(&e->attr, &arg.attr); + + return send_reply_req(req, &arg, sizeof(arg)); +} + +int fuse_reply_attr(fuse_req_t req, const struct stat *attr, + double attr_timeout) +{ + struct fuse_attr_out arg; + + memset(&arg, 0, sizeof(arg)); + arg.attr_valid = calc_timeout_sec(attr_timeout); + arg.attr_valid_nsec = calc_timeout_nsec(attr_timeout); + convert_stat(attr, &arg.attr); + + return send_reply_req(req, &arg, sizeof(arg)); +} + +int fuse_reply_readlink(fuse_req_t req, const char *link) +{ + return send_reply_req(req, link, strlen(link)); +} + +int fuse_reply_open(fuse_req_t req, const struct fuse_file_info *f) +{ + struct fuse_open_out arg; + + memset(&arg, 0, sizeof(arg)); + arg.fh = f->fh; + + return send_reply_req(req, &arg, sizeof(arg)); +} + +int fuse_reply_write(fuse_req_t req, size_t count) +{ + struct fuse_write_out arg; + + memset(&arg, 0, sizeof(arg)); + arg.size = count; + + return send_reply_req(req, &arg, sizeof(arg)); +} + +int fuse_reply_buf(fuse_req_t req, const char *buf, size_t size) +{ + return send_reply_req(req, buf, size); +} + +int fuse_reply_statfs(fuse_req_t req, const struct statfs *statfs) +{ + struct fuse_statfs_out arg; + + memset(&arg, 0, sizeof(arg)); + convert_statfs(statfs, &arg.st); + + return send_reply_req(req, &arg, sizeof(arg)); +} + +int fuse_reply_xattr(fuse_req_t req, size_t count) +{ + struct fuse_getxattr_out arg; + + memset(&arg, 0, sizeof(arg)); + arg.size = count; + + return send_reply_req(req, &arg, sizeof(arg)); +} + static void do_lookup(fuse_req_t req, fuse_ino_t nodeid, char *name) { if (req->f->op.lookup) @@ -205,10 +348,11 @@ static void do_lookup(fuse_req_t req, fuse_ino_t nodeid, char *name) fuse_reply_err(req, ENOSYS); } -static void do_forget(fuse_req_t req, fuse_ino_t nodeid) +static void do_forget(fuse_req_t req, fuse_ino_t nodeid, + struct fuse_forget_in *arg) { if (req->f->op.forget) - req->f->op.forget(req, nodeid); + req->f->op.forget(req, nodeid, arg->nlookup); } static void do_getattr(fuse_req_t req, fuse_ino_t nodeid) @@ -222,9 +366,11 @@ static void do_getattr(fuse_req_t req, fuse_ino_t nodeid) static void do_setattr(fuse_req_t req, fuse_ino_t nodeid, struct fuse_setattr_in *arg) { - if (req->f->op.setattr) - req->f->op.setattr(req, nodeid, &arg->attr, arg->valid); - else + if (req->f->op.setattr) { + struct stat stbuf; + convert_attr(&arg->attr, &stbuf); + req->f->op.setattr(req, nodeid, &stbuf, arg->valid); + } else fuse_reply_err(req, ENOSYS); } @@ -304,27 +450,26 @@ static void do_open(fuse_req_t req, fuse_ino_t nodeid, struct fuse_open_in *arg) { struct fuse_file_info fi; - + memset(&fi, 0, sizeof(fi)); fi.flags = arg->flags; if (req->f->op.open) req->f->op.open(req, nodeid, &fi); else - fuse_reply_err(req, ENOSYS); + fuse_reply_open(req, &fi); } static void do_read(fuse_req_t req, fuse_ino_t nodeid, struct fuse_read_in *arg) { - struct fuse_file_info fi; + if (req->f->op.read) { + struct fuse_file_info fi; - memset(&fi, 0, sizeof(fi)); - fi.fh = arg->fh; - - if (req->f->op.read) + memset(&fi, 0, sizeof(fi)); + fi.fh = arg->fh; req->f->op.read(req, nodeid, arg->size, arg->offset, &fi); - else + } else fuse_reply_err(req, ENOSYS); } @@ -338,7 +483,8 @@ static void do_write(fuse_req_t req, fuse_ino_t nodeid, fi.writepage = arg->write_flags & 1; if (req->f->op.write) - req->f->op.write(req, nodeid, PARAM(arg), arg->size, arg->offset, &fi); + req->f->op.write(req, nodeid, PARAM(arg), arg->size, + arg->offset, &fi); else fuse_reply_err(req, ENOSYS); } @@ -369,7 +515,7 @@ static void do_release(fuse_req_t req, fuse_ino_t nodeid, if (req->f->op.release) req->f->op.release(req, nodeid, &fi); else - fuse_reply_err(req, ENOSYS); + fuse_reply_err(req, 0); } static void do_fsync(fuse_req_t req, fuse_ino_t nodeid, @@ -397,7 +543,7 @@ static void do_opendir(fuse_req_t req, fuse_ino_t nodeid, if (req->f->op.opendir) req->f->op.opendir(req, nodeid, &fi); else - fuse_reply_err(req, ENOSYS); + fuse_reply_open(req, &fi); } static void do_readdir(fuse_req_t req, fuse_ino_t nodeid, @@ -426,7 +572,7 @@ static void do_releasedir(fuse_req_t req, fuse_ino_t nodeid, if (req->f->op.releasedir) req->f->op.releasedir(req, nodeid, &fi); else - fuse_reply_err(req, ENOSYS); + fuse_reply_err(req, 0); } static void do_fsyncdir(fuse_req_t req, fuse_ino_t nodeid, @@ -446,7 +592,7 @@ static void do_fsyncdir(fuse_req_t req, fuse_ino_t nodeid, static void do_statfs(fuse_req_t req, fuse_ino_t nodeid) { if (req->f->op.statfs) - res = req->f->op.statfs(req, nodeid); + req->f->op.statfs(req, nodeid); else fuse_reply_err(req, ENOSYS); } @@ -458,7 +604,8 @@ static void do_setxattr(fuse_req_t req, fuse_ino_t nodeid, unsigned char *value = name + strlen(name) + 1; if (req->f->op.setxattr) - req->f->op.setxattr(req, nodeid, name, value, arg->size, arg->flags); + req->f->op.setxattr(req, nodeid, name, value, arg->size, + arg->flags); else fuse_reply_err(req, ENOSYS); } @@ -489,17 +636,12 @@ static void do_removexattr(fuse_req_t req, fuse_ino_t nodeid, char *name) fuse_reply_err(req, ENOSYS); } -static void do_init(struct fuse_ll *f, struct fuse_in_header *in, +static void do_init(struct fuse_ll *f, uint64_t unique, struct fuse_init_in_out *arg) { struct fuse_init_in_out outarg; - if (in->padding == 5) { - arg->minor = arg->major; - arg->major = in->padding; - } - - if (f->flags & FUSE_DEBUG) { + if (f->debug) { printf("INIT: %u.%u\n", arg->major, arg->minor); fflush(stdout); } @@ -507,26 +649,19 @@ static void do_init(struct fuse_ll *f, struct fuse_in_header *in, if (f->op.init) f->user_data = f->op.init(); - if (arg->major == 5) { - f->major = 5; - f->minor = 1; - } else if (arg->major == 6) { - f->major = 6; - f->minor = 1; - } else { - f->major = FUSE_KERNEL_VERSION; - f->minor = FUSE_KERNEL_MINOR_VERSION; - } + f->major = FUSE_KERNEL_VERSION; + f->minor = FUSE_KERNEL_MINOR_VERSION; + memset(&outarg, 0, sizeof(outarg)); outarg.major = f->major; outarg.minor = f->minor; - if (f->flags & FUSE_DEBUG) { + if (f->debug) { printf(" INIT: %u.%u\n", outarg.major, outarg.minor); fflush(stdout); } - send_reply(f, in, 0, &outarg, sizeof(outarg)); + send_reply(f, unique, 0, &outarg, sizeof(outarg)); } static void free_cmd(struct fuse_cmd *cmd) @@ -535,169 +670,172 @@ static void free_cmd(struct fuse_cmd *cmd) free(cmd); } -void fuse_process_cmd(struct fuse_ll *f, struct fuse_cmd *cmd) +void fuse_ll_process_cmd(struct fuse_ll *f, struct fuse_cmd *cmd) { struct fuse_in_header *in = (struct fuse_in_header *) cmd->buf; - void *inarg = cmd->buf + SIZEOF_COMPAT(f, fuse_in_header); - struct fuse_context *ctx = fuse_get_context(); + void *inarg = cmd->buf + sizeof(struct fuse_in_header); + struct fuse_req *req; - fuse_dec_avail(f); - - if ((f->flags & FUSE_DEBUG)) { + if (f->debug) { printf("unique: %llu, opcode: %s (%i), nodeid: %lu, insize: %i\n", in->unique, opname(in->opcode), in->opcode, (unsigned long) in->nodeid, cmd->buflen); fflush(stdout); } - if (!f->got_init && in->opcode != FUSE_INIT) { - /* Old kernel version probably */ - send_reply(f, in, -EPROTO, NULL, 0); + if (!f->got_init) { + if (in->opcode != FUSE_INIT) + send_reply(f, in->unique, -EPROTO, NULL, 0); + else + do_init(f, in->unique, (struct fuse_init_in_out *) inarg); goto out; } - if ((f->flags & FUSE_ALLOW_ROOT) && in->uid != f->owner && in->uid != 0 && + if (f->allow_root && in->uid != f->owner && in->uid != 0 && in->opcode != FUSE_INIT && in->opcode != FUSE_READ && in->opcode != FUSE_WRITE && in->opcode != FUSE_FSYNC && in->opcode != FUSE_RELEASE && in->opcode != FUSE_READDIR && in->opcode != FUSE_FSYNCDIR && in->opcode != FUSE_RELEASEDIR) { - send_reply(f, in, -EACCES, NULL, 0); + send_reply(f, in->unique, -EACCES, NULL, 0); goto out; } - ctx->fuse = f; - ctx->uid = in->uid; - ctx->gid = in->gid; - ctx->pid = in->pid; - ctx->private_data = f->user_data; + req = (struct fuse_req *) malloc(sizeof(struct fuse_req)); + if (req == NULL) { + fprintf(stderr, "fuse: failed to allocate request\n"); + goto out; + } + + req->f = f; + req->unique = in->unique; + req->uid = in->uid; + req->gid = in->gid; + req->pid = in->pid; switch (in->opcode) { case FUSE_LOOKUP: - do_lookup(f, req, nodeid, (char *) inarg); + do_lookup(req, in->nodeid, (char *) inarg); break; - do_forget(f, in, (struct fuse_forget_in *) inarg); + case FUSE_FORGET: + do_forget(req, in->nodeid, (struct fuse_forget_in *) inarg); break; - } + case FUSE_GETATTR: - do_getattr(f, in); + do_getattr(req, in->nodeid); break; case FUSE_SETATTR: - do_setattr(f, in, (struct fuse_setattr_in *) inarg); + do_setattr(req, in->nodeid, (struct fuse_setattr_in *) inarg); break; case FUSE_READLINK: - do_readlink(f, in); + do_readlink(req, in->nodeid); break; case FUSE_MKNOD: - do_mknod(f, in, (struct fuse_mknod_in *) inarg); + do_mknod(req, in->nodeid, (struct fuse_mknod_in *) inarg); break; case FUSE_MKDIR: - do_mkdir(f, in, (struct fuse_mkdir_in *) inarg); + do_mkdir(req, in->nodeid, (struct fuse_mkdir_in *) inarg); break; case FUSE_UNLINK: - do_unlink(f, in, (char *) inarg); + do_unlink(req, in->nodeid, (char *) inarg); break; case FUSE_RMDIR: - do_rmdir(f, in, (char *) inarg); + do_rmdir(req, in->nodeid, (char *) inarg); break; case FUSE_SYMLINK: - do_symlink(f, in, (char *) inarg, + do_symlink(req, in->nodeid, (char *) inarg, ((char *) inarg) + strlen((char *) inarg) + 1); break; case FUSE_RENAME: - do_rename(f, in, (struct fuse_rename_in *) inarg); + do_rename(req, in->nodeid, (struct fuse_rename_in *) inarg); break; case FUSE_LINK: - do_link(f, in, (struct fuse_link_in *) inarg); + do_link(req, in->nodeid, (struct fuse_link_in *) inarg); break; case FUSE_OPEN: - do_open(f, in, (struct fuse_open_in *) inarg); + do_open(req, in->nodeid, (struct fuse_open_in *) inarg); break; case FUSE_FLUSH: - do_flush(f, in, (struct fuse_flush_in *) inarg); + do_flush(req, in->nodeid, (struct fuse_flush_in *) inarg); break; case FUSE_RELEASE: - do_release(f, in, (struct fuse_release_in *) inarg); + do_release(req, in->nodeid, (struct fuse_release_in *) inarg); break; case FUSE_READ: - do_read(f, in, (struct fuse_read_in *) inarg); + do_read(req, in->nodeid, (struct fuse_read_in *) inarg); break; case FUSE_WRITE: - do_write(f, in, (struct fuse_write_in *) inarg); + do_write(req, in->nodeid, (struct fuse_write_in *) inarg); break; case FUSE_STATFS: - do_statfs(f, in); + do_statfs(req, in->nodeid); break; case FUSE_FSYNC: - do_fsync(f, in, (struct fuse_fsync_in *) inarg); + do_fsync(req, in->nodeid, (struct fuse_fsync_in *) inarg); break; case FUSE_SETXATTR: - do_setxattr(f, in, (struct fuse_setxattr_in *) inarg); + do_setxattr(req, in->nodeid, (struct fuse_setxattr_in *) inarg); break; case FUSE_GETXATTR: - do_getxattr(f, in, (struct fuse_getxattr_in *) inarg); + do_getxattr(req, in->nodeid, (struct fuse_getxattr_in *) inarg); break; case FUSE_LISTXATTR: - do_listxattr(f, in, (struct fuse_getxattr_in *) inarg); + do_listxattr(req, in->nodeid, (struct fuse_getxattr_in *) inarg); break; case FUSE_REMOVEXATTR: - do_removexattr(f, in, (char *) inarg); - break; - - case FUSE_INIT: - do_init(f, in, (struct fuse_init_in_out *) inarg); + do_removexattr(req, in->nodeid, (char *) inarg); break; case FUSE_OPENDIR: - do_opendir(f, in, (struct fuse_open_in *) inarg); + do_opendir(req, in->nodeid, (struct fuse_open_in *) inarg); break; case FUSE_READDIR: - do_readdir(f, in, (struct fuse_read_in *) inarg); + do_readdir(req, in->nodeid, (struct fuse_read_in *) inarg); break; case FUSE_RELEASEDIR: - do_releasedir(f, in, (struct fuse_release_in *) inarg); + do_releasedir(req, in->nodeid, (struct fuse_release_in *) inarg); break; case FUSE_FSYNCDIR: - do_fsyncdir(f, in, (struct fuse_fsync_in *) inarg); + do_fsyncdir(req, in->nodeid, (struct fuse_fsync_in *) inarg); break; default: - send_reply(f, in, -ENOSYS, NULL, 0); + fuse_reply_err(req, ENOSYS); } out: free_cmd(cmd); } -int fuse_exited(struct fuse_ll* f) +int fuse_ll_exited(struct fuse_ll* f) { return f->exited; } -struct fuse_cmd *fuse_read_cmd(struct fuse_ll *f) +struct fuse_cmd *fuse_ll_read_cmd(struct fuse_ll *f) { ssize_t res; struct fuse_cmd *cmd; @@ -716,12 +854,12 @@ struct fuse_cmd *fuse_read_cmd(struct fuse_ll *f) return NULL; } in = (struct fuse_in_header *) cmd->buf; - inarg = cmd->buf + SIZEOF_COMPAT(f, fuse_in_header); + inarg = cmd->buf + sizeof(struct fuse_in_header); res = read(f->fd, cmd->buf, FUSE_MAX_IN); if (res == -1) { free_cmd(cmd); - if (fuse_exited(f) || errno == EINTR || errno == ENOENT) + if (fuse_ll_exited(f) || errno == EINTR || errno == ENOENT) return NULL; /* ENODEV means we got unmounted, so we silenty return failure */ @@ -730,14 +868,14 @@ struct fuse_cmd *fuse_read_cmd(struct fuse_ll *f) perror("fuse: reading device"); } - fuse_exit(f); + f->exited = 1; return NULL; } - if ((size_t) res < SIZEOF_COMPAT(f, fuse_in_header)) { + if ((size_t) res < sizeof(struct fuse_in_header)) { free_cmd(cmd); /* Cannot happen */ fprintf(stderr, "short read on fuse device\n"); - fuse_exit(f); + f->exited = 1; return NULL; } cmd->buflen = res; @@ -746,7 +884,7 @@ struct fuse_cmd *fuse_read_cmd(struct fuse_ll *f) return cmd; } -int fuse_loop(struct fuse_ll *f) +int fuse_ll_loop(struct fuse_ll *f) { if (f == NULL) return -1; @@ -754,69 +892,29 @@ int fuse_loop(struct fuse_ll *f) while (1) { struct fuse_cmd *cmd; - if (fuse_exited(f)) + if (fuse_ll_exited(f)) break; - cmd = fuse_read_cmd(f); + cmd = fuse_ll_read_cmd(f); if (cmd == NULL) continue; - fuse_process_cmd(f, cmd); + fuse_ll_process_cmd(f, cmd); } f->exited = 0; return 0; } -int fuse_invalidate(struct fuse_ll *f, const char *path) -{ - (void) f; - (void) path; - return -EINVAL; -} - -void fuse_exit(struct fuse_ll *f) -{ - f->exited = 1; -} - -struct fuse_context *fuse_get_context() -{ - static struct fuse_context context; - if (fuse_getcontext) - return fuse_getcontext(); - else - return &context; -} - -void fuse_set_getcontext_func(struct fuse_context *(*func)(void)) -{ - fuse_getcontext = func; -} - -static int begins_with(const char *s, const char *beg) -{ - if (strncmp(s, beg, strlen(beg)) == 0) - return 1; - else - return 0; -} - -int fuse_is_lib_option(const char *opt) +int fuse_ll_is_lib_option(const char *opt) { if (strcmp(opt, "debug") == 0 || - strcmp(opt, "hard_remove") == 0 || - strcmp(opt, "use_ino") == 0 || - strcmp(opt, "allow_root") == 0 || - strcmp(opt, "readdir_ino") == 0 || - begins_with(opt, "umask=") || - begins_with(opt, "uid=") || - begins_with(opt, "gid=")) + strcmp(opt, "allow_root") == 0) return 1; else return 0; } -static int parse_lib_opts(struct fuse_ll *f, const char *opts) +static int parse_ll_opts(struct fuse_ll *f, const char *opts) { if (opts) { char *xopts = strdup(opts); @@ -830,21 +928,9 @@ static int parse_lib_opts(struct fuse_ll *f, const char *opts) while((opt = strsep(&s, ","))) { if (strcmp(opt, "debug") == 0) - f->flags |= FUSE_DEBUG; - else if (strcmp(opt, "hard_remove") == 0) - f->flags |= FUSE_HARD_REMOVE; - else if (strcmp(opt, "use_ino") == 0) - f->flags |= FUSE_USE_INO; + f->debug = 1; else if (strcmp(opt, "allow_root") == 0) - f->flags |= FUSE_ALLOW_ROOT; - else if (strcmp(opt, "readdir_ino") == 0) - f->flags |= FUSE_READDIR_INO; - else if (sscanf(opt, "umask=%o", &f->umask) == 1) - f->flags |= FUSE_SET_MODE; - else if (sscanf(opt, "uid=%u", &f->uid) == 1) - f->flags |= FUSE_SET_UID; - else if(sscanf(opt, "gid=%u", &f->gid) == 1) - f->flags |= FUSE_SET_GID; + f->allow_root = 1; else fprintf(stderr, "fuse: warning: unknown option `%s'\n", opt); } @@ -853,15 +939,15 @@ static int parse_lib_opts(struct fuse_ll *f, const char *opts) return 0; } -struct fuse_ll *fuse_lowlevel_new(int fd, const char *opts, - const struct fuse_lowlevel_operations *op, - size_t op_size) +struct fuse_ll *fuse_ll_new(int fd, const char *opts, + const struct fuse_ll_operations *op, + size_t op_size) { struct fuse_ll *f; - if (sizeof(struct fuse_lowlevel_operations) < op_size) { + if (sizeof(struct fuse_ll_operations) < op_size) { fprintf(stderr, "fuse: warning: library too old, some operations may not not work\n"); - op_size = sizeof(struct fuse_lowlevel_operations); + op_size = sizeof(struct fuse_ll_operations); } f = (struct fuse_ll *) calloc(1, sizeof(struct fuse_ll)); @@ -870,7 +956,7 @@ struct fuse_ll *fuse_lowlevel_new(int fd, const char *opts, goto out; } - if (parse_lib_opts(f, opts) == -1) + if (parse_ll_opts(f, opts) == -1) goto out_free; f->fd = fd; @@ -886,4 +972,8 @@ struct fuse_ll *fuse_lowlevel_new(int fd, const char *opts, return NULL; } +void fuse_ll_destroy(struct fuse_ll *f) +{ + free(f); +} |