summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCsaba Henk <csaba@gluster.com>2009-07-13 22:28:07 +0200
committerCsaba Henk <csaba@gluster.com>2009-08-12 06:21:04 -0700
commitd5910898f1602dc16ab158b06c37abcd98a0588a (patch)
tree8ea867f1f530554e81f9b1d604a6925f55d93540
parent57a6cb9806ad9d99e6866a21d16fcb1bafef000c (diff)
basic version of direct FUSE interface (ie. not relying on libfuse)
-rw-r--r--configure.ac41
-rw-r--r--xlators/mount/fuse/src/Makefile.am6
-rw-r--r--xlators/mount/fuse/src/fuse-bridge.c1708
-rw-r--r--xlators/mount/fuse/src/fuse-extra.c155
-rw-r--r--xlators/mount/fuse/src/fuse-extra.h42
-rw-r--r--xlators/mount/fuse/src/fuse_kernel.h509
6 files changed, 1472 insertions, 989 deletions
diff --git a/configure.ac b/configure.ac
index 71f663fa710..0347eb075c6 100644
--- a/configure.ac
+++ b/configure.ac
@@ -206,47 +206,8 @@ AC_ARG_ENABLE([fuse-client],
AC_HELP_STRING([--disable-fuse-client],
[Do not build the fuse client. NOTE: you cannot mount glusterfs without the client]))
-if test "x$enable_fuse_client" != "xno"; then
- AC_CHECK_LIB([fuse],
- [fuse_req_interrupt_func],
- [HAVE_LIBFUSE="yes"],
- [HAVE_LIBFUSE="no"])
-
- if test "x$HAVE_LIBFUSE" = "xyes"; then
- AC_TRY_COMPILE([#define FUSE_USE_VERSION 26
- #define _FILE_OFFSET_BITS 64
- #include <fuse.h>],
- #define _GLFS_FUSE_VERSION_28 28
- #if (FUSE_VERSION < _GLFS_FUSE_VERSION_28)
- #error "fuse version 2.8 not found"
- #endif
- ,
- [HAVE_FUSE_VERSION_28="yes"],
- [HAVE_FUSE_VERSION_28="no"])
-
- AC_CHECK_LIB([fuse],
- [fuse_reply_iov],
- [HAVE_FUSE_REPLY_IOV="yes"],
- [HAVE_FUSE_REPLY_IOV="no"])
-
- fi
-fi
-
-if test "x$HAVE_FUSE_REPLY_IOV" = "xyes"; then
- AC_DEFINE(HAVE_FUSE_REPLY_IOV, 1, [found fuse_reply_iov])
-fi
-
-if test "x$HAVE_LIBFUSE" = "xyes" -a "x$HAVE_FUSE_VERSION_28" = "xyes"; then
- AC_DEFINE(HAVE_FUSE_VERSION_28, 1, [found fuse 2.8 version])
-fi
-
-if test "x$enable_fuse_client" = "xyes" -a "x$HAVE_LIBFUSE" = "xno"; then
- echo "FUSE requested but not found."
- exit 1
-fi
-
BUILD_FUSE_CLIENT=no
-if test "x$enable_fuse_client" != "xno" -a "x$HAVE_LIBFUSE" = "xyes"; then
+if test "x$enable_fuse_client" != "xno"; then
FUSE_CLIENT_SUBDIR=fuse
BUILD_FUSE_CLIENT="yes"
fi
diff --git a/xlators/mount/fuse/src/Makefile.am b/xlators/mount/fuse/src/Makefile.am
index 9d8d45e4f02..cc4fe9de683 100644
--- a/xlators/mount/fuse/src/Makefile.am
+++ b/xlators/mount/fuse/src/Makefile.am
@@ -1,10 +1,10 @@
-noinst_HEADERS = fuse-extra.h
+noinst_HEADERS = fuse_kernel.h
xlator_LTLIBRARIES = fuse.la
xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/mount
-fuse_la_SOURCES = fuse-bridge.c fuse-extra.c
-fuse_la_LDFLAGS = -module -avoidversion -shared -nostartfiles $(GF_FUSE_LDADD)
+fuse_la_SOURCES = fuse-bridge.c
+fuse_la_LDFLAGS = -module -avoidversion -shared -nostartfiles
AM_CFLAGS = -fPIC -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE -D$(GF_HOST_OS) -Wall \
-I$(top_srcdir)/libglusterfs/src $(GF_CFLAGS) -DFUSE_USE_VERSION=26
diff --git a/xlators/mount/fuse/src/fuse-bridge.c b/xlators/mount/fuse/src/fuse-bridge.c
index efc8ea54d1b..2700d6ed05d 100644
--- a/xlators/mount/fuse/src/fuse-bridge.c
+++ b/xlators/mount/fuse/src/fuse-bridge.c
@@ -28,6 +28,9 @@
#include <stdint.h>
#include <signal.h>
#include <pthread.h>
+#include <stddef.h>
+#include <dirent.h>
+#include <sys/mount.h>
#ifndef _CONFIG_H
#define _CONFIG_H
@@ -41,9 +44,8 @@
#include "defaults.h"
#include "common-utils.h"
-#include <fuse/fuse_lowlevel.h>
+#include "fuse_kernel.h"
-#include "fuse-extra.h"
#include "list.h"
#include "dict.h"
@@ -57,11 +59,16 @@
#define ZR_DIRECT_IO_OPT "direct-io-mode"
#define ZR_STRICT_VOLFILE_CHECK "strict-volfile-check"
+#define FUSE_711_OP_HIGH (FUSE_POLL + 1)
+#define OFFSET_MAX 0x7fffffffffffffffLL
+#define GLUSTERFS_XATTR_LEN_MAX 65536
+
+typedef struct fuse_in_header fuse_in_header_t;
+typedef void (fuse_handler_t) (xlator_t *this, fuse_in_header_t *finh,
+ void *msg);
+
struct fuse_private {
int fd;
- struct fuse *fuse;
- struct fuse_session *se;
- struct fuse_chan *ch;
char *volfile;
size_t volfile_size;
char *mount_point;
@@ -78,16 +85,16 @@ struct fuse_private {
};
typedef struct fuse_private fuse_private_t;
-#define _FI_TO_FD(fi) ((fd_t *)((long)fi->fh))
+#define _FH_TO_FD(fh) ((fd_t *)(uintptr_t)(fh))
-#define FI_TO_FD(fi) ((_FI_TO_FD (fi))?(fd_ref (_FI_TO_FD(fi))):((fd_t *) 0))
+#define FH_TO_FD(fh) ((_FH_TO_FD (fh))?(fd_ref (_FH_TO_FD (fh))):((fd_t *) 0))
#define FUSE_FOP(state, ret, op_num, fop, args ...) \
do { \
call_frame_t *frame = NULL; \
xlator_t *xl = NULL; \
\
- frame = get_call_frame_for_req (state, 1); \
+ frame = get_call_frame_for_req (state); \
if (!frame) { \
/* This is not completely clean, as some \
* earlier allocations might remain unfreed \
@@ -97,9 +104,11 @@ typedef struct fuse_private fuse_private_t;
*/ \
gf_log ("glusterfs-fuse", \
GF_LOG_ERROR, \
- "FUSE message unique %"PRIu64":" \
+ "FUSE message" \
+ " unique %"PRIu64" opcode %d:" \
" frame allocation failed", \
- req_callid (state->req)); \
+ state->finh->unique, \
+ state->finh->opcode); \
free_state (state); \
return; \
} \
@@ -114,20 +123,21 @@ typedef struct fuse_private fuse_private_t;
(((_errno == ENOENT) || (_errno == ESTALE))? \
GF_LOG_DEBUG)
-#define STATE_FROM_REQ(req, state) \
- do { \
- state = state_from_req (req); \
- if (!state) { \
- gf_log ("glusterfs-fuse", \
- GF_LOG_ERROR, \
- "FUSE message unique %"PRIu64":" \
- " state allocation failed", \
- req_callid (req)); \
- \
- fuse_reply_err (req, ENOMEM); \
- \
- return; \
- } \
+#define GET_STATE(this, finh, state) \
+ do { \
+ state = get_state (this, finh); \
+ if (!state) { \
+ gf_log ("glusterfs-fuse", \
+ GF_LOG_ERROR, \
+ "FUSE message unique %"PRIu64" opcode %d:" \
+ " state allocation failed", \
+ finh->unique, finh->opcode); \
+ \
+ send_fuse_err (this, finh, ENOMEM); \
+ FREE (finh); \
+ \
+ return; \
+ } \
} while (0)
@@ -137,7 +147,7 @@ typedef struct {
inode_table_t *itable;
loc_t loc;
loc_t loc2;
- fuse_req_t req;
+ fuse_in_header_t *finh;
int32_t flags;
off_t off;
size_t size;
@@ -148,8 +158,6 @@ typedef struct {
char is_revalidate;
} fuse_state_t;
-int fuse_chan_receive (struct fuse_chan *ch, char *buf, int32_t size);
-
static void
free_state (fuse_state_t *state)
@@ -170,6 +178,10 @@ free_state (fuse_state_t *state)
fd_unref (state->fd);
state->fd = (void *)0xfdfdfdfd;
}
+ if (state->finh) {
+ FREE (state->finh);
+ state->finh = NULL;
+ }
#ifdef DEBUG
memset (state, 0x90, sizeof (*state));
#endif
@@ -179,66 +191,45 @@ free_state (fuse_state_t *state)
fuse_state_t *
-state_from_req (fuse_req_t req)
+get_state (xlator_t *this, fuse_in_header_t *finh)
{
fuse_state_t *state = NULL;
- xlator_t *this = NULL;
-
- this = fuse_req_userdata (req);
state = (void *)calloc (1, sizeof (*state));
if (!state)
return NULL;
state->pool = this->ctx->pool;
state->itable = this->itable;
- state->req = req;
+ state->finh = finh;
state->this = this;
return state;
}
-static pid_t
-get_pid_from_req (fuse_req_t req)
-{
- const struct fuse_ctx *ctx = NULL;
-
- ctx = fuse_req_ctx (req);
- return ctx->pid;
-}
-
-
static call_frame_t *
-get_call_frame_for_req (fuse_state_t *state, char d)
+get_call_frame_for_req (fuse_state_t *state)
{
call_pool_t *pool = NULL;
- fuse_req_t req = NULL;
- const struct fuse_ctx *ctx = NULL;
+ fuse_in_header_t *finh = NULL;
call_frame_t *frame = NULL;
xlator_t *this = NULL;
fuse_private_t *priv = NULL;
pool = state->pool;
- req = state->req;
-
- if (req) {
- this = fuse_req_userdata (req);
- } else {
- this = state->this;
- }
+ finh = state->finh;
+ this = state->this;
priv = this->private;
frame = create_frame (this, pool);
if (!frame)
return NULL;
- if (req) {
- ctx = fuse_req_ctx (req);
-
- frame->root->uid = ctx->uid;
- frame->root->gid = ctx->gid;
- frame->root->pid = ctx->pid;
- frame->root->unique = req_callid (req);
+ if (finh) {
+ frame->root->uid = finh->uid;
+ frame->root->gid = finh->gid;
+ frame->root->pid = finh->pid;
+ frame->root->unique = finh->unique;
}
frame->root->type = GF_OP_TYPE_FOP_REQUEST;
@@ -247,6 +238,66 @@ get_call_frame_for_req (fuse_state_t *state, char d)
}
+/*
+ * iov_out should contain a fuse_out_header at zeroth position.
+ * The error value of this header is sent to kernel.
+ */
+static int
+send_fuse_iov (xlator_t *this, fuse_in_header_t *finh, struct iovec *iov_out,
+ int count)
+{
+ fuse_private_t *priv = NULL;
+ struct fuse_out_header *fouh = NULL;
+ int res, i;
+
+ priv = this->private;
+
+ fouh = iov_out[0].iov_base;
+ iov_out[0].iov_len = sizeof (*fouh);
+ fouh->len = 0;
+ for (i = 0; i < count; i++)
+ fouh->len += iov_out[i].iov_len;
+ fouh->unique = finh->unique;
+
+ res = writev (priv->fd, iov_out, count);
+
+ if (res == -1)
+ return errno;
+ if (res != fouh->len)
+ return EINVAL;
+ return 0;
+}
+
+static int
+send_fuse_data (xlator_t *this, fuse_in_header_t *finh, void *data, size_t size)
+{
+ struct fuse_out_header fouh = {0, };
+ struct iovec iov_out[2];
+
+ fouh.error = 0;
+ iov_out[0].iov_base = &fouh;
+ iov_out[1].iov_base = data;
+ iov_out[1].iov_len = size;
+
+ return send_fuse_iov (this, finh, iov_out, 2);
+}
+
+#define send_fuse_obj(this, finh, obj) \
+ send_fuse_data (this, finh, obj, sizeof (*(obj)))
+
+static int
+send_fuse_err (xlator_t *this, fuse_in_header_t *finh, int error)
+{
+ struct fuse_out_header fouh = {0, };
+ struct iovec iov_out;
+
+ fouh.error = -error;
+ iov_out.iov_base = &fouh;
+
+ return send_fuse_iov (this, finh, &iov_out, 1);
+}
+
+
GF_MUST_CHECK static int32_t
fuse_loc_fill (loc_t *loc, fuse_state_t *state, ino_t ino,
ino_t par, const char *name)
@@ -351,6 +402,51 @@ need_fresh_lookup (int32_t op_ret, int32_t op_errno,
return 0;
}
+/* courtesy of folly/fuse */
+static void
+stat2attr (struct stat *st, struct fuse_attr *fa)
+{
+ fa->ino = st->st_ino;
+ fa->size = st->st_size;
+ fa->blocks = st->st_blocks;
+ fa->atime = st->st_atime;
+ fa->mtime = st->st_mtime;
+ fa->ctime = st->st_ctime;
+ fa->atimensec = ST_ATIM_NSEC (st);
+ fa->mtimensec = ST_MTIM_NSEC (st);
+ fa->ctimensec = ST_CTIM_NSEC (st);
+ fa->mode = st->st_mode;
+ fa->nlink = st->st_nlink;
+ fa->uid = st->st_uid;
+ fa->gid = st->st_gid;
+ fa->rdev = st->st_rdev;
+ fa->blksize = st->st_blksize;
+}
+
+/* courtesy of fuse */
+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;
+}
+
+/* courtesy of fuse */
+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);
+}
static int
fuse_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
@@ -363,13 +459,14 @@ fuse_entry_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
inode_t *inode, struct stat *buf)
{
fuse_state_t *state = NULL;
- fuse_req_t req = NULL;
- struct fuse_entry_param e = {0, };
+ fuse_in_header_t *finh = NULL;
+ struct fuse_entry_out feo = {0, };
+ struct fuse_attr_out *fao = NULL;
fuse_private_t *priv = NULL;
priv = this->private;
state = frame->root->state;
- req = state->req;
+ finh = state->finh;
if (!op_ret && state->loc.ino == 1) {
buf->st_ino = 1;
@@ -391,7 +488,7 @@ fuse_entry_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
if (op_ret == 0) {
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRId64": %s() %s => %"PRId64" (%"PRId64")",
+ "%"PRIu64": %s() %s => %"PRId64" (%"PRId64")",
frame->root->unique, gf_fop_list[frame->root->op],
state->loc.path, buf->st_ino, state->loc.ino);
@@ -399,38 +496,56 @@ fuse_entry_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
inode_lookup (inode);
- /* TODO: make these timeouts configurable (via meta?) */
- e.ino = inode->ino;
-
-#ifdef GF_DARWIN_HOST_OS
- e.generation = 0;
-#else
- e.generation = buf->st_ctime;
-#endif
-
buf->st_blksize = this->ctx->page_size;
- e.entry_timeout = priv->entry_timeout;
- e.attr_timeout = priv->attribute_timeout;
- e.attr = *buf;
+ stat2attr (buf, &feo.attr);
- if (!e.ino || !buf->st_ino) {
+ if (!inode->ino || !buf->st_ino) {
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
- "%"PRId64": %s() %s returning inode 0",
+ "%"PRIu64": %s() %s returning inode 0",
frame->root->unique,
gf_fop_list[frame->root->op], state->loc.path);
}
- if (state->loc.parent)
- fuse_reply_entry (req, &e);
- else
- fuse_reply_attr (req, buf, priv->attribute_timeout);
+ if (state->loc.parent) {
+ /* TODO: make these timeouts configurable (via meta?) */
+ feo.nodeid = inode->ino;
+
+#ifdef GF_DARWIN_HOST_OS
+ feo.generation = 0;
+#else
+ feo.generation = buf->st_ctime;
+#endif
+
+ feo.entry_valid =
+ calc_timeout_sec (priv->entry_timeout);
+ feo.entry_valid_nsec =
+ calc_timeout_nsec (priv->entry_timeout);
+ feo.attr_valid =
+ calc_timeout_sec (priv->attribute_timeout);
+ feo.attr_valid_nsec =
+ calc_timeout_nsec (priv->attribute_timeout);
+
+ send_fuse_obj (this, finh, &feo);
+ } else {
+ /* Refurbish the entry_out as attr_out. Too hacky?... */
+ fao = (struct fuse_attr_out *)
+ ((char *)&feo.attr -
+ offsetof (struct fuse_attr_out, attr));
+
+ fao->attr_valid =
+ calc_timeout_sec (priv->attribute_timeout);
+ fao->attr_valid_nsec =
+ calc_timeout_nsec (priv->attribute_timeout);
+
+ send_fuse_obj (this, finh, fao);
+ }
} else {
gf_log ("glusterfs-fuse",
(op_errno == ENOENT ? GF_LOG_TRACE : GF_LOG_WARNING),
- "%"PRId64": %s() %s => -1 (%s)", frame->root->unique,
+ "%"PRIu64": %s() %s => -1 (%s)", frame->root->unique,
gf_fop_list[frame->root->op], state->loc.path,
strerror (op_errno));
- fuse_reply_err (req, op_errno);
+ send_fuse_err (this, state->finh, op_errno);
}
free_state (state);
@@ -450,27 +565,29 @@ fuse_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
static void
-fuse_lookup (fuse_req_t req, fuse_ino_t par, const char *name)
+fuse_lookup (xlator_t *this, fuse_in_header_t *finh, void *msg)
{
+ char *name = msg;
+
fuse_state_t *state = NULL;
int32_t ret = -1;
- STATE_FROM_REQ (req, state);
+ GET_STATE (this, finh, state);
- ret = fuse_loc_fill (&state->loc, state, 0, par, name);
+ ret = fuse_loc_fill (&state->loc, state, 0, finh->nodeid, name);
if (ret < 0) {
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
- "%"PRIu64": LOOKUP %"PRId64"/%s (fuse_loc_fill() failed)",
- req_callid (req), (ino_t)par, name);
+ "%"PRIu64": LOOKUP %"PRIu64"/%s (fuse_loc_fill() failed)",
+ finh->unique, finh->nodeid, name);
free_state (state);
- fuse_reply_err (req, ENOENT);
+ send_fuse_err (this, finh, ENOENT);
return;
}
if (!state->loc.inode) {
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRIu64": LOOKUP %s", req_callid (req),
+ "%"PRIu64": LOOKUP %s", finh->unique,
state->loc.path);
state->loc.inode = inode_new (state->itable);
@@ -478,7 +595,7 @@ fuse_lookup (fuse_req_t req, fuse_ino_t par, const char *name)
state->is_revalidate = -1;
} else {
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRIu64": LOOKUP %s(%"PRId64")", req_callid (req),
+ "%"PRIu64": LOOKUP %s(%"PRId64")", finh->unique,
state->loc.path, state->loc.inode->ino);
state->is_revalidate = 1;
}
@@ -491,30 +608,30 @@ fuse_lookup (fuse_req_t req, fuse_ino_t par, const char *name)
static void
-fuse_forget (fuse_req_t req, fuse_ino_t ino, unsigned long nlookup)
+fuse_forget (xlator_t *this, fuse_in_header_t *finh, void *msg)
+
{
- inode_t *fuse_inode;
- xlator_t *this = NULL;
+ struct fuse_forget_in *ffi = msg;
- this = fuse_req_userdata (req);
+ inode_t *fuse_inode;
- if (ino == 1) {
- fuse_reply_none (req);
+ if (finh->nodeid == 1) {
+ FREE (finh);
return;
}
- fuse_inode = inode_search (this->itable, ino, NULL);
+ fuse_inode = inode_search (this->itable, finh->nodeid, NULL);
if (fuse_inode) {
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "got forget on inode (%lu)", ino);
- inode_forget (fuse_inode, nlookup);
+ "got forget on inode (%"PRIu64")", finh->nodeid);
+ inode_forget (fuse_inode, ffi->nlookup);
inode_unref (fuse_inode);
} else {
gf_log ("glusterfs-fuse", GF_LOG_DEBUG,
- "got forget, but inode (%lu) not found", ino);
+ "got forget, but inode (%"PRIu64") not found", finh->nodeid);
}
- fuse_reply_none (req);
+ FREE (finh);
}
@@ -522,17 +639,18 @@ static int
fuse_attr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct stat *buf)
{
- fuse_state_t *state;
- fuse_req_t req;
- fuse_private_t *priv = NULL;
+ fuse_state_t *state;
+ fuse_in_header_t *finh;
+ fuse_private_t *priv = NULL;
+ struct fuse_attr_out fao;
priv = this->private;
state = frame->root->state;
- req = state->req;
+ finh = state->finh;
if (op_ret == 0) {
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRId64": %s() %s => %"PRId64, frame->root->unique,
+ "%"PRIu64": %s() %s => %"PRId64, frame->root->unique,
gf_fop_list[frame->root->op],
state->loc.path ? state->loc.path : "ERR",
buf->st_ino);
@@ -540,16 +658,21 @@ fuse_attr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
/* TODO: make these timeouts configurable via meta */
/* TODO: what if the inode number has changed by now */
buf->st_blksize = this->ctx->page_size;
+ stat2attr (buf, &fao.attr);
+
+ fao.attr_valid = calc_timeout_sec (priv->attribute_timeout);
+ fao.attr_valid_nsec =
+ calc_timeout_nsec (priv->attribute_timeout);
- fuse_reply_attr (req, buf, priv->attribute_timeout);
+ send_fuse_obj (this, finh, &fao);
} else {
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
- "%"PRId64": %s() %s => -1 (%s)", frame->root->unique,
+ "%"PRIu64": %s() %s => -1 (%s)", frame->root->unique,
gf_fop_list[frame->root->op],
state->loc.path ? state->loc.path : "ERR",
strerror (op_errno));
- fuse_reply_err (req, op_errno);
+ send_fuse_err (this, finh, op_errno);
}
free_state (state);
@@ -559,21 +682,21 @@ fuse_attr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
static void
-fuse_getattr (fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi)
+fuse_getattr (xlator_t *this, fuse_in_header_t *finh, void *msg)
{
fuse_state_t *state;
fd_t *fd = NULL;
int32_t ret = -1;
- STATE_FROM_REQ (req, state);
+ GET_STATE (this, finh, state);
- if (ino == 1) {
- ret = fuse_loc_fill (&state->loc, state, ino, 0, NULL);
+ if (finh->nodeid == 1) {
+ ret = fuse_loc_fill (&state->loc, state, finh->nodeid, 0, NULL);
if (ret < 0) {
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
- "%"PRIu64": GETATTR %"PRId64" (fuse_loc_fill() failed)",
- req_callid (req), (ino_t)ino);
- fuse_reply_err (req, ENOENT);
+ "%"PRIu64": GETATTR %"PRIu64" (fuse_loc_fill() failed)",
+ finh->unique, finh->nodeid);
+ send_fuse_err (this, finh, ENOENT);
free_state (state);
return;
}
@@ -590,17 +713,17 @@ fuse_getattr (fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi)
return;
}
- ret = fuse_loc_fill (&state->loc, state, ino, 0, NULL);
+ ret = fuse_loc_fill (&state->loc, state, finh->nodeid, 0, NULL);
if (!state->loc.inode) {
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
- "%"PRIu64": GETATTR %"PRId64" (%s) (fuse_loc_fill() returned NULL inode)",
- req_callid (req), (int64_t)ino, state->loc.path);
- fuse_reply_err (req, ENOENT);
+ "%"PRIu64": GETATTR %"PRIu64" (%s) (fuse_loc_fill() returned NULL inode)",
+ finh->unique, finh->nodeid, state->loc.path);
+ send_fuse_err (this, finh, ENOENT);
return;
}
- fd = fd_lookup (state->loc.inode, get_pid_from_req (req));
+ fd = fd_lookup (state->loc.inode, finh->pid);
state->fd = fd;
if (!fd || S_ISDIR (state->loc.inode->st_mode)) {
/* this is the @ret of fuse_loc_fill, checked here
@@ -608,16 +731,16 @@ fuse_getattr (fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi)
*/
if (ret < 0) {
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
- "%"PRIu64": GETATTR %"PRId64" (fuse_loc_fill() failed)",
- req_callid (req), (ino_t)ino);
- fuse_reply_err (req, ENOENT);
+ "%"PRIu64": GETATTR %"PRIu64" (fuse_loc_fill() failed)",
+ finh->unique, finh->nodeid);
+ send_fuse_err (this, finh, ENOENT);
free_state (state);
return;
}
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRIu64": GETATTR %"PRId64" (%s)",
- req_callid (req), (int64_t)ino, state->loc.path);
+ "%"PRIu64": GETATTR %"PRIu64" (%s)",
+ finh->unique, finh->nodeid, state->loc.path);
FUSE_FOP (state, fuse_attr_cbk, GF_FOP_STAT,
@@ -625,8 +748,8 @@ fuse_getattr (fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi)
} else {
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRIu64": FGETATTR %"PRId64" (%s/%p)",
- req_callid (req), (int64_t)ino, state->loc.path, fd);
+ "%"PRIu64": FGETATTR %"PRIu64" (%s/%p)",
+ finh->unique, finh->nodeid, state->loc.path, fd);
FUSE_FOP (state,fuse_attr_cbk, GF_FOP_FSTAT,
fstat, fd);
@@ -639,30 +762,30 @@ fuse_fd_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, fd_t *fd)
{
fuse_state_t *state;
- fuse_req_t req;
+ fuse_in_header_t *finh;
fuse_private_t *priv = NULL;
- struct fuse_file_info fi = {0, };
+ struct fuse_open_out foo = {0, };
priv = this->private;
state = frame->root->state;
- req = state->req;
+ finh = state->finh;
if (op_ret >= 0) {
- fi.fh = (unsigned long) fd;
- fi.flags = state->flags;
+ foo.fh = (uintptr_t) fd;
+ foo.open_flags = 0;
if (!S_ISDIR (fd->inode->st_mode)) {
- if (((fi.flags & O_ACCMODE) != O_RDONLY) &&
+ if (((state->flags & O_ACCMODE) != O_RDONLY) &&
priv->direct_io_mode)
- fi.direct_io = 1;
+ foo.open_flags |= FOPEN_DIRECT_IO;
}
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRId64": %s() %s => %p", frame->root->unique,
+ "%"PRIu64": %s() %s => %p", frame->root->unique,
gf_fop_list[frame->root->op], state->loc.path, fd);
fd_ref (fd);
- if (fuse_reply_open (req, &fi) == -ENOENT) {
+ if (send_fuse_obj (this, finh, &foo) == ENOENT) {
gf_log ("glusterfs-fuse", GF_LOG_DEBUG,
"open(%s) got EINTR", state->loc.path);
fd_unref (fd);
@@ -672,11 +795,11 @@ fuse_fd_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
fd_bind (fd);
} else {
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
- "%"PRId64": %s() %s => -1 (%s)", frame->root->unique,
+ "%"PRIu64": %s() %s => -1 (%s)", frame->root->unique,
gf_fop_list[frame->root->op], state->loc.path,
strerror (op_errno));
- fuse_reply_err (req, op_errno);
+ send_fuse_err (this, finh, op_errno);
}
out:
free_state (state);
@@ -686,53 +809,51 @@ out:
static void
-do_chmod (fuse_req_t req, fuse_ino_t ino, struct stat *attr,
- struct fuse_file_info *fi)
+do_chmod (xlator_t *this, fuse_in_header_t *finh, struct fuse_setattr_in *fsi)
{
fuse_state_t *state = NULL;
fd_t *fd = NULL;
int32_t ret = -1;
- STATE_FROM_REQ (req, state);
- if (fi) {
- fd = FI_TO_FD (fi);
+ GET_STATE (this, finh, state);
+ if (fsi->valid & FATTR_FH) {
+ fd = FH_TO_FD (fsi->fh);
state->fd = fd;
}
if (fd) {
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRIu64": FCHMOD %p", req_callid (req), fd);
+ "%"PRIu64": FCHMOD %p", finh->unique, fd);
FUSE_FOP (state, fuse_attr_cbk, GF_FOP_FCHMOD,
- fchmod, fd, attr->st_mode);
+ fchmod, fd, fsi->mode);
} else {
- ret = fuse_loc_fill (&state->loc, state, ino, 0, NULL);
+ ret = fuse_loc_fill (&state->loc, state, finh->nodeid, 0, NULL);
if ((state->loc.inode == NULL) ||
(ret < 0)) {
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
- "%"PRIu64": CHMOD %"PRId64" (%s) (fuse_loc_fill() failed)",
- req_callid (req), (int64_t)ino,
+ "%"PRIu64": CHMOD %"PRIu64" (%s) (fuse_loc_fill() failed)",
+ finh->unique, finh->nodeid,
state->loc.path);
- fuse_reply_err (req, ENOENT);
+ send_fuse_err (this, finh, ENOENT);
free_state (state);
return;
}
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRIu64": CHMOD %s", req_callid (req),
+ "%"PRIu64": CHMOD %s", finh->unique,
state->loc.path);
FUSE_FOP (state, fuse_attr_cbk, GF_FOP_CHMOD,
- chmod, &state->loc, attr->st_mode);
+ chmod, &state->loc, fsi->mode);
}
}
static void
-do_chown (fuse_req_t req, fuse_ino_t ino, struct stat *attr,
- int valid, struct fuse_file_info *fi)
+do_chown (xlator_t *this, fuse_in_header_t *finh, struct fuse_setattr_in *fsi)
{
fuse_state_t *state = NULL;
fd_t *fd = NULL;
@@ -740,36 +861,36 @@ do_chown (fuse_req_t req, fuse_ino_t ino, struct stat *attr,
uid_t uid = 0;
gid_t gid = 0;
- uid = (valid & FUSE_SET_ATTR_UID) ? attr->st_uid : (uid_t) -1;
- gid = (valid & FUSE_SET_ATTR_GID) ? attr->st_gid : (gid_t) -1;
- STATE_FROM_REQ (req, state);
+ uid = (fsi->valid & FATTR_UID) ? fsi->uid : (uid_t) -1;
+ gid = (fsi->valid & FATTR_GID) ? fsi->gid : (gid_t) -1;
+ GET_STATE (this, finh, state);
- if (fi) {
- fd = FI_TO_FD (fi);
+ if (fsi->valid & FATTR_FH) {
+ fd = FH_TO_FD (fsi->fh);
state->fd = fd;
}
if (fd) {
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRIu64": FCHOWN %p", req_callid (req), fd);
+ "%"PRIu64": FCHOWN %p", finh->unique, fd);
FUSE_FOP (state, fuse_attr_cbk, GF_FOP_FCHOWN,
fchown, fd, uid, gid);
} else {
- ret = fuse_loc_fill (&state->loc, state, ino, 0, NULL);
+ ret = fuse_loc_fill (&state->loc, state, finh->nodeid, 0, NULL);
if ((state->loc.inode == NULL) ||
(ret < 0)) {
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
- "%"PRIu64": CHOWN %"PRId64" (%s) (fuse_loc_fill() failed)",
- req_callid (req), (int64_t)ino,
+ "%"PRIu64": CHOWN %"PRIu64" (%s) (fuse_loc_fill() failed)",
+ finh->unique, finh->nodeid,
state->loc.path);
- fuse_reply_err (req, ENOENT);
+ send_fuse_err (this, finh, ENOENT);
free_state (state);
return;
}
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRIu64": CHOWN %s", req_callid (req),
+ "%"PRIu64": CHOWN %s", finh->unique,
state->loc.path);
FUSE_FOP (state, fuse_attr_cbk, GF_FOP_CHOWN,
@@ -779,47 +900,46 @@ do_chown (fuse_req_t req, fuse_ino_t ino, struct stat *attr,
static void
-do_truncate (fuse_req_t req, fuse_ino_t ino, struct stat *attr,
- struct fuse_file_info *fi)
+do_truncate (xlator_t *this, fuse_in_header_t *finh, struct fuse_setattr_in *fsi)
{
fuse_state_t *state = NULL;
fd_t *fd = NULL;
int32_t ret = -1;
- STATE_FROM_REQ (req, state);
+ GET_STATE (this, finh, state);
- if (fi) {
- fd = FI_TO_FD (fi);
+ if (fsi->valid & FATTR_FH) {
+ fd = FH_TO_FD (fsi->fh);
state->fd = fd;
}
if (fd) {
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRIu64": FTRUNCATE %p/%"PRId64, req_callid (req),
- fd, attr->st_size);
+ "%"PRIu64": FTRUNCATE %p/%"PRId64, finh->unique,
+ fd, fsi->size);
FUSE_FOP (state, fuse_attr_cbk, GF_FOP_FTRUNCATE,
- ftruncate, fd, attr->st_size);
+ ftruncate, fd, fsi->size);
} else {
- ret = fuse_loc_fill (&state->loc, state, ino, 0, NULL);
+ ret = fuse_loc_fill (&state->loc, state, finh->nodeid, 0, NULL);
if ((state->loc.inode == NULL) ||
(ret < 0)) {
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
"%"PRIu64": TRUNCATE %s/%"PRId64" (fuse_loc_fill() failed)",
- req_callid (req), state->loc.path,
- attr->st_size);
- fuse_reply_err (req, ENOENT);
+ finh->unique, state->loc.path,
+ fsi->size);
+ send_fuse_err (this, finh, ENOENT);
free_state (state);
return;
}
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRIu64": TRUNCATE %s/%"PRId64"(%lu)",
- req_callid (req),
- state->loc.path, attr->st_size, ino);
+ "%"PRIu64": TRUNCATE %s/%"PRId64"(%"PRIu64")",
+ finh->unique,
+ state->loc.path, fsi->size, finh->nodeid);
FUSE_FOP (state, fuse_attr_cbk, GF_FOP_TRUNCATE,
- truncate, &state->loc, attr->st_size);
+ truncate, &state->loc, fsi->size);
}
return;
@@ -827,32 +947,32 @@ do_truncate (fuse_req_t req, fuse_ino_t ino, struct stat *attr,
static void
-do_utimes (fuse_req_t req, fuse_ino_t ino, struct stat *attr)
+do_utimes (xlator_t *this, fuse_in_header_t *finh, struct fuse_setattr_in *fsi)
{
fuse_state_t *state = NULL;
struct timespec tv[2];
int32_t ret = -1;
- tv[0].tv_sec = attr->st_atime;
- tv[0].tv_nsec = ST_ATIM_NSEC (attr);
- tv[1].tv_sec = attr->st_mtime;
- tv[1].tv_nsec = ST_ATIM_NSEC (attr);
+ tv[0].tv_sec = fsi->atime;
+ tv[0].tv_nsec = fsi->atimensec;
+ tv[1].tv_sec = fsi->mtime;
+ tv[1].tv_nsec = fsi->mtimensec;
- STATE_FROM_REQ (req, state);
- ret = fuse_loc_fill (&state->loc, state, ino, 0, NULL);
+ GET_STATE (this, finh, state);
+ ret = fuse_loc_fill (&state->loc, state, finh->nodeid, 0, NULL);
if ((state->loc.inode == NULL) ||
(ret < 0)) {
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
"%"PRIu64": UTIMENS %s (fuse_loc_fill() failed)",
- req_callid (req), state->loc.path);
- fuse_reply_err (req, ENOENT);
+ finh->unique, state->loc.path);
+ send_fuse_err (this, finh, ENOENT);
free_state (state);
return;
}
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRIu64": UTIMENS (%lu)%s", req_callid (req),
- ino, state->loc.path);
+ "%"PRIu64": UTIMENS (%"PRIu64")%s", finh->unique,
+ finh->nodeid, state->loc.path);
FUSE_FOP (state, fuse_attr_cbk, GF_FOP_UTIMENS,
utimens, &state->loc, tv);
@@ -860,20 +980,24 @@ do_utimes (fuse_req_t req, fuse_ino_t ino, struct stat *attr)
static void
-fuse_setattr (fuse_req_t req, fuse_ino_t ino, struct stat *attr,
- int valid, struct fuse_file_info *fi)
-{
-
- if (valid & FUSE_SET_ATTR_MODE)
- do_chmod (req, ino, attr, fi);
- else if (valid & (FUSE_SET_ATTR_UID | FUSE_SET_ATTR_GID))
- do_chown (req, ino, attr, valid, fi);
- else if (valid & FUSE_SET_ATTR_SIZE)
- do_truncate (req, ino, attr, fi);
- else if (valid & (FUSE_SET_ATTR_ATIME | FUSE_SET_ATTR_MTIME))
- do_utimes (req, ino, attr);
+fuse_setattr (xlator_t *this, fuse_in_header_t *finh, void *msg)
+{
+ struct fuse_setattr_in *fsi = msg;
+
+ if (fsi->valid & FATTR_MODE)
+ do_chmod (this, finh, fsi);
+ else if (fsi->valid & (FATTR_UID | FATTR_GID))
+ do_chown (this, finh, fsi);
+ else if (fsi->valid & FATTR_SIZE)
+ do_truncate (this, finh, fsi);
+ else if (fsi->valid & (FATTR_ATIME | FATTR_MTIME))
+ do_utimes (this, finh, fsi);
else
- fuse_getattr (req, ino, fi);
+ /* As of now, getattr uses only the header.
+ * If it happens to change, we'll have to
+ * do some refactoring...
+ */
+ fuse_getattr (this, finh, NULL);
}
@@ -884,15 +1008,15 @@ fuse_err_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno)
{
fuse_state_t *state = frame->root->state;
- fuse_req_t req = state->req;
+ fuse_in_header_t *finh = state->finh;
if (op_ret == 0) {
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRId64": %s() %s => 0", frame->root->unique,
+ "%"PRIu64": %s() %s => 0", frame->root->unique,
gf_fop_list[frame->root->op],
state->loc.path ? state->loc.path : "ERR");
- fuse_reply_err (req, 0);
+ send_fuse_err (this, finh, 0);
} else {
if (frame->root->op == GF_FOP_SETXATTR) {
op_ret = gf_compat_setxattr (state->dict);
@@ -913,7 +1037,7 @@ fuse_err_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
goto nolog;
}
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
- "%"PRId64": %s() %s => -1 (%s)",
+ "%"PRIu64": %s() %s => -1 (%s)",
frame->root->unique,
gf_fop_list[frame->root->op],
state->loc.path ? state->loc.path : "ERR",
@@ -921,7 +1045,7 @@ fuse_err_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
}
nolog:
- fuse_reply_err (req, op_errno);
+ send_fuse_err (this, finh, op_errno);
}
free_state (state);
@@ -935,11 +1059,11 @@ static int
fuse_unlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno)
{
- fuse_state_t *state = NULL;
- fuse_req_t req = NULL;
+ fuse_state_t *state = NULL;
+ fuse_in_header_t *finh = NULL;
state = frame->root->state;
- req = state->req;
+ finh = state->finh;
if (op_ret == 0)
inode_unlink (state->loc.inode, state->loc.parent,
@@ -947,18 +1071,18 @@ fuse_unlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
if (op_ret == 0) {
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRId64": %s() %s => 0", frame->root->unique,
+ "%"PRIu64": %s() %s => 0", frame->root->unique,
gf_fop_list[frame->root->op], state->loc.path);
- fuse_reply_err (req, 0);
+ send_fuse_err (this, finh, 0);
} else {
gf_log ("glusterfs-fuse",
op_errno == ENOTEMPTY ? GF_LOG_DEBUG : GF_LOG_WARNING,
- "%"PRId64": %s() %s => -1 (%s)", frame->root->unique,
+ "%"PRIu64": %s() %s => -1 (%s)", frame->root->unique,
gf_fop_list[frame->root->op], state->loc.path,
strerror (op_errno));
- fuse_reply_err (req, op_errno);
+ send_fuse_err (this, finh, op_errno);
}
free_state (state);
@@ -969,31 +1093,33 @@ fuse_unlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
static void
-fuse_access (fuse_req_t req, fuse_ino_t ino, int mask)
+fuse_access (xlator_t *this, fuse_in_header_t *finh, void *msg)
{
+ struct fuse_access_in *fai = msg;
+
fuse_state_t *state = NULL;
int32_t ret = -1;
- STATE_FROM_REQ (req, state);
+ GET_STATE (this, finh, state);
- ret = fuse_loc_fill (&state->loc, state, ino, 0, NULL);
+ ret = fuse_loc_fill (&state->loc, state, finh->nodeid, 0, NULL);
if ((state->loc.inode == NULL) ||
(ret < 0)) {
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
- "%"PRIu64": ACCESS %"PRId64" (%s) (fuse_loc_fill() failed)",
- req_callid (req), (int64_t)ino, state->loc.path);
- fuse_reply_err (req, ENOENT);
+ "%"PRIu64": ACCESS %"PRIu64" (%s) (fuse_loc_fill() failed)",
+ finh->unique, finh->nodeid, state->loc.path);
+ send_fuse_err (this, finh, ENOENT);
free_state (state);
return;
}
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRIu64" ACCESS %s/%lu mask=%d", req_callid (req),
- state->loc.path, ino, mask);
+ "%"PRIu64" ACCESS %s/%"PRIu64" mask=%d", finh->unique,
+ state->loc.path, finh->nodeid, fai->mask);
FUSE_FOP (state, fuse_err_cbk,
GF_FOP_ACCESS, access,
- &state->loc, mask);
+ &state->loc, fai->mask);
return;
}
@@ -1003,26 +1129,26 @@ static int
fuse_readlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, const char *linkname)
{
- fuse_state_t *state = NULL;
- fuse_req_t req = NULL;
+ fuse_state_t *state = NULL;
+ fuse_in_header_t *finh = NULL;
state = frame->root->state;
- req = state->req;
+ finh = state->finh;
if (op_ret > 0) {
((char *)linkname)[op_ret] = '\0';
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRId64": %s => %s", frame->root->unique,
+ "%"PRIu64": %s => %s", frame->root->unique,
state->loc.path, linkname);
- fuse_reply_readlink (req, linkname);
+ send_fuse_data (this, finh, (void *)linkname, op_ret + 1);
} else {
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
- "%"PRId64": %s => -1 (%s)", frame->root->unique,
+ "%"PRIu64": %s => -1 (%s)", frame->root->unique,
state->loc.path, strerror (op_errno));
- fuse_reply_err (req, op_errno);
+ send_fuse_err (this, finh, op_errno);
}
free_state (state);
@@ -1033,26 +1159,26 @@ fuse_readlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
static void
-fuse_readlink (fuse_req_t req, fuse_ino_t ino)
+fuse_readlink (xlator_t *this, fuse_in_header_t *finh, void *msg)
{
fuse_state_t *state = NULL;
int32_t ret = -1;
- STATE_FROM_REQ (req, state);
- ret = fuse_loc_fill (&state->loc, state, ino, 0, NULL);
+ GET_STATE (this, finh, state);
+ ret = fuse_loc_fill (&state->loc, state, finh->nodeid, 0, NULL);
if ((state->loc.inode == NULL) ||
(ret < 0)) {
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
"%"PRIu64" READLINK %s/%"PRId64" (fuse_loc_fill() returned NULL inode)",
- req_callid (req), state->loc.path,
+ finh->unique, state->loc.path,
state->loc.inode->ino);
- fuse_reply_err (req, ENOENT);
+ send_fuse_err (this, finh, ENOENT);
free_state (state);
return;
}
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRIu64" READLINK %s/%"PRId64, req_callid (req),
+ "%"PRIu64" READLINK %s/%"PRId64, finh->unique,
state->loc.path, state->loc.inode->ino);
FUSE_FOP (state, fuse_readlink_cbk, GF_FOP_READLINK,
@@ -1063,19 +1189,21 @@ fuse_readlink (fuse_req_t req, fuse_ino_t ino)
static void
-fuse_mknod (fuse_req_t req, fuse_ino_t par, const char *name,
- mode_t mode, dev_t rdev)
+fuse_mknod (xlator_t *this, fuse_in_header_t *finh, void *msg)
{
+ struct fuse_mknod_in *fmi = msg;
+ char *name = (char *)(fmi + 1);
+
fuse_state_t *state = NULL;
int32_t ret = -1;
- STATE_FROM_REQ (req, state);
- ret = fuse_loc_fill (&state->loc, state, 0, par, name);
+ GET_STATE (this, finh, state);
+ ret = fuse_loc_fill (&state->loc, state, 0, finh->nodeid, name);
if (ret < 0) {
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
"%"PRIu64" MKNOD %s (fuse_loc_fill() failed)",
- req_callid (req), state->loc.path);
- fuse_reply_err (req, ENOENT);
+ finh->unique, state->loc.path);
+ send_fuse_err (this, finh, ENOENT);
free_state (state);
return;
}
@@ -1083,29 +1211,32 @@ fuse_mknod (fuse_req_t req, fuse_ino_t par, const char *name,
state->loc.inode = inode_new (state->itable);
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRIu64": MKNOD %s", req_callid (req),
+ "%"PRIu64": MKNOD %s", finh->unique,
state->loc.path);
FUSE_FOP (state, fuse_entry_cbk, GF_FOP_MKNOD,
- mknod, &state->loc, mode, rdev);
+ mknod, &state->loc, fmi->mode, fmi->rdev);
return;
}
static void
-fuse_mkdir (fuse_req_t req, fuse_ino_t par, const char *name, mode_t mode)
+fuse_mkdir (xlator_t *this, fuse_in_header_t *finh, void *msg)
{
+ struct fuse_mknod_in *fmi = msg;
+ char *name = (char *)(fmi + 1);
+
fuse_state_t *state;
int32_t ret = -1;
- STATE_FROM_REQ (req, state);
- ret = fuse_loc_fill (&state->loc, state, 0, par, name);
+ GET_STATE (this, finh, state);
+ ret = fuse_loc_fill (&state->loc, state, 0, finh->nodeid, name);
if (ret < 0) {
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
"%"PRIu64" MKDIR %s (fuse_loc_fill() failed)",
- req_callid (req), state->loc.path);
- fuse_reply_err (req, ENOENT);
+ finh->unique, state->loc.path);
+ send_fuse_err (this, finh, ENOENT);
free_state (state);
return;
}
@@ -1113,38 +1244,40 @@ fuse_mkdir (fuse_req_t req, fuse_ino_t par, const char *name, mode_t mode)
state->loc.inode = inode_new (state->itable);
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRIu64": MKDIR %s", req_callid (req),
+ "%"PRIu64": MKDIR %s", finh->unique,
state->loc.path);
FUSE_FOP (state, fuse_entry_cbk, GF_FOP_MKDIR,
- mkdir, &state->loc, mode);
+ mkdir, &state->loc, fmi->mode);
return;
}
static void
-fuse_unlink (fuse_req_t req, fuse_ino_t par, const char *name)
+fuse_unlink (xlator_t *this, fuse_in_header_t *finh, void *msg)
{
+ char *name = msg;
+
fuse_state_t *state = NULL;
int32_t ret = -1;
- STATE_FROM_REQ (req, state);
+ GET_STATE (this, finh, state);
- ret = fuse_loc_fill (&state->loc, state, 0, par, name);
+ ret = fuse_loc_fill (&state->loc, state, 0, finh->nodeid, name);
if ((state->loc.inode == NULL) ||
(ret < 0)) {
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
"%"PRIu64": UNLINK %s (fuse_loc_fill() returned NULL inode)",
- req_callid (req), state->loc.path);
- fuse_reply_err (req, ENOENT);
+ finh->unique, state->loc.path);
+ send_fuse_err (this, finh, ENOENT);
free_state (state);
return;
}
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRIu64": UNLINK %s", req_callid (req),
+ "%"PRIu64": UNLINK %s", finh->unique,
state->loc.path);
FUSE_FOP (state, fuse_unlink_cbk, GF_FOP_UNLINK,
@@ -1155,25 +1288,27 @@ fuse_unlink (fuse_req_t req, fuse_ino_t par, const char *name)
static void
-fuse_rmdir (fuse_req_t req, fuse_ino_t par, const char *name)
+fuse_rmdir (xlator_t *this, fuse_in_header_t *finh, void *msg)
{
+ char *name = msg;
+
fuse_state_t *state = NULL;
int32_t ret = -1;
- STATE_FROM_REQ (req, state);
- ret = fuse_loc_fill (&state->loc, state, 0, par, name);
+ GET_STATE (this, finh, state);
+ ret = fuse_loc_fill (&state->loc, state, 0, finh->nodeid, name);
if ((state->loc.inode == NULL) ||
(ret < 0)) {
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
"%"PRIu64": RMDIR %s (fuse_loc_fill() failed)",
- req_callid (req), state->loc.path);
- fuse_reply_err (req, ENOENT);
+ finh->unique, state->loc.path);
+ send_fuse_err (this, finh, ENOENT);
free_state (state);
return;
}
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRIu64": RMDIR %s", req_callid (req),
+ "%"PRIu64": RMDIR %s", finh->unique,
state->loc.path);
FUSE_FOP (state, fuse_unlink_cbk, GF_FOP_RMDIR,
@@ -1184,19 +1319,21 @@ fuse_rmdir (fuse_req_t req, fuse_ino_t par, const char *name)
static void
-fuse_symlink (fuse_req_t req, const char *linkname, fuse_ino_t par,
- const char *name)
+fuse_symlink (xlator_t *this, fuse_in_header_t *finh, void *msg)
{
+ char *name = msg;
+ char *linkname = name + strlen (name) + 1;
+
fuse_state_t *state = NULL;
int32_t ret = -1;
- STATE_FROM_REQ (req, state);
- ret = fuse_loc_fill (&state->loc, state, 0, par, name);
+ GET_STATE (this, finh, state);
+ ret = fuse_loc_fill (&state->loc, state, 0, finh->nodeid, name);
if (ret < 0) {
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
"%"PRIu64" SYMLINK %s -> %s (fuse_loc_fill() failed)",
- req_callid (req), state->loc.path, linkname);
- fuse_reply_err (req, ENOENT);
+ finh->unique, state->loc.path, linkname);
+ send_fuse_err (this, finh, ENOENT);
free_state (state);
return;
}
@@ -1204,7 +1341,7 @@ fuse_symlink (fuse_req_t req, const char *linkname, fuse_ino_t par,
state->loc.inode = inode_new (state->itable);
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRIu64": SYMLINK %s -> %s", req_callid (req),
+ "%"PRIu64": SYMLINK %s -> %s", finh->unique,
state->loc.path, linkname);
FUSE_FOP (state, fuse_entry_cbk, GF_FOP_SYMLINK,
@@ -1218,15 +1355,15 @@ int
fuse_rename_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct stat *buf)
{
- fuse_state_t *state = NULL;
- fuse_req_t req = NULL;
+ fuse_state_t *state = NULL;
+ fuse_in_header_t *finh = NULL;
state = frame->root->state;
- req = state->req;
+ finh = state->finh;
if (op_ret == 0) {
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRId64": %s -> %s => 0 (buf->st_ino=%"PRId64" , loc->ino=%"PRId64")",
+ "%"PRIu64": %s -> %s => 0 (buf->st_ino=%"PRId64" , loc->ino=%"PRId64")",
frame->root->unique, state->loc.path, state->loc2.path,
buf->st_ino, state->loc.ino);
@@ -1244,13 +1381,13 @@ fuse_rename_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
state->loc2.parent, state->loc2.name,
state->loc.inode, buf);
- fuse_reply_err (req, 0);
+ send_fuse_err (this, finh, 0);
} else {
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
- "%"PRId64": %s -> %s => -1 (%s)", frame->root->unique,
+ "%"PRIu64": %s -> %s => -1 (%s)", frame->root->unique,
state->loc.path, state->loc2.path,
strerror (op_errno));
- fuse_reply_err (req, op_errno);
+ send_fuse_err (this, finh, op_errno);
}
free_state (state);
@@ -1260,42 +1397,45 @@ fuse_rename_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
static void
-fuse_rename (fuse_req_t req, fuse_ino_t oldpar, const char *oldname,
- fuse_ino_t newpar, const char *newname)
+fuse_rename (xlator_t *this, fuse_in_header_t *finh, void *msg)
{
+ struct fuse_rename_in *fri = msg;
+ char *oldname = (char *)(fri + 1);
+ char *newname = oldname + strlen (oldname) + 1;
+
fuse_state_t *state = NULL;
int32_t ret = -1;
- STATE_FROM_REQ (req, state);
+ GET_STATE (this, finh, state);
- ret = fuse_loc_fill (&state->loc, state, 0, oldpar, oldname);
+ ret = fuse_loc_fill (&state->loc, state, 0, finh->nodeid, oldname);
if ((state->loc.inode == NULL) ||
(ret < 0)) {
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
"for %s %"PRIu64": RENAME `%s' -> `%s' (fuse_loc_fill() failed)",
- state->loc.path, req_callid (req), state->loc.path,
+ state->loc.path, finh->unique, state->loc.path,
state->loc2.path);
- fuse_reply_err (req, ENOENT);
+ send_fuse_err (this, finh, ENOENT);
free_state (state);
return;
}
- ret = fuse_loc_fill (&state->loc2, state, 0, newpar, newname);
+ ret = fuse_loc_fill (&state->loc2, state, 0, fri->newdir, newname);
if (ret < 0) {
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
"for %s %"PRIu64": RENAME `%s' -> `%s' (fuse_loc_fill() failed)",
- state->loc.path, req_callid (req), state->loc.path,
+ state->loc.path, finh->unique, state->loc.path,
state->loc2.path);
- fuse_reply_err (req, ENOENT);
+ send_fuse_err (this, finh, ENOENT);
free_state (state);
return;
}
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
"%"PRIu64": RENAME `%s (%"PRId64")' -> `%s (%"PRId64")'",
- req_callid (req), state->loc.path, state->loc.ino,
+ finh->unique, state->loc.path, state->loc.ino,
state->loc2.path, state->loc2.ino);
FUSE_FOP (state, fuse_rename_cbk, GF_FOP_RENAME,
@@ -1306,24 +1446,28 @@ fuse_rename (fuse_req_t req, fuse_ino_t oldpar, const char *oldname,
static void
-fuse_link (fuse_req_t req, fuse_ino_t ino, fuse_ino_t par, const char *name)
+fuse_link (xlator_t *this, fuse_in_header_t *finh, void *msg)
{
+ struct fuse_link_in *fli = msg;
+ char *name = (char *)(fli + 1);
+
fuse_state_t *state = NULL;
int32_t ret = -1;
- STATE_FROM_REQ (req, state);
+ GET_STATE (this, finh, state);
- ret = fuse_loc_fill (&state->loc, state, 0, par, name);
+ ret = fuse_loc_fill (&state->loc, state, 0, finh->nodeid, name);
if (ret == 0)
- ret = fuse_loc_fill (&state->loc2, state, ino, 0, NULL);
+ ret = fuse_loc_fill (&state->loc2, state, fli->oldnodeid, 0,
+ NULL);
if ((state->loc2.inode == NULL) ||
(ret < 0)) {
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
"fuse_loc_fill() failed for %s %"PRIu64": LINK %s %s",
- state->loc2.path, req_callid (req),
+ state->loc2.path, finh->unique,
state->loc2.path, state->loc.path);
- fuse_reply_err (req, ENOENT);
+ send_fuse_err (this, finh, ENOENT);
free_state (state);
return;
}
@@ -1331,7 +1475,7 @@ fuse_link (fuse_req_t req, fuse_ino_t ino, fuse_ino_t par, const char *name)
state->loc.inode = inode_ref (state->loc2.inode);
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
"%"PRIu64": LINK() %s (%"PRId64") -> %s (%"PRId64")",
- req_callid (req), state->loc2.path, state->loc2.ino,
+ finh->unique, state->loc2.path, state->loc2.ino,
state->loc.path, state->loc.ino);
FUSE_FOP (state, fuse_entry_cbk, GF_FOP_LINK,
@@ -1347,42 +1491,46 @@ fuse_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
fd_t *fd, inode_t *inode, struct stat *buf)
{
fuse_state_t *state = NULL;
- fuse_req_t req = NULL;
+ fuse_in_header_t *finh = NULL;
fuse_private_t *priv = NULL;
- struct fuse_file_info fi = {0, };
- struct fuse_entry_param e = {0, };
+ struct fuse_out_header fouh = {0, };
+ struct fuse_entry_out feo = {0, };
+ struct fuse_open_out foo = {0, };
+ struct iovec iov_out[3];
state = frame->root->state;
priv = this->private;
- req = state->req;
- fi.flags = state->flags;
+ finh = state->finh;
+ foo.open_flags = 0;
if (op_ret >= 0) {
- fi.fh = (unsigned long) fd;
+ foo.fh = (uintptr_t) fd;
- if (((fi.flags & O_ACCMODE) != O_RDONLY)
- && priv->direct_io_mode)
- fi.direct_io = 1;
+ if (((state->flags & O_ACCMODE) != O_RDONLY) &&
+ priv->direct_io_mode)
+ foo.open_flags |= FOPEN_DIRECT_IO;
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRId64": %s() %s => %p (ino=%"PRId64")",
+ "%"PRIu64": %s() %s => %p (ino=%"PRId64")",
frame->root->unique, gf_fop_list[frame->root->op],
state->loc.path, fd, buf->st_ino);
- e.ino = buf->st_ino;
+ buf->st_blksize = this->ctx->page_size;
+ stat2attr (buf, &feo.attr);
+
+ feo.nodeid = buf->st_ino;
#ifdef GF_DARWIN_HOST_OS
- e.generation = 0;
+ feo.generation = 0;
#else
- e.generation = buf->st_ctime;
+ feo.generation = buf->st_ctime;
#endif
- buf->st_blksize = this->ctx->page_size;
- e.entry_timeout = priv->entry_timeout;
- e.attr_timeout = priv->attribute_timeout;
- e.attr = *buf;
-
- fi.keep_cache = 0;
+ feo.entry_valid = calc_timeout_sec (priv->entry_timeout);
+ feo.entry_valid_nsec = calc_timeout_nsec (priv->entry_timeout);
+ feo.attr_valid = calc_timeout_sec (priv->attribute_timeout);
+ feo.attr_valid_nsec =
+ calc_timeout_nsec (priv->attribute_timeout);
inode_link (inode, state->loc.parent,
state->loc.name, buf);
@@ -1390,7 +1538,14 @@ fuse_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
inode_lookup (inode);
fd_ref (fd);
- if (fuse_reply_create (req, &e, &fi) == -ENOENT) {
+
+ fouh.error = 0;
+ iov_out[0].iov_base = &fouh;
+ iov_out[1].iov_base = &feo;
+ iov_out[1].iov_len = sizeof (feo);
+ iov_out[2].iov_base = &foo;
+ iov_out[2].iov_len = sizeof (foo);
+ if (send_fuse_iov (this, finh, iov_out, 3) == ENOENT) {
gf_log ("glusterfs-fuse", GF_LOG_DEBUG,
"create(%s) got EINTR", state->loc.path);
inode_forget (inode, 1);
@@ -1401,9 +1556,9 @@ fuse_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
fd_bind (fd);
} else {
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
- "%"PRIu64": %s => -1 (%s)", req_callid (req),
+ "%"PRIu64": %s => -1 (%s)", finh->unique,
state->loc.path, strerror (op_errno));
- fuse_reply_err (req, op_errno);
+ send_fuse_err (this, finh, op_errno);
}
out:
free_state (state);
@@ -1414,75 +1569,79 @@ out:
static void
-fuse_create (fuse_req_t req, fuse_ino_t par, const char *name,
- mode_t mode, struct fuse_file_info *fi)
+fuse_create (xlator_t *this, fuse_in_header_t *finh, void *msg)
{
+ struct fuse_open_in *foi = msg;
+ char *name = (char *)(foi + 1);
+
fuse_state_t *state = NULL;
fd_t *fd = NULL;
int32_t ret = -1;
- STATE_FROM_REQ (req, state);
- state->flags = fi->flags;
+ GET_STATE (this, finh, state);
+ state->flags = foi->flags;
- ret = fuse_loc_fill (&state->loc, state, 0, par, name);
+ ret = fuse_loc_fill (&state->loc, state, 0, finh->nodeid, name);
if (ret < 0) {
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
"%"PRIu64" CREATE %s (fuse_loc_fill() failed)",
- req_callid (req), state->loc.path);
- fuse_reply_err (req, ENOENT);
+ finh->unique, state->loc.path);
+ send_fuse_err (this, finh, ENOENT);
free_state (state);
return;
}
state->loc.inode = inode_new (state->itable);
- fd = fd_create (state->loc.inode, get_pid_from_req (req));
+ fd = fd_create (state->loc.inode, finh->pid);
state->fd = fd;
fd->flags = state->flags;
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRIu64": CREATE %s", req_callid (req),
+ "%"PRIu64": CREATE %s", finh->unique,
state->loc.path);
FUSE_FOP (state, fuse_create_cbk, GF_FOP_CREATE,
- create, &state->loc, state->flags, mode, fd);
+ create, &state->loc, state->flags, foi->mode, fd);
return;
}
static void
-fuse_open (fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi)
+fuse_open (xlator_t *this, fuse_in_header_t *finh, void *msg)
{
+ struct fuse_open_in *foi = msg;
+
fuse_state_t *state = NULL;
fd_t *fd = NULL;
int32_t ret = -1;
- STATE_FROM_REQ (req, state);
- state->flags = fi->flags;
+ GET_STATE (this, finh, state);
+ state->flags = foi->flags;
- ret = fuse_loc_fill (&state->loc, state, ino, 0, NULL);
+ ret = fuse_loc_fill (&state->loc, state, finh->nodeid, 0, NULL);
if ((state->loc.inode == NULL) ||
(ret < 0)) {
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
"%"PRIu64": OPEN %s (fuse_loc_fill() failed)",
- req_callid (req), state->loc.path);
+ finh->unique, state->loc.path);
- fuse_reply_err (req, ENOENT);
+ send_fuse_err (this, finh, ENOENT);
free_state (state);
return;
}
- fd = fd_create (state->loc.inode, get_pid_from_req (req));
+ fd = fd_create (state->loc.inode, finh->pid);
state->fd = fd;
- fd->flags = fi->flags;
+ fd->flags = foi->flags;
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRIu64": OPEN %s", req_callid (req),
+ "%"PRIu64": OPEN %s", finh->unique,
state->loc.path);
FUSE_FOP (state, fuse_fd_cbk, GF_FOP_OPEN,
- open, &state->loc, fi->flags, fd);
+ open, &state->loc, foi->flags, fd);
return;
}
@@ -1495,28 +1654,34 @@ fuse_readv_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
struct stat *stbuf, struct iobref *iobref)
{
fuse_state_t *state = NULL;
- fuse_req_t req = NULL;
+ fuse_in_header_t *finh = NULL;
+ struct fuse_out_header fouh = {0, };
+ struct iovec *iov_out = NULL;
state = frame->root->state;
- req = state->req;
+ finh = state->finh;
if (op_ret >= 0) {
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRId64": READ => %d/%"GF_PRI_SIZET",%"PRId64"/%"PRId64,
+ "%"PRIu64": READ => %d/%"GF_PRI_SIZET",%"PRId64"/%"PRId64,
frame->root->unique,
op_ret, state->size, state->off, stbuf->st_size);
-#ifdef HAVE_FUSE_REPLY_IOV
- fuse_reply_iov (req, vector, count);
-#else
- fuse_reply_vec (req, vector, count);
-#endif
+ iov_out = CALLOC (count + 1, sizeof (*iov_out));
+ if (iov_out) {
+ fouh.error = 0;
+ iov_out[0].iov_base = &fouh;
+ memcpy (iov_out + 1, vector, count * sizeof (*iov_out));
+ send_fuse_iov (this, finh, iov_out, count + 1);
+ FREE (iov_out);
+ } else
+ send_fuse_err (this, finh, ENOMEM);
} else {
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
- "%"PRId64": READ => %d (%s)", frame->root->unique,
+ "%"PRIu64": READ => %d (%s)", frame->root->unique,
op_ret, strerror (op_errno));
- fuse_reply_err (req, op_errno);
+ send_fuse_err (this, finh, op_errno);
}
free_state (state);
@@ -1527,25 +1692,26 @@ fuse_readv_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
static void
-fuse_readv (fuse_req_t req, fuse_ino_t ino, size_t size, off_t off,
- struct fuse_file_info *fi)
+fuse_readv (xlator_t *this, fuse_in_header_t *finh, void *msg)
{
+ struct fuse_read_in *fri = msg;
+
fuse_state_t *state = NULL;
fd_t *fd = NULL;
- STATE_FROM_REQ (req, state);
- state->size = size;
- state->off = off;
+ GET_STATE (this, finh, state);
+ state->size = fri->size;
+ state->off = fri->offset;
- fd = FI_TO_FD (fi);
+ fd = FH_TO_FD (fri->fh);
state->fd = fd;
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRIu64": READ (%p, size=%"GF_PRI_SIZET", offset=%"PRId64")",
- req_callid (req), fd, size, off);
+ "%"PRIu64": READ (%p, size=%"PRIu32", offset=%"PRIu64")",
+ finh->unique, fd, fri->size, fri->offset);
FUSE_FOP (state, fuse_readv_cbk, GF_FOP_READ,
- readv, fd, size, off);
+ readv, fd, fri->size, fri->offset);
}
@@ -1556,24 +1722,26 @@ fuse_writev_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
struct stat *stbuf)
{
fuse_state_t *state = NULL;
- fuse_req_t req = NULL;
+ fuse_in_header_t *finh = NULL;
+ struct fuse_write_out fwo = {0, };
state = frame->root->state;
- req = state->req;
+ finh = state->finh;
if (op_ret >= 0) {
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRId64": WRITE => %d/%"GF_PRI_SIZET",%"PRId64"/%"PRId64,
+ "%"PRIu64": WRITE => %d/%"GF_PRI_SIZET",%"PRId64"/%"PRId64,
frame->root->unique,
op_ret, state->size, state->off, stbuf->st_size);
- fuse_reply_write (req, op_ret);
+ fwo.size = op_ret;
+ send_fuse_obj (this, finh, &fwo);
} else {
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
- "%"PRId64": WRITE => -1 (%s)", frame->root->unique,
+ "%"PRIu64": WRITE => -1 (%s)", frame->root->unique,
strerror (op_errno));
- fuse_reply_err (req, op_errno);
+ send_fuse_err (this, finh, op_errno);
}
free_state (state);
@@ -1584,33 +1752,34 @@ fuse_writev_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
static void
-fuse_write (fuse_req_t req, fuse_ino_t ino, const char *buf,
- size_t size, off_t off,
- struct fuse_file_info *fi)
+fuse_write (xlator_t *this, fuse_in_header_t *finh, void *msg)
{
+ struct fuse_write_in *fwi = msg;
+ char *buf = (char *)(fwi + 1);
+
fuse_state_t *state = NULL;
struct iovec vector;
fd_t *fd = NULL;
struct iobref *iobref = NULL;
struct iobuf *iobuf = NULL;
- STATE_FROM_REQ (req, state);
- state->size = size;
- state->off = off;
- fd = FI_TO_FD (fi);
+ GET_STATE (this, finh, state);
+ state->size = fwi->size;
+ state->off = fwi->offset;
+ fd = FH_TO_FD (fwi->fh);
state->fd = fd;
vector.iov_base = (void *)buf;
- vector.iov_len = size;
+ vector.iov_len = fwi->size;
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRIu64": WRITE (%p, size=%"GF_PRI_SIZET", offset=%"PRId64")",
- req_callid (req), fd, size, off);
+ "%"PRIu64": WRITE (%p, size=%"PRIu32", offset=%"PRId64")",
+ finh->unique, fd, fwi->size, fwi->offset);
iobref = iobref_new ();
if (!iobref) {
- gf_log("glusterfs-fuse", GF_LOG_ERROR,
- "%"PRIu64": WRITE iobref allocation failed",
- req_callid (req));
+ gf_log ("glusterfs-fuse", GF_LOG_ERROR,
+ "%"PRIu64": WRITE iobref allocation failed",
+ finh->unique);
free_state (state);
return;
@@ -1619,7 +1788,7 @@ fuse_write (fuse_req_t req, fuse_ino_t ino, const char *buf,
iobref_add (iobref, iobuf);
FUSE_FOP (state, fuse_writev_cbk, GF_FOP_WRITE,
- writev, fd, &vector, 1, off, iobref);
+ writev, fd, &vector, 1, fwi->offset, iobref);
iobref_unref (iobref);
return;
@@ -1627,17 +1796,19 @@ fuse_write (fuse_req_t req, fuse_ino_t ino, const char *buf,
static void
-fuse_flush (fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi)
+fuse_flush (xlator_t *this, fuse_in_header_t *finh, void *msg)
{
+ struct fuse_flush_in *ffi = msg;
+
fuse_state_t *state = NULL;
fd_t *fd = NULL;
- STATE_FROM_REQ (req, state);
- fd = FI_TO_FD (fi);
+ GET_STATE (this, finh, state);
+ fd = FH_TO_FD (ffi->fh);
state->fd = fd;
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRIu64": FLUSH %p", req_callid (req), fd);
+ "%"PRIu64": FLUSH %p", finh->unique, fd);
FUSE_FOP (state, fuse_err_cbk, GF_FOP_FLUSH,
flush, fd);
@@ -1647,19 +1818,21 @@ fuse_flush (fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi)
static void
-fuse_release (fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi)
+fuse_release (xlator_t *this, fuse_in_header_t *finh, void *msg)
{
+ struct fuse_release_in *fri = msg;
+
fuse_state_t *state = NULL;
- STATE_FROM_REQ (req, state);
- state->fd = FI_TO_FD (fi);
+ GET_STATE (this, finh, state);
+ state->fd = FH_TO_FD (fri->fh);
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRIu64": RELEASE %p", req_callid (req), state->fd);
+ "%"PRIu64": RELEASE %p", finh->unique, state->fd);
fd_unref (state->fd);
- fuse_reply_err (req, 0);
+ send_fuse_err (this, finh, 0);
free_state (state);
return;
@@ -1667,51 +1840,57 @@ fuse_release (fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi)
static void
-fuse_fsync (fuse_req_t req, fuse_ino_t ino, int datasync,
- struct fuse_file_info *fi)
+fuse_fsync (xlator_t *this, fuse_in_header_t *finh, void *msg)
{
+ struct fuse_fsync_in *fsi = msg;
+
fuse_state_t *state = NULL;
fd_t *fd = NULL;
- STATE_FROM_REQ (req, state);
- fd = FI_TO_FD (fi);
+ GET_STATE (this, finh, state);
+ fd = FH_TO_FD (fsi->fh);
state->fd = fd;
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRIu64": FSYNC %p", req_callid (req), fd);
+ "%"PRIu64": FSYNC %p", finh->unique, fd);
+ /* fsync_flags: 1 means "datasync" (no defines for this) */
FUSE_FOP (state, fuse_err_cbk, GF_FOP_FSYNC,
- fsync, fd, datasync);
+ fsync, fd, fsi->fsync_flags & 1);
return;
}
static void
-fuse_opendir (fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi)
+fuse_opendir (xlator_t *this, fuse_in_header_t *finh, void *msg)
{
+ /*
+ struct fuse_open_in *foi = msg;
+ */
+
fuse_state_t *state = NULL;
fd_t *fd = NULL;
int32_t ret = -1;
- STATE_FROM_REQ (req, state);
- ret = fuse_loc_fill (&state->loc, state, ino, 0, NULL);
+ GET_STATE (this, finh, state);
+ ret = fuse_loc_fill (&state->loc, state, finh->nodeid, 0, NULL);
if ((state->loc.inode == NULL) ||
(ret < 0)) {
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
"%"PRIu64": OPENDIR %s (fuse_loc_fill() failed)",
- req_callid (req), state->loc.path);
+ finh->unique, state->loc.path);
- fuse_reply_err (req, ENOENT);
+ send_fuse_err (this, finh, ENOENT);
free_state (state);
return;
}
- fd = fd_create (state->loc.inode, get_pid_from_req (req));
+ fd = fd_create (state->loc.inode, finh->pid);
state->fd = fd;
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRIu64": OPENDIR %s", req_callid (req),
+ "%"PRIu64": OPENDIR %s", finh->unique,
state->loc.path);
FUSE_FOP (state, fuse_fd_cbk, GF_FOP_OPENDIR,
@@ -1724,53 +1903,54 @@ fuse_readdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, gf_dirent_t *entries)
{
fuse_state_t *state = NULL;
- fuse_req_t req = NULL;
+ fuse_in_header_t *finh = NULL;
int size = 0;
- int entry_size = 0;
char *buf = NULL;
gf_dirent_t *entry = NULL;
- struct stat stbuf = {0, };
+ struct fuse_dirent *fde = NULL;
state = frame->root->state;
- req = state->req;
+ finh = state->finh;
if (op_ret < 0) {
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
- "%"PRId64": READDIR => -1 (%s)", frame->root->unique,
+ "%"PRIu64": READDIR => -1 (%s)", frame->root->unique,
strerror (op_errno));
- fuse_reply_err (req, op_errno);
+ send_fuse_err (this, finh, op_errno);
goto out;
}
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRId64": READDIR => %d/%"GF_PRI_SIZET",%"PRId64,
+ "%"PRIu64": READDIR => %d/%"GF_PRI_SIZET",%"PRId64,
frame->root->unique, op_ret, state->size, state->off);
list_for_each_entry (entry, &entries->list, list) {
- size += fuse_dirent_size (strlen (entry->d_name));
+ size += FUSE_DIRENT_ALIGN (FUSE_NAME_OFFSET +
+ strlen (entry->d_name));
}
buf = CALLOC (1, size);
if (!buf) {
gf_log ("glusterfs-fuse", GF_LOG_DEBUG,
- "%"PRId64": READDIR => -1 (%s)", frame->root->unique,
+ "%"PRIu64": READDIR => -1 (%s)", frame->root->unique,
strerror (ENOMEM));
- fuse_reply_err (req, ENOMEM);
+ send_fuse_err (this, finh, ENOMEM);
goto out;
}
size = 0;
list_for_each_entry (entry, &entries->list, list) {
- stbuf.st_ino = entry->d_ino;
- entry_size = fuse_dirent_size (strlen (entry->d_name));
- fuse_add_direntry (req, buf + size, entry_size,
- entry->d_name, &stbuf,
- entry->d_off);
- size += entry_size;
+ fde = (struct fuse_dirent *)(buf + size);
+ fde->ino = entry->d_ino;
+ fde->off = entry->d_off;
+ fde->type = entry->d_type;
+ fde->namelen = strlen (entry->d_name);
+ strncpy (fde->name, entry->d_name, fde->namelen);
+ size += FUSE_DIRENT_SIZE (fde);
}
- fuse_reply_buf (req, (void *)buf, size);
+ send_fuse_data (this, finh, buf, size);
out:
free_state (state);
@@ -1783,41 +1963,44 @@ out:
static void
-fuse_readdir (fuse_req_t req, fuse_ino_t ino, size_t size, off_t off,
- struct fuse_file_info *fi)
+fuse_readdir (xlator_t *this, fuse_in_header_t *finh, void *msg)
{
+ struct fuse_read_in *fri = msg;
+
fuse_state_t *state = NULL;
fd_t *fd = NULL;
- STATE_FROM_REQ (req, state);
- state->size = size;
- state->off = off;
- fd = FI_TO_FD (fi);
+ GET_STATE (this, finh, state);
+ state->size = fri->size;
+ state->off = fri->offset;
+ fd = FH_TO_FD (fri->fh);
state->fd = fd;
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRIu64": READDIR (%p, size=%"GF_PRI_SIZET", offset=%"PRId64")",
- req_callid (req), fd, size, off);
+ "%"PRIu64": READDIR (%p, size=%"PRIu32", offset=%"PRId64")",
+ finh->unique, fd, fri->size, fri->offset);
FUSE_FOP (state, fuse_readdir_cbk, GF_FOP_READDIR,
- readdir, fd, size, off);
+ readdir, fd, fri->size, fri->offset);
}
static void
-fuse_releasedir (fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi)
+fuse_releasedir (xlator_t *this, fuse_in_header_t *finh, void *msg)
{
+ struct fuse_release_in *fri = msg;
+
fuse_state_t *state = NULL;
- STATE_FROM_REQ (req, state);
- state->fd = FI_TO_FD (fi);
+ GET_STATE (this, finh, state);
+ state->fd = FH_TO_FD (fri->fh);
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRIu64": RELEASEDIR %p", req_callid (req), state->fd);
+ "%"PRIu64": RELEASEDIR %p", finh->unique, state->fd);
fd_unref (state->fd);
- fuse_reply_err (req, 0);
+ send_fuse_err (this, finh, 0);
free_state (state);
@@ -1826,19 +2009,20 @@ fuse_releasedir (fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi)
static void
-fuse_fsyncdir (fuse_req_t req, fuse_ino_t ino, int datasync,
- struct fuse_file_info *fi)
+fuse_fsyncdir (xlator_t *this, fuse_in_header_t *finh, void *msg)
{
+ struct fuse_fsync_in *fsi = msg;
+
fuse_state_t *state = NULL;
fd_t *fd = NULL;
- fd = FI_TO_FD (fi);
+ fd = FH_TO_FD (fsi->fh);
- STATE_FROM_REQ (req, state);
+ GET_STATE (this, finh, state);
state->fd = fd;
FUSE_FOP (state, fuse_err_cbk, GF_FOP_FSYNCDIR,
- fsyncdir, fd, datasync);
+ fsyncdir, fd, fsi->fsync_flags & 1);
return;
}
@@ -1849,10 +2033,11 @@ fuse_statfs_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct statvfs *buf)
{
fuse_state_t *state = NULL;
- fuse_req_t req = NULL;
+ fuse_in_header_t *finh = NULL;
+ struct fuse_statfs_out fso = {{0, }, };
state = frame->root->state;
- req = state->req;
+ finh = state->finh;
/*
Filesystems (like ZFS on solaris) reports
different ->f_frsize and ->f_bsize. Old coreutils
@@ -1881,13 +2066,22 @@ fuse_statfs_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
buf->f_frsize = buf->f_bsize =this->ctx->page_size;
#endif /* GF_DARWIN_HOST_OS */
- fuse_reply_statfs (req, buf);
+ fso.st.bsize = buf->f_bsize;
+ fso.st.frsize = buf->f_frsize;
+ fso.st.blocks = buf->f_blocks;
+ fso.st.bfree = buf->f_bfree;
+ fso.st.bavail = buf->f_bavail;
+ fso.st.files = buf->f_files;
+ fso.st.ffree = buf->f_ffree;
+ fso.st.namelen = buf->f_namemax;
+
+ send_fuse_obj (this, finh, &fso);
} else {
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
- "%"PRId64": ERR => -1 (%s)", frame->root->unique,
+ "%"PRIu64": ERR => -1 (%s)", frame->root->unique,
strerror (op_errno));
- fuse_reply_err (req, op_errno);
+ send_fuse_err (this, finh, op_errno);
}
free_state (state);
@@ -1898,26 +2092,26 @@ fuse_statfs_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
static void
-fuse_statfs (fuse_req_t req, fuse_ino_t ino)
+fuse_statfs (xlator_t *this, fuse_in_header_t *finh, void *msg)
{
fuse_state_t *state = NULL;
int32_t ret = -1;
- STATE_FROM_REQ (req, state);
+ GET_STATE (this, finh, state);
ret = fuse_loc_fill (&state->loc, state, 1, 0, NULL);
if ((state->loc.inode == NULL) ||
(ret < 0)) {
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
"%"PRIu64": STATFS (fuse_loc_fill() fail)",
- req_callid (req));
+ finh->unique);
- fuse_reply_err (req, ENOENT);
+ send_fuse_err (this, finh, ENOENT);
free_state (state);
return;
}
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRIu64": STATFS", req_callid (req));
+ "%"PRIu64": STATFS", finh->unique);
FUSE_FOP (state, fuse_statfs_cbk, GF_FOP_STATFS,
statfs, &state->loc);
@@ -1925,77 +2119,84 @@ fuse_statfs (fuse_req_t req, fuse_ino_t ino)
static void
-fuse_setxattr (fuse_req_t req, fuse_ino_t ino, const char *name,
- const char *value, size_t size, int flags)
+fuse_setxattr (xlator_t *this, fuse_in_header_t *finh, void *msg)
{
+ struct fuse_setxattr_in *fsi = msg;
+ char *name = (char *)(fsi + 1);
+ char *value = name + strlen (name) + 1;
+
fuse_state_t *state = NULL;
char *dict_value = NULL;
int32_t ret = -1;
#ifdef DISABLE_POSIX_ACL
if (!strncmp (name, "system.", 7)) {
- fuse_reply_err (req, EOPNOTSUPP);
+ send_fuse_err (this, finh, EOPNOTSUPP);
return;
}
#endif
- STATE_FROM_REQ (req, state);
- state->size = size;
- ret = fuse_loc_fill (&state->loc, state, ino, 0, NULL);
+ GET_STATE (this, finh, state);
+ state->size = fsi->size;
+ ret = fuse_loc_fill (&state->loc, state, finh->nodeid, 0, NULL);
if ((state->loc.inode == NULL) ||
(ret < 0)) {
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
- "%"PRIu64": SETXATTR %s/%"PRId64" (%s) (fuse_loc_fill() failed)",
- req_callid (req),
- state->loc.path, (int64_t)ino, name);
+ "%"PRIu64": SETXATTR %s/%"PRIu64" (%s) (fuse_loc_fill() failed)",
+ finh->unique,
+ state->loc.path, finh->nodeid, name);
- fuse_reply_err (req, ENOENT);
+ send_fuse_err (this, finh, ENOENT);
free_state (state);
return;
}
state->dict = get_new_dict ();
if (!state->dict) {
- gf_log("glusterfs-fuse", GF_LOG_ERROR,
- "%"PRIu64": SETXATTR dict allocation failed",
- req_callid (req));
+ gf_log ("glusterfs-fuse", GF_LOG_ERROR,
+ "%"PRIu64": SETXATTR dict allocation failed",
+ finh->unique);
free_state (state);
return;
}
- dict_value = memdup (value, size);
+ dict_value = memdup (value, fsi->size);
dict_set (state->dict, (char *)name,
- data_from_dynptr ((void *)dict_value, size));
+ data_from_dynptr ((void *)dict_value, fsi->size));
dict_ref (state->dict);
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRIu64": SETXATTR %s/%"PRId64" (%s)", req_callid (req),
- state->loc.path, (int64_t)ino, name);
+ "%"PRIu64": SETXATTR %s/%"PRIu64" (%s)", finh->unique,
+ state->loc.path, finh->nodeid, name);
FUSE_FOP (state, fuse_err_cbk, GF_FOP_SETXATTR,
- setxattr, &state->loc, state->dict, flags);
+ setxattr, &state->loc, state->dict, fsi->flags);
return;
}
static void
-fuse_reply_xattr_buf (fuse_state_t *state, fuse_req_t req, const char *value,
- size_t ret)
+send_fuse_xattr (xlator_t *this, fuse_in_header_t *finh, const char *value,
+ size_t size, size_t expected)
{
+ struct fuse_getxattr_out fgxo;
+
/* linux kernel limits the size of xattr value to 64k */
- if (ret > GLUSTERFS_XATTR_LEN_MAX)
- fuse_reply_err (req, E2BIG);
- else if (state->size) {
+ if (size > GLUSTERFS_XATTR_LEN_MAX)
+ send_fuse_err (this, finh, E2BIG);
+ else if (expected) {
/* if callback for getxattr and asks for value */
- if (ret > state->size)
+ if (size > expected)
/* reply would be bigger than
* what was asked by kernel */
- fuse_reply_err (req, ERANGE);
+ send_fuse_err (this, finh, ERANGE);
else
- fuse_reply_buf (req, value, ret);
- } else
- fuse_reply_xattr (req, ret);
+ send_fuse_data (this, finh, (void *)value, size);
+ } else {
+ fgxo.size = size;
+ send_fuse_obj (this, finh, &fgxo);
+ }
}
static int
@@ -2005,7 +2206,7 @@ fuse_xattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int need_to_free_dict = 0;
char *value = "";
fuse_state_t *state = NULL;
- fuse_req_t req = NULL;
+ fuse_in_header_t *finh = NULL;
int32_t dummy_ret = 0;
data_t *value_data = NULL;
fuse_private_t *priv = NULL;
@@ -2019,7 +2220,7 @@ fuse_xattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
priv = this->private;
ret = op_ret;
state = frame->root->state;
- req = state->req;
+ finh = state->finh;
dummy_ret = 0;
#ifdef GF_DARWIN_HOST_OS
@@ -2048,7 +2249,7 @@ fuse_xattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
if (ret >= 0) {
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRId64": %s() %s => %d", frame->root->unique,
+ "%"PRIu64": %s() %s => %d", frame->root->unique,
gf_fop_list[frame->root->op], state->loc.path, op_ret);
/* if successful */
@@ -2059,7 +2260,7 @@ fuse_xattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
ret = value_data->len; /* Don't return the value for '\0' */
value = value_data->data;
- fuse_reply_xattr_buf (state, req, value, ret);
+ send_fuse_xattr (this, finh, value, ret, state->size);
/* if(ret >...)...else if...else */
} else if (!strcmp (state->name, "user.glusterfs-booster-volfile")) {
if (!priv->volfile) {
@@ -2070,7 +2271,7 @@ fuse_xattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
gf_log (this->name,
GF_LOG_ERROR,
"fstat on fd (%d) failed (%s)", fd, strerror (errno));
- fuse_reply_err (req, ENODATA);
+ send_fuse_err (this, finh, ENODATA);
}
priv->volfile_size = st.st_size;
@@ -2081,16 +2282,17 @@ fuse_xattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
}
}
- fuse_reply_xattr_buf (state, req, priv->volfile, priv->volfile_size);
+ send_fuse_xattr (this, finh, priv->volfile,
+ priv->volfile_size, state->size);
/* if(ret >...)...else if...else */
} else if (!strcmp (state->name, "user.glusterfs-booster-path")) {
- fuse_reply_xattr_buf (state, req, state->loc.path,
- strlen (state->loc.path) + 1);
+ send_fuse_xattr (this, finh, state->loc.path,
+ strlen (state->loc.path) + 1, state->size);
} else if (!strcmp (state->name, "user.glusterfs-booster-mount")) {
- fuse_reply_xattr_buf (state, req, priv->mount_point,
- strlen(priv->mount_point) + 1);
+ send_fuse_xattr (this, finh, priv->mount_point,
+ strlen (priv->mount_point) + 1, state->size);
} else {
- fuse_reply_err (req, ENODATA);
+ send_fuse_err (this, finh, ENODATA);
} /* if(value_data)...else */
} else {
/* if callback for listxattr */
@@ -2109,7 +2311,7 @@ fuse_xattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
len += strlen (trav->key) + 1;
trav = trav->next;
} /* while(trav) */
- fuse_reply_xattr_buf (state, req, value, len);
+ send_fuse_xattr (this, finh, value, len, state->size);
} /* if(state->name)...else */
} else {
/* if failure - no need to check if listxattr or getxattr */
@@ -2126,20 +2328,20 @@ fuse_xattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
else
{
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
- "%"PRId64": %s() %s => -1 (%s)",
+ "%"PRIu64": %s() %s => -1 (%s)",
frame->root->unique,
gf_fop_list[frame->root->op],
state->loc.path, strerror (op_errno));
}
} else {
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
- "%"PRId64": %s() %s => -1 (%s)",
+ "%"PRIu64": %s() %s => -1 (%s)",
frame->root->unique,
gf_fop_list[frame->root->op], state->loc.path,
strerror (op_errno));
} /* if(op_errno!= ENODATA)...else */
- fuse_reply_err (req, op_errno);
+ send_fuse_err (this, finh, op_errno);
} /* if(op_ret>=0)...else */
if (need_to_free_dict)
@@ -2153,37 +2355,40 @@ fuse_xattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
static void
-fuse_getxattr (fuse_req_t req, fuse_ino_t ino, const char *name, size_t size)
+fuse_getxattr (xlator_t *this, fuse_in_header_t *finh, void *msg)
{
+ struct fuse_getxattr_in *fgxi = msg;
+ char *name = (char *)(msg + 1);
+
fuse_state_t *state = NULL;
int32_t ret = -1;
#ifdef DISABLE_POSIX_ACL
if (!strncmp (name, "system.", 7)) {
- fuse_reply_err (req, ENODATA);
+ send_fuse_err (this, finh, ENODATA);
return;
}
#endif
- STATE_FROM_REQ (req, state);
- state->size = size;
+ GET_STATE (this, finh, state);
+ state->size = fgxi->size;
state->name = strdup (name);
- ret = fuse_loc_fill (&state->loc, state, ino, 0, NULL);
+ ret = fuse_loc_fill (&state->loc, state, finh->nodeid, 0, NULL);
if ((state->loc.inode == NULL) ||
(ret < 0)) {
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
- "%"PRIu64": GETXATTR %s/%"PRId64" (%s) (fuse_loc_fill() failed)",
- req_callid (req), state->loc.path, (int64_t)ino, name);
+ "%"PRIu64": GETXATTR %s/%"PRIu64" (%s) (fuse_loc_fill() failed)",
+ finh->unique, state->loc.path, finh->nodeid, name);
- fuse_reply_err (req, ENOENT);
+ send_fuse_err (this, finh, ENOENT);
free_state (state);
return;
}
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRIu64": GETXATTR %s/%"PRId64" (%s)", req_callid (req),
- state->loc.path, (int64_t)ino, name);
+ "%"PRIu64": GETXATTR %s/%"PRIu64" (%s)", finh->unique,
+ state->loc.path, finh->nodeid, name);
FUSE_FOP (state, fuse_xattr_cbk, GF_FOP_GETXATTR,
getxattr, &state->loc, name);
@@ -2193,28 +2398,30 @@ fuse_getxattr (fuse_req_t req, fuse_ino_t ino, const char *name, size_t size)
static void
-fuse_listxattr (fuse_req_t req, fuse_ino_t ino, size_t size)
+fuse_listxattr (xlator_t *this, fuse_in_header_t *finh, void *msg)
{
+ struct fuse_getxattr_in *fgxi = msg;
+
fuse_state_t *state = NULL;
int32_t ret = -1;
- STATE_FROM_REQ (req, state);
- state->size = size;
- ret = fuse_loc_fill (&state->loc, state, ino, 0, NULL);
+ GET_STATE (this, finh, state);
+ state->size = fgxi->size;
+ ret = fuse_loc_fill (&state->loc, state, finh->nodeid, 0, NULL);
if ((state->loc.inode == NULL) ||
(ret < 0)) {
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
- "%"PRIu64": LISTXATTR %s/%"PRId64" (fuse_loc_fill() failed)",
- req_callid (req), state->loc.path, (int64_t)ino);
+ "%"PRIu64": LISTXATTR %s/%"PRIu64" (fuse_loc_fill() failed)",
+ finh->unique, state->loc.path, finh->nodeid);
- fuse_reply_err (req, ENOENT);
+ send_fuse_err (this, finh, ENOENT);
free_state (state);
return;
}
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRIu64": LISTXATTR %s/%"PRId64, req_callid (req),
- state->loc.path, (int64_t)ino);
+ "%"PRIu64": LISTXATTR %s/%"PRIu64, finh->unique,
+ state->loc.path, finh->nodeid);
FUSE_FOP (state, fuse_xattr_cbk, GF_FOP_GETXATTR,
getxattr, &state->loc, NULL);
@@ -2224,28 +2431,30 @@ fuse_listxattr (fuse_req_t req, fuse_ino_t ino, size_t size)
static void
-fuse_removexattr (fuse_req_t req, fuse_ino_t ino, const char *name)
+fuse_removexattr (xlator_t *this, fuse_in_header_t *finh, void *msg)
{
+ char *name = msg;
+
fuse_state_t *state = NULL;
int32_t ret = -1;
- STATE_FROM_REQ (req, state);
- ret = fuse_loc_fill (&state->loc, state, ino, 0, NULL);
+ GET_STATE (this, finh, state);
+ ret = fuse_loc_fill (&state->loc, state, finh->nodeid, 0, NULL);
if ((state->loc.inode == NULL) ||
(ret < 0)) {
gf_log ("glusterfs-fuse", GF_LOG_DEBUG,
- "%"PRIu64": REMOVEXATTR %s/%"PRId64" (%s) (fuse_loc_fill() failed)",
- req_callid (req), state->loc.path, (int64_t)ino, name);
+ "%"PRIu64": REMOVEXATTR %s/%"PRIu64" (%s) (fuse_loc_fill() failed)",
+ finh->unique, state->loc.path, finh->nodeid, name);
- fuse_reply_err (req, ENOENT);
+ send_fuse_err (this, finh, ENOENT);
free_state (state);
return;
}
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRIu64": REMOVEXATTR %s/%"PRId64" (%s)", req_callid (req),
- state->loc.path, (int64_t)ino, name);
+ "%"PRIu64": REMOVEXATTR %s/%"PRIu64" (%s)", finh->unique,
+ state->loc.path, finh->nodeid, name);
FUSE_FOP (state, fuse_err_cbk, GF_FOP_REMOVEXATTR,
removexattr, &state->loc, name);
@@ -2263,11 +2472,22 @@ fuse_getlk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
fuse_state_t *state = NULL;
state = frame->root->state;
+ struct fuse_lk_out flo = {{0, }, };
if (op_ret == 0) {
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRId64": ERR => 0", frame->root->unique);
- fuse_reply_lock (state->req, lock);
+ "%"PRIu64": ERR => 0", frame->root->unique);
+ flo.lk.type = lock->l_type;
+ flo.lk.pid = lock->l_pid;
+ if (lock->l_type == F_UNLCK)
+ flo.lk.start = flo.lk.end = 0;
+ else {
+ flo.lk.start = lock->l_start;
+ flo.lk.end = lock->l_len ?
+ (lock->l_start + lock->l_len - 1) :
+ OFFSET_MAX;
+ }
+ send_fuse_obj (this, state->finh, &flo);
} else {
if (op_errno == ENOSYS) {
gf_fuse_lk_enosys_log++;
@@ -2279,10 +2499,10 @@ fuse_getlk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
}
} else {
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
- "%"PRId64": ERR => -1 (%s)",
+ "%"PRIu64": ERR => -1 (%s)",
frame->root->unique, strerror (op_errno));
}
- fuse_reply_err (state->req, op_errno);
+ send_fuse_err (this, state->finh, op_errno);
}
free_state (state);
@@ -2292,23 +2512,40 @@ fuse_getlk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
}
+/* courtesy of fuse */
+static void
+convert_fuse_file_lock (struct fuse_file_lock *fl, struct flock *flock)
+{
+ memset (flock, 0, sizeof (struct flock));
+ flock->l_type = fl->type;
+ flock->l_whence = SEEK_SET;
+ flock->l_start = fl->start;
+ if (fl->end == OFFSET_MAX)
+ flock->l_len = 0;
+ else
+ flock->l_len = fl->end - fl->start + 1;
+ flock->l_pid = fl->pid;
+}
+
static void
-fuse_getlk (fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi,
- struct flock *lock)
+fuse_getlk (xlator_t *this, fuse_in_header_t *finh, void *msg)
{
+ struct fuse_lk_in *fli = msg;
+
fuse_state_t *state = NULL;
fd_t *fd = NULL;
+ struct flock lock = {0, };
- fd = FI_TO_FD (fi);
- STATE_FROM_REQ (req, state);
- state->req = req;
+ fd = FH_TO_FD (fli->fh);
+ GET_STATE (this, finh, state);
state->fd = fd;
+ convert_fuse_file_lock (&fli->lk, &lock);
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRIu64": GETLK %p", req_callid (req), fd);
+ "%"PRIu64": GETLK %p", finh->unique, fd);
FUSE_FOP (state, fuse_getlk_cbk, GF_FOP_LK,
- lk, fd, F_GETLK, lock);
+ lk, fd, F_GETLK, &lock);
return;
}
@@ -2324,8 +2561,8 @@ fuse_setlk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
if (op_ret == 0) {
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRId64": ERR => 0", frame->root->unique);
- fuse_reply_err (state->req, 0);
+ "%"PRIu64": ERR => 0", frame->root->unique);
+ send_fuse_err (this, state->finh, 0);
} else {
if (op_errno == ENOSYS) {
gf_fuse_lk_enosys_log++;
@@ -2337,11 +2574,11 @@ fuse_setlk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
}
} else {
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
- "%"PRId64": ERR => -1 (%s)",
+ "%"PRIu64": ERR => -1 (%s)",
frame->root->unique, strerror (op_errno));
}
- fuse_reply_err (state->req, op_errno);
+ send_fuse_err (this, state->finh, op_errno);
}
free_state (state);
@@ -2352,76 +2589,102 @@ fuse_setlk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
static void
-fuse_setlk (fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi,
- struct flock *lock, int sleep)
+fuse_setlk (xlator_t *this, fuse_in_header_t *finh, void *msg)
{
+ struct fuse_lk_in *fli = msg;
+
fuse_state_t *state = NULL;
fd_t *fd = NULL;
+ struct flock lock = {0, };
- fd = FI_TO_FD (fi);
- STATE_FROM_REQ (req, state);
- state->req = req;
+ fd = FH_TO_FD (fli->fh);
+ GET_STATE (this, finh, state);
+ state->finh = finh;
state->fd = fd;
+ convert_fuse_file_lock (&fli->lk, &lock);
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRIu64": SETLK %p (sleep=%d)", req_callid (req), fd,
- sleep);
+ "%"PRIu64": SETLK%s %p", finh->unique,
+ finh->opcode == FUSE_SETLK ? "" : "W", fd);
FUSE_FOP (state, fuse_setlk_cbk, GF_FOP_LK,
- lk, fd, (sleep ? F_SETLKW : F_SETLK), lock);
+ lk, fd, finh->opcode == FUSE_SETLK ? F_SETLK : F_SETLKW,
+ &lock);
return;
}
static void
-fuse_init (void *data, struct fuse_conn_info *conn)
+fuse_init (xlator_t *this, fuse_in_header_t *finh, void *msg)
{
- return;
+ struct fuse_init_in *fini = msg;
+
+ struct fuse_init_out fino;
+ fuse_private_t *priv = NULL;
+ int ret;
+
+ priv = this->private;
+
+ if (!priv->first_call) {
+ gf_log ("glusterfs-fuse", GF_LOG_ERROR,
+ "got INIT after first message");
+
+ close (priv->fd);
+ goto out;
+ }
+
+ if (fini->major != FUSE_KERNEL_VERSION ||
+ fini->minor < 9) {
+ gf_log ("glusterfs-fuse", GF_LOG_ERROR,
+ "unsupported FUSE protocol version %d.%d",
+ fini->major, fini->minor);
+
+ close (priv->fd);
+ goto out;
+ }
+
+ fino.major = FUSE_KERNEL_VERSION;
+ fino.minor = FUSE_KERNEL_MINOR_VERSION;
+ fino.max_readahead = 1 << 17;
+ fino.max_write = 1 << 17;
+ fino.flags = FUSE_ASYNC_READ | FUSE_POSIX_LOCKS | FUSE_BIG_WRITES;
+
+ ret = send_fuse_obj (this, finh, &fino);
+ if (ret == 0)
+ gf_log ("glusterfs-fuse", GF_LOG_INFO,
+ "FUSE inited with protocol versions:"
+ " glusterfs %d.%d kernel %d.%d",
+ FUSE_KERNEL_VERSION, FUSE_KERNEL_MINOR_VERSION,
+ fini->major, fini->minor);
+ else {
+ gf_log ("glusterfs-fuse", GF_LOG_ERROR,
+ "FUSE init failed (%s)", strerror (ret));
+
+ close (priv->fd);
+ }
+
+ out:
+ FREE (finh);
}
+
static void
-fuse_destroy (void *data)
-{
-
-}
-
-static struct fuse_lowlevel_ops fuse_ops = {
- .init = fuse_init,
- .destroy = fuse_destroy,
- .lookup = fuse_lookup,
- .forget = fuse_forget,
- .getattr = fuse_getattr,
- .setattr = fuse_setattr,
- .opendir = fuse_opendir,
- .readdir = fuse_readdir,
- .releasedir = fuse_releasedir,
- .access = fuse_access,
- .readlink = fuse_readlink,
- .mknod = fuse_mknod,
- .mkdir = fuse_mkdir,
- .unlink = fuse_unlink,
- .rmdir = fuse_rmdir,
- .symlink = fuse_symlink,
- .rename = fuse_rename,
- .link = fuse_link,
- .create = fuse_create,
- .open = fuse_open,
- .read = fuse_readv,
- .write = fuse_write,
- .flush = fuse_flush,
- .release = fuse_release,
- .fsync = fuse_fsync,
- .fsyncdir = fuse_fsyncdir,
- .statfs = fuse_statfs,
- .setxattr = fuse_setxattr,
- .getxattr = fuse_getxattr,
- .listxattr = fuse_listxattr,
- .removexattr = fuse_removexattr,
- .getlk = fuse_getlk,
- .setlk = fuse_setlk
-};
+fuse_enosys (xlator_t *this, fuse_in_header_t *finh, void *msg)
+{
+ send_fuse_err (this, finh, ENOSYS);
+ FREE (finh);
+}
+
+
+static void
+fuse_discard (xlator_t *this, fuse_in_header_t *finh, void *msg)
+{
+ FREE (finh);
+}
+
+static fuse_handler_t *fuse_ops[FUSE_711_OP_HIGH];
int
fuse_root_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
@@ -2493,33 +2756,44 @@ fuse_root_lookup (xlator_t *this)
}
+
static void *
fuse_thread_proc (void *data)
{
char *mount_point = NULL;
xlator_t *this = NULL;
fuse_private_t *priv = NULL;
- int32_t res = 0;
+ ssize_t res = 0;
struct iobuf *iobuf = NULL;
- size_t chan_size = 0;
+ fuse_in_header_t *finh;
+ struct iovec iov_in[2];
this = data;
priv = this->private;
- chan_size = fuse_chan_bufsize (priv->ch);
THIS = this;
- while (!fuse_session_exited (priv->se)) {
+ iov_in[0].iov_len = sizeof (fuse_in_header_t);
+ iov_in[1].iov_len = ((struct iobuf_pool *)this->ctx->iobuf_pool)
+ ->page_size;
+
+ for (;;) {
iobuf = iobuf_get (this->ctx->iobuf_pool);
+ iov_in[0].iov_base = CALLOC (1, sizeof (*finh));
- if (!iobuf) {
+ if (!iobuf || !iov_in[0].iov_base) {
gf_log (this->name, GF_LOG_ERROR,
"Out of memory");
+ if (iobuf)
+ iobuf_unref (iobuf);
+ FREE (iov_in[0].iov_base);
sleep (10);
continue;
}
- res = fuse_chan_receive (priv->ch, iobuf->ptr, chan_size);
+ iov_in[1].iov_base = iobuf->ptr;
+
+ res = readv (priv->fd, iov_in, 2);
if (priv->first_call) {
if (priv->first_call > 1) {
@@ -2532,25 +2806,35 @@ fuse_thread_proc (void *data)
if (res == -1) {
if (errno != EINTR) {
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
- "fuse_chan_receive() returned -1 (%d)", errno);
+ "read from /dev/fuse returned -1 (%d)", errno);
}
- if (errno == ENODEV) {
- iobuf_unref (iobuf);
+ if (errno == ENODEV || errno == EBADF)
break;
- }
+ iobuf_unref (iobuf);
+ FREE (iov_in[0].iov_base);
continue;
}
+ if (res < sizeof (finh)) {
+ gf_log ("glusterfs-fuse", GF_LOG_WARNING, "short read on /dev/fuse");
+ break;
+ }
+
+ finh = (fuse_in_header_t *)iov_in[0].iov_base;
+ if (res != finh->len) {
+ gf_log ("glusterfs-fuse", GF_LOG_WARNING, "inconsistent read on /dev/fuse");
+ break;
+ }
priv->iobuf = iobuf;
- if (res && res != -1) {
- fuse_session_process (priv->se, iobuf->ptr,
- res, priv->ch);
- }
+ fuse_ops[finh->opcode] (this, finh, iov_in[1].iov_base);
iobuf_unref (iobuf);
}
+ iobuf_unref (iobuf);
+ FREE (iov_in[0].iov_base);
+
if (dict_get (this->options, ZR_MOUNTPOINT_OPT))
mount_point = data_to_str (dict_get (this->options,
ZR_MOUNTPOINT_OPT));
@@ -2560,10 +2844,6 @@ fuse_thread_proc (void *data)
dict_del (this->options, ZR_MOUNTPOINT_OPT);
}
- fuse_session_remove_chan (priv->ch);
- fuse_session_destroy (priv->se);
- // fuse_unmount (priv->mount_point, priv->ch);
-
raise (SIGTERM);
return NULL;
@@ -2628,18 +2908,6 @@ notify (xlator_t *this, int32_t event, void *data, ...)
return 0;
}
-static struct fuse_opt subtype_workaround[] = {
- FUSE_OPT_KEY ("subtype=", 0),
- FUSE_OPT_KEY ("fssubtype=", 0),
- FUSE_OPT_END
-};
-
-static int
-subtype_workaround_optproc (void *data, const char *arg, int key,
- struct fuse_args *outargs)
-{
- return key ? 1 : 0;
-}
int
init (xlator_t *this_xl)
@@ -2648,10 +2916,10 @@ init (xlator_t *this_xl)
dict_t *options = NULL;
char *value_string = NULL;
char *fsname = NULL;
- char *fsname_opt = NULL;
+ char *mount_param = NULL;
fuse_private_t *priv = NULL;
struct stat stbuf = {0,};
- struct fuse_args args = FUSE_ARGS_INIT (0, NULL);
+ int i = 0;
int xl_name_allocated = 0;
if (this_xl == NULL)
@@ -2665,78 +2933,24 @@ init (xlator_t *this_xl)
if (this_xl->name == NULL) {
this_xl->name = strdup ("fuse");
if (!this_xl->name) {
- gf_log("glusterfs-fuse", GF_LOG_ERROR,
- "Out of memory");
+ gf_log ("glusterfs-fuse", GF_LOG_ERROR,
+ "Out of memory");
goto cleanup_exit;
}
xl_name_allocated = 1;
}
- fsname = this_xl->ctx->cmd_args.volume_file;
- fsname = (fsname ? fsname : this_xl->ctx->cmd_args.volfile_server);
- fsname = (fsname ? fsname : "glusterfs");
- ret = asprintf (&fsname_opt, "-ofsname=%s", fsname);
-
- if (ret != -1)
- ret = fuse_opt_add_arg (&args, "glusterfs");
- if (ret != -1)
- ret = fuse_opt_add_arg (&args, fsname_opt);
- if (ret != -1)
- ret = fuse_opt_add_arg (&args, "-oallow_other");
- if (ret != -1)
- ret = fuse_opt_add_arg (&args, "-odefault_permissions");
-#ifdef GF_DARWIN_HOST_OS
- if (ret != -1)
- ret = fuse_opt_add_arg (&args, "-ofssubtype=glusterfs");
- if (ret != -1 && !dict_get (options, "macfuse-local"))
- /* This way, GlusterFS will be detected as 'servers' instead
- * of 'devices'. This method is useful if you want to do
- * 'umount <mount_point>' over network, instead of 'eject'ing
- * it from desktop. Works better for servers
- */
- ret = fuse_opt_add_arg (&args, "-olocal");
-#else /* ! DARWIN_OS */
- if (ret != -1)
- ret = fuse_opt_add_arg (&args, "-osubtype=glusterfs");
- if (ret != -1)
- ret = fuse_opt_add_arg (&args, "-omax_readahead=131072");
- if (ret != -1)
- ret = fuse_opt_add_arg (&args, "-omax_read=131072");
- if (ret != -1)
- ret = fuse_opt_add_arg (&args, "-omax_write=131072");
- if (ret != -1)
- ret = fuse_opt_add_arg (&args, "-osuid");
-#if GF_LINUX_HOST_OS /* LINUX */
- /* '-o dev', '-o nonempty' is supported only on Linux */
- if (ret != -1)
- ret = fuse_opt_add_arg (&args, "-ononempty");
- if (ret != -1)
- ret = fuse_opt_add_arg (&args, "-odev");
-#ifdef HAVE_FUSE_VERSION_28
- if (ret != -1)
- ret = fuse_opt_add_arg (&args, "-obig_writes");
-#endif /* FUSE 2.8 */
-
-#endif /* LINUX */
-#endif /* ! DARWIN_OS */
-
- if (ret == -1) {
- gf_log("glusterfs-fuse", GF_LOG_ERROR,
- "Out of memory");
-
- goto cleanup_exit;
- }
-
priv = CALLOC (1, sizeof (*priv));
if (!priv) {
- gf_log("glusterfs-fuse", GF_LOG_ERROR,
- "Out of memory");
+ gf_log ("glusterfs-fuse", GF_LOG_ERROR,
+ "Out of memory");
goto cleanup_exit;
}
this_xl->private = (void *) priv;
priv->mount_point = NULL;
+ priv->fd = -1;
/* get options from option dictionary */
ret = dict_get_str (options, ZR_MOUNTPOINT_OPT, &value_string);
@@ -2773,8 +2987,8 @@ init (xlator_t *this_xl)
}
priv->mount_point = strdup (value_string);
if (!priv->mount_point) {
- gf_log("glusterfs-fuse", GF_LOG_ERROR,
- "Out of memory");
+ gf_log ("glusterfs-fuse", GF_LOG_ERROR,
+ "Out of memory");
goto cleanup_exit;
}
@@ -2803,102 +3017,97 @@ init (xlator_t *this_xl)
&priv->strict_volfile_check);
}
+ fsname = this_xl->ctx->cmd_args.volume_file;
+ fsname = (fsname ? fsname : this_xl->ctx->cmd_args.volfile_server);
+ fsname = (fsname ? fsname : "glusterfs");
+
this_xl->itable = inode_table_new (0, this_xl);
if (!this_xl->itable) {
- gf_log("glusterfs-fuse", GF_LOG_ERROR,
- "Out of memory");
+ gf_log ("glusterfs-fuse", GF_LOG_ERROR,
+ "Out of memory");
goto cleanup_exit;
}
- priv->ch = fuse_mount (priv->mount_point, &args);
- if (priv->ch == NULL) {
- if (errno == ENOTCONN) {
- gf_log ("glusterfs-fuse", GF_LOG_ERROR,
- "A stale mount is present on %s. "
- "Run 'umount %s' and try again",
- priv->mount_point,
- priv->mount_point);
- } else {
- if (errno == ENOENT) {
- gf_log ("glusterfs-fuse", GF_LOG_ERROR,
- "Unable to mount on %s. Run "
- "'modprobe fuse' and try again",
- priv->mount_point);
- } else {
- gf_log ("glusterfs-fuse", GF_LOG_DEBUG,
- "fuse_mount() failed with error %s "
- "on mount point %s",
- strerror (errno),
- priv->mount_point);
- }
- }
+ priv->fd = open ("/dev/fuse", O_RDWR);
+ if (priv->fd == -1) {
+ gf_log ("glusterfs-fuse", GF_LOG_ERROR,
+ "cannot open /dev/fuse (%s)", strerror (errno));
goto cleanup_exit;
}
+ ret = asprintf (&mount_param,
+ "allow_other,default_permissions,max_read=131072,"
+ "fd=%i,rootmode=%o,user_id=%i,group_id=%i",
+ priv->fd, stbuf.st_mode & S_IFMT, getuid (), getgid ());
+ if (ret == -1) {
+ gf_log ("glusterfs-fuse", GF_LOG_ERROR,
+ "Out of memory");
- errno = 0;
-
- priv->se = fuse_lowlevel_new (&args, &fuse_ops,
- sizeof (fuse_ops), this_xl);
- if (priv->se == NULL && !errno) {
- /*
- * Option parsing misery. Can happen if libfuse is of
- * FUSE < 2.7.0, as then the "-o subtype" option is not
- * handled.
- *
- * Best we can do to is to handle it at runtime -- this is not
- * a binary incompatibility issue (which should dealt with at
- * compile time), but a behavioural incompatibility issue. Ie.
- * we can't tell in advance whether the lib we use supports
- * "-o subtype". So try to be clever now.
- *
- * Delete the subtype option, and try again.
- */
- if (fuse_opt_parse (&args, NULL, subtype_workaround,
- subtype_workaround_optproc) == 0)
- priv->se = fuse_lowlevel_new (&args, &fuse_ops,
- sizeof (fuse_ops),
- this_xl);
- }
-
- if (priv->se == NULL) {
- gf_log ("glusterfs-fuse", GF_LOG_DEBUG,
- "fuse_lowlevel_new() failed with error %s on "
- "mount point %s",
- strerror (errno), priv->mount_point);
- goto umount_exit;
+ goto cleanup_exit;
}
-
- ret = fuse_set_signal_handlers (priv->se);
+ ret = mount (fsname, priv->mount_point, "fuse.glusterfs", 0,
+ mount_param);
if (ret == -1) {
- gf_log ("glusterfs-fuse", GF_LOG_DEBUG,
- "fuse_set_signal_handlers() failed on mount point %s",
- priv->mount_point);
- goto umount_exit;
- }
-
- fuse_opt_free_args (&args);
- FREE (fsname_opt);
+ gf_log ("glusterfs-fuse", GF_LOG_ERROR,
+ "mount failed (%s)", strerror (errno));
- fuse_session_add_chan (priv->se, priv->ch);
+ goto cleanup_exit;
+ }
- priv->fd = fuse_chan_fd (priv->ch);
+ FREE (mount_param);
this_xl->ctx->top = this_xl;
priv->first_call = 2;
+
+ for (i = 0; i < FUSE_711_OP_HIGH; i++)
+ fuse_ops[i] = fuse_enosys;
+ fuse_ops[FUSE_INIT] = fuse_init;
+ fuse_ops[FUSE_DESTROY] = fuse_discard;
+ fuse_ops[FUSE_LOOKUP] = fuse_lookup;
+ fuse_ops[FUSE_FORGET] = fuse_forget;
+ fuse_ops[FUSE_GETATTR] = fuse_getattr;
+ fuse_ops[FUSE_SETATTR] = fuse_setattr;
+ fuse_ops[FUSE_OPENDIR] = fuse_opendir;
+ fuse_ops[FUSE_READDIR] = fuse_readdir;
+ fuse_ops[FUSE_RELEASEDIR] = fuse_releasedir;
+ fuse_ops[FUSE_ACCESS] = fuse_access;
+ fuse_ops[FUSE_READLINK] = fuse_readlink;
+ fuse_ops[FUSE_MKNOD] = fuse_mknod;
+ fuse_ops[FUSE_MKDIR] = fuse_mkdir;
+ fuse_ops[FUSE_UNLINK] = fuse_unlink;
+ fuse_ops[FUSE_RMDIR] = fuse_rmdir;
+ fuse_ops[FUSE_SYMLINK] = fuse_symlink;
+ fuse_ops[FUSE_RENAME] = fuse_rename;
+ fuse_ops[FUSE_LINK] = fuse_link;
+ fuse_ops[FUSE_CREATE] = fuse_create;
+ fuse_ops[FUSE_OPEN] = fuse_open;
+ fuse_ops[FUSE_READ] = fuse_readv;
+ fuse_ops[FUSE_WRITE] = fuse_write;
+ fuse_ops[FUSE_FLUSH] = fuse_flush;
+ fuse_ops[FUSE_RELEASE] = fuse_release;
+ fuse_ops[FUSE_FSYNC] = fuse_fsync;
+ fuse_ops[FUSE_FSYNCDIR] = fuse_fsyncdir;
+ fuse_ops[FUSE_STATFS] = fuse_statfs;
+ fuse_ops[FUSE_SETXATTR] = fuse_setxattr;
+ fuse_ops[FUSE_GETXATTR] = fuse_getxattr;
+ fuse_ops[FUSE_LISTXATTR] = fuse_listxattr;
+ fuse_ops[FUSE_REMOVEXATTR] = fuse_removexattr;
+ fuse_ops[FUSE_GETLK] = fuse_getlk;
+ fuse_ops[FUSE_SETLK] = fuse_setlk;
+ fuse_ops[FUSE_SETLKW] = fuse_setlk;
+
return 0;
-umount_exit:
- fuse_unmount (priv->mount_point, priv->ch);
cleanup_exit:
if (xl_name_allocated)
FREE (this_xl->name);
- fuse_opt_free_args (&args);
- FREE (fsname_opt);
- if (priv)
+ FREE (mount_param);
+ if (priv) {
FREE (priv->mount_point);
+ close (priv->fd);
+ }
FREE (priv);
return -1;
}
@@ -2916,6 +3125,8 @@ fini (xlator_t *this_xl)
if ((priv = this_xl->private) == NULL)
return;
+ close (priv->fd);
+
if (dict_get (this_xl->options, ZR_MOUNTPOINT_OPT))
mount_point = data_to_str (dict_get (this_xl->options,
ZR_MOUNTPOINT_OPT));
@@ -2924,8 +3135,7 @@ fini (xlator_t *this_xl)
"Unmounting '%s'.", mount_point);
dict_del (this_xl->options, ZR_MOUNTPOINT_OPT);
- fuse_session_exit (priv->se);
- fuse_unmount (mount_point, priv->ch);
+ umount (mount_point);
}
}
diff --git a/xlators/mount/fuse/src/fuse-extra.c b/xlators/mount/fuse/src/fuse-extra.c
deleted file mode 100644
index 422ff4b563d..00000000000
--- a/xlators/mount/fuse/src/fuse-extra.c
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- Copyright (c) 2006-2009 Z RESEARCH, Inc. <http://www.zresearch.com>
- This file is part of GlusterFS.
-
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _CONFIG_H
-#define _CONFIG_H
-#include "config.h"
-#endif /* _CONFIG_H */
-
-#include "fuse-extra.h"
-#include "common-utils.h"
-#include <stdio.h>
-#include <pthread.h>
-#include <stdlib.h>
-#include <string.h>
-#include "common-utils.h"
-
-struct fuse_req;
-struct fuse_ll;
-
-struct fuse_req {
- struct fuse_ll *f;
- uint64_t unique;
- int ctr;
- pthread_mutex_t lock;
- struct fuse_ctx ctx;
- struct fuse_chan *ch;
- int interrupted;
- union {
- struct {
- uint64_t unique;
- } i;
- struct {
- fuse_interrupt_func_t func;
- void *data;
- } ni;
- } u;
- struct fuse_req *next;
- struct fuse_req *prev;
-};
-
-#ifdef HAVE_FUSE_VERSION_28
-struct fuse_ll {
- int debug;
- int allow_root;
- int atomic_o_trunc;
- int big_writes;
- struct fuse_lowlevel_ops op;
- int got_init;
- void *userdata;
- uid_t owner;
- struct fuse_conn_info conn;
- struct fuse_req list;
- struct fuse_req interrupts;
- pthread_mutex_t lock;
- int got_destroy;
-};
-#else
-struct fuse_ll {
- int debug;
- int allow_root;
- struct fuse_lowlevel_ops op;
- int got_init;
- void *userdata;
- uid_t owner;
- struct fuse_conn_info conn;
- struct fuse_req list;
- struct fuse_req interrupts;
- pthread_mutex_t lock;
- int got_destroy;
-};
-#endif /* FUSE 2.8 */
-
-struct fuse_out_header {
- uint32_t len;
- int32_t error;
- uint64_t unique;
-};
-
-uint64_t req_callid (fuse_req_t req)
-{
- return req->unique;
-}
-
-static void destroy_req(fuse_req_t req)
-{
- pthread_mutex_destroy (&req->lock);
- FREE (req);
-}
-
-static void list_del_req(struct fuse_req *req)
-{
- struct fuse_req *prev = req->prev;
- struct fuse_req *next = req->next;
- prev->next = next;
- next->prev = prev;
-}
-
-static void
-free_req (fuse_req_t req)
-{
- int ctr;
- struct fuse_ll *f = req->f;
-
- pthread_mutex_lock(&req->lock);
- req->u.ni.func = NULL;
- req->u.ni.data = NULL;
- pthread_mutex_unlock(&req->lock);
-
- pthread_mutex_lock(&f->lock);
- list_del_req(req);
- ctr = --req->ctr;
- pthread_mutex_unlock(&f->lock);
- if (!ctr)
- destroy_req(req);
-}
-
-int32_t
-fuse_reply_vec (fuse_req_t req,
- struct iovec *vector,
- int32_t count)
-{
- int32_t error = 0;
- struct fuse_out_header out;
- struct iovec *iov;
- int res;
-
- iov = alloca ((count + 1) * sizeof (*vector));
- out.unique = req->unique;
- out.error = error;
- iov[0].iov_base = &out;
- iov[0].iov_len = sizeof(struct fuse_out_header);
- memcpy (&iov[1], vector, count * sizeof (*vector));
- count++;
- out.len = iov_length(iov, count);
- res = fuse_chan_send(req->ch, iov, count);
- free_req(req);
-
- return res;
-}
diff --git a/xlators/mount/fuse/src/fuse-extra.h b/xlators/mount/fuse/src/fuse-extra.h
deleted file mode 100644
index 5688e34c76d..00000000000
--- a/xlators/mount/fuse/src/fuse-extra.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- Copyright (c) 2007-2009 Z RESEARCH, Inc. <http://www.zresearch.com>
- This file is part of GlusterFS.
-
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _FUSE_EXTRA_H
-#define _FUSE_EXTRA_H
-
-#ifndef _CONFIG_H
-#define _CONFIG_H
-#include "config.h"
-#endif /* _CONFIG_H */
-
-#include <stdlib.h>
-#include <fuse/fuse_lowlevel.h>
-
-#define GLUSTERFS_XATTR_LEN_MAX 65536
-
-uint64_t req_callid (fuse_req_t req);
-
-size_t fuse_dirent_size (size_t dname_len);
-
-int32_t
-fuse_reply_vec (fuse_req_t req,
- struct iovec *vector,
- int32_t count);
-
-#endif /* _FUSE_EXTRA_H */
diff --git a/xlators/mount/fuse/src/fuse_kernel.h b/xlators/mount/fuse/src/fuse_kernel.h
new file mode 100644
index 00000000000..df558e394ff
--- /dev/null
+++ b/xlators/mount/fuse/src/fuse_kernel.h
@@ -0,0 +1,509 @@
+/*
+ This file defines the kernel interface of FUSE
+ Copyright (C) 2001-2008 Miklos Szeredi <miklos@szeredi.hu>
+
+ This program can be distributed under the terms of the GNU GPL.
+ See the file COPYING.
+
+ This -- and only this -- header file may also be distributed under
+ the terms of the BSD Licence as follows:
+
+ Copyright (C) 2001-2007 Miklos Szeredi. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+*/
+
+/*
+ * This file defines the kernel interface of FUSE
+ *
+ * Protocol changelog:
+ *
+ * 7.9:
+ * - new fuse_getattr_in input argument of GETATTR
+ * - add lk_flags in fuse_lk_in
+ * - add lock_owner field to fuse_setattr_in, fuse_read_in and fuse_write_in
+ * - add blksize field to fuse_attr
+ * - add file flags field to fuse_read_in and fuse_write_in
+ *
+ * 7.10
+ * - add nonseekable open flag
+ *
+ * 7.11
+ * - add IOCTL message
+ * - add unsolicited notification support
+ * - add POLL message and NOTIFY_POLL notification
+ */
+
+#ifndef _LINUX_FUSE_H
+#define _LINUX_FUSE_H
+
+#include <sys/types.h>
+#define __u64 uint64_t
+#define __u32 uint32_t
+#define __s32 int32_t
+
+/** Version number of this interface */
+#define FUSE_KERNEL_VERSION 7
+
+/** Minor version number of this interface */
+#define FUSE_KERNEL_MINOR_VERSION 11
+
+/** The node ID of the root inode */
+#define FUSE_ROOT_ID 1
+
+/* Make sure all structures are padded to 64bit boundary, so 32bit
+ userspace works under 64bit kernels */
+
+struct fuse_attr {
+ __u64 ino;
+ __u64 size;
+ __u64 blocks;
+ __u64 atime;
+ __u64 mtime;
+ __u64 ctime;
+ __u32 atimensec;
+ __u32 mtimensec;
+ __u32 ctimensec;
+ __u32 mode;
+ __u32 nlink;
+ __u32 uid;
+ __u32 gid;
+ __u32 rdev;
+ __u32 blksize;
+ __u32 padding;
+};
+
+struct fuse_kstatfs {
+ __u64 blocks;
+ __u64 bfree;
+ __u64 bavail;
+ __u64 files;
+ __u64 ffree;
+ __u32 bsize;
+ __u32 namelen;
+ __u32 frsize;
+ __u32 padding;
+ __u32 spare[6];
+};
+
+struct fuse_file_lock {
+ __u64 start;
+ __u64 end;
+ __u32 type;
+ __u32 pid; /* tgid */
+};
+
+/**
+ * Bitmasks for fuse_setattr_in.valid
+ */
+#define FATTR_MODE (1 << 0)
+#define FATTR_UID (1 << 1)
+#define FATTR_GID (1 << 2)
+#define FATTR_SIZE (1 << 3)
+#define FATTR_ATIME (1 << 4)
+#define FATTR_MTIME (1 << 5)
+#define FATTR_FH (1 << 6)
+#define FATTR_ATIME_NOW (1 << 7)
+#define FATTR_MTIME_NOW (1 << 8)
+#define FATTR_LOCKOWNER (1 << 9)
+
+/**
+ * Flags returned by the OPEN request
+ *
+ * FOPEN_DIRECT_IO: bypass page cache for this open file
+ * FOPEN_KEEP_CACHE: don't invalidate the data cache on open
+ * FOPEN_NONSEEKABLE: the file is not seekable
+ */
+#define FOPEN_DIRECT_IO (1 << 0)
+#define FOPEN_KEEP_CACHE (1 << 1)
+#define FOPEN_NONSEEKABLE (1 << 2)
+
+/**
+ * INIT request/reply flags
+ *
+ * FUSE_EXPORT_SUPPORT: filesystem handles lookups of "." and ".."
+ */
+#define FUSE_ASYNC_READ (1 << 0)
+#define FUSE_POSIX_LOCKS (1 << 1)
+#define FUSE_FILE_OPS (1 << 2)
+#define FUSE_ATOMIC_O_TRUNC (1 << 3)
+#define FUSE_EXPORT_SUPPORT (1 << 4)
+#define FUSE_BIG_WRITES (1 << 5)
+
+/**
+ * Release flags
+ */
+#define FUSE_RELEASE_FLUSH (1 << 0)
+
+/**
+ * Getattr flags
+ */
+#define FUSE_GETATTR_FH (1 << 0)
+
+/**
+ * Lock flags
+ */
+#define FUSE_LK_FLOCK (1 << 0)
+
+/**
+ * WRITE flags
+ *
+ * FUSE_WRITE_CACHE: delayed write from page cache, file handle is guessed
+ * FUSE_WRITE_LOCKOWNER: lock_owner field is valid
+ */
+#define FUSE_WRITE_CACHE (1 << 0)
+#define FUSE_WRITE_LOCKOWNER (1 << 1)
+
+/**
+ * Read flags
+ */
+#define FUSE_READ_LOCKOWNER (1 << 1)
+
+/**
+ * Ioctl flags
+ *
+ * FUSE_IOCTL_COMPAT: 32bit compat ioctl on 64bit machine
+ * FUSE_IOCTL_UNRESTRICTED: not restricted to well-formed ioctls, retry allowed
+ * FUSE_IOCTL_RETRY: retry with new iovecs
+ *
+ * FUSE_IOCTL_MAX_IOV: maximum of in_iovecs + out_iovecs
+ */
+#define FUSE_IOCTL_COMPAT (1 << 0)
+#define FUSE_IOCTL_UNRESTRICTED (1 << 1)
+#define FUSE_IOCTL_RETRY (1 << 2)
+
+#define FUSE_IOCTL_MAX_IOV 256
+
+/**
+ * Poll flags
+ *
+ * FUSE_POLL_SCHEDULE_NOTIFY: request poll notify
+ */
+#define FUSE_POLL_SCHEDULE_NOTIFY (1 << 0)
+
+enum fuse_opcode {
+ FUSE_LOOKUP = 1,
+ FUSE_FORGET = 2, /* no reply */
+ FUSE_GETATTR = 3,
+ FUSE_SETATTR = 4,
+ FUSE_READLINK = 5,
+ FUSE_SYMLINK = 6,
+ FUSE_MKNOD = 8,
+ FUSE_MKDIR = 9,
+ FUSE_UNLINK = 10,
+ FUSE_RMDIR = 11,
+ FUSE_RENAME = 12,
+ FUSE_LINK = 13,
+ FUSE_OPEN = 14,
+ FUSE_READ = 15,
+ FUSE_WRITE = 16,
+ FUSE_STATFS = 17,
+ FUSE_RELEASE = 18,
+ FUSE_FSYNC = 20,
+ FUSE_SETXATTR = 21,
+ FUSE_GETXATTR = 22,
+ FUSE_LISTXATTR = 23,
+ FUSE_REMOVEXATTR = 24,
+ FUSE_FLUSH = 25,
+ FUSE_INIT = 26,
+ FUSE_OPENDIR = 27,
+ FUSE_READDIR = 28,
+ FUSE_RELEASEDIR = 29,
+ FUSE_FSYNCDIR = 30,
+ FUSE_GETLK = 31,
+ FUSE_SETLK = 32,
+ FUSE_SETLKW = 33,
+ FUSE_ACCESS = 34,
+ FUSE_CREATE = 35,
+ FUSE_INTERRUPT = 36,
+ FUSE_BMAP = 37,
+ FUSE_DESTROY = 38,
+ FUSE_IOCTL = 39,
+ FUSE_POLL = 40,
+};
+
+enum fuse_notify_code {
+ FUSE_NOTIFY_POLL = 1,
+ FUSE_NOTIFY_CODE_MAX,
+};
+
+/* The read buffer is required to be at least 8k, but may be much larger */
+#define FUSE_MIN_READ_BUFFER 8192
+
+#define FUSE_COMPAT_ENTRY_OUT_SIZE 120
+
+struct fuse_entry_out {
+ __u64 nodeid; /* Inode ID */
+ __u64 generation; /* Inode generation: nodeid:gen must
+ be unique for the fs's lifetime */
+ __u64 entry_valid; /* Cache timeout for the name */
+ __u64 attr_valid; /* Cache timeout for the attributes */
+ __u32 entry_valid_nsec;
+ __u32 attr_valid_nsec;
+ struct fuse_attr attr;
+};
+
+struct fuse_forget_in {
+ __u64 nlookup;
+};
+
+struct fuse_getattr_in {
+ __u32 getattr_flags;
+ __u32 dummy;
+ __u64 fh;
+};
+
+#define FUSE_COMPAT_ATTR_OUT_SIZE 96
+
+struct fuse_attr_out {
+ __u64 attr_valid; /* Cache timeout for the attributes */
+ __u32 attr_valid_nsec;
+ __u32 dummy;
+ struct fuse_attr attr;
+};
+
+struct fuse_mknod_in {
+ __u32 mode;
+ __u32 rdev;
+};
+
+struct fuse_mkdir_in {
+ __u32 mode;
+ __u32 padding;
+};
+
+struct fuse_rename_in {
+ __u64 newdir;
+};
+
+struct fuse_link_in {
+ __u64 oldnodeid;
+};
+
+struct fuse_setattr_in {
+ __u32 valid;
+ __u32 padding;
+ __u64 fh;
+ __u64 size;
+ __u64 lock_owner;
+ __u64 atime;
+ __u64 mtime;
+ __u64 unused2;
+ __u32 atimensec;
+ __u32 mtimensec;
+ __u32 unused3;
+ __u32 mode;
+ __u32 unused4;
+ __u32 uid;
+ __u32 gid;
+ __u32 unused5;
+};
+
+struct fuse_open_in {
+ __u32 flags;
+ __u32 mode;
+};
+
+struct fuse_open_out {
+ __u64 fh;
+ __u32 open_flags;
+ __u32 padding;
+};
+
+struct fuse_release_in {
+ __u64 fh;
+ __u32 flags;
+ __u32 release_flags;
+ __u64 lock_owner;
+};
+
+struct fuse_flush_in {
+ __u64 fh;
+ __u32 unused;
+ __u32 padding;
+ __u64 lock_owner;
+};
+
+struct fuse_read_in {
+ __u64 fh;
+ __u64 offset;
+ __u32 size;
+ __u32 read_flags;
+ __u64 lock_owner;
+ __u32 flags;
+ __u32 padding;
+};
+
+#define FUSE_COMPAT_WRITE_IN_SIZE 24
+
+struct fuse_write_in {
+ __u64 fh;
+ __u64 offset;
+ __u32 size;
+ __u32 write_flags;
+ __u64 lock_owner;
+ __u32 flags;
+ __u32 padding;
+};
+
+struct fuse_write_out {
+ __u32 size;
+ __u32 padding;
+};
+
+#define FUSE_COMPAT_STATFS_SIZE 48
+
+struct fuse_statfs_out {
+ struct fuse_kstatfs st;
+};
+
+struct fuse_fsync_in {
+ __u64 fh;
+ __u32 fsync_flags;
+ __u32 padding;
+};
+
+struct fuse_setxattr_in {
+ __u32 size;
+ __u32 flags;
+};
+
+struct fuse_getxattr_in {
+ __u32 size;
+ __u32 padding;
+};
+
+struct fuse_getxattr_out {
+ __u32 size;
+ __u32 padding;
+};
+
+struct fuse_lk_in {
+ __u64 fh;
+ __u64 owner;
+ struct fuse_file_lock lk;
+ __u32 lk_flags;
+ __u32 padding;
+};
+
+struct fuse_lk_out {
+ struct fuse_file_lock lk;
+};
+
+struct fuse_access_in {
+ __u32 mask;
+ __u32 padding;
+};
+
+struct fuse_init_in {
+ __u32 major;
+ __u32 minor;
+ __u32 max_readahead;
+ __u32 flags;
+};
+
+struct fuse_init_out {
+ __u32 major;
+ __u32 minor;
+ __u32 max_readahead;
+ __u32 flags;
+ __u32 unused;
+ __u32 max_write;
+};
+
+struct fuse_interrupt_in {
+ __u64 unique;
+};
+
+struct fuse_bmap_in {
+ __u64 block;
+ __u32 blocksize;
+ __u32 padding;
+};
+
+struct fuse_bmap_out {
+ __u64 block;
+};
+
+struct fuse_ioctl_in {
+ __u64 fh;
+ __u32 flags;
+ __u32 cmd;
+ __u64 arg;
+ __u32 in_size;
+ __u32 out_size;
+};
+
+struct fuse_ioctl_out {
+ __s32 result;
+ __u32 flags;
+ __u32 in_iovs;
+ __u32 out_iovs;
+};
+
+struct fuse_poll_in {
+ __u64 fh;
+ __u64 kh;
+ __u32 flags;
+ __u32 padding;
+};
+
+struct fuse_poll_out {
+ __u32 revents;
+ __u32 padding;
+};
+
+struct fuse_notify_poll_wakeup_out {
+ __u64 kh;
+};
+
+struct fuse_in_header {
+ __u32 len;
+ __u32 opcode;
+ __u64 unique;
+ __u64 nodeid;
+ __u32 uid;
+ __u32 gid;
+ __u32 pid;
+ __u32 padding;
+};
+
+struct fuse_out_header {
+ __u32 len;
+ __s32 error;
+ __u64 unique;
+};
+
+struct fuse_dirent {
+ __u64 ino;
+ __u64 off;
+ __u32 namelen;
+ __u32 type;
+ char name[0];
+};
+
+#define FUSE_NAME_OFFSET offsetof(struct fuse_dirent, name)
+#define FUSE_DIRENT_ALIGN(x) (((x) + sizeof(__u64) - 1) & ~(sizeof(__u64) - 1))
+#define FUSE_DIRENT_SIZE(d) \
+ FUSE_DIRENT_ALIGN(FUSE_NAME_OFFSET + (d)->namelen)
+
+#endif /* _LINUX_FUSE_H */