summaryrefslogtreecommitdiffstats
path: root/xlators/mount/fuse
diff options
context:
space:
mode:
Diffstat (limited to 'xlators/mount/fuse')
-rw-r--r--xlators/mount/fuse/src/Makefile.am11
-rw-r--r--xlators/mount/fuse/src/fuse-bridge.c1758
-rw-r--r--xlators/mount/fuse/src/fuse-extra.c155
-rw-r--r--xlators/mount/fuse/src/fuse-extra.h42
4 files changed, 1000 insertions, 966 deletions
diff --git a/xlators/mount/fuse/src/Makefile.am b/xlators/mount/fuse/src/Makefile.am
index 9d8d45e4f02..a4d1fd76064 100644
--- a/xlators/mount/fuse/src/Makefile.am
+++ b/xlators/mount/fuse/src/Makefile.am
@@ -1,13 +1,14 @@
-
-noinst_HEADERS = fuse-extra.h
+noinst_HEADERS = $(CONTRIBDIR)/fuse-include/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 $(CONTRIBDIR)/fuse-lib/misc.c \
+ $(CONTRIBDIR)/fuse-lib/mount.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
+ -I$(top_srcdir)/libglusterfs/src -I$(CONTRIBDIR)/fuse-include \
+ $(GF_CFLAGS) -DFUSERMOUNT_DIR=\"$(bindir)\"
CLEANFILES =
diff --git a/xlators/mount/fuse/src/fuse-bridge.c b/xlators/mount/fuse/src/fuse-bridge.c
index b0ac84ea8de..d20876a3bba 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
@@ -37,13 +40,13 @@
#include "glusterfs.h"
#include "logging.h"
#include "xlator.h"
-#include "glusterfs.h"
#include "defaults.h"
#include "common-utils.h"
-#include <fuse/fuse_lowlevel.h>
+#include "fuse_kernel.h"
+#include "fuse-misc.h"
+#include "fuse-mount.h"
-#include "fuse-extra.h"
#include "list.h"
#include "dict.h"
@@ -57,11 +60,16 @@
#define ZR_DIRECT_IO_OPT "direct-io-mode"
#define ZR_STRICT_VOLFILE_CHECK "strict-volfile-check"
+#define FUSE_712_OP_HIGH (FUSE_POLL + 1)
+#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;
+ uint32_t proto_minor;
char *volfile;
size_t volfile_size;
char *mount_point;
@@ -69,6 +77,7 @@ struct fuse_private {
pthread_t fuse_thread;
char fuse_thread_started;
uint32_t direct_io_mode;
+ size_t *msg0_len_p;
double entry_timeout;
double attribute_timeout;
pthread_cond_t first_call_cond;
@@ -78,16 +87,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 +106,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 +125,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 +149,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 +160,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 +180,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 +193,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 +240,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 +404,26 @@ need_fresh_lookup (int32_t op_ret, int32_t op_errno,
return 0;
}
+/* courtesy of folly */
+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;
+}
static int
fuse_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
@@ -363,13 +436,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 +465,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 +473,62 @@ 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);
+
+ priv->proto_minor >= 9 ?
+ send_fuse_obj (this, finh, &feo) :
+ send_fuse_data (this, finh, &feo,
+ FUSE_COMPAT_ENTRY_OUT_SIZE);
+ } 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);
+
+ priv->proto_minor >= 9 ?
+ send_fuse_obj (this, finh, fao) :
+ send_fuse_data (this, finh, fao,
+ FUSE_COMPAT_ATTR_OUT_SIZE);
+ }
} 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 +548,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 +578,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 +591,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 +622,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 +641,24 @@ 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);
+ priv->proto_minor >= 9 ?
+ send_fuse_obj (this, finh, &fao) :
+ send_fuse_data (this, finh, &fao,
+ FUSE_COMPAT_ATTR_OUT_SIZE);
} 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 +668,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 +699,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 +717,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 +734,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 +748,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 +781,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 +795,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 +847,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 +886,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 +933,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 +966,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 +994,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 +1023,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 +1031,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 +1045,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 +1057,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 +1079,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 +1115,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 +1145,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 +1175,26 @@ 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)
{
- fuse_state_t *state = NULL;
- int32_t ret = -1;
+ struct fuse_mknod_in *fmi = msg;
+ char *name = (char *)(fmi + 1);
+
+ fuse_state_t *state = NULL;
+ fuse_private_t *priv = NULL;
+ int32_t ret = -1;
+
+ priv = this->private;
+ if (priv->proto_minor < 12)
+ name = (char *)msg + FUSE_COMPAT_MKNOD_IN_SIZE;
- 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 +1202,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 +1235,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 +1279,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 +1310,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 +1332,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 +1346,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 +1372,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 +1388,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 +1437,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 +1466,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 +1482,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 +1529,16 @@ 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 = priv->proto_minor >= 9 ?
+ sizeof (feo) :
+ FUSE_COMPAT_ENTRY_OUT_SIZE;
+ 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 +1549,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 +1562,84 @@ 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_create_in *fci = msg;
+ char *name = (char *)(fci + 1);
+
+ fuse_private_t *priv = NULL;
fuse_state_t *state = NULL;
fd_t *fd = NULL;
int32_t ret = -1;
- STATE_FROM_REQ (req, state);
- state->flags = fi->flags;
+ priv = this->private;
+ if (priv->proto_minor < 12)
+ name = (char *)((struct fuse_open_in *)msg + 1);
+
+ GET_STATE (this, finh, state);
+ state->flags = fci->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, fci->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 +1652,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 +1690,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 +1720,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 +1750,40 @@ 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)
{
+ /* WRITE is special, metadata is attached to in_header,
+ * and msg is the payload as-is.
+ */
+ struct fuse_write_in *fwi = (struct fuse_write_in *)
+ (finh + 1);
+
+ fuse_private_t *priv = NULL;
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);
+ priv = this->private;
+
+ 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_base = msg;
+ 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 +1792,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 +1800,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 +1822,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 +1844,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 +1907,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 +1967,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 +2013,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 +2037,13 @@ 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;
+ fuse_private_t *priv = NULL;
+ struct fuse_statfs_out fso = {{0, }, };
state = frame->root->state;
- req = state->req;
+ priv = this->private;
+ finh = state->finh;
/*
Filesystems (like ZFS on solaris) reports
different ->f_frsize and ->f_bsize. Old coreutils
@@ -1881,13 +2072,23 @@ 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;
+
+ priv->proto_minor >= 4 ?
+ send_fuse_obj (this, finh, &fso) :
+ send_fuse_data (this, finh, &fso, FUSE_COMPAT_STATFS_SIZE);
} 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 +2099,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 +2126,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 +2213,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 +2227,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 +2256,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 +2267,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 +2278,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 +2289,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 +2318,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 +2335,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 +2362,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 +2405,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 +2438,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 +2479,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 +2506,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);
@@ -2293,22 +2520,24 @@ fuse_getlk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
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 +2553,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++;
@@ -2335,13 +2564,13 @@ fuse_setlk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
"'features/posix-locks' on server side "
"will add SETLK support.");
}
- } else if (op_errno != EAGAIN) {
- gf_log ("glusterfs-fuse", GF_LOG_ERROR,
- "%"PRId64": ERR => -1 (%s)",
+ } else {
+ gf_log ("glusterfs-fuse", GF_LOG_WARNING,
+ "%"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,77 +2581,111 @@ 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) {
+ gf_log ("glusterfs-fuse", GF_LOG_ERROR,
+ "unsupported FUSE protocol version %d.%d",
+ fini->major, fini->minor);
+
+ close (priv->fd);
+ goto out;
+ }
+ priv->proto_minor = fini->minor;
+
+ 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;
+ if (fini->minor >= 6 /* fuse_init_in has flags */ &&
+ fini->flags & FUSE_BIG_WRITES) {
+ /* no need for direct I/O mode if big writes are supported */
+ priv->direct_io_mode = 0;
+ fino.flags |= FUSE_BIG_WRITES;
+ }
+ if (fini->minor < 9)
+ *priv->msg0_len_p = sizeof(*finh) + FUSE_COMPAT_WRITE_IN_SIZE;
+
+ 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_712_OP_HIGH];
+
int
fuse_root_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno,
@@ -2493,33 +2756,54 @@ 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];
+ void *msg = NULL;
+ const size_t msg0_size = sizeof (*finh) + 128;
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 (*finh) + sizeof (struct fuse_write_in);
+ iov_in[1].iov_len = ((struct iobuf_pool *)this->ctx->iobuf_pool)
+ ->page_size;
+ priv->msg0_len_p = &iov_in[0].iov_len;
+
+ for (;;) {
iobuf = iobuf_get (this->ctx->iobuf_pool);
+ /* Add extra 128 byte to the first iov so that it can
+ * accomodate "ordinary" non-write requests. It's not
+ * guaranteed to be big enough, as SETXATTR and namespace
+ * operations with very long names may grow behind it,
+ * but it's good enough in most cases (and we can handle
+ * rest via realloc).
+ */
+ iov_in[0].iov_base = CALLOC (1, msg0_size);
- 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) {
@@ -2530,27 +2814,73 @@ fuse_thread_proc (void *data)
}
if (res == -1) {
+ if (errno == ENODEV || errno == EBADF) {
+ gf_log ("glusterfs-fuse", GF_LOG_NORMAL,
+ "terminating upon getting %s when "
+ "reading /dev/fuse",
+ errno == ENODEV ? "ENODEV" : "EBADF");
+
+ break;
+ }
if (errno != EINTR) {
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
- "fuse_chan_receive() returned -1 (%d)", errno);
- }
- if (errno == ENODEV) {
- iobuf_unref (iobuf);
- break;
+ "read from /dev/fuse returned -1 (%s)",
+ strerror (errno));
}
- continue;
+
+ goto cont_err;
+ }
+ 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);
+ if (finh->opcode == FUSE_WRITE)
+ msg = iov_in[1].iov_base;
+ else {
+ if (res > msg0_size) {
+ iov_in[0].iov_base =
+ realloc (iov_in[0].iov_base, res);
+ if (iov_in[0].iov_base)
+ finh = (fuse_in_header_t *)
+ iov_in[0].iov_base;
+ else {
+ gf_log ("glusterfs-fuse", GF_LOG_ERROR,
+ "Out of memory");
+ send_fuse_err (this, finh, ENOMEM);
+
+ goto cont_err;
+ }
+ }
+
+ if (res > iov_in[0].iov_len)
+ memcpy (iov_in[0].iov_base + iov_in[0].iov_len,
+ iov_in[1].iov_base,
+ res - iov_in[0].iov_len);
+
+ msg = finh + 1;
}
+ fuse_ops[finh->opcode] (this, finh, msg);
iobuf_unref (iobuf);
+ continue;
+
+ cont_err:
+ iobuf_unref (iobuf);
+ FREE (iov_in[0].iov_base);
}
+ 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 +2890,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 +2954,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 +2962,9 @@ init (xlator_t *this_xl)
dict_t *options = NULL;
char *value_string = NULL;
char *fsname = NULL;
- char *fsname_opt = 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 +2978,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 +3032,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 +3062,74 @@ 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 = gf_fuse_mount (priv->mount_point, fsname,
+ "allow_other,default_permissions,"
+ "max_read=131072");
+ if (priv->fd == -1)
goto cleanup_exit;
- }
-
- 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;
- }
-
- ret = fuse_set_signal_handlers (priv->se);
- 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);
-
- fuse_session_add_chan (priv->se, priv->ch);
-
- priv->fd = fuse_chan_fd (priv->ch);
this_xl->ctx->top = this_xl;
priv->first_call = 2;
+
+ for (i = 0; i < FUSE_712_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)
+ if (priv) {
FREE (priv->mount_point);
+ close (priv->fd);
+ }
FREE (priv);
return -1;
}
@@ -2924,8 +3155,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);
+ gf_fuse_unmount (mount_point, priv->fd);
}
}
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 */