summaryrefslogtreecommitdiffstats
path: root/xlators/mount/fuse/src/fuse-bridge.c
diff options
context:
space:
mode:
Diffstat (limited to 'xlators/mount/fuse/src/fuse-bridge.c')
-rw-r--r--xlators/mount/fuse/src/fuse-bridge.c1292
1 files changed, 559 insertions, 733 deletions
diff --git a/xlators/mount/fuse/src/fuse-bridge.c b/xlators/mount/fuse/src/fuse-bridge.c
index b1de4692a..ea5b5ae38 100644
--- a/xlators/mount/fuse/src/fuse-bridge.c
+++ b/xlators/mount/fuse/src/fuse-bridge.c
@@ -25,283 +25,11 @@
* fuse_loc_fill() and inode_path() return success/failure.
*/
-
-#include <stdint.h>
-#include <signal.h>
-#include <pthread.h>
-#include <stddef.h>
-#include <dirent.h>
-#include <sys/mount.h>
-#include <sys/time.h>
-
-#ifndef _CONFIG_H
-#define _CONFIG_H
-#include "config.h"
-#endif /* _CONFIG_H */
-
-#include "glusterfs.h"
-#include "logging.h"
-#include "xlator.h"
-#include "defaults.h"
-#include "common-utils.h"
-#include "glusterfsd-common.h"
-#include "statedump.h"
-
-#ifdef GF_DARWIN_HOST_OS
-/* This is MacFUSE's marker for MacFUSE-specific code */
-#define __FreeBSD__ 10
-#include "fuse_kernel_macfuse.h"
-#else
-#include "fuse_kernel.h"
-#endif
-#include "fuse-misc.h"
-#include "fuse-mount.h"
-#include "fuse-mem-types.h"
-
-#include "list.h"
-#include "dict.h"
-
-/* TODO: when supporting posix acl, remove this definition */
-#define DISABLE_POSIX_ACL
-
-#ifdef GF_LINUX_HOST_OS
-#define FUSE_OP_HIGH (FUSE_POLL + 1)
-#endif
-#ifdef GF_DARWIN_HOST_OS
-#define FUSE_OP_HIGH (FUSE_DESTROY + 1)
-#endif
-#define GLUSTERFS_XATTR_LEN_MAX 65536
-
-#define MAX_FUSE_PROC_DELAY 1
+#include "fuse-bridge.h"
static int gf_fuse_conn_err_log;
static int gf_fuse_xattr_enotsup_log;
-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;
- uint32_t proto_minor;
- char *volfile;
- size_t volfile_size;
- char *mount_point;
- struct iobuf *iobuf;
-
- 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 sync_cond;
- pthread_mutex_t sync_mutex;
- char child_up;
-
- char init_recvd;
-
- gf_boolean_t strict_volfile_check;
-
- fuse_handler_t **fuse_ops;
- fuse_handler_t **fuse_ops0;
- pthread_mutex_t fuse_dump_mutex;
- int fuse_dump_fd;
-
- glusterfs_graph_t *next_graph;
- xlator_t *active_subvol;
-};
-typedef struct fuse_private fuse_private_t;
-
-#define _FH_TO_FD(fh) ((fd_t *)(uintptr_t)(fh))
-
-#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); \
- if (!frame) { \
- /* This is not completely clean, as some \
- * earlier allocations might remain unfreed \
- * if we return at this point, but still \
- * better than trying to go on with a NULL \
- * frame ... \
- */ \
- gf_log ("glusterfs-fuse", \
- GF_LOG_ERROR, \
- "FUSE message" \
- " unique %"PRIu64" opcode %d:" \
- " frame allocation failed", \
- state->finh->unique, \
- state->finh->opcode); \
- free_state (state); \
- return; \
- } \
- xl = fuse_state_subvol (state); \
- \
- frame->root->state = state; \
- frame->root->op = op_num; \
- frame->op = op_num; \
- STACK_WIND (frame, ret, xl, xl->fops->fop, args); \
- } while (0)
-
-#define GF_SELECT_LOG_LEVEL(_errno) \
- (((_errno == ENOENT) || (_errno == ESTALE))? \
- GF_LOG_DEBUG)
-
-#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); \
- GF_FREE (finh); \
- \
- return; \
- } \
- } while (0)
-
-
-typedef struct {
- void *pool;
- xlator_t *this;
- inode_table_t *itable;
- loc_t loc;
- loc_t loc2;
- fuse_in_header_t *finh;
- int32_t flags;
- off_t off;
- size_t size;
- unsigned long nlookup;
- fd_t *fd;
- dict_t *dict;
- char *name;
- char is_revalidate;
- gf_boolean_t truncate_needed;
- gf_lock_t lock;
- uint64_t lk_owner;
-} fuse_state_t;
-
-
-xlator_t *
-fuse_state_subvol (fuse_state_t *state)
-{
- xlator_t *subvol = NULL;
-
- if (!state)
- return NULL;
-
- if (state->loc.inode)
- subvol = state->loc.inode->table->xl;
-
- if (state->fd)
- subvol = state->fd->inode->table->xl;
-
- return subvol;
-}
-
-
-xlator_t *
-fuse_active_subvol (xlator_t *fuse)
-{
- fuse_private_t *priv = NULL;
-
- priv = fuse->private;
-
- return priv->active_subvol;
-}
-
-
-static void
-free_state (fuse_state_t *state)
-{
- loc_wipe (&state->loc);
-
- loc_wipe (&state->loc2);
-
- if (state->dict) {
- dict_unref (state->dict);
- state->dict = (void *)0xaaaaeeee;
- }
- if (state->name) {
- GF_FREE (state->name);
- state->name = NULL;
- }
- if (state->fd) {
- fd_unref (state->fd);
- state->fd = (void *)0xfdfdfdfd;
- }
- if (state->finh) {
- GF_FREE (state->finh);
- state->finh = NULL;
- }
-#ifdef DEBUG
- memset (state, 0x90, sizeof (*state));
-#endif
- GF_FREE (state);
- state = NULL;
-}
-
-
-fuse_state_t *
-get_state (xlator_t *this, fuse_in_header_t *finh)
-{
- fuse_state_t *state = NULL;
-
- state = (void *)GF_CALLOC (1, sizeof (*state),
- gf_fuse_mt_fuse_state_t);
- if (!state)
- return NULL;
- state->pool = this->ctx->pool;
- state->finh = finh;
- state->this = this;
-
- LOCK_INIT (&state->lock);
-
- return state;
-}
-
-
-static call_frame_t *
-get_call_frame_for_req (fuse_state_t *state)
-{
- call_pool_t *pool = NULL;
- fuse_in_header_t *finh = NULL;
- call_frame_t *frame = NULL;
- xlator_t *this = NULL;
-
- pool = state->pool;
- finh = state->finh;
- this = state->this;
-
- frame = create_frame (this, pool);
- if (!frame)
- return NULL;
-
- if (finh) {
- frame->root->uid = finh->uid;
- frame->root->gid = finh->gid;
- frame->root->pid = finh->pid;
- frame->root->lk_owner = state->lk_owner;
- frame->root->unique = finh->unique;
- }
-
- frame->root->type = GF_OP_TYPE_FOP;
-
- return frame;
-}
-
/*
* iov_out should contain a fuse_out_header at zeroth position.
@@ -378,142 +106,6 @@ send_fuse_err (xlator_t *this, fuse_in_header_t *finh, int error)
return send_fuse_iov (this, finh, &iov_out, 1);
}
-static inode_t *
-fuse_ino_to_inode (uint64_t ino, xlator_t *fuse)
-{
- inode_t *inode = NULL;
- xlator_t *active_subvol = NULL;
-
- if (ino == 1) {
- active_subvol = fuse_active_subvol (fuse);
- inode = active_subvol->itable->root;
- } else {
- inode = (inode_t *) (unsigned long) ino;
- inode_ref (inode);
- }
-
- return inode;
-}
-
-static uint64_t
-inode_to_nodeid (inode_t *inode)
-{
- if (!inode || inode->ino == 1)
- return 1;
-
- return (unsigned long) inode;
-}
-
-
-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)
-{
- inode_t *inode = NULL;
- inode_t *parent = NULL;
- int32_t ret = -1;
- char *path = NULL;
-
- /* resistance against multiple invocation of loc_fill not to get
- reference leaks via inode_search() */
-
- if (name) {
- parent = loc->parent;
- if (!parent) {
- parent = fuse_ino_to_inode (par, state->this);
- loc->parent = parent;
- }
-
- inode = loc->inode;
- if (!inode) {
- inode = inode_grep (parent->table, parent, name);
- loc->inode = inode;
- }
-
- ret = inode_path (parent, name, &path);
- if (ret <= 0) {
- gf_log ("glusterfs-fuse", GF_LOG_DEBUG,
- "inode_path failed for %"PRId64"/%s",
- parent->ino, name);
- goto fail;
- }
- loc->path = path;
- } else {
- inode = loc->inode;
- if (!inode) {
- inode = fuse_ino_to_inode (ino, state->this);
- loc->inode = inode;
- }
-
- parent = loc->parent;
- if (!parent) {
- parent = inode_parent (inode, par, name);
- loc->parent = parent;
- }
-
- ret = inode_path (inode, NULL, &path);
- if (ret <= 0) {
- gf_log ("glusterfs-fuse", GF_LOG_DEBUG,
- "inode_path failed for %"PRId64,
- inode->ino);
- goto fail;
- }
- loc->path = path;
- }
-
- if (inode)
- loc->ino = inode->ino;
-
- if (loc->path) {
- loc->name = strrchr (loc->path, '/');
- if (loc->name)
- loc->name++;
- else
- loc->name = "";
- }
-
- if ((ino != 1) && (parent == NULL)) {
- gf_log ("fuse-bridge", GF_LOG_DEBUG,
- "failed to search parent for %"PRId64"/%s (%"PRId64")",
- (ino_t)par, name, (ino_t)ino);
- ret = -1;
- goto fail;
- }
- ret = 0;
-fail:
- return ret;
-}
-
-
-/* courtesy of folly */
-static void
-stat2attr (struct iatt *st, struct fuse_attr *fa)
-{
- fa->ino = st->ia_ino;
- fa->size = st->ia_size;
- fa->blocks = st->ia_blocks;
- fa->atime = st->ia_atime;
- fa->mtime = st->ia_mtime;
- fa->ctime = st->ia_ctime;
- fa->atimensec = st->ia_atime_nsec;
- fa->mtimensec = st->ia_mtime_nsec;
- fa->ctimensec = st->ia_ctime_nsec;
- fa->mode = st_mode_from_ia (st->ia_prot, st->ia_type);
- fa->nlink = st->ia_nlink;
- fa->uid = st->ia_uid;
- fa->gid = st->ia_gid;
- fa->rdev = st->ia_rdev;
-#if FUSE_KERNEL_MINOR_VERSION >= 9
- fa->blksize = st->ia_blksize;
-#endif
-#ifdef GF_DARWIN_HOST_OS
- fa->crtime = (uint64_t)-1;
- fa->crtimensec = (uint32_t)-1;
- fa->flags = 0;
-#endif
-}
-
-
static int
fuse_entry_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno,
@@ -540,7 +132,7 @@ fuse_entry_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
state->loc.path, buf->ia_ino, state->loc.ino);
buf->ia_blksize = this->ctx->page_size;
- stat2attr (buf, &feo.attr);
+ gf_fuse_stat2attr (buf, &feo.attr);
if (!buf->ia_ino) {
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
@@ -566,7 +158,8 @@ fuse_entry_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
inode_lookup (linked_inode);
/* TODO: make these timeouts configurable (via meta?) */
- feo.nodeid = inode_to_nodeid (linked_inode);
+ /* should we do linked_node or inode */
+ feo.nodeid = inode_to_fuse_nodeid (linked_inode);
feo.generation = linked_inode->generation;
@@ -598,7 +191,7 @@ fuse_entry_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
send_fuse_err (this, state->finh, op_errno);
}
- free_state (state);
+ free_fuse_state (state);
STACK_DESTROY (frame->root);
return 0;
}
@@ -644,14 +237,24 @@ fuse_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
return 0;
}
+void
+fuse_lookup_resume (fuse_state_t *state)
+{
+ if (!state->loc.inode)
+ state->loc.inode = inode_new (state->loc.parent->table);
+
+ state->dict = dict_new ();
+
+ FUSE_FOP (state, fuse_lookup_cbk, GF_FOP_LOOKUP,
+ lookup, &state->loc, state->dict);
+}
static void
fuse_lookup (xlator_t *this, fuse_in_header_t *finh, void *msg)
{
- char *name = msg;
-
- fuse_state_t *state = NULL;
- int32_t ret = -1;
+ char *name = msg;
+ fuse_state_t *state = NULL;
+ int32_t ret = -1;
GET_STATE (this, finh, state);
@@ -662,27 +265,23 @@ fuse_lookup (xlator_t *this, fuse_in_header_t *finh, void *msg)
"%"PRIu64": LOOKUP %"PRIu64"/%s (fuse_loc_fill() failed)",
finh->unique, finh->nodeid, name);
send_fuse_err (this, finh, ENOENT);
- free_state (state);
+ free_fuse_state (state);
return;
}
- if (!state->loc.inode) {
- gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRIu64": LOOKUP %s", finh->unique,
- state->loc.path);
-
- state->loc.inode = inode_new (state->loc.parent->table);
- } else {
+ if (state->loc.inode) {
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
"%"PRIu64": LOOKUP %s(%"PRId64")", finh->unique,
state->loc.path, state->loc.inode->ino);
state->is_revalidate = 1;
+ } else {
+ gf_log ("glusterfs-fuse", GF_LOG_TRACE,
+ "%"PRIu64": LOOKUP %s", finh->unique,
+ state->loc.path);
}
- state->dict = dict_new ();
+ fuse_resolve_and_resume (state, fuse_lookup_resume);
- FUSE_FOP (state, fuse_lookup_cbk, GF_FOP_LOOKUP,
- lookup, &state->loc, state->dict);
}
@@ -732,7 +331,7 @@ fuse_truncate_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 */
postbuf->ia_blksize = this->ctx->page_size;
- stat2attr (postbuf, &fao.attr);
+ gf_fuse_stat2attr (postbuf, &fao.attr);
fao.attr_valid = calc_timeout_sec (priv->attribute_timeout);
fao.attr_valid_nsec =
@@ -756,7 +355,7 @@ fuse_truncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
send_fuse_err (this, finh, op_errno);
}
- free_state (state);
+ free_fuse_state (state);
STACK_DESTROY (frame->root);
return 0;
@@ -786,7 +385,7 @@ 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->ia_blksize = this->ctx->page_size;
- stat2attr (buf, &fao.attr);
+ gf_fuse_stat2attr (buf, &fao.attr);
fao.attr_valid = calc_timeout_sec (priv->attribute_timeout);
fao.attr_valid_nsec =
@@ -812,7 +411,7 @@ fuse_attr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
send_fuse_err (this, finh, op_errno);
}
- free_state (state);
+ free_fuse_state (state);
STACK_DESTROY (frame->root);
return 0;
@@ -830,6 +429,28 @@ fuse_root_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
return 0;
}
+void
+fuse_getattr_resume (fuse_state_t *state)
+{
+ if (!state->fd || IA_ISDIR (state->loc.inode->ia_type)) {
+ gf_log ("glusterfs-fuse", GF_LOG_TRACE,
+ "%"PRIu64": GETATTR %"PRIu64" (%s)",
+ state->finh->unique, state->finh->nodeid,
+ state->loc.path);
+
+ FUSE_FOP (state, fuse_attr_cbk, GF_FOP_STAT,
+ stat, &state->loc);
+ } else {
+
+ gf_log ("glusterfs-fuse", GF_LOG_TRACE,
+ "%"PRIu64": FGETATTR %"PRIu64" (%s/%p)",
+ state->finh->unique, state->finh->nodeid,
+ state->loc.path, state->fd);
+
+ FUSE_FOP (state, fuse_attr_cbk, GF_FOP_FSTAT,
+ fstat, state->fd);
+ }
+}
static void
fuse_getattr (xlator_t *this, fuse_in_header_t *finh, void *msg)
@@ -844,10 +465,10 @@ fuse_getattr (xlator_t *this, fuse_in_header_t *finh, void *msg)
ret = fuse_loc_fill (&state->loc, state, finh->nodeid, 0, NULL);
if (ret < 0) {
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
- "%"PRIu64": GETATTR %"PRIu64" (fuse_loc_fill() failed)",
- finh->unique, finh->nodeid);
+ "%"PRIu64": GETATTR on / (fuse_loc_fill() failed)",
+ finh->unique);
send_fuse_err (this, finh, ENOENT);
- free_state (state);
+ free_fuse_state (state);
return;
}
@@ -858,18 +479,18 @@ fuse_getattr (xlator_t *this, fuse_in_header_t *finh, void *msg)
return;
}
- ret = fuse_loc_fill (&state->loc, state, finh->nodeid, 0, NULL);
+ ret = fuse_loc_fill (&state->loc, state, state->finh->nodeid, 0, NULL);
if (!state->loc.inode) {
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
"%"PRIu64": GETATTR %"PRIu64" (%s) (fuse_loc_fill() returned NULL inode)",
- finh->unique, finh->nodeid, state->loc.path);
- send_fuse_err (this, finh, ENOENT);
- free_state (state);
+ state->finh->unique, state->finh->nodeid, state->loc.path);
+ send_fuse_err (state->this, state->finh, ENOENT);
+ free_fuse_state (state);
return;
}
- fd = fd_lookup (state->loc.inode, finh->pid);
+ fd = fd_lookup (state->loc.inode, state->finh->pid);
state->fd = fd;
if (!fd || IA_ISDIR (state->loc.inode->ia_type)) {
/* this is the @ret of fuse_loc_fill, checked here
@@ -878,28 +499,15 @@ fuse_getattr (xlator_t *this, fuse_in_header_t *finh, void *msg)
if (ret < 0) {
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
"%"PRIu64": GETATTR %"PRIu64" (fuse_loc_fill() failed)",
- finh->unique, finh->nodeid);
- send_fuse_err (this, finh, ENOENT);
- free_state (state);
+ state->finh->unique, state->finh->nodeid);
+ send_fuse_err (state->this, state->finh, ENOENT);
+ free_fuse_state (state);
return;
}
-
- gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRIu64": GETATTR %"PRIu64" (%s)",
- finh->unique, finh->nodeid, state->loc.path);
-
-
- FUSE_FOP (state, fuse_attr_cbk, GF_FOP_STAT,
- stat, &state->loc);
- } else {
-
- gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRIu64": FGETATTR %"PRIu64" (%s/%p)",
- finh->unique, finh->nodeid, state->loc.path, fd);
-
- FUSE_FOP (state,fuse_attr_cbk, GF_FOP_FSTAT,
- fstat, fd);
+ state->fd = NULL;
}
+
+ fuse_resolve_and_resume (state, fuse_getattr_resume);
}
@@ -960,7 +568,7 @@ fuse_fd_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
send_fuse_err (this, finh, op_errno);
}
out:
- free_state (state);
+ free_fuse_state (state);
STACK_DESTROY (frame->root);
return 0;
}
@@ -1009,7 +617,7 @@ fuse_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
statpost->ia_blksize = this->ctx->page_size;
- stat2attr (statpost, &fao.attr);
+ gf_fuse_stat2attr (statpost, &fao.attr);
fao.attr_valid = calc_timeout_sec (priv->attribute_timeout);
fao.attr_valid_nsec =
@@ -1040,7 +648,7 @@ fuse_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
}
if (op_done) {
- free_state (state);
+ free_fuse_state (state);
}
STACK_DESTROY (frame->root);
@@ -1081,18 +689,40 @@ fattr_to_gf_set_attr (int32_t valid)
| FATTR_ATIME | FATTR_MTIME \
| FATTR_MODE)
+void
+fuse_setattr_resume (fuse_state_t *state)
+{
+ if ((state->valid & (FATTR_MASK)) != FATTR_SIZE) {
+ if (state->fd &&
+ !((state->valid & FATTR_ATIME) ||
+ (state->valid & FATTR_MTIME))) {
+ /*
+ there is no "futimes" call, so don't send
+ fsetattr if ATIME or MTIME is set
+ */
+
+ FUSE_FOP (state, fuse_setattr_cbk, GF_FOP_FSETATTR,
+ fsetattr, state->fd, &state->attr,
+ fattr_to_gf_set_attr (state->valid));
+ } else {
+ FUSE_FOP (state, fuse_setattr_cbk, GF_FOP_SETATTR,
+ setattr, &state->loc, &state->attr,
+ fattr_to_gf_set_attr (state->valid));
+ }
+ } else {
+ fuse_do_truncate (state, state->size);
+ }
+
+}
static void
fuse_setattr (xlator_t *this, fuse_in_header_t *finh, void *msg)
{
struct fuse_setattr_in *fsi = msg;
- struct iatt attr = {0, };
-
fuse_private_t *priv = NULL;
fuse_state_t *state = NULL;
int32_t ret = -1;
- int32_t valid = 0;
GET_STATE (this, finh, state);
@@ -1132,7 +762,7 @@ fuse_setattr (xlator_t *this, fuse_in_header_t *finh, void *msg)
finh->unique, state->loc.path);
send_fuse_err (this, finh, ENOENT);
- free_state (state);
+ free_fuse_state (state);
return;
}
@@ -1141,48 +771,32 @@ fuse_setattr (xlator_t *this, fuse_in_header_t *finh, void *msg)
"%"PRIu64": SETATTR (%"PRIu64")%s", finh->unique,
finh->nodeid, state->loc.path);
- valid = fsi->valid;
+ state->valid = fsi->valid;
if (fsi->valid & FATTR_FH) {
state->fd = FH_TO_FD (fsi->fh);
}
- if ((valid & (FATTR_MASK)) != FATTR_SIZE) {
- if (valid & FATTR_SIZE) {
+ if ((fsi->valid & (FATTR_MASK)) != FATTR_SIZE) {
+ if (fsi->valid & FATTR_SIZE) {
state->size = fsi->size;
state->truncate_needed = _gf_true;
}
- attr.ia_size = fsi->size;
- attr.ia_atime = fsi->atime;
- attr.ia_mtime = fsi->mtime;
- attr.ia_atime_nsec = fsi->atimensec;
- attr.ia_mtime_nsec = fsi->mtimensec;
+ state->attr.ia_size = fsi->size;
+ state->attr.ia_atime = fsi->atime;
+ state->attr.ia_mtime = fsi->mtime;
+ state->attr.ia_atime_nsec = fsi->atimensec;
+ state->attr.ia_mtime_nsec = fsi->mtimensec;
- attr.ia_prot = ia_prot_from_st_mode (fsi->mode);
- attr.ia_uid = fsi->uid;
- attr.ia_gid = fsi->gid;
-
- if (state->fd &&
- !((fsi->valid & FATTR_ATIME) || (fsi->valid & FATTR_MTIME))) {
-
- /*
- there is no "futimes" call, so don't send
- fsetattr if ATIME or MTIME is set
- */
-
- FUSE_FOP (state, fuse_setattr_cbk, GF_FOP_FSETATTR,
- fsetattr, state->fd, &attr,
- fattr_to_gf_set_attr (fsi->valid));
- } else {
- FUSE_FOP (state, fuse_setattr_cbk, GF_FOP_SETATTR,
- setattr, &state->loc, &attr,
- fattr_to_gf_set_attr (fsi->valid));
- }
+ state->attr.ia_prot = ia_prot_from_st_mode (fsi->mode);
+ state->attr.ia_uid = fsi->uid;
+ state->attr.ia_gid = fsi->gid;
} else {
- fuse_do_truncate (state, fsi->size);
+ state->size = fsi->size;
}
+ fuse_resolve_and_resume (state, fuse_setattr_resume);
}
@@ -1211,7 +825,7 @@ fuse_err_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
send_fuse_err (this, finh, op_errno);
}
- free_state (state);
+ free_fuse_state (state);
STACK_DESTROY (frame->root);
return 0;
@@ -1272,12 +886,24 @@ fuse_unlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
send_fuse_err (this, finh, op_errno);
}
- free_state (state);
+ free_fuse_state (state);
STACK_DESTROY (frame->root);
return 0;
}
+void
+fuse_access_resume (fuse_state_t *state)
+{
+ gf_log ("glusterfs-fuse", GF_LOG_TRACE,
+ "%"PRIu64" ACCESS %s/%"PRIu64" mask=%d",
+ state->finh->unique, state->loc.path,
+ state->finh->nodeid, state->mask);
+
+ FUSE_FOP (state, fuse_err_cbk, GF_FOP_ACCESS, access,
+ &state->loc, state->mask);
+
+}
static void
fuse_access (xlator_t *this, fuse_in_header_t *finh, void *msg)
@@ -1296,18 +922,13 @@ fuse_access (xlator_t *this, fuse_in_header_t *finh, void *msg)
"%"PRIu64": ACCESS %"PRIu64" (%s) (fuse_loc_fill() failed)",
finh->unique, finh->nodeid, state->loc.path);
send_fuse_err (this, finh, ENOENT);
- free_state (state);
+ free_fuse_state (state);
return;
}
- gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"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, fai->mask);
+ state->mask = fai->mask;
+ fuse_resolve_and_resume (state, fuse_access_resume);
return;
}
@@ -1339,12 +960,23 @@ fuse_readlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
send_fuse_err (this, finh, op_errno);
}
- free_state (state);
+ free_fuse_state (state);
STACK_DESTROY (frame->root);
return 0;
}
+void
+fuse_readlink_resume (fuse_state_t *state)
+{
+ gf_log ("glusterfs-fuse", GF_LOG_TRACE,
+ "%"PRIu64" READLINK %s/%"PRId64, state->finh->unique,
+ state->loc.path, state->loc.inode->ino);
+
+ FUSE_FOP (state, fuse_readlink_cbk, GF_FOP_READLINK,
+ readlink, &state->loc, 4096);
+
+}
static void
fuse_readlink (xlator_t *this, fuse_in_header_t *finh, void *msg)
@@ -1360,20 +992,31 @@ fuse_readlink (xlator_t *this, fuse_in_header_t *finh, void *msg)
"%"PRIu64" READLINK %s (fuse_loc_fill() returned NULL inode)",
finh->unique, state->loc.path);
send_fuse_err (this, finh, ENOENT);
- free_state (state);
+ free_fuse_state (state);
return;
}
- gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRIu64" READLINK %s/%"PRId64, finh->unique,
- state->loc.path, state->loc.inode->ino);
-
- FUSE_FOP (state, fuse_readlink_cbk, GF_FOP_READLINK,
- readlink, &state->loc, 4096);
+ fuse_resolve_and_resume (state, fuse_readlink_resume);
return;
}
+void
+fuse_mknod_resume (fuse_state_t *state)
+{
+ if (!state->loc.inode)
+ state->loc.inode = inode_new (state->loc.parent->table);
+ else
+ gf_log (state->this->name, GF_LOG_ERROR, "inode already present");
+
+ gf_log ("glusterfs-fuse", GF_LOG_TRACE,
+ "%"PRIu64": MKNOD %s", state->finh->unique,
+ state->loc.path);
+
+ FUSE_FOP (state, fuse_newentry_cbk, GF_FOP_MKNOD,
+ mknod, &state->loc, state->mode, state->rdev);
+
+}
static void
fuse_mknod (xlator_t *this, fuse_in_header_t *finh, void *msg)
@@ -1398,22 +1041,33 @@ fuse_mknod (xlator_t *this, fuse_in_header_t *finh, void *msg)
"%"PRIu64" MKNOD %s (fuse_loc_fill() failed)",
finh->unique, state->loc.path);
send_fuse_err (this, finh, ENOENT);
- free_state (state);
+ free_fuse_state (state);
return;
}
- state->loc.inode = inode_new (state->loc.parent->table);
-
- gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRIu64": MKNOD %s", finh->unique,
- state->loc.path);
+ state->mode = fmi->mode;
+ state->rdev = fmi->rdev;
- FUSE_FOP (state, fuse_newentry_cbk, GF_FOP_MKNOD,
- mknod, &state->loc, fmi->mode, fmi->rdev);
+ fuse_resolve_and_resume (state, fuse_mknod_resume);
return;
}
+void
+fuse_mkdir_resume (fuse_state_t *state)
+{
+ if (!state->loc.inode)
+ state->loc.inode = inode_new (state->loc.parent->table);
+ else
+ gf_log (state->this->name, GF_LOG_ERROR, "inode already present");
+
+ gf_log ("glusterfs-fuse", GF_LOG_TRACE,
+ "%"PRIu64": MKDIR %s", state->finh->unique,
+ state->loc.path);
+
+ FUSE_FOP (state, fuse_newentry_cbk, GF_FOP_MKDIR,
+ mkdir, &state->loc, state->mode);
+}
static void
fuse_mkdir (xlator_t *this, fuse_in_header_t *finh, void *msg)
@@ -1431,23 +1085,35 @@ fuse_mkdir (xlator_t *this, fuse_in_header_t *finh, void *msg)
"%"PRIu64" MKDIR %s (fuse_loc_fill() failed)",
finh->unique, state->loc.path);
send_fuse_err (this, finh, ENOENT);
- free_state (state);
+ free_fuse_state (state);
return;
}
- state->loc.inode = inode_new (state->loc.parent->table);
+ state->mode = fmi->mode;
+
+ fuse_resolve_and_resume (state, fuse_mkdir_resume);
+ return;
+}
+
+void
+fuse_unlink_resume (fuse_state_t *state)
+{
+ if (!state->loc.inode) {
+ gf_log ("fuse", GF_LOG_WARNING, "path resolving failed");
+ send_fuse_err (state->this, state->finh, ENOENT);
+ free_fuse_state (state);
+ return;
+ }
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRIu64": MKDIR %s", finh->unique,
+ "%"PRIu64": UNLINK %s", state->finh->unique,
state->loc.path);
- FUSE_FOP (state, fuse_newentry_cbk, GF_FOP_MKDIR,
- mkdir, &state->loc, fmi->mode);
+ FUSE_FOP (state, fuse_unlink_cbk, GF_FOP_UNLINK,
+ unlink, &state->loc);
- return;
}
-
static void
fuse_unlink (xlator_t *this, fuse_in_header_t *finh, void *msg)
{
@@ -1457,29 +1123,38 @@ fuse_unlink (xlator_t *this, fuse_in_header_t *finh, void *msg)
int32_t ret = -1;
GET_STATE (this, finh, state);
-
ret = fuse_loc_fill (&state->loc, state, 0, finh->nodeid, name);
-
- if ((state->loc.inode == NULL) ||
- (ret < 0)) {
+ if (ret < 0) {
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
"%"PRIu64": UNLINK %s (fuse_loc_fill() returned NULL inode)",
finh->unique, state->loc.path);
send_fuse_err (this, finh, ENOENT);
- free_state (state);
+ free_fuse_state (state);
return;
}
- gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRIu64": UNLINK %s", finh->unique,
- state->loc.path);
-
- FUSE_FOP (state, fuse_unlink_cbk, GF_FOP_UNLINK,
- unlink, &state->loc);
+ fuse_resolve_and_resume (state, fuse_unlink_resume);
return;
}
+void
+fuse_rmdir_resume (fuse_state_t *state)
+{
+ if (!state->loc.inode) {
+ gf_log ("fuse", GF_LOG_WARNING, "path resolving failed");
+ send_fuse_err (state->this, state->finh, ENOENT);
+ free_fuse_state (state);
+ return;
+ }
+
+ gf_log ("glusterfs-fuse", GF_LOG_TRACE,
+ "%"PRIu64": RMDIR %s", state->finh->unique,
+ state->loc.path);
+
+ FUSE_FOP (state, fuse_unlink_cbk, GF_FOP_RMDIR,
+ rmdir, &state->loc);
+}
static void
fuse_rmdir (xlator_t *this, fuse_in_header_t *finh, void *msg)
@@ -1491,26 +1166,34 @@ fuse_rmdir (xlator_t *this, fuse_in_header_t *finh, void *msg)
GET_STATE (this, finh, state);
ret = fuse_loc_fill (&state->loc, state, 0, finh->nodeid, name);
- if ((state->loc.inode == NULL) ||
- (ret < 0)) {
+ if (ret < 0) {
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
"%"PRIu64": RMDIR %s (fuse_loc_fill() failed)",
finh->unique, state->loc.path);
send_fuse_err (this, finh, ENOENT);
- free_state (state);
+ free_fuse_state (state);
return;
}
- gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRIu64": RMDIR %s", finh->unique,
- state->loc.path);
-
- FUSE_FOP (state, fuse_unlink_cbk, GF_FOP_RMDIR,
- rmdir, &state->loc);
-
+ fuse_resolve_and_resume (state, fuse_rmdir_resume);
return;
}
+void
+fuse_symlink_resume (fuse_state_t *state)
+{
+ if (!state->loc.inode)
+ state->loc.inode = inode_new (state->loc.parent->table);
+ else
+ gf_log (state->this->name, GF_LOG_ERROR, "inode already present");
+
+ gf_log ("glusterfs-fuse", GF_LOG_TRACE,
+ "%"PRIu64": SYMLINK %s -> %s", state->finh->unique,
+ state->loc.path, state->name);
+
+ FUSE_FOP (state, fuse_newentry_cbk, GF_FOP_SYMLINK,
+ symlink, state->name, &state->loc);
+}
static void
fuse_symlink (xlator_t *this, fuse_in_header_t *finh, void *msg)
@@ -1528,19 +1211,12 @@ fuse_symlink (xlator_t *this, fuse_in_header_t *finh, void *msg)
"%"PRIu64" SYMLINK %s -> %s (fuse_loc_fill() failed)",
finh->unique, state->loc.path, linkname);
send_fuse_err (this, finh, ENOENT);
- free_state (state);
+ free_fuse_state (state);
return;
}
- state->loc.inode = inode_new (state->loc.parent->table);
-
- gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRIu64": SYMLINK %s -> %s", finh->unique,
- state->loc.path, linkname);
-
- FUSE_FOP (state, fuse_newentry_cbk, GF_FOP_SYMLINK,
- symlink, linkname, &state->loc);
-
+ state->name = gf_strdup (linkname);
+ fuse_resolve_and_resume (state, fuse_symlink_resume);
return;
}
@@ -1586,11 +1262,28 @@ fuse_rename_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
send_fuse_err (this, finh, op_errno);
}
- free_state (state);
+ free_fuse_state (state);
STACK_DESTROY (frame->root);
return 0;
}
+void
+fuse_rename_resume (fuse_state_t *state)
+{
+ if (!state->loc.inode) {
+ send_fuse_err (state->this, state->finh, ENOENT);
+ free_fuse_state (state);
+ return;
+ }
+
+ gf_log ("glusterfs-fuse", GF_LOG_TRACE,
+ "%"PRIu64": RENAME `%s (%"PRId64")' -> `%s (%"PRId64")'",
+ state->finh->unique, state->loc.path, state->loc.ino,
+ state->loc2.path, state->loc2.ino);
+
+ FUSE_FOP (state, fuse_rename_cbk, GF_FOP_RENAME,
+ rename, &state->loc, &state->loc2);
+}
static void
fuse_rename (xlator_t *this, fuse_in_header_t *finh, void *msg)
@@ -1605,15 +1298,14 @@ fuse_rename (xlator_t *this, fuse_in_header_t *finh, void *msg)
GET_STATE (this, finh, state);
ret = fuse_loc_fill (&state->loc, state, 0, finh->nodeid, oldname);
- if ((state->loc.inode == NULL) ||
- (ret < 0)) {
+ if (ret < 0) {
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
"for %s %"PRIu64": RENAME `%s' -> `%s' (fuse_loc_fill() failed)",
state->loc.path, finh->unique, state->loc.path,
state->loc2.path);
send_fuse_err (this, finh, ENOENT);
- free_state (state);
+ free_fuse_state (state);
return;
}
@@ -1625,21 +1317,31 @@ fuse_rename (xlator_t *this, fuse_in_header_t *finh, void *msg)
state->loc2.path);
send_fuse_err (this, finh, ENOENT);
- free_state (state);
+ free_fuse_state (state);
return;
- }
-
- gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRIu64": RENAME `%s (%"PRId64")' -> `%s (%"PRId64")'",
- finh->unique, state->loc.path, state->loc.ino,
- state->loc2.path, state->loc2.ino);
+ }
- FUSE_FOP (state, fuse_rename_cbk, GF_FOP_RENAME,
- rename, &state->loc, &state->loc2);
+ fuse_resolve_and_resume (state, fuse_rename_resume);
return;
}
+void
+fuse_link_resume (fuse_state_t *state)
+{
+ if (!state->loc.inode)
+ state->loc.inode = inode_ref (state->loc2.inode);
+ else
+ gf_log (state->this->name, GF_LOG_ERROR, "inode already present");
+
+ gf_log ("glusterfs-fuse", GF_LOG_TRACE,
+ "%"PRIu64": LINK() %s (%"PRId64") -> %s (%"PRId64")",
+ state->finh->unique, state->loc2.path, state->loc2.ino,
+ state->loc.path, state->loc.ino);
+
+ FUSE_FOP (state, fuse_newentry_cbk, GF_FOP_LINK,
+ link, &state->loc2, &state->loc);
+}
static void
fuse_link (xlator_t *this, fuse_in_header_t *finh, void *msg)
@@ -1664,18 +1366,11 @@ fuse_link (xlator_t *this, fuse_in_header_t *finh, void *msg)
state->loc2.path, finh->unique,
state->loc2.path, state->loc.path);
send_fuse_err (this, finh, ENOENT);
- free_state (state);
+ free_fuse_state (state);
return;
}
- state->loc.inode = inode_ref (state->loc2.inode);
- gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRIu64": LINK() %s (%"PRId64") -> %s (%"PRId64")",
- finh->unique, state->loc2.path, state->loc2.ino,
- state->loc.path, state->loc.ino);
-
- FUSE_FOP (state, fuse_newentry_cbk, GF_FOP_LINK,
- link, &state->loc2, &state->loc);
+ fuse_resolve_and_resume (state, fuse_link_resume);
return;
}
@@ -1696,7 +1391,6 @@ fuse_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
struct iovec iov_out[3];
inode_t *linked_inode = NULL;
-
state = frame->root->state;
priv = this->private;
finh = state->finh;
@@ -1714,7 +1408,7 @@ fuse_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
state->loc.path, fd, buf->ia_ino);
buf->ia_blksize = this->ctx->page_size;
- stat2attr (buf, &feo.attr);
+ gf_fuse_stat2attr (buf, &feo.attr);
linked_inode = inode_link (inode, state->loc.parent,
state->loc.name, buf);
@@ -1738,11 +1432,12 @@ fuse_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
inode_lookup (linked_inode);
+ inode_ref (state->loc.parent);
inode_unref (linked_inode);
fd_ref (fd);
- feo.nodeid = inode_to_nodeid (linked_inode);
+ feo.nodeid = inode_to_fuse_nodeid (linked_inode);
feo.generation = linked_inode->generation;
@@ -1780,12 +1475,34 @@ fuse_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
send_fuse_err (this, finh, op_errno);
}
out:
- free_state (state);
+ free_fuse_state (state);
STACK_DESTROY (frame->root);
return 0;
}
+void
+fuse_create_resume (fuse_state_t *state)
+{
+ fd_t *fd = NULL;
+
+ if (!state->loc.inode)
+ state->loc.inode = inode_new (state->loc.parent->table);
+ else
+ gf_log (state->this->name, GF_LOG_ERROR, "inode already present");
+
+ fd = fd_create (state->loc.inode, state->finh->pid);
+ state->fd = fd;
+ fd->flags = state->flags;
+
+ gf_log ("glusterfs-fuse", GF_LOG_TRACE,
+ "%"PRIu64": CREATE %s", state->finh->unique,
+ state->loc.path);
+
+ FUSE_FOP (state, fuse_create_cbk, GF_FOP_CREATE,
+ create, &state->loc, state->flags, state->mode, fd);
+
+}
static void
fuse_create (xlator_t *this, fuse_in_header_t *finh, void *msg)
@@ -1799,7 +1516,6 @@ fuse_create (xlator_t *this, fuse_in_header_t *finh, void *msg)
fuse_private_t *priv = NULL;
fuse_state_t *state = NULL;
- fd_t *fd = NULL;
int32_t ret = -1;
priv = this->private;
@@ -1809,7 +1525,6 @@ fuse_create (xlator_t *this, fuse_in_header_t *finh, void *msg)
#endif
GET_STATE (this, finh, state);
- state->flags = fci->flags;
ret = fuse_loc_fill (&state->loc, state, 0, finh->nodeid, name);
if (ret < 0) {
@@ -1817,38 +1532,44 @@ fuse_create (xlator_t *this, fuse_in_header_t *finh, void *msg)
"%"PRIu64" CREATE %s (fuse_loc_fill() failed)",
finh->unique, state->loc.path);
send_fuse_err (this, finh, ENOENT);
- free_state (state);
+ free_fuse_state (state);
return;
}
- state->loc.inode = inode_new (state->loc.parent->table);
+ state->mode = fci->mode;
+ state->flags = fci->flags;
+
+ fuse_resolve_and_resume (state, fuse_create_resume);
+
+ return;
+}
+
+void
+fuse_open_resume (fuse_state_t *state)
+{
+ fd_t *fd = NULL;
- fd = fd_create (state->loc.inode, finh->pid);
+ fd = fd_create (state->loc.inode, state->finh->pid);
state->fd = fd;
fd->flags = state->flags;
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRIu64": CREATE %s", finh->unique,
+ "%"PRIu64": OPEN %s", state->finh->unique,
state->loc.path);
- FUSE_FOP (state, fuse_create_cbk, GF_FOP_CREATE,
- create, &state->loc, state->flags, fci->mode, fd);
-
- return;
+ FUSE_FOP (state, fuse_fd_cbk, GF_FOP_OPEN,
+ open, &state->loc, state->flags, fd, 0);
}
-
static void
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;
GET_STATE (this, finh, state);
- state->flags = foi->flags;
ret = fuse_loc_fill (&state->loc, state, finh->nodeid, 0, NULL);
if ((state->loc.inode == NULL) ||
@@ -1858,20 +1579,12 @@ fuse_open (xlator_t *this, fuse_in_header_t *finh, void *msg)
finh->unique, state->loc.path);
send_fuse_err (this, finh, ENOENT);
- free_state (state);
+ free_fuse_state (state);
return;
}
- fd = fd_create (state->loc.inode, finh->pid);
- state->fd = fd;
- fd->flags = foi->flags;
-
- gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRIu64": OPEN %s", finh->unique,
- state->loc.path);
-
- FUSE_FOP (state, fuse_fd_cbk, GF_FOP_OPEN,
- open, &state->loc, foi->flags, fd, 0);
+ state->flags = foi->flags;
+ fuse_resolve_and_resume (state, fuse_open_resume);
return;
}
@@ -1915,12 +1628,22 @@ fuse_readv_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
send_fuse_err (this, finh, op_errno);
}
- free_state (state);
+ free_fuse_state (state);
STACK_DESTROY (frame->root);
return 0;
}
+void
+fuse_readv_resume (fuse_state_t *state)
+{
+ gf_log ("glusterfs-fuse", GF_LOG_TRACE,
+ "%"PRIu64": READ (%p, size=%zu, offset=%"PRIu64")",
+ state->finh->unique, state->fd, state->size, state->off);
+
+ FUSE_FOP (state, fuse_readv_cbk, GF_FOP_READ,
+ readv, state->fd, state->size, state->off);
+}
static void
fuse_readv (xlator_t *this, fuse_in_header_t *finh, void *msg)
@@ -1933,8 +1656,6 @@ fuse_readv (xlator_t *this, fuse_in_header_t *finh, void *msg)
GET_STATE (this, finh, state);
- state->size = fri->size;
- state->off = fri->offset;
fd = FH_TO_FD (fri->fh);
state->fd = fd;
@@ -1946,13 +1667,10 @@ fuse_readv (xlator_t *this, fuse_in_header_t *finh, void *msg)
state->lk_owner = fri->lock_owner;
#endif
- gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"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, fri->size, fri->offset);
+ state->size = fri->size;
+ state->off = fri->offset;
+ fuse_resolve_and_resume (state, fuse_readv_resume);
}
@@ -1984,12 +1702,43 @@ fuse_writev_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
send_fuse_err (this, finh, op_errno);
}
- free_state (state);
+ free_fuse_state (state);
STACK_DESTROY (frame->root);
return 0;
}
+void
+fuse_write_resume (fuse_state_t *state)
+{
+ struct iobref *iobref = NULL;
+ struct iobuf *iobuf = NULL;
+
+ if (!state->fd || !state->fd->inode) {
+ send_fuse_err (state->this, state->finh, EBADFD);
+ free_fuse_state (state);
+ return;
+ }
+
+ iobref = iobref_new ();
+ if (!iobref) {
+ gf_log ("glusterfs-fuse", GF_LOG_ERROR,
+ "%"PRIu64": WRITE iobref allocation failed",
+ state->finh->unique);
+ send_fuse_err (state->this, state->finh, ENOMEM);
+
+ free_fuse_state (state);
+ return;
+ }
+
+ iobuf = ((fuse_private_t *) (state->this->private))->iobuf;
+ iobref_add (iobref, iobuf);
+
+ FUSE_FOP (state, fuse_writev_cbk, GF_FOP_WRITE, writev, state->fd,
+ &state->vector, 1, state->off, iobref);
+
+ iobref_unref (iobref);
+}
static void
fuse_write (xlator_t *this, fuse_in_header_t *finh, void *msg)
@@ -2002,20 +1751,15 @@ fuse_write (xlator_t *this, fuse_in_header_t *finh, void *msg)
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;
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 = msg;
- vector.iov_len = fwi->size;
+ state->size = fwi->size;
+ state->off = fwi->offset;
/* See comment by similar code in fuse_settatr */
priv = this->private;
@@ -2028,25 +1772,20 @@ fuse_write (xlator_t *this, fuse_in_header_t *finh, void *msg)
"%"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",
- finh->unique);
-
- free_state (state);
- return;
- }
- iobuf = ((fuse_private_t *) (state->this->private))->iobuf;
- iobref_add (iobref, iobuf);
+ state->vector.iov_base = msg;
+ state->vector.iov_len = fwi->size;
- FUSE_FOP (state, fuse_writev_cbk, GF_FOP_WRITE,
- writev, fd, &vector, 1, fwi->offset, iobref);
+ fuse_resolve_and_resume (state, fuse_write_resume);
- iobref_unref (iobref);
return;
}
+void
+fuse_flush_resume (fuse_state_t *state)
+{
+ FUSE_FOP (state, fuse_err_cbk, GF_FOP_FLUSH,
+ flush, state->fd);
+}
static void
fuse_flush (xlator_t *this, fuse_in_header_t *finh, void *msg)
@@ -2067,22 +1806,30 @@ fuse_flush (xlator_t *this, fuse_in_header_t *finh, void *msg)
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
"%"PRIu64": FLUSH %p", finh->unique, fd);
- FUSE_FOP (state, fuse_err_cbk, GF_FOP_FLUSH,
- flush, fd);
+ fuse_resolve_and_resume (state, fuse_flush_resume);
return;
}
+static int
+fuse_release_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno)
+{
+ STACK_DESTROY (frame->root);
+
+ return 0;
+}
static void
fuse_release (xlator_t *this, fuse_in_header_t *finh, void *msg)
{
- struct fuse_release_in *fri = msg;
-
- fd_t *fd = NULL;
- int do_flush = 0;
-
- fuse_state_t *state = NULL;
+ struct fuse_release_in *fri = msg;
+ fd_t *new_fd = NULL;
+ fd_t *fd = NULL;
+ int do_flush = 0;
+ uint64_t tmp_fd_ctx = 0;
+ int ret = 0;
+ fuse_state_t *state = NULL;
GET_STATE (this, finh, state);
fd = FH_TO_FD (fri->fh);
@@ -2122,25 +1869,47 @@ fuse_release (xlator_t *this, fuse_in_header_t *finh, void *msg)
do_flush = 1;
#endif
+ /* TODO */
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
"%"PRIu64": RELEASE %p%s", finh->unique, fd,
do_flush ? " (FLUSH implied)" : "");
if (do_flush) {
state->lk_owner = (uint64_t)-1;
+ ret = fd_ctx_get (fd, this, &tmp_fd_ctx);
+ if (!ret) {
+ new_fd = (fd_t *)(long)tmp_fd_ctx;
+ FUSE_FOP (state, fuse_release_cbk, GF_FOP_FLUSH, flush,
+ new_fd);
+ fd_unref (new_fd);
+ }
+
FUSE_FOP (state, fuse_err_cbk, GF_FOP_FLUSH, flush, fd);
+
fd_unref (fd);
} else {
+ ret = fd_ctx_get (fd, this, &tmp_fd_ctx);
+ if (!ret) {
+ new_fd = (fd_t *)(long)tmp_fd_ctx;
+ fd_unref (new_fd);
+ }
fd_unref (fd);
send_fuse_err (this, finh, 0);
- free_state (state);
+ free_fuse_state (state);
}
return;
}
+void
+fuse_fsync_resume (fuse_state_t *state)
+{
+ /* fsync_flags: 1 means "datasync" (no defines for this) */
+ FUSE_FOP (state, fuse_fsync_cbk, GF_FOP_FSYNC,
+ fsync, state->fd, state->flags & 1);
+}
static void
fuse_fsync (xlator_t *this, fuse_in_header_t *finh, void *msg)
@@ -2157,13 +1926,26 @@ fuse_fsync (xlator_t *this, fuse_in_header_t *finh, void *msg)
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
"%"PRIu64": FSYNC %p", finh->unique, fd);
- /* fsync_flags: 1 means "datasync" (no defines for this) */
- FUSE_FOP (state, fuse_fsync_cbk, GF_FOP_FSYNC,
- fsync, fd, fsi->fsync_flags & 1);
-
+ state->flags = fsi->fsync_flags;
+ fuse_resolve_and_resume (state, fuse_fsync_resume);
return;
}
+void
+fuse_opendir_resume (fuse_state_t *state)
+{
+ fd_t *fd = NULL;
+
+ fd = fd_create (state->loc.inode, state->finh->pid);
+ state->fd = fd;
+
+ gf_log ("glusterfs-fuse", GF_LOG_TRACE,
+ "%"PRIu64": OPENDIR %s", state->finh->unique,
+ state->loc.path);
+
+ FUSE_FOP (state, fuse_fd_cbk, GF_FOP_OPENDIR,
+ opendir, &state->loc, fd);
+}
static void
fuse_opendir (xlator_t *this, fuse_in_header_t *finh, void *msg)
@@ -2173,31 +1955,21 @@ fuse_opendir (xlator_t *this, fuse_in_header_t *finh, void *msg)
*/
fuse_state_t *state = NULL;
- fd_t *fd = NULL;
int32_t ret = -1;
GET_STATE (this, finh, state);
ret = fuse_loc_fill (&state->loc, state, finh->nodeid, 0, NULL);
- if ((state->loc.inode == NULL) ||
- (ret < 0)) {
+ if ((state->loc.inode == NULL) || (ret < 0)) {
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
"%"PRIu64": OPENDIR %s (fuse_loc_fill() failed)",
finh->unique, state->loc.path);
send_fuse_err (this, finh, ENOENT);
- free_state (state);
+ free_fuse_state (state);
return;
}
- fd = fd_create (state->loc.inode, finh->pid);
- state->fd = fd;
-
- gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRIu64": OPENDIR %s", finh->unique,
- state->loc.path);
-
- FUSE_FOP (state, fuse_fd_cbk, GF_FOP_OPENDIR,
- opendir, &state->loc, fd);
+ fuse_resolve_and_resume (state, fuse_opendir_resume);
}
@@ -2289,7 +2061,7 @@ fuse_readdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
send_fuse_data (this, finh, buf, size);
out:
- free_state (state);
+ free_fuse_state (state);
STACK_DESTROY (frame->root);
if (buf)
GF_FREE (buf);
@@ -2297,6 +2069,16 @@ out:
}
+void
+fuse_readdir_resume (fuse_state_t *state)
+{
+ gf_log ("glusterfs-fuse", GF_LOG_TRACE,
+ "%"PRIu64": READDIR (%p, size=%zu, offset=%"PRId64")",
+ state->finh->unique, state->fd, state->size, state->off);
+
+ FUSE_FOP (state, fuse_readdir_cbk, GF_FOP_READDIR,
+ readdir, state->fd, state->size, state->off);
+}
static void
fuse_readdir (xlator_t *this, fuse_in_header_t *finh, void *msg)
@@ -2312,37 +2094,48 @@ fuse_readdir (xlator_t *this, fuse_in_header_t *finh, void *msg)
fd = FH_TO_FD (fri->fh);
state->fd = fd;
- gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"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, fri->size, fri->offset);
+ fuse_resolve_and_resume (state, fuse_readdir_resume);
}
static void
fuse_releasedir (xlator_t *this, fuse_in_header_t *finh, void *msg)
{
- struct fuse_release_in *fri = msg;
-
- fuse_state_t *state = NULL;
+ struct fuse_release_in *fri = msg;
+ fd_t *new_fd = NULL;
+ uint64_t tmp_fd_ctx = 0;
+ int ret = 0;
+ fuse_state_t *state = NULL;
GET_STATE (this, finh, state);
state->fd = FH_TO_FD (fri->fh);
+ /* TODO: free 'new-fd' in the ctx */
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
"%"PRIu64": RELEASEDIR %p", finh->unique, state->fd);
+ ret = fd_ctx_get (state->fd, this, &tmp_fd_ctx);
+ if (!ret) {
+ new_fd = (fd_t *)(long)tmp_fd_ctx;
+ fd_unref (new_fd);
+ }
+
fd_unref (state->fd);
send_fuse_err (this, finh, 0);
- free_state (state);
+ free_fuse_state (state);
return;
}
+void
+fuse_fsyncdir_resume (fuse_state_t *state)
+{
+ FUSE_FOP (state, fuse_err_cbk, GF_FOP_FSYNCDIR,
+ fsyncdir, state->fd, state->flags & 1);
+
+}
static void
fuse_fsyncdir (xlator_t *this, fuse_in_header_t *finh, void *msg)
@@ -2357,8 +2150,8 @@ fuse_fsyncdir (xlator_t *this, fuse_in_header_t *finh, void *msg)
GET_STATE (this, finh, state);
state->fd = fd;
- FUSE_FOP (state, fuse_err_cbk, GF_FOP_FSYNCDIR,
- fsyncdir, fd, fsi->fsync_flags & 1);
+ state->flags = fsi->fsync_flags;
+ fuse_resolve_and_resume (state, fuse_fsyncdir_resume);
return;
}
@@ -2423,13 +2216,12 @@ fuse_statfs_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
send_fuse_err (this, finh, op_errno);
}
- free_state (state);
+ free_fuse_state (state);
STACK_DESTROY (frame->root);
return 0;
}
-
static void
fuse_statfs (xlator_t *this, fuse_in_header_t *finh, void *msg)
{
@@ -2445,7 +2237,7 @@ fuse_statfs (xlator_t *this, fuse_in_header_t *finh, void *msg)
finh->unique);
send_fuse_err (this, finh, ENOENT);
- free_state (state);
+ free_fuse_state (state);
return;
}
@@ -2456,6 +2248,16 @@ fuse_statfs (xlator_t *this, fuse_in_header_t *finh, void *msg)
statfs, &state->loc);
}
+void
+fuse_setxattr_resume (fuse_state_t *state)
+{
+ gf_log ("glusterfs-fuse", GF_LOG_TRACE,
+ "%"PRIu64": SETXATTR %s/%"PRIu64" (%s)", state->finh->unique,
+ state->loc.path, state->finh->nodeid, state->name);
+
+ FUSE_FOP (state, fuse_setxattr_cbk, GF_FOP_SETXATTR,
+ setxattr, &state->loc, state->dict, state->flags);
+}
static void
fuse_setxattr (xlator_t *this, fuse_in_header_t *finh, void *msg)
@@ -2499,7 +2301,7 @@ fuse_setxattr (xlator_t *this, fuse_in_header_t *finh, void *msg)
state->loc.path, finh->nodeid, name);
send_fuse_err (this, finh, ENOENT);
- free_state (state);
+ free_fuse_state (state);
return;
}
@@ -2509,7 +2311,7 @@ fuse_setxattr (xlator_t *this, fuse_in_header_t *finh, void *msg)
"%"PRIu64": SETXATTR dict allocation failed",
finh->unique);
- free_state (state);
+ free_fuse_state (state);
return;
}
@@ -2518,12 +2320,10 @@ fuse_setxattr (xlator_t *this, fuse_in_header_t *finh, void *msg)
data_from_dynptr ((void *)dict_value, fsi->size));
dict_ref (state->dict);
- gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRIu64": SETXATTR %s/%"PRIu64" (%s)", finh->unique,
- state->loc.path, finh->nodeid, name);
+ state->flags = fsi->flags;
+ state->name = gf_strdup (name);
- FUSE_FOP (state, fuse_setxattr_cbk, GF_FOP_SETXATTR,
- setxattr, &state->loc, state->dict, fsi->flags);
+ fuse_resolve_and_resume (state, fuse_setxattr_resume);
return;
}
@@ -2638,12 +2438,22 @@ out:
if (need_to_free_dict)
dict_unref (dict);
- free_state (state);
+ free_fuse_state (state);
STACK_DESTROY (frame->root);
return 0;
}
+void
+fuse_getxattr_resume (fuse_state_t *state)
+{
+ gf_log ("glusterfs-fuse", GF_LOG_TRACE,
+ "%"PRIu64": GETXATTR %s/%"PRIu64" (%s)", state->finh->unique,
+ state->loc.path, state->finh->nodeid, state->name);
+
+ FUSE_FOP (state, fuse_xattr_cbk, GF_FOP_GETXATTR,
+ getxattr, &state->loc, state->name);
+}
static void
fuse_getxattr (xlator_t *this, fuse_in_header_t *finh, void *msg)
@@ -2683,8 +2493,6 @@ fuse_getxattr (xlator_t *this, fuse_in_header_t *finh, void *msg)
#endif
GET_STATE (this, finh, state);
- state->size = fgxi->size;
- state->name = gf_strdup (name);
ret = fuse_loc_fill (&state->loc, state, finh->nodeid, 0, NULL);
if ((state->loc.inode == NULL) ||
@@ -2694,20 +2502,27 @@ fuse_getxattr (xlator_t *this, fuse_in_header_t *finh, void *msg)
finh->unique, state->loc.path, finh->nodeid, name);
send_fuse_err (this, finh, ENOENT);
- free_state (state);
+ free_fuse_state (state);
return;
}
- gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"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);
+ state->size = fgxi->size;
+ state->name = gf_strdup (name);
+ fuse_resolve_and_resume (state, fuse_getxattr_resume);
return;
}
+void
+fuse_listxattr_resume (fuse_state_t *state)
+{
+ gf_log ("glusterfs-fuse", GF_LOG_TRACE,
+ "%"PRIu64": LISTXATTR %s/%"PRIu64, state->finh->unique,
+ state->loc.path, state->finh->nodeid);
+
+ FUSE_FOP (state, fuse_xattr_cbk, GF_FOP_GETXATTR,
+ getxattr, &state->loc, NULL);
+}
static void
fuse_listxattr (xlator_t *this, fuse_in_header_t *finh, void *msg)
@@ -2718,7 +2533,7 @@ fuse_listxattr (xlator_t *this, fuse_in_header_t *finh, void *msg)
int32_t ret = -1;
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)) {
@@ -2727,20 +2542,26 @@ fuse_listxattr (xlator_t *this, fuse_in_header_t *finh, void *msg)
finh->unique, state->loc.path, finh->nodeid);
send_fuse_err (this, finh, ENOENT);
- free_state (state);
+ free_fuse_state (state);
return;
}
- gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRIu64": LISTXATTR %s/%"PRIu64, finh->unique,
- state->loc.path, finh->nodeid);
-
- FUSE_FOP (state, fuse_xattr_cbk, GF_FOP_GETXATTR,
- getxattr, &state->loc, NULL);
+ state->size = fgxi->size;
+ fuse_resolve_and_resume (state, fuse_listxattr_resume);
return;
}
+void
+fuse_removexattr_resume (fuse_state_t *state)
+{
+ gf_log ("glusterfs-fuse", GF_LOG_TRACE,
+ "%"PRIu64": REMOVEXATTR %s/%"PRIu64" (%s)", state->finh->unique,
+ state->loc.path, state->finh->nodeid, state->name);
+
+ FUSE_FOP (state, fuse_err_cbk, GF_FOP_REMOVEXATTR,
+ removexattr, &state->loc, state->name);
+}
static void
fuse_removexattr (xlator_t *this, fuse_in_header_t *finh, void *msg)
@@ -2760,17 +2581,12 @@ fuse_removexattr (xlator_t *this, fuse_in_header_t *finh, void *msg)
finh->unique, state->loc.path, finh->nodeid, name);
send_fuse_err (this, finh, ENOENT);
- free_state (state);
+ free_fuse_state (state);
return;
}
- gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"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);
-
+ state->name = gf_strdup (name);
+ fuse_resolve_and_resume (state, fuse_removexattr_resume);
return;
}
@@ -2817,12 +2633,21 @@ fuse_getlk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
send_fuse_err (this, state->finh, op_errno);
}
- free_state (state);
+ free_fuse_state (state);
STACK_DESTROY (frame->root);
return 0;
}
+void
+fuse_getlk_resume (fuse_state_t *state)
+{
+ gf_log ("glusterfs-fuse", GF_LOG_TRACE,
+ "%"PRIu64": GETLK %p", state->finh->unique, state->fd);
+
+ FUSE_FOP (state, fuse_getlk_cbk, GF_FOP_LK,
+ lk, state->fd, F_GETLK, &state->lk_lock);
+}
static void
fuse_getlk (xlator_t *this, fuse_in_header_t *finh, void *msg)
@@ -2831,20 +2656,15 @@ fuse_getlk (xlator_t *this, fuse_in_header_t *finh, void *msg)
fuse_state_t *state = NULL;
fd_t *fd = NULL;
- struct flock lock = {0, };
fd = FH_TO_FD (fli->fh);
GET_STATE (this, finh, state);
state->fd = fd;
- convert_fuse_file_lock (&fli->lk, &lock);
+ convert_fuse_file_lock (&fli->lk, &state->lk_lock);
state->lk_owner = fli->owner;
- gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRIu64": GETLK %p", finh->unique, fd);
-
- FUSE_FOP (state, fuse_getlk_cbk, GF_FOP_LK,
- lk, fd, F_GETLK, &lock);
+ fuse_resolve_and_resume (state, fuse_getlk_resume);
return;
}
@@ -2889,13 +2709,25 @@ fuse_setlk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
send_fuse_err (this, state->finh, op_errno);
}
- free_state (state);
+ free_fuse_state (state);
STACK_DESTROY (frame->root);
return 0;
}
+void
+fuse_setlk_resume (fuse_state_t *state)
+{
+ gf_log ("glusterfs-fuse", GF_LOG_TRACE,
+ "%"PRIu64": SETLK%s %p", state->finh->unique,
+ state->finh->opcode == FUSE_SETLK ? "" : "W", state->fd);
+
+ FUSE_FOP (state, fuse_setlk_cbk, GF_FOP_LK, lk, state->fd,
+ state->finh->opcode == FUSE_SETLK ? F_SETLK : F_SETLKW,
+ &state->lk_lock);
+}
+
static void
fuse_setlk (xlator_t *this, fuse_in_header_t *finh, void *msg)
{
@@ -2903,23 +2735,16 @@ fuse_setlk (xlator_t *this, fuse_in_header_t *finh, void *msg)
fuse_state_t *state = NULL;
fd_t *fd = NULL;
- struct flock lock = {0, };
fd = FH_TO_FD (fli->fh);
GET_STATE (this, finh, state);
state->finh = finh;
state->fd = fd;
- convert_fuse_file_lock (&fli->lk, &lock);
+ convert_fuse_file_lock (&fli->lk, &state->lk_lock);
state->lk_owner = fli->owner;
- gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRIu64": SETLK%s %p", finh->unique,
- finh->opcode == FUSE_SETLK ? "" : "W", fd);
-
- FUSE_FOP (state, fuse_setlk_cbk, GF_FOP_LK,
- lk, fd, finh->opcode == FUSE_SETLK ? F_SETLK : F_SETLKW,
- &lock);
+ fuse_resolve_and_resume (state, fuse_setlk_resume);
return;
}
@@ -3142,8 +2967,9 @@ fuse_graph_sync (xlator_t *this)
unlock:
pthread_mutex_unlock (&priv->sync_mutex);
- if (need_first_lookup)
+ if (need_first_lookup) {
fuse_first_lookup (this);
+ }
return 0;
}