* Low level API *
* ----------------------------------------------------------- */
-#include <fuse_common.h>
+#include "fuse_common.h"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/statfs.h>
+#include <utime.h>
#ifdef __cplusplus
extern "C" {
struct fuse_entry_param {
fuse_ino_t ino;
unsigned long generation;
- const struct stat *attr;
+ struct stat attr;
double attr_timeout;
double entry_timeout;
- unsigned int direct_io : 1;
};
/* 'to_set' flags in setattr */
#define FUSE_SET_ATTR_MTIME (1 << 5)
#define FUSE_SET_ATTR_CTIME (1 << 6)
-struct fuse_lowlevel_operations {
+/* ------------------------------------------ */
+
+struct fuse_ll_operations {
+ void* (*init) (void);
+ void (*destroy) (void *);
+
void (*lookup) (fuse_req_t req, fuse_ino_t parent, const char *name);
- void (*forget) (fuse_req_t req, fuse_ino_t ino);
+ void (*forget) (fuse_req_t req, fuse_ino_t ino, unsigned long nlookup);
void (*getattr) (fuse_req_t req, fuse_ino_t ino);
void (*setattr) (fuse_req_t req, fuse_ino_t ino, struct stat *attr,
int to_set);
fuse_ino_t newparent, const char *newname);
void (*link) (fuse_req_t req, fuse_ino_t ino, fuse_ino_t newparent,
const char *newname);
- void (*open) (fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *f);
+ void (*open) (fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi);
void (*read) (fuse_req_t req, fuse_ino_t ino, size_t size, off_t off,
- struct fuse_file_info *f);
+ struct fuse_file_info *fi);
void (*write) (fuse_req_t req, fuse_ino_t ino, const char *buf,
- size_t size, off_t off, struct fuse_file_info *f);
- void (*flush) (fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *f);
- void (*release) (fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *f);
+ size_t size, off_t off, struct fuse_file_info *fi);
+ void (*flush) (fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi);
+ void (*release) (fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi);
void (*fsync) (fuse_req_t req, fuse_ino_t ino, int datasync,
- struct fuse_file_info *f);
- void (*opendir) (fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *f);
+ struct fuse_file_info *fi);
+ void (*opendir) (fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi);
void (*readdir) (fuse_req_t req, fuse_ino_t ino, size_t size, off_t off,
- struct fuse_file_info *f);
+ struct fuse_file_info *fi);
void (*releasedir) (fuse_req_t req, fuse_ino_t ino,
- struct fuse_file_info *f);
+ struct fuse_file_info *fi);
void (*fsyncdir) (fuse_req_t req, fuse_ino_t ino, int datasync,
- struct fuse_file_info *f);
+ struct fuse_file_info *fi);
void (*statfs) (fuse_req_t req, fuse_ino_t ino);
void (*setxattr)(fuse_req_t req, fuse_ino_t ino, const char *name,
const char *value, size_t size, int flags);
void (*removexattr)(fuse_req_t req, fuse_ino_t ino, const char *name);
};
-/* all except release and forget */
+/* ------------------------------------------ */
+
+/* all except forget */
int fuse_reply_err(fuse_req_t req, int err);
-/* forget, unlink, rmdir, rename, setxattr, removexattr, release, releasedir */
-int fuse_reply_ok(fuse_req_t req);
+/* forget */
+int fuse_reply_none(fuse_req_t req);
/* lookup, mknod, mkdir, symlink, link */
-int fuse_reply_entry(fuse_req_t req, struct fuse_entry_param *e);
+int fuse_reply_entry(fuse_req_t req, const struct fuse_entry_param *e);
/* getattr, setattr */
-int fuse_reply_attr(fuse_req_t req, int struct stat *attr, double attr_timeout);
+int fuse_reply_attr(fuse_req_t req, const struct stat *attr,
+ double attr_timeout);
+
/* readlink */
int fuse_reply_readlink(fuse_req_t req, const char *link);
-/* open, flush, fsync, opendir, fsyncdir */
-int fuse_reply_file_info(fuse_req_t req, const struct fuse_file_info *f);
+/* open, opendir */
+int fuse_reply_open(fuse_req_t req, const struct fuse_file_info *fi);
/* write */
-int fuse_reply_write(fuse_req_t req, size_t count,
- const struct fuse_file_info *f);
+int fuse_reply_write(fuse_req_t req, size_t count);
-/* read, readdir */
-int fuse_reply_buf(fuse_req_t req, const char *buf, size_t size,
- const struct fuse_file_info *f);
+/* read, readdir, getxattr, listxattr */
+int fuse_reply_buf(fuse_req_t req, const char *buf, size_t size);
/* statfs */
int fuse_reply_statfs(fuse_req_t req, const struct statfs *statfs);
/* getxattr, listxattr */
-int fuse_reply_xattr(fuse_req_t req, const char *buf, size_t size);
+int fuse_reply_xattr(fuse_req_t req, size_t count);
+
+/* ------------------------------------------ */
/* return the size of a directory entry */
size_t fuse_dirent_size(size_t namelen);
/* add a directory entry to the buffer */
-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);
+
+/* ------------------------------------------ */
+
+struct fuse_ll *fuse_ll_new(int fd, const char *opts,
+ const struct fuse_ll_operations *op,
+ size_t op_size);
+
+void fuse_ll_destroy(struct fuse_ll *f);
+
+int fuse_ll_is_lib_option(const char *opt);
+
+int fuse_ll_loop(struct fuse_ll *f);
+
+int fuse_ll_exited(struct fuse_ll* f);
+
+struct fuse_cmd *fuse_ll_read_cmd(struct fuse_ll *f);
+
+void fuse_ll_process_cmd(struct fuse_ll *f, struct fuse_cmd *cmd);
+
+/* ------------------------------------------ */
#ifdef __cplusplus
}
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>
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;
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) {
}
}
-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;
#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;
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 */
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];
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);
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;
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;
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)
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)
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);
}
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);
}
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);
}
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,
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,
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,
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);
}
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);
}
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);
}
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)
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;
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 */
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;
return cmd;
}
-int fuse_loop(struct fuse_ll *f)
+int fuse_ll_loop(struct fuse_ll *f)
{
if (f == NULL)
return -1;
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);
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);
}
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));
goto out;
}
- if (parse_lib_opts(f, opts) == -1)
+ if (parse_ll_opts(f, opts) == -1)
goto out_free;
f->fd = fd;
return NULL;
}
+void fuse_ll_destroy(struct fuse_ll *f)
+{
+ free(f);
+}