summaryrefslogtreecommitdiffstats
path: root/glusterfs-guts/src/fuse-bridge.c
diff options
context:
space:
mode:
authorVijay Bellur <vijay@gluster.com>2010-03-24 04:22:33 +0000
committerAnand V. Avati <avati@dev.gluster.com>2010-03-24 05:42:29 -0700
commitbd1242b66da347e61db5f2e51638eca9e641b20d (patch)
tree5202f5c7a93b2521ebef63b6ff69db932ab47cdb /glusterfs-guts/src/fuse-bridge.c
parent08fd3a63f56c3bae0cbf57d59a3e4c32da791312 (diff)
Remove glusterfs-guts from the repository.
Goodbye, glusterfs-guts/! Signed-off-by: Vijay Bellur <vijay@gluster.com> Signed-off-by: Anand V. Avati <avati@dev.gluster.com> BUG: 734 (keep only the working/usable code in build tree to focus more on development) URL: http://bugs.gluster.com/cgi-bin/bugzilla3/show_bug.cgi?id=734
Diffstat (limited to 'glusterfs-guts/src/fuse-bridge.c')
-rw-r--r--glusterfs-guts/src/fuse-bridge.c2725
1 files changed, 0 insertions, 2725 deletions
diff --git a/glusterfs-guts/src/fuse-bridge.c b/glusterfs-guts/src/fuse-bridge.c
deleted file mode 100644
index 3b7be5f985c..00000000000
--- a/glusterfs-guts/src/fuse-bridge.c
+++ /dev/null
@@ -1,2725 +0,0 @@
-/*
- Copyright (c) 2006-2009 Gluster, Inc. <http://www.gluster.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/>.
-*/
-
-
-#include <stdint.h>
-#include <signal.h>
-#include <pthread.h>
-
-#ifndef _CONFIG_H
-#define _CONFIG_H
-#include "config.h"
-#endif /* _CONFIG_H */
-
-#include "glusterfs.h"
-#include "logging.h"
-#include "xlator.h"
-#include "glusterfs.h"
-#include "transport.h"
-#include "defaults.h"
-#include "common-utils.h"
-
-#include <fuse/fuse_lowlevel.h>
-
-#include "fuse-extra.h"
-#include "list.h"
-
-#include "guts-lowlevel.h"
-
-#define BIG_FUSE_CHANNEL_SIZE 1048576
-
-struct fuse_private {
- int fd;
- struct fuse *fuse;
- struct fuse_session *se;
- struct fuse_chan *ch;
- char *mountpoint;
-};
-
-char glusterfs_fuse_direct_io_mode = 1;
-float glusterfs_fuse_entry_timeout = 1.0;
-float glusterfs_fuse_attr_timeout = 1.0;
-
-#define FI_TO_FD(fi) ((fd_t *)((long)fi->fh))
-
-#define FUSE_FOP(state, ret, op, args ...) \
-do { \
- call_frame_t *frame = get_call_frame_for_req (state, 1); \
- xlator_t *xl = frame->this->children ? \
- frame->this->children->xlator : NULL; \
- dict_t *refs = frame->root->req_refs; \
- frame->root->state = state; \
- STACK_WIND (frame, ret, xl, xl->fops->op, args); \
- dict_unref (refs); \
-} while (0)
-
-#define FUSE_FOP_NOREPLY(state, op, args ...) \
-do { \
- call_frame_t *_frame = get_call_frame_for_req (state, 0); \
- xlator_t *xl = _frame->this->children->xlator; \
- _frame->root->req_refs = NULL; \
- STACK_WIND (_frame, fuse_nop_cbk, xl, xl->fops->op, args); \
-} while (0)
-
-typedef struct {
- loc_t loc;
- inode_t *parent;
- inode_t *inode;
- char *name;
-} fuse_loc_t;
-
-typedef struct {
- void *pool;
- xlator_t *this;
- inode_table_t *itable;
- fuse_loc_t fuse_loc;
- fuse_loc_t fuse_loc2;
- fuse_req_t req;
-
- int32_t flags;
- off_t off;
- size_t size;
- unsigned long nlookup;
- fd_t *fd;
- dict_t *dict;
- char *name;
- char is_revalidate;
-} fuse_state_t;
-
-
-static void
-loc_wipe (loc_t *loc)
-{
- if (loc->inode) {
- inode_unref (loc->inode);
- loc->inode = NULL;
- }
- if (loc->path) {
- FREE (loc->path);
- loc->path = NULL;
- }
-}
-
-
-static inode_t *
-dummy_inode (inode_table_t *table)
-{
- inode_t *dummy;
-
- dummy = CALLOC (1, sizeof (*dummy));
- ERR_ABORT (dummy);
-
- dummy->table = table;
-
- INIT_LIST_HEAD (&dummy->list);
- INIT_LIST_HEAD (&dummy->inode_hash);
- INIT_LIST_HEAD (&dummy->fds);
- INIT_LIST_HEAD (&dummy->dentry.name_hash);
- INIT_LIST_HEAD (&dummy->dentry.inode_list);
-
- dummy->ref = 1;
- dummy->ctx = get_new_dict ();
-
- LOCK_INIT (&dummy->lock);
- return dummy;
-}
-
-static void
-fuse_loc_wipe (fuse_loc_t *fuse_loc)
-{
- loc_wipe (&fuse_loc->loc);
- if (fuse_loc->name) {
- FREE (fuse_loc->name);
- fuse_loc->name = NULL;
- }
- if (fuse_loc->inode) {
- inode_unref (fuse_loc->inode);
- fuse_loc->inode = NULL;
- }
- if (fuse_loc->parent) {
- inode_unref (fuse_loc->parent);
- fuse_loc->parent = NULL;
- }
-}
-
-
-static void
-free_state (fuse_state_t *state)
-{
- fuse_loc_wipe (&state->fuse_loc);
-
- fuse_loc_wipe (&state->fuse_loc2);
-
- if (state->dict) {
- dict_unref (state->dict);
- state->dict = (void *)0xaaaaeeee;
- }
- if (state->name) {
- FREE (state->name);
- state->name = NULL;
- }
-#ifdef DEBUG
- memset (state, 0x90, sizeof (*state));
-#endif
- FREE (state);
- state = NULL;
-}
-
-
-static int32_t
-fuse_nop_cbk (call_frame_t *frame,
- void *cookie,
- xlator_t *this,
- int32_t op_ret,
- int32_t op_errno)
-{
- if (frame->root->state)
- free_state (frame->root->state);
-
- frame->root->state = EEEEKS;
- STACK_DESTROY (frame->root);
- return 0;
-}
-
-fuse_state_t *
-state_from_req (fuse_req_t req)
-{
- fuse_state_t *state;
- transport_t *trans = fuse_req_userdata (req);
-
- state = (void *)calloc (1, sizeof (*state));
- ERR_ABORT (state);
- state->pool = trans->xl->ctx->pool;
- state->itable = trans->xl->itable;
- state->req = req;
- state->this = trans->xl;
-
- return state;
-}
-
-
-static call_frame_t *
-get_call_frame_for_req (fuse_state_t *state, char d)
-{
- call_pool_t *pool = state->pool;
- fuse_req_t req = state->req;
- const struct fuse_ctx *ctx = NULL;
- call_ctx_t *cctx = NULL;
- transport_t *trans = NULL;
-
- cctx = CALLOC (1, sizeof (*cctx));
- ERR_ABORT (cctx);
- cctx->frames.root = cctx;
-
- if (req) {
- ctx = fuse_req_ctx(req);
-
- cctx->uid = ctx->uid;
- cctx->gid = ctx->gid;
- cctx->pid = ctx->pid;
- cctx->unique = req_callid (req);
- }
-
- if (req) {
- trans = fuse_req_userdata (req);
- cctx->frames.this = trans->xl;
- cctx->trans = trans;
- } else {
- cctx->frames.this = state->this;
- }
-
- if (d) {
- cctx->req_refs = dict_ref (get_new_dict ());
- dict_set (cctx->req_refs, NULL, trans->buf);
- cctx->req_refs->is_locked = 1;
- }
-
- cctx->pool = pool;
- LOCK (&pool->lock);
- list_add (&cctx->all_frames, &pool->all_frames);
- UNLOCK (&pool->lock);
-
- return &cctx->frames;
-}
-
-
-static void
-fuse_loc_fill (fuse_loc_t *fuse_loc,
- fuse_state_t *state,
- ino_t ino,
- const char *name)
-{
- size_t n;
- inode_t *inode, *parent = NULL;
-
- /* resistance against multiple invocation of loc_fill not to get
- reference leaks via inode_search() */
- inode = fuse_loc->inode;
- if (!inode) {
- inode = inode_search (state->itable, ino, name);
- }
- fuse_loc->inode = inode;
-
- if (name) {
- if (!fuse_loc->name)
- fuse_loc->name = strdup (name);
-
- parent = fuse_loc->parent;
- if (!parent) {
- if (inode)
- parent = inode_parent (inode, ino);
- else
- parent = inode_search (state->itable, ino, NULL);
- }
- }
- fuse_loc->parent = parent;
-
- if (inode) {
- fuse_loc->loc.inode = inode_ref (inode);
- fuse_loc->loc.ino = inode->ino;
- }
-
- if (parent) {
- n = inode_path (parent, name, NULL, 0) + 1;
- fuse_loc->loc.path = CALLOC (1, n);
- ERR_ABORT (fuse_loc->loc.path);
- inode_path (parent, name, (char *)fuse_loc->loc.path, n);
- } else if (inode) {
- n = inode_path (inode, NULL, NULL, 0) + 1;
- fuse_loc->loc.path = CALLOC (1, n);
- ERR_ABORT (fuse_loc->loc.path);
- inode_path (inode, NULL, (char *)fuse_loc->loc.path, n);
- }
-}
-
-static int32_t
-fuse_lookup_cbk (call_frame_t *frame,
- void *cookie,
- xlator_t *this,
- int32_t op_ret,
- int32_t op_errno,
- inode_t *inode,
- struct stat *stat,
- dict_t *dict,
- struct stat *postparent);
-
-static int32_t
-fuse_entry_cbk (call_frame_t *frame,
- void *cookie,
- xlator_t *this,
- int32_t op_ret,
- int32_t op_errno,
- inode_t *inode,
- struct stat *buf)
-{
- fuse_state_t *state;
- fuse_req_t req;
- struct fuse_entry_param e = {0, };
-
- state = frame->root->state;
- req = state->req;
-
- if (!op_ret) {
- if (inode->ino == 1)
- buf->st_ino = 1;
- }
-
- if (!op_ret && inode && inode->ino && buf && inode->ino != buf->st_ino) {
- /* temporary workaround to handle AFR returning differnt inode number */
- gf_log ("glusterfs-fuse", GF_LOG_WARNING,
- "%"PRId64": %s => inode number changed %"PRId64" -> %"PRId64,
- frame->root->unique, state->fuse_loc.loc.path,
- inode->ino, buf->st_ino);
- inode_unref (state->fuse_loc.loc.inode);
- state->fuse_loc.loc.inode = dummy_inode (state->itable);
- state->is_revalidate = 2;
-
- STACK_WIND (frame, fuse_lookup_cbk,
- FIRST_CHILD (this), FIRST_CHILD (this)->fops->lookup,
- &state->fuse_loc.loc,
- 0);
-
- return 0;
- }
-
- if (op_ret == 0) {
- ino_t ino = buf->st_ino;
- inode_t *fuse_inode;
-
- gf_log ("glusterfs-fuse", GF_LOG_DEBUG,
- "%"PRId64": %s => %"PRId64, frame->root->unique,
- state->fuse_loc.loc.path, ino);
-
- try_again:
- fuse_inode = inode_update (state->itable, state->fuse_loc.parent,
- state->fuse_loc.name, buf);
-
- if (fuse_inode->ctx) {
- /* if the inode was already in the hash, checks to flush out
- old name hashes */
- if ((fuse_inode->st_mode ^ buf->st_mode) & S_IFMT) {
- gf_log ("glusterfs-fuse", GF_LOG_WARNING,
- "%"PRId64": %s => %"PRId64" Rehashing %x/%x",
- frame->root->unique,
- state->fuse_loc.loc.path, ino, (S_IFMT & buf->st_ino),
- (S_IFMT & fuse_inode->st_mode));
-
- fuse_inode->st_mode = buf->st_mode;
- inode_unhash_name (state->itable, fuse_inode);
- inode_unref (fuse_inode);
- goto try_again;
- }
- if (buf->st_nlink == 1) {
- /* no other name hashes should exist */
- if (!list_empty (&fuse_inode->dentry.inode_list)) {
- gf_log ("glusterfs-fuse", GF_LOG_WARNING,
- "%"PRId64": %s => %"PRId64" Rehashing because st_nlink less than dentry maps",
- frame->root->unique,
- state->fuse_loc.loc.path, ino);
- inode_unhash_name (state->itable, fuse_inode);
- inode_unref (fuse_inode);
- goto try_again;
- }
- if ((state->fuse_loc.parent != fuse_inode->dentry.parent) ||
- strcmp (state->fuse_loc.name, fuse_inode->dentry.name)) {
- gf_log ("glusterfs-fuse", GF_LOG_WARNING,
- "%"PRId64": %s => %"PRId64" Rehashing because single st_nlink does not match dentry map",
- frame->root->unique,
- state->fuse_loc.loc.path, ino);
- inode_unhash_name (state->itable, fuse_inode);
- inode_unref (fuse_inode);
- goto try_again;
- }
- }
- }
-
- if ((fuse_inode->ctx != inode->ctx) &&
- list_empty (&fuse_inode->fds)) {
- dict_t *swap = inode->ctx;
- inode->ctx = fuse_inode->ctx;
- fuse_inode->ctx = swap;
- fuse_inode->generation = inode->generation;
- fuse_inode->st_mode = buf->st_mode;
- }
-
- inode_lookup (fuse_inode);
-
- inode_unref (fuse_inode);
-
- /* TODO: make these timeouts configurable (via meta?) */
- e.ino = fuse_inode->ino;
- e.generation = buf->st_ctime;
- e.entry_timeout = glusterfs_fuse_entry_timeout;
- e.attr_timeout = glusterfs_fuse_attr_timeout;
- e.attr = *buf;
- e.attr.st_blksize = BIG_FUSE_CHANNEL_SIZE;
- if (state->fuse_loc.parent)
- fuse_reply_entry (req, &e);
- else
- fuse_reply_attr (req, buf, glusterfs_fuse_attr_timeout);
- } else {
- if (state->is_revalidate == -1 && op_errno == ENOENT) {
- gf_log ("glusterfs-fuse", GF_LOG_DEBUG,
- "%"PRId64": %s => -1 (%d)", frame->root->unique,
- state->fuse_loc.loc.path, op_errno);
- } else {
- gf_log ("glusterfs-fuse", GF_LOG_ERROR,
- "%"PRId64": %s => -1 (%d)", frame->root->unique,
- state->fuse_loc.loc.path, op_errno);
- }
-
- if (state->is_revalidate == 1) {
- gf_log ("glusterfs-fuse", GF_LOG_DEBUG,
- "unlinking stale dentry for `%s'",
- state->fuse_loc.loc.path);
-
- if (state->fuse_loc.parent)
- inode_unlink (state->itable, state->fuse_loc.parent,
- state->fuse_loc.name);
-
- inode_unref (state->fuse_loc.loc.inode);
- state->fuse_loc.loc.inode = dummy_inode (state->itable);
- state->is_revalidate = 2;
-
- STACK_WIND (frame, fuse_lookup_cbk,
- FIRST_CHILD (this), FIRST_CHILD (this)->fops->lookup,
- &state->fuse_loc.loc, 0);
-
- return 0;
- }
-
- fuse_reply_err (req, op_errno);
- }
-
- free_state (state);
- STACK_DESTROY (frame->root);
- return 0;
-}
-
-
-static int32_t
-fuse_lookup_cbk (call_frame_t *frame,
- void *cookie,
- xlator_t *this,
- int32_t op_ret,
- int32_t op_errno,
- inode_t *inode,
- struct stat *stat,
- dict_t *dict)
-{
- fuse_entry_cbk (frame, cookie, this, op_ret, op_errno, inode, stat);
- return 0;
-}
-
-
-static void
-fuse_lookup (fuse_req_t req,
- fuse_ino_t par,
- const char *name)
-{
- fuse_state_t *state;
-
- state = state_from_req (req);
-
- fuse_loc_fill (&state->fuse_loc, state, par, name);
-
- if (!state->fuse_loc.loc.inode) {
- gf_log ("glusterfs-fuse", GF_LOG_DEBUG,
- "%"PRId64": LOOKUP %s", req_callid (req),
- state->fuse_loc.loc.path);
-
- state->fuse_loc.loc.inode = dummy_inode (state->itable);
- /* to differntiate in entry_cbk what kind of call it is */
- state->is_revalidate = -1;
- } else {
- gf_log ("glusterfs-fuse", GF_LOG_DEBUG,
- "%"PRId64": LOOKUP %s(%"PRId64")", req_callid (req),
- state->fuse_loc.loc.path, state->fuse_loc.loc.inode->ino);
- state->is_revalidate = 1;
- }
-
- FUSE_FOP (state, fuse_lookup_cbk, lookup,
- &state->fuse_loc.loc, 0);
-}
-
-
-static void
-fuse_forget (fuse_req_t req,
- fuse_ino_t ino,
- unsigned long nlookup)
-{
- inode_t *fuse_inode;
- fuse_state_t *state;
-
- if (ino == 1) {
- fuse_reply_none (req);
- return;
- }
-
- state = state_from_req (req);
- fuse_inode = inode_search (state->itable, ino, NULL);
- inode_forget (fuse_inode, nlookup);
- inode_unref (fuse_inode);
-
- free_state (state);
- fuse_reply_none (req);
-}
-
-
-static int32_t
-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;
-
- state = frame->root->state;
- req = state->req;
-
- if (op_ret == 0) {
- gf_log ("glusterfs-fuse", GF_LOG_DEBUG,
- "%"PRId64": %s => %"PRId64, frame->root->unique,
- state->fuse_loc.loc.path ? state->fuse_loc.loc.path : "ERR",
- buf->st_ino);
- /* TODO: make these timeouts configurable via meta */
- /* TODO: what if the inode number has changed by now */
- buf->st_blksize = BIG_FUSE_CHANNEL_SIZE;
- fuse_reply_attr (req, buf, glusterfs_fuse_attr_timeout);
- } else {
- gf_log ("glusterfs-fuse", GF_LOG_ERROR,
- "%"PRId64"; %s => -1 (%d)", frame->root->unique,
- state->fuse_loc.loc.path ? state->fuse_loc.loc.path : "ERR",
- op_errno);
- fuse_reply_err (req, op_errno);
- }
-
- free_state (state);
- STACK_DESTROY (frame->root);
- return 0;
-}
-
-
-static void
-fuse_getattr (fuse_req_t req,
- fuse_ino_t ino,
- struct fuse_file_info *fi)
-{
- fuse_state_t *state;
-
- state = state_from_req (req);
-
- if (ino == 1) {
- fuse_loc_fill (&state->fuse_loc, state, ino, NULL);
- if (state->fuse_loc.loc.inode)
- state->is_revalidate = 1;
- else
- state->is_revalidate = -1;
- FUSE_FOP (state,
- fuse_lookup_cbk, lookup, &state->fuse_loc.loc, 0);
- return;
- }
-
- fuse_loc_fill (&state->fuse_loc, state, ino, NULL);
- if (!state->fuse_loc.loc.inode) {
- gf_log ("glusterfs-fuse", GF_LOG_ERROR,
- "%"PRId64": GETATTR %"PRId64" (%s) (fuse_loc_fill() returned NULL inode)",
- req_callid (req), (int64_t)ino, state->fuse_loc.loc.path);
- fuse_reply_err (req, EINVAL);
- return;
- }
-
- if (list_empty (&state->fuse_loc.loc.inode->fds) ||
- S_ISDIR (state->fuse_loc.loc.inode->st_mode)) {
-
- gf_log ("glusterfs-fuse", GF_LOG_DEBUG,
- "%"PRId64": GETATTR %"PRId64" (%s)",
- req_callid (req), (int64_t)ino, state->fuse_loc.loc.path);
-
- FUSE_FOP (state,
- fuse_attr_cbk,
- stat,
- &state->fuse_loc.loc);
- } else {
- fd_t *fd = list_entry (state->fuse_loc.loc.inode->fds.next,
- fd_t, inode_list);
-
- gf_log ("glusterfs-fuse", GF_LOG_DEBUG,
- "%"PRId64": FGETATTR %"PRId64" (%s/%p)",
- req_callid (req), (int64_t)ino, state->fuse_loc.loc.path, fd);
-
- FUSE_FOP (state,
- fuse_attr_cbk,
- fstat, fd);
- }
-}
-
-
-static int32_t
-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;
-
- state = frame->root->state;
- req = state->req;
- fd = state->fd;
-
- if (op_ret >= 0) {
- struct fuse_file_info fi = {0, };
-
- LOCK (&fd->inode->lock);
- list_add (&fd->inode_list, &fd->inode->fds);
- UNLOCK (&fd->inode->lock);
-
- fi.fh = (unsigned long) fd;
- fi.flags = state->flags;
-
- if (!S_ISDIR (fd->inode->st_mode)) {
- if ((fi.flags & 3) && glusterfs_fuse_direct_io_mode)
- fi.direct_io = 1;
- }
-
- gf_log ("glusterfs-fuse", GF_LOG_DEBUG,
- "%"PRId64": %s => %p", frame->root->unique,
- state->fuse_loc.loc.path, fd);
-
- if (fuse_reply_open (req, &fi) == -ENOENT) {
- gf_log ("glusterfs-fuse", GF_LOG_WARNING, "open() got EINTR");
- state->req = 0;
-
- if (S_ISDIR (fd->inode->st_mode))
- FUSE_FOP_NOREPLY (state, closedir, fd);
- else
- FUSE_FOP_NOREPLY (state, close, fd);
- }
- } else {
- gf_log ("glusterfs-fuse", GF_LOG_ERROR,
- "%"PRId64": %s => -1 (%d)", frame->root->unique,
- state->fuse_loc.loc.path, op_errno);
- fuse_reply_err (req, op_errno);
- fd_destroy (fd);
- }
-
- free_state (state);
- STACK_DESTROY (frame->root);
- return 0;
-}
-
-
-
-static void
-do_chmod (fuse_req_t req,
- fuse_ino_t ino,
- struct stat *attr,
- struct fuse_file_info *fi)
-{
- fuse_state_t *state = state_from_req (req);
-
- if (fi) {
- gf_log ("glusterfs-fuse", GF_LOG_DEBUG,
- "%"PRId64": FCHMOD %p", req_callid (req), FI_TO_FD (fi));
-
- FUSE_FOP (state,
- fuse_attr_cbk,
- fchmod,
- FI_TO_FD (fi),
- attr->st_mode);
- } else {
- fuse_loc_fill (&state->fuse_loc, state, ino, NULL);
- if (!state->fuse_loc.loc.inode) {
- gf_log ("glusterfs-fuse", GF_LOG_ERROR,
- "%"PRId64": CHMOD %"PRId64" (%s) (fuse_loc_fill() returned NULL inode)",
- req_callid (req), (int64_t)ino, state->fuse_loc.loc.path);
- fuse_reply_err (req, EINVAL);
- return;
- }
-
-
- gf_log ("glusterfs-fuse", GF_LOG_DEBUG,
- "%"PRId64": CHMOD %s", req_callid (req),
- state->fuse_loc.loc.path);
-
- FUSE_FOP (state,
- fuse_attr_cbk,
- chmod,
- &state->fuse_loc.loc,
- attr->st_mode);
- }
-}
-
-static void
-do_chown (fuse_req_t req,
- fuse_ino_t ino,
- struct stat *attr,
- int valid,
- struct fuse_file_info *fi)
-{
- fuse_state_t *state;
-
- uid_t uid = (valid & FUSE_SET_ATTR_UID) ? attr->st_uid : (uid_t) -1;
- gid_t gid = (valid & FUSE_SET_ATTR_GID) ? attr->st_gid : (gid_t) -1;
-
- state = state_from_req (req);
-
- if (fi) {
- gf_log ("glusterfs-fuse", GF_LOG_DEBUG,
- "%"PRId64": FCHOWN %p", req_callid (req), FI_TO_FD (fi));
-
- FUSE_FOP (state,
- fuse_attr_cbk,
- fchown,
- FI_TO_FD (fi),
- uid,
- gid);
- } else {
- fuse_loc_fill (&state->fuse_loc, state, ino, NULL);
- if (!state->fuse_loc.loc.inode) {
- gf_log ("glusterfs-fuse", GF_LOG_ERROR,
- "%"PRId64": CHOWN %"PRId64" (%s) (fuse_loc_fill() returned NULL inode)",
- req_callid (req), (int64_t)ino, state->fuse_loc.loc.path);
- fuse_reply_err (req, EINVAL);
- return;
- }
-
- gf_log ("glusterfs-fuse", GF_LOG_DEBUG,
- "%"PRId64": CHOWN %s", req_callid (req),
- state->fuse_loc.loc.path);
-
- FUSE_FOP (state,
- fuse_attr_cbk,
- chown,
- &state->fuse_loc.loc,
- uid,
- gid);
- }
-}
-
-static void
-do_truncate (fuse_req_t req,
- fuse_ino_t ino,
- struct stat *attr,
- struct fuse_file_info *fi)
-{
- fuse_state_t *state;
-
- state = state_from_req (req);
-
- if (fi) {
- gf_log ("glusterfs-fuse", GF_LOG_DEBUG,
- "%"PRId64": FTRUNCATE %p/%"PRId64, req_callid (req),
- FI_TO_FD (fi), attr->st_size);
-
- FUSE_FOP (state,
- fuse_attr_cbk,
- ftruncate,
- FI_TO_FD (fi),
- attr->st_size);
- } else {
- fuse_loc_fill (&state->fuse_loc, state, ino, NULL);
- if (!state->fuse_loc.loc.inode) {
- gf_log ("glusterfs-fuse", GF_LOG_ERROR,
- "%"PRId64": TRUNCATE %s/%"PRId64" (fuse_loc_fill() returned NULL inode)",
- req_callid (req), state->fuse_loc.loc.path, attr->st_size);
- fuse_reply_err (req, EINVAL);
- return;
- }
-
- gf_log ("glusterfs-fuse", GF_LOG_DEBUG,
- "%"PRId64": TRUNCATE %s/%"PRId64, req_callid (req),
- state->fuse_loc.loc.path, attr->st_size);
-
- FUSE_FOP (state,
- fuse_attr_cbk,
- truncate,
- &state->fuse_loc.loc,
- attr->st_size);
- }
-
- return;
-}
-
-static void
-do_utimes (fuse_req_t req,
- fuse_ino_t ino,
- struct stat *attr)
-{
- fuse_state_t *state;
-
- struct timespec tv[2];
-#ifdef FUSE_STAT_HAS_NANOSEC
- tv[0] = ST_ATIM(attr);
- tv[1] = ST_MTIM(attr);
-#else
- tv[0].tv_sec = attr->st_atime;
- tv[0].tv_nsec = 0;
- tv[1].tv_sec = attr->st_mtime;
- tv[1].tv_nsec = 0;
-#endif
-
- state = state_from_req (req);
- fuse_loc_fill (&state->fuse_loc, state, ino, NULL);
- if (!state->fuse_loc.loc.inode) {
- gf_log ("glusterfs-fuse", GF_LOG_ERROR,
- "%"PRId64": UTIMENS %s (fuse_loc_fill() returned NULL inode)",
- req_callid (req), state->fuse_loc.loc.path);
- fuse_reply_err (req, EINVAL);
- return;
- }
-
- gf_log ("glusterfs-fuse", GF_LOG_DEBUG,
- "%"PRId64": UTIMENS %s", req_callid (req),
- state->fuse_loc.loc.path);
-
- FUSE_FOP (state,
- fuse_attr_cbk,
- utimens,
- &state->fuse_loc.loc,
- tv);
-}
-
-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)) == (FUSE_SET_ATTR_ATIME | FUSE_SET_ATTR_MTIME))
- do_utimes (req, ino, attr);
-
- if (!valid)
- fuse_getattr (req, ino, fi);
-}
-
-
-static int32_t
-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;
-
- if (op_ret == 0) {
- gf_log ("glusterfs-fuse", GF_LOG_DEBUG,
- "%"PRId64": %s => 0", frame->root->unique,
- state->fuse_loc.loc.path ? state->fuse_loc.loc.path : "ERR");
- fuse_reply_err (req, 0);
- } else {
- gf_log ("glusterfs-fuse", GF_LOG_ERROR,
- "%"PRId64": %s => -1 (%d)", frame->root->unique,
- state->fuse_loc.loc.path ? state->fuse_loc.loc.path : "ERR",
- op_errno);
- fuse_reply_err (req, op_errno);
- }
-
- if (state->fd)
- fd_destroy (state->fd);
-
- free_state (state);
- STACK_DESTROY (frame->root);
-
- return 0;
-}
-
-
-
-static int32_t
-fuse_unlink_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;
-
- if (op_ret == 0)
- inode_unlink (state->itable, state->fuse_loc.parent, state->fuse_loc.name);
-
- if (op_ret == 0) {
- gf_log ("glusterfs-fuse", GF_LOG_DEBUG,
- "%"PRId64": %s => 0", frame->root->unique,
- state->fuse_loc.loc.path);
-
- fuse_reply_err (req, 0);
- } else {
- gf_log ("glusterfs-fuse", (op_errno == ENOTEMPTY) ? GF_LOG_DEBUG : GF_LOG_ERROR,
- "%"PRId64": %s => -1 (%d)", frame->root->unique,
- state->fuse_loc.loc.path, op_errno);
-
- fuse_reply_err (req, op_errno);
- }
-
- free_state (state);
- STACK_DESTROY (frame->root);
-
- return 0;
-}
-
-
-static void
-fuse_access (fuse_req_t req,
- fuse_ino_t ino,
- int mask)
-{
- fuse_state_t *state;
-
- state = state_from_req (req);
-
- fuse_loc_fill (&state->fuse_loc, state, ino, NULL);
- if (!state->fuse_loc.loc.inode) {
- gf_log ("glusterfs-fuse", GF_LOG_ERROR,
- "%"PRId64": ACCESS %"PRId64" (%s) (fuse_loc_fill() returned NULL inode)",
- req_callid (req), (int64_t)ino, state->fuse_loc.loc.path);
- fuse_reply_err (req, EINVAL);
- return;
- }
-
- FUSE_FOP (state,
- fuse_err_cbk,
- access,
- &state->fuse_loc.loc,
- mask);
-
- return;
-}
-
-
-
-static int32_t
-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 = frame->root->state;
- fuse_req_t req = state->req;
-
- if (op_ret > 0) {
- ((char *)linkname)[op_ret] = '\0';
-
- gf_log ("glusterfs-fuse", GF_LOG_DEBUG,
- "%"PRId64": %s => %s", frame->root->unique,
- state->fuse_loc.loc.path, linkname);
-
- fuse_reply_readlink(req, linkname);
- } else {
- gf_log ("glusterfs-fuse", GF_LOG_ERROR,
- "%"PRId64": %s => -1 (%d)", frame->root->unique,
- state->fuse_loc.loc.path, op_errno);
- fuse_reply_err(req, op_errno);
- }
-
- free_state (state);
- STACK_DESTROY (frame->root);
-
- return 0;
-}
-
-static void
-fuse_readlink (fuse_req_t req,
- fuse_ino_t ino)
-{
- fuse_state_t *state;
-
- state = state_from_req (req);
- fuse_loc_fill (&state->fuse_loc, state, ino, NULL);
- if (!state->fuse_loc.loc.inode) {
- gf_log ("glusterfs-fuse", GF_LOG_ERROR,
- "%"PRId64" READLINK %s/%"PRId64" (fuse_loc_fill() returned NULL inode)",
- req_callid (req), state->fuse_loc.loc.path, state->fuse_loc.loc.inode->ino);
- fuse_reply_err (req, EINVAL);
- return;
- }
-
- gf_log ("glusterfs-fuse", GF_LOG_DEBUG,
- "%"PRId64" READLINK %s/%"PRId64, req_callid (req),
- state->fuse_loc.loc.path, state->fuse_loc.loc.inode->ino);
-
- FUSE_FOP (state,
- fuse_readlink_cbk,
- readlink,
- &state->fuse_loc.loc,
- 4096);
-
- return;
-}
-
-
-static void
-fuse_mknod (fuse_req_t req,
- fuse_ino_t par,
- const char *name,
- mode_t mode,
- dev_t rdev)
-{
- fuse_state_t *state;
-
- state = state_from_req (req);
- fuse_loc_fill (&state->fuse_loc, state, par, name);
-
- state->fuse_loc.loc.inode = dummy_inode (state->itable);
-
- gf_log ("glusterfs-fuse", GF_LOG_DEBUG,
- "%"PRId64": MKNOD %s", req_callid (req),
- state->fuse_loc.loc.path);
-
- FUSE_FOP (state,
- fuse_entry_cbk,
- mknod,
- &state->fuse_loc.loc,
- mode,
- rdev);
-
- return;
-}
-
-
-static void
-fuse_mkdir (fuse_req_t req,
- fuse_ino_t par,
- const char *name,
- mode_t mode)
-{
- fuse_state_t *state;
-
- state = state_from_req (req);
- fuse_loc_fill (&state->fuse_loc, state, par, name);
-
- state->fuse_loc.loc.inode = dummy_inode (state->itable);
-
- gf_log ("glusterfs-fuse", GF_LOG_DEBUG,
- "%"PRId64": MKDIR %s", req_callid (req),
- state->fuse_loc.loc.path);
-
- FUSE_FOP (state,
- fuse_entry_cbk,
- mkdir,
- &state->fuse_loc.loc,
- mode);
-
- return;
-}
-
-
-static void
-fuse_unlink (fuse_req_t req,
- fuse_ino_t par,
- const char *name)
-{
- fuse_state_t *state;
-
- state = state_from_req (req);
-
- gf_log ("glusterfs-fuse", GF_LOG_DEBUG,
- "%"PRId64": UNLINK %s", req_callid (req),
- state->fuse_loc.loc.path);
-
- fuse_loc_fill (&state->fuse_loc, state, par, name);
- if (!state->fuse_loc.loc.inode) {
- gf_log ("glusterfs-fuse", GF_LOG_ERROR,
- "%"PRId64": UNLINK %s (fuse_loc_fill() returned NULL inode)", req_callid (req),
- state->fuse_loc.loc.path);
- fuse_reply_err (req, EINVAL);
- return;
- }
-
- FUSE_FOP (state,
- fuse_unlink_cbk,
- unlink,
- &state->fuse_loc.loc);
-
- return;
-}
-
-
-static void
-fuse_rmdir (fuse_req_t req,
- fuse_ino_t par,
- const char *name)
-{
- fuse_state_t *state;
-
- state = state_from_req (req);
- fuse_loc_fill (&state->fuse_loc, state, par, name);
- if (!state->fuse_loc.loc.inode) {
- gf_log ("glusterfs-fuse", GF_LOG_DEBUG,
- "%"PRId64": RMDIR %s (fuse_loc_fill() returned NULL inode)", req_callid (req),
- state->fuse_loc.loc.path);
- fuse_reply_err (req, EINVAL);
- return;
- }
-
- gf_log ("glusterfs-fuse", GF_LOG_DEBUG,
- "%"PRId64": RMDIR %s", req_callid (req),
- state->fuse_loc.loc.path);
-
- FUSE_FOP (state,
- fuse_unlink_cbk,
- rmdir,
- &state->fuse_loc.loc);
-
- return;
-}
-
-
-static void
-fuse_symlink (fuse_req_t req,
- const char *linkname,
- fuse_ino_t par,
- const char *name)
-{
- fuse_state_t *state;
-
- state = state_from_req (req);
- fuse_loc_fill (&state->fuse_loc, state, par, name);
-
- state->fuse_loc.loc.inode = dummy_inode (state->itable);
-
- gf_log ("glusterfs-fuse", GF_LOG_DEBUG,
- "%"PRId64": SYMLINK %s -> %s", req_callid (req),
- state->fuse_loc.loc.path, linkname);
-
- FUSE_FOP (state,
- fuse_entry_cbk,
- symlink,
- linkname,
- &state->fuse_loc.loc);
- return;
-}
-
-
-int32_t
-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 = frame->root->state;
- fuse_req_t req = state->req;
-
- if (op_ret == 0) {
- gf_log ("glusterfs-fuse", GF_LOG_DEBUG,
- "%"PRId64": %s -> %s => 0", frame->root->unique,
- state->fuse_loc.loc.path,
- state->fuse_loc2.loc.path);
-
- inode_t *inode;
- {
- /* ugly ugly - to stay blind to situation where
- rename happens on a new inode
- */
- buf->st_ino = state->fuse_loc.loc.ino;
- }
- inode = inode_rename (state->itable,
- state->fuse_loc.parent,
- state->fuse_loc.name,
- state->fuse_loc2.parent,
- state->fuse_loc2.name,
- buf);
-
- inode_unref (inode);
- fuse_reply_err (req, 0);
- } else {
- gf_log ("glusterfs-fuse", GF_LOG_ERROR,
- "%"PRId64": %s -> %s => -1 (%d)", frame->root->unique,
- state->fuse_loc.loc.path,
- state->fuse_loc2.loc.path, op_errno);
- fuse_reply_err (req, op_errno);
- }
-
- free_state (state);
- STACK_DESTROY (frame->root);
- return 0;
-}
-
-
-static void
-fuse_rename (fuse_req_t req,
- fuse_ino_t oldpar,
- const char *oldname,
- fuse_ino_t newpar,
- const char *newname)
-{
- fuse_state_t *state;
-
- state = state_from_req (req);
-
- fuse_loc_fill (&state->fuse_loc, state, oldpar, oldname);
- if (!state->fuse_loc.loc.inode) {
- gf_log ("glusterfs-fuse", GF_LOG_ERROR,
- "for %s %"PRId64": RENAME `%s' -> `%s' (fuse_loc_fill() returned NULL inode)",
- state->fuse_loc.loc.path, req_callid (req), state->fuse_loc.loc.path,
- state->fuse_loc2.loc.path);
-
- fuse_reply_err (req, EINVAL);
- return;
- }
-
- fuse_loc_fill (&state->fuse_loc2, state, newpar, newname);
-
- gf_log ("glusterfs-fuse", GF_LOG_DEBUG,
- "%"PRId64": RENAME `%s' -> `%s'",
- req_callid (req), state->fuse_loc.loc.path,
- state->fuse_loc2.loc.path);
-
- FUSE_FOP (state,
- fuse_rename_cbk,
- rename,
- &state->fuse_loc.loc,
- &state->fuse_loc2.loc);
-
- return;
-}
-
-
-static void
-fuse_link (fuse_req_t req,
- fuse_ino_t ino,
- fuse_ino_t par,
- const char *name)
-{
- fuse_state_t *state;
-
- state = state_from_req (req);
-
- fuse_loc_fill (&state->fuse_loc, state, par, name);
- fuse_loc_fill (&state->fuse_loc2, state, ino, NULL);
- if (!state->fuse_loc2.loc.inode) {
- gf_log ("glusterfs-fuse", GF_LOG_ERROR,
- "fuse_loc_fill() returned NULL inode for %s %"PRId64": LINK %s %s",
- state->fuse_loc2.loc.path, req_callid (req),
- state->fuse_loc2.loc.path, state->fuse_loc.loc.path);
- fuse_reply_err (req, EINVAL);
- return;
- }
-
- state->fuse_loc.loc.inode = inode_ref (state->fuse_loc2.loc.inode);
- gf_log ("glusterfs-fuse", GF_LOG_DEBUG,
- "%"PRId64": LINK %s %s", req_callid (req),
- state->fuse_loc2.loc.path, state->fuse_loc.loc.path);
-
- FUSE_FOP (state,
- fuse_entry_cbk,
- link,
- &state->fuse_loc2.loc,
- state->fuse_loc.loc.path);
-
- return;
-}
-
-
-static int32_t
-fuse_create_cbk (call_frame_t *frame,
- void *cookie,
- xlator_t *this,
- int32_t op_ret,
- int32_t op_errno,
- fd_t *fd,
- inode_t *inode,
- struct stat *buf)
-{
- fuse_state_t *state = frame->root->state;
- fuse_req_t req = state->req;
-
- struct fuse_file_info fi = {0, };
- struct fuse_entry_param e = {0, };
-
- fd = state->fd;
-
- fi.flags = state->flags;
- if (op_ret >= 0) {
- inode_t *fuse_inode;
- fi.fh = (unsigned long) fd;
-
- if ((fi.flags & 3) && glusterfs_fuse_direct_io_mode)
- fi.direct_io = 1;
-
- gf_log ("glusterfs-fuse", GF_LOG_DEBUG,
- "%"PRId64": %s => %p", frame->root->unique,
- state->fuse_loc.loc.path, fd);
-
- fuse_inode = inode_update (state->itable,
- state->fuse_loc.parent,
- state->fuse_loc.name,
- buf);
- if (fuse_inode->ctx) {
- inode_unhash_name (state->itable, fuse_inode);
- inode_unref (fuse_inode);
-
- fuse_inode = inode_update (state->itable,
- state->fuse_loc.parent,
- state->fuse_loc.name,
- buf);
- }
-
-
- {
- if (fuse_inode->ctx != inode->ctx) {
- dict_t *swap = inode->ctx;
- inode->ctx = fuse_inode->ctx;
- fuse_inode->ctx = swap;
- fuse_inode->generation = inode->generation;
- fuse_inode->st_mode = buf->st_mode;
- }
-
- inode_lookup (fuse_inode);
-
- /* list_del (&fd->inode_list); */
-
- LOCK (&fuse_inode->lock);
- list_add (&fd->inode_list, &fuse_inode->fds);
- inode_unref (fd->inode);
- fd->inode = inode_ref (fuse_inode);
- UNLOCK (&fuse_inode->lock);
-
- // inode_destroy (inode);
- }
-
- inode_unref (fuse_inode);
-
- e.ino = fuse_inode->ino;
- e.generation = buf->st_ctime;
- e.entry_timeout = glusterfs_fuse_entry_timeout;
- e.attr_timeout = glusterfs_fuse_attr_timeout;
- e.attr = *buf;
- e.attr.st_blksize = BIG_FUSE_CHANNEL_SIZE;
-
- fi.keep_cache = 0;
-
- // if (fi.flags & 1)
- // fi.direct_io = 1;
-
- if (fuse_reply_create (req, &e, &fi) == -ENOENT) {
- gf_log ("glusterfs-fuse", GF_LOG_WARNING, "create() got EINTR");
- /* TODO: forget this node too */
- state->req = 0;
- FUSE_FOP_NOREPLY (state, close, fd);
- }
- } else {
- gf_log ("glusterfs-fuse", GF_LOG_ERROR,
- "%"PRId64": %s => -1 (%d)", req_callid (req),
- state->fuse_loc.loc.path, op_errno);
- fuse_reply_err (req, op_errno);
- fd_destroy (fd);
- }
-
- free_state (state);
- STACK_DESTROY (frame->root);
-
- return 0;
-}
-
-
-static void
-fuse_create (fuse_req_t req,
- fuse_ino_t par,
- const char *name,
- mode_t mode,
- struct fuse_file_info *fi)
-{
- fuse_state_t *state;
- fd_t *fd;
-
- state = state_from_req (req);
- state->flags = fi->flags;
-
- fuse_loc_fill (&state->fuse_loc, state, par, name);
- state->fuse_loc.loc.inode = dummy_inode (state->itable);
-
- fd = fd_create (state->fuse_loc.loc.inode);
- state->fd = fd;
-
-
- LOCK (&fd->inode->lock);
- list_del_init (&fd->inode_list);
- UNLOCK (&fd->inode->lock);
-
- gf_log ("glusterfs-fuse", GF_LOG_DEBUG,
- "%"PRId64": CREATE %s", req_callid (req),
- state->fuse_loc.loc.path);
-
- FUSE_FOP (state,
- fuse_create_cbk,
- create,
- &state->fuse_loc.loc,
- state->flags,
- mode, fd);
-
- return;
-}
-
-
-static void
-fuse_open (fuse_req_t req,
- fuse_ino_t ino,
- struct fuse_file_info *fi)
-{
- fuse_state_t *state;
- fd_t *fd;
-
- state = state_from_req (req);
- state->flags = fi->flags;
-
- fuse_loc_fill (&state->fuse_loc, state, ino, NULL);
- if (!state->fuse_loc.loc.inode) {
- gf_log ("glusterfs-fuse", GF_LOG_ERROR,
- "%"PRId64": OPEN %s (fuse_loc_fill() returned NULL inode)", req_callid (req),
- state->fuse_loc.loc.path);
-
- fuse_reply_err (req, EINVAL);
- return;
- }
-
-
- fd = fd_create (state->fuse_loc.loc.inode);
- state->fd = fd;
-
- LOCK (&fd->inode->lock);
- list_del_init (&fd->inode_list);
- UNLOCK (&fd->inode->lock);
-
- gf_log ("glusterfs-fuse", GF_LOG_DEBUG,
- "%"PRId64": OPEN %s", req_callid (req),
- state->fuse_loc.loc.path);
-
- FUSE_FOP (state,
- fuse_fd_cbk,
- open,
- &state->fuse_loc.loc,
- fi->flags, fd);
-
- return;
-}
-
-
-static int32_t
-fuse_readv_cbk (call_frame_t *frame,
- void *cookie,
- xlator_t *this,
- int32_t op_ret,
- int32_t op_errno,
- struct iovec *vector,
- int32_t count,
- struct stat *stbuf)
-{
- fuse_state_t *state = frame->root->state;
- fuse_req_t req = state->req;
-
- if (op_ret >= 0) {
- gf_log ("glusterfs-fuse", GF_LOG_DEBUG,
- "%"PRId64": READ => %d/%d,%"PRId64"/%"PRId64, frame->root->unique,
- op_ret, state->size, state->off, stbuf->st_size);
-
- fuse_reply_vec (req, vector, count);
- } else {
- gf_log ("glusterfs-fuse", GF_LOG_ERROR,
- "%"PRId64": READ => -1 (%d)", frame->root->unique, op_errno);
-
- fuse_reply_err (req, op_errno);
- }
-
- free_state (state);
- STACK_DESTROY (frame->root);
-
- return 0;
-}
-
-static void
-fuse_readv (fuse_req_t req,
- fuse_ino_t ino,
- size_t size,
- off_t off,
- struct fuse_file_info *fi)
-{
- fuse_state_t *state;
-
- state = state_from_req (req);
- state->size = size;
- state->off = off;
-
- gf_log ("glusterfs-fuse", GF_LOG_DEBUG,
- "%"PRId64": READ (%p, size=%d, offset=%"PRId64")",
- req_callid (req), FI_TO_FD (fi), size, off);
-
- FUSE_FOP (state,
- fuse_readv_cbk,
- readv,
- FI_TO_FD (fi),
- size,
- off);
-
-}
-
-
-static int32_t
-fuse_writev_cbk (call_frame_t *frame,
- void *cookie,
- xlator_t *this,
- int32_t op_ret,
- int32_t op_errno,
- struct stat *stbuf)
-{
- fuse_state_t *state = frame->root->state;
- fuse_req_t req = state->req;
-
- if (op_ret >= 0) {
- gf_log ("glusterfs-fuse", GF_LOG_DEBUG,
- "%"PRId64": WRITE => %d/%d,%"PRId64"/%"PRId64, frame->root->unique,
- op_ret, state->size, state->off, stbuf->st_size);
-
- fuse_reply_write (req, op_ret);
- } else {
- gf_log ("glusterfs-fuse", GF_LOG_ERROR,
- "%"PRId64": WRITE => -1 (%d)", frame->root->unique, op_errno);
-
- fuse_reply_err (req, op_errno);
- }
-
- free_state (state);
- STACK_DESTROY (frame->root);
-
- return 0;
-}
-
-
-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_state_t *state;
- struct iovec vector;
-
- state = state_from_req (req);
- state->size = size;
- state->off = off;
-
- vector.iov_base = (void *)buf;
- vector.iov_len = size;
-
- gf_log ("glusterfs-fuse", GF_LOG_DEBUG,
- "%"PRId64": WRITE (%p, size=%d, offset=%"PRId64")",
- req_callid (req), FI_TO_FD (fi), size, off);
-
- FUSE_FOP (state,
- fuse_writev_cbk,
- writev,
- FI_TO_FD (fi),
- &vector,
- 1,
- off);
- return;
-}
-
-
-static void
-fuse_flush (fuse_req_t req,
- fuse_ino_t ino,
- struct fuse_file_info *fi)
-{
- fuse_state_t *state;
-
- state = state_from_req (req);
-
- gf_log ("glusterfs-fuse", GF_LOG_DEBUG,
- "%"PRId64": FLUSH %p", req_callid (req), FI_TO_FD (fi));
-
- FUSE_FOP (state,
- fuse_err_cbk,
- flush,
- FI_TO_FD (fi));
-
- return;
-}
-
-
-static void
-fuse_release (fuse_req_t req,
- fuse_ino_t ino,
- struct fuse_file_info *fi)
-{
- fuse_state_t *state;
-
- state = state_from_req (req);
- state->fd = FI_TO_FD (fi);
-
- LOCK (&state->fd->inode->lock);
- list_del_init (&state->fd->inode_list);
- UNLOCK (&state->fd->inode->lock);
-
- gf_log ("glusterfs-fuse", GF_LOG_DEBUG,
- "%"PRId64": CLOSE %p", req_callid (req), FI_TO_FD (fi));
-
- FUSE_FOP (state, fuse_err_cbk, close, state->fd);
- return;
-}
-
-
-static void
-fuse_fsync (fuse_req_t req,
- fuse_ino_t ino,
- int datasync,
- struct fuse_file_info *fi)
-{
- fuse_state_t *state;
-
- state = state_from_req (req);
-
- gf_log ("glusterfs-fuse", GF_LOG_DEBUG,
- "%"PRId64": FSYNC %p", req_callid (req), FI_TO_FD (fi));
-
- FUSE_FOP (state,
- fuse_err_cbk,
- fsync,
- FI_TO_FD (fi),
- datasync);
-
- return;
-}
-
-static void
-fuse_opendir (fuse_req_t req,
- fuse_ino_t ino,
- struct fuse_file_info *fi)
-{
- fuse_state_t *state;
- fd_t *fd;
-
- state = state_from_req (req);
- fuse_loc_fill (&state->fuse_loc, state, ino, NULL);
- if (!state->fuse_loc.loc.inode) {
- gf_log ("glusterfs-fuse", GF_LOG_ERROR,
- "%"PRId64": OPEN %s (fuse_loc_fill() returned NULL inode)", req_callid (req),
- state->fuse_loc.loc.path);
-
- fuse_reply_err (req, EINVAL);
- return;
- }
-
-
- fd = fd_create (state->fuse_loc.loc.inode);
- state->fd = fd;
-
- LOCK (&fd->inode->lock);
- list_del_init (&fd->inode_list);
- UNLOCK (&fd->inode->lock);
-
- gf_log ("glusterfs-fuse", GF_LOG_DEBUG,
- "%"PRId64": OPEN %s", req_callid (req),
- state->fuse_loc.loc.path);
-
- FUSE_FOP (state,
- fuse_fd_cbk,
- opendir,
- &state->fuse_loc.loc, fd);
-}
-
-#if 0
-
-void
-fuse_dir_reply (fuse_req_t req,
- size_t size,
- off_t off,
- fd_t *fd)
-{
- char *buf;
- size_t size_limited;
- data_t *buf_data;
-
- buf_data = dict_get (fd->ctx, "__fuse__getdents__internal__@@!!");
- buf = buf_data->data;
- size_limited = size;
-
- if (size_limited > (buf_data->len - off))
- size_limited = (buf_data->len - off);
-
- if (off > buf_data->len) {
- size_limited = 0;
- off = 0;
- }
-
- fuse_reply_buf (req, buf + off, size_limited);
-}
-
-
-static int32_t
-fuse_getdents_cbk (call_frame_t *frame,
- void *cookie,
- xlator_t *this,
- int32_t op_ret,
- int32_t op_errno,
- dir_entry_t *entries,
- int32_t count)
-{
- fuse_state_t *state = frame->root->state;
- fuse_req_t req = state->req;
-
- if (op_ret < 0) {
- gf_log ("glusterfs-fuse", GF_LOG_ERROR,
- "%"PRId64": READDIR => -1 (%d)",
- frame->root->unique, op_errno);
-
- fuse_reply_err (state->req, op_errno);
- } else {
- dir_entry_t *trav;
- size_t size = 0;
- char *buf;
- data_t *buf_data;
-
- gf_log ("glusterfs-fuse", GF_LOG_DEBUG,
- "%"PRId64": READDIR => %d entries",
- frame->root->unique, count);
-
- for (trav = entries->next; trav; trav = trav->next) {
- size += fuse_add_direntry (req, NULL, 0, trav->name, NULL, 0);
- }
-
- buf = CALLOC (1, size);
- ERR_ABORT (buf);
- buf_data = data_from_dynptr (buf, size);
- size = 0;
-
- for (trav = entries->next; trav; trav = trav->next) {
- size_t entry_size;
- entry_size = fuse_add_direntry (req, NULL, 0, trav->name, NULL, 0);
- fuse_add_direntry (req, buf + size, entry_size, trav->name,
- &trav->buf, entry_size + size);
- size += entry_size;
- }
-
- dict_set (state->fd->ctx,
- "__fuse__getdents__internal__@@!!",
- buf_data);
-
- fuse_dir_reply (state->req, state->size, state->off, state->fd);
- }
-
- free_state (state);
- STACK_DESTROY (frame->root);
-
- return 0;
-}
-
-static void
-fuse_getdents (fuse_req_t req,
- fuse_ino_t ino,
- struct fuse_file_info *fi,
- size_t size,
- off_t off,
- int32_t flag)
-{
- fuse_state_t *state;
- fd_t *fd = FI_TO_FD (fi);
-
- gf_log ("glusterfs-fuse", GF_LOG_DEBUG,
- "%"PRId64": GETDENTS %p", req_callid (req), FI_TO_FD (fi));
-
- if (!off)
- dict_del (fd->ctx, "__fuse__getdents__internal__@@!!");
-
- if (dict_get (fd->ctx, "__fuse__getdents__internal__@@!!")) {
- fuse_dir_reply (req, size, off, fd);
- return;
- }
-
- state = state_from_req (req);
-
- state->size = size;
- state->off = off;
- state->fd = fd;
-
- FUSE_FOP (state,
- fuse_getdents_cbk,
- getdents,
- fd,
- size,
- off,
- 0);
-}
-
-#endif
-
-static int32_t
-fuse_readdir_cbk (call_frame_t *frame,
- void *cookie,
- xlator_t *this,
- int32_t op_ret,
- int32_t op_errno,
- gf_dirent_t *buf)
-{
- fuse_state_t *state = frame->root->state;
- fuse_req_t req = state->req;
-
- if (op_ret >= 0) {
- gf_log ("glusterfs-fuse", GF_LOG_DEBUG,
- "%"PRId64": READDIR => %d/%d,%"PRId64, frame->root->unique,
- op_ret, state->size, state->off);
-
- fuse_reply_buf (req, (void *)buf, op_ret);
- } else {
- gf_log ("glusterfs-fuse", GF_LOG_ERROR,
- "%"PRId64": READDIR => -1 (%d)", frame->root->unique, op_errno);
-
- fuse_reply_err (req, op_errno);
- }
-
- free_state (state);
- STACK_DESTROY (frame->root);
-
- return 0;
-
-}
-
-static void
-fuse_readdir (fuse_req_t req,
- fuse_ino_t ino,
- size_t size,
- off_t off,
- struct fuse_file_info *fi)
-{
- fuse_state_t *state;
-
- state = state_from_req (req);
- state->size = size;
- state->off = off;
-
- gf_log ("glusterfs-fuse", GF_LOG_DEBUG,
- "%"PRId64": READDIR (%p, size=%d, offset=%"PRId64")",
- req_callid (req), FI_TO_FD (fi), size, off);
-
- FUSE_FOP (state,
- fuse_readdir_cbk,
- readdir,
- FI_TO_FD (fi),
- size,
- off);
-}
-
-
-static void
-fuse_releasedir (fuse_req_t req,
- fuse_ino_t ino,
- struct fuse_file_info *fi)
-{
- fuse_state_t *state;
-
- state = state_from_req (req);
- state->fd = FI_TO_FD (fi);
-
- LOCK (&state->fd->inode->lock);
- list_del_init (&state->fd->inode_list);
- UNLOCK (&state->fd->inode->lock);
-
- gf_log ("glusterfs-fuse", GF_LOG_DEBUG,
- "%"PRId64": CLOSEDIR %p", req_callid (req), FI_TO_FD (fi));
-
- FUSE_FOP (state, fuse_err_cbk, closedir, state->fd);
-}
-
-
-static void
-fuse_fsyncdir (fuse_req_t req,
- fuse_ino_t ino,
- int datasync,
- struct fuse_file_info *fi)
-{
- fuse_state_t *state;
-
- state = state_from_req (req);
-
- FUSE_FOP (state,
- fuse_err_cbk,
- fsyncdir,
- FI_TO_FD (fi),
- datasync);
-
- return;
-}
-
-
-static int32_t
-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 = frame->root->state;
- fuse_req_t req = state->req;
-
- /*
- Filesystems (like ZFS on solaris) reports
- different ->f_frsize and ->f_bsize. Old coreutils
- df tools use statfs() and do not see ->f_frsize.
- the ->f_blocks, ->f_bavail and ->f_bfree are
- w.r.t ->f_frsize and not ->f_bsize which makes the
- df tools report wrong values.
-
- Scale the block counts to match ->f_bsize.
- */
- /* TODO: with old coreutils, f_bsize is taken from stat()'s st_blksize
- * so the df with old coreutils this wont work :(
- */
-
- if (op_ret == 0) {
-
- buf->f_blocks *= buf->f_frsize;
- buf->f_blocks /= BIG_FUSE_CHANNEL_SIZE;
-
- buf->f_bavail *= buf->f_frsize;
- buf->f_bavail /= BIG_FUSE_CHANNEL_SIZE;
-
- buf->f_bfree *= buf->f_frsize;
- buf->f_bfree /= BIG_FUSE_CHANNEL_SIZE;
-
- buf->f_frsize = buf->f_bsize = BIG_FUSE_CHANNEL_SIZE;
-
- fuse_reply_statfs (req, buf);
-
- } else {
- gf_log ("glusterfs-fuse", GF_LOG_ERROR,
- "%"PRId64": ERR => -1 (%d)", frame->root->unique, op_errno);
- fuse_reply_err (req, op_errno);
- }
-
- free_state (state);
- STACK_DESTROY (frame->root);
-
- return 0;
-}
-
-
-static void
-fuse_statfs (fuse_req_t req,
- fuse_ino_t ino)
-{
- fuse_state_t *state;
-
- state = state_from_req (req);
- fuse_loc_fill (&state->fuse_loc, state, 1, NULL);
- if (!state->fuse_loc.loc.inode) {
- gf_log ("glusterfs-fuse", GF_LOG_ERROR,
- "%"PRId64": STATFS (fuse_loc_fill() returned NULL inode)", req_callid (req));
-
- fuse_reply_err (req, EINVAL);
- return;
- }
-
- gf_log ("glusterfs-fuse", GF_LOG_DEBUG,
- "%"PRId64": STATFS", req_callid (req));
-
- FUSE_FOP (state,
- fuse_statfs_cbk,
- statfs,
- &state->fuse_loc.loc);
-}
-
-static void
-fuse_setxattr (fuse_req_t req,
- fuse_ino_t ino,
- const char *name,
- const char *value,
- size_t size,
- int flags)
-{
- fuse_state_t *state;
-
- state = state_from_req (req);
- state->size = size;
- fuse_loc_fill (&state->fuse_loc, state, ino, NULL);
- if (!state->fuse_loc.loc.inode) {
- gf_log ("glusterfs-fuse", GF_LOG_ERROR,
- "%"PRId64": SETXATTR %s/%"PRId64" (%s) (fuse_loc_fill() returned NULL inode)",
- req_callid (req),
- state->fuse_loc.loc.path, (int64_t)ino, name);
-
- fuse_reply_err (req, EINVAL);
- return;
- }
-
- state->dict = get_new_dict ();
-
- dict_set (state->dict, (char *)name,
- bin_to_data ((void *)value, size));
- dict_ref (state->dict);
-
- gf_log ("glusterfs-fuse", GF_LOG_DEBUG,
- "%"PRId64": SETXATTR %s/%"PRId64" (%s)", req_callid (req),
- state->fuse_loc.loc.path, (int64_t)ino, name);
-
- FUSE_FOP (state,
- fuse_err_cbk,
- setxattr,
- &state->fuse_loc.loc,
- state->dict,
- flags);
-
- return;
-}
-
-
-static int32_t
-fuse_xattr_cbk (call_frame_t *frame,
- void *cookie,
- xlator_t *this,
- int32_t op_ret,
- int32_t op_errno,
- dict_t *dict)
-{
- int32_t ret = op_ret;
- char *value = "";
- fuse_state_t *state = frame->root->state;
- fuse_req_t req = state->req;
-
- if (ret >= 0) {
- gf_log ("glusterfs-fuse", GF_LOG_DEBUG,
- "%"PRId64": %s => %d", frame->root->unique,
- state->fuse_loc.loc.path, op_ret);
-
- /* if successful */
- if (state->name) {
- /* if callback for getxattr */
- data_t *value_data = dict_get (dict, state->name);
- if (value_data) {
- ret = value_data->len; /* Don't return the value for '\0' */
- value = value_data->data;
-
- if (state->size) {
- /* if callback for getxattr and asks for value */
- fuse_reply_buf (req, value, ret);
- } else {
- /* if callback for getxattr and asks for value length only */
- fuse_reply_xattr (req, ret);
- }
- } else {
- fuse_reply_err (req, ENODATA);
- }
- } else {
- /* if callback for listxattr */
- int32_t len = 0;
- data_pair_t *trav = dict->members_list;
- while (trav) {
- len += strlen (trav->key) + 1;
- trav = trav->next;
- }
- value = alloca (len + 1);
- ERR_ABORT (value);
- len = 0;
- trav = dict->members_list;
- while (trav) {
- strcpy (value + len, trav->key);
- value[len + strlen(trav->key)] = '\0';
- len += strlen (trav->key) + 1;
- trav = trav->next;
- }
- if (state->size) {
- /* if callback for listxattr and asks for list of keys */
- fuse_reply_buf (req, value, len);
- } else {
- /* if callback for listxattr and asks for length of keys only */
- fuse_reply_xattr (req, len);
- }
- }
- } else {
- /* if failure - no need to check if listxattr or getxattr */
- if (op_errno != ENODATA) {
- gf_log ("glusterfs-fuse", GF_LOG_ERROR,
- "%"PRId64": %s => -1 (%d)", frame->root->unique,
- state->fuse_loc.loc.path, op_errno);
- } else {
- gf_log ("glusterfs-fuse", GF_LOG_DEBUG,
- "%"PRId64": %s => -1 (%d)", frame->root->unique,
- state->fuse_loc.loc.path, op_errno);
- }
-
- fuse_reply_err (req, op_errno);
- }
-
- free_state (state);
- STACK_DESTROY (frame->root);
-
- return 0;
-}
-
-
-static void
-fuse_getxattr (fuse_req_t req,
- fuse_ino_t ino,
- const char *name,
- size_t size)
-{
- fuse_state_t *state;
-
- state = state_from_req (req);
- state->size = size;
- state->name = strdup (name);
- fuse_loc_fill (&state->fuse_loc, state, ino, NULL);
- if (!state->fuse_loc.loc.inode) {
- gf_log ("glusterfs-fuse", GF_LOG_ERROR,
- "%"PRId64": GETXATTR %s/%"PRId64" (%s) (fuse_loc_fill() returned NULL inode)",
- req_callid (req), state->fuse_loc.loc.path, (int64_t)ino, name);
-
- fuse_reply_err (req, EINVAL);
- return;
- }
-
- gf_log ("glusterfs-fuse", GF_LOG_DEBUG,
- "%"PRId64": GETXATTR %s/%"PRId64" (%s)", req_callid (req),
- state->fuse_loc.loc.path, (int64_t)ino, name);
-
- FUSE_FOP (state,
- fuse_xattr_cbk,
- getxattr,
- &state->fuse_loc.loc);
-
- return;
-}
-
-
-static void
-fuse_listxattr (fuse_req_t req,
- fuse_ino_t ino,
- size_t size)
-{
- fuse_state_t *state;
-
- state = state_from_req (req);
- state->size = size;
- fuse_loc_fill (&state->fuse_loc, state, ino, NULL);
- if (!state->fuse_loc.loc.inode) {
- gf_log ("glusterfs-fuse", GF_LOG_ERROR,
- "%"PRId64": LISTXATTR %s/%"PRId64" (fuse_loc_fill() returned NULL inode)",
- req_callid (req), state->fuse_loc.loc.path, (int64_t)ino);
-
- fuse_reply_err (req, EINVAL);
- return;
- }
-
- gf_log ("glusterfs-fuse", GF_LOG_DEBUG,
- "%"PRId64": LISTXATTR %s/%"PRId64, req_callid (req),
- state->fuse_loc.loc.path, (int64_t)ino);
-
- FUSE_FOP (state,
- fuse_xattr_cbk,
- getxattr,
- &state->fuse_loc.loc);
-
- return;
-}
-
-
-static void
-fuse_removexattr (fuse_req_t req,
- fuse_ino_t ino,
- const char *name)
-
-{
- fuse_state_t *state;
-
- state = state_from_req (req);
- fuse_loc_fill (&state->fuse_loc, state, ino, NULL);
- if (!state->fuse_loc.loc.inode) {
- gf_log ("glusterfs-fuse", GF_LOG_ERROR,
- "%"PRId64": REMOVEXATTR %s/%"PRId64" (%s) (fuse_loc_fill() returned NULL inode)",
- req_callid (req), state->fuse_loc.loc.path, (int64_t)ino, name);
-
- fuse_reply_err (req, EINVAL);
- return;
- }
-
- gf_log ("glusterfs-fuse", GF_LOG_DEBUG,
- "%"PRId64": REMOVEXATTR %s/%"PRId64" (%s)", req_callid (req),
- state->fuse_loc.loc.path, (int64_t)ino, name);
-
- FUSE_FOP (state,
- fuse_err_cbk,
- removexattr,
- &state->fuse_loc.loc,
- name);
-
- return;
-}
-
-static int32_t
-fuse_getlk_cbk (call_frame_t *frame,
- void *cookie,
- xlator_t *this,
- int32_t op_ret,
- int32_t op_errno,
- struct flock *lock)
-{
- fuse_state_t *state = frame->root->state;
-
- if (op_ret == 0) {
- gf_log ("glusterfs-fuse", GF_LOG_DEBUG,
- "%"PRId64": ERR => 0", frame->root->unique);
- fuse_reply_lock (state->req, lock);
- } else {
- gf_log ("glusterfs-fuse", GF_LOG_ERROR,
- "%"PRId64": ERR => -1 (%d)", frame->root->unique, op_errno);
- fuse_reply_err (state->req, op_errno);
- }
-
- free_state (state);
- STACK_DESTROY (frame->root);
-
- return 0;
-}
-
-static void
-fuse_getlk (fuse_req_t req,
- fuse_ino_t ino,
- struct fuse_file_info *fi,
- struct flock *lock)
-{
- fuse_state_t *state;
-
- state = state_from_req (req);
- state->req = req;
-
- gf_log ("glusterfs-fuse", GF_LOG_DEBUG,
- "%"PRId64": GETLK %p", req_callid (req), FI_TO_FD (fi));
-
- FUSE_FOP (state,
- fuse_getlk_cbk,
- lk,
- FI_TO_FD (fi),
- F_GETLK,
- lock);
-
- return;
-}
-
-static int32_t
-fuse_setlk_cbk (call_frame_t *frame,
- void *cookie,
- xlator_t *this,
- int32_t op_ret,
- int32_t op_errno,
- struct flock *lock)
-{
- fuse_state_t *state = frame->root->state;
-
- if (op_ret == 0) {
- gf_log ("glusterfs-fuse", GF_LOG_DEBUG,
- "%"PRId64": ERR => 0", frame->root->unique);
- fuse_reply_err (state->req, 0);
- } else {
- gf_log ("glusterfs-fuse", GF_LOG_ERROR,
- "%"PRId64": ERR => -1 (%d)", frame->root->unique, op_errno);
- fuse_reply_err (state->req, op_errno);
- }
-
- free_state (state);
- STACK_DESTROY (frame->root);
-
- return 0;
-}
-
-static void
-fuse_setlk (fuse_req_t req,
- fuse_ino_t ino,
- struct fuse_file_info *fi,
- struct flock *lock,
- int sleep)
-{
- fuse_state_t *state;
-
- state = state_from_req (req);
- state->req = req;
-
- gf_log ("glusterfs-fuse", GF_LOG_DEBUG,
- "%"PRId64": SETLK %p (sleep=%d)", req_callid (req), FI_TO_FD (fi),
- sleep);
-
- FUSE_FOP (state,
- fuse_setlk_cbk,
- lk,
- FI_TO_FD(fi),
- (sleep ? F_SETLKW : F_SETLK),
- lock);
-
- return;
-}
-
-
-int32_t
-fuse_forget_notify (call_frame_t *frame, xlator_t *this,
- inode_t *inode)
-{
- return 0;
-}
-
-struct xlator_fops fuse_xl_fops = {
- .forget = fuse_forget_notify
-};
-
-static void
-fuse_init (void *data, struct fuse_conn_info *conn)
-{
- transport_t *trans = data;
- struct fuse_private *priv = trans->private;
- xlator_t *xl = trans->xl;
- int32_t ret;
-
- xl->name = "fuse";
- xl->fops = &fuse_xl_fops;
- xl->itable = inode_table_new (0, xl);
- xl->notify = default_notify;
- ret = xlator_tree_init (xl);
- if (ret == 0) {
-
- } else {
- fuse_unmount (priv->mountpoint, priv->ch);
- exit (1);
- }
-}
-
-
-static void
-fuse_destroy (void *data)
-{
-
-}
-
-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
-};
-
-
-static int32_t
-fuse_transport_disconnect (transport_t *this)
-{
- struct fuse_private *priv = this->private;
-
- gf_log ("glusterfs-fuse",
- GF_LOG_DEBUG,
- "cleaning up fuse transport in disconnect handler");
-
- fuse_session_remove_chan (priv->ch);
- fuse_session_destroy (priv->se);
- fuse_unmount (priv->mountpoint, priv->ch);
-
- FREE (priv);
- priv = NULL;
- this->private = NULL;
-
- /* TODO: need graceful exit. every xlator should be ->fini()'ed
- and come out of main poll loop cleanly
- */
- exit (0);
-
- return -1;
-}
-
-
-static int32_t
-fuse_transport_init (transport_t *this,
- dict_t *options,
- event_notify_fn_t notify)
-{
- char *mountpoint = strdup (data_to_str (dict_get (options,
- "mountpoint")));
- char *source;
- asprintf (&source, "fsname=glusterfs");
- char *argv[] = { "glusterfs",
-
-#ifndef GF_DARWIN_HOST_OS
- "-o", "nonempty",
-#endif
- "-o", "allow_other",
- "-o", "default_permissions",
- "-o", source,
- "-o", "max_readahead=1048576",
- "-o", "max_read=1048576",
- "-o", "max_write=1048576",
- NULL };
-#ifdef GF_DARWIN_HOST_OS
- int argc = 13;
-#else
- int argc = 15;
-#endif
-
- struct fuse_args args = FUSE_ARGS_INIT(argc,
- argv);
- struct fuse_private *priv = NULL;
- int32_t res;
-
- priv = CALLOC (1, sizeof (*priv));
- ERR_ABORT (priv);
-
-
- this->notify = notify;
- this->private = (void *)priv;
-
- priv->ch = fuse_mount (mountpoint, &args);
- if (!priv->ch) {
- gf_log ("glusterfs-fuse",
- GF_LOG_ERROR, "fuse_mount failed (%s)\n", strerror (errno));
- fuse_opt_free_args(&args);
- goto err_free;
- }
-
- priv->se = fuse_lowlevel_new (&args, &fuse_ops, sizeof (fuse_ops), this);
- fuse_opt_free_args(&args);
-
- res = fuse_set_signal_handlers (priv->se);
- if (res == -1) {
- gf_log ("glusterfs-fuse", GF_LOG_ERROR, "fuse_set_signal_handlers failed");
- goto err;
- }
-
- fuse_session_add_chan (priv->se, priv->ch);
-
- priv->fd = fuse_chan_fd (priv->ch);
- this->buf = data_ref (data_from_dynptr (NULL, 0));
- this->buf->is_locked = 1;
-
- priv->mountpoint = mountpoint;
-
- transport_ref (this);
- //poll_register (this->xl_private, priv->fd, this);
-
- return 0;
-
- err:
- fuse_unmount (mountpoint, priv->ch);
- err_free:
- FREE (mountpoint);
- mountpoint = NULL;
- return -1;
-}
-
-void
-guts_log_req (void *, int32_t);
-
-static void *
-fuse_thread_proc (void *data)
-{
- transport_t *trans = data;
- struct fuse_private *priv = trans->private;
- int32_t res = 0;
- data_t *buf = trans->buf;
- int32_t ref = 0;
- size_t chan_size = fuse_chan_bufsize (priv->ch);
- char *recvbuf = CALLOC (1, chan_size);
- ERR_ABORT (recvbuf);
-
- while (!fuse_session_exited (priv->se)) {
- int32_t fuse_chan_receive (struct fuse_chan * ch,
- char *buf,
- int32_t size);
-
-
- res = fuse_chan_receive (priv->ch,
- recvbuf,
- chan_size);
-
- if (res == -1) {
- transport_disconnect (trans);
- }
-
- buf = trans->buf;
-
- if (res && res != -1) {
- if (buf->len < (res)) {
- if (buf->data) {
- FREE (buf->data);
- buf->data = NULL;
- }
- buf->data = CALLOC (1, res);
- ERR_ABORT (buf->data);
- buf->len = res;
- }
- memcpy (buf->data, recvbuf, res); // evil evil
- guts_log_req (buf->data, res);
- fuse_session_process (priv->se,
- buf->data,
- res,
- priv->ch);
- }
-
- LOCK (&buf->lock);
- ref = buf->refcount;
- UNLOCK (&buf->lock);
- if (1) {
- data_unref (buf);
-
- trans->buf = data_ref (data_from_dynptr (NULL, 0));
- trans->buf->is_locked = 1;
- }
- }
-
- exit (0);
-
- return NULL;
-}
-
-
-static int32_t
-fuse_transport_notify (xlator_t *xl,
- int32_t event,
- void *data,
- ...)
-{
- transport_t *trans = data;
- struct fuse_private *priv = trans->private;
- int32_t res = 0;
- data_t *buf;
- int32_t ref = 0;
-
- if (event == GF_EVENT_POLLERR) {
- gf_log ("glusterfs-fuse", GF_LOG_ERROR, "got GF_EVENT_POLLERR");
- transport_disconnect (trans);
- return -1;
- }
-
- if (event != GF_EVENT_POLLIN) {
- gf_log ("glusterfs-fuse", GF_LOG_WARNING, "Ignoring notify event %d",
- event);
- return 0;
- }
-
- if (!fuse_session_exited(priv->se)) {
- static size_t chan_size = 0;
-
- int32_t fuse_chan_receive (struct fuse_chan * ch,
- char *buf,
- int32_t size);
- if (!chan_size)
- chan_size = fuse_chan_bufsize (priv->ch) ;
-
- buf = trans->buf;
-
- if (!buf->data) {
- buf->data = MALLOC (chan_size);
- ERR_ABORT (buf->data);
- buf->len = chan_size;
- }
-
- res = fuse_chan_receive (priv->ch,
- buf->data,
- chan_size);
- /* if (res == -1) {
- transport_destroy (trans);
- */
- if (res && res != -1) {
- /* trace the request and log it to tio file */
- guts_log_req (buf->data, res);
- fuse_session_process (priv->se,
- buf->data,
- res,
- priv->ch);
- }
-
- LOCK (&buf->lock);
- ref = buf->refcount;
- UNLOCK (&buf->lock);
- /* TODO do the check with a lock */
- if (ref > 1) {
- data_unref (buf);
-
- // trans->buf = data_ref (data_from_dynptr (malloc (fuse_chan_bufsize (priv->ch)),
- trans->buf = data_ref (data_from_dynptr (NULL, 0));
- trans->buf->data = MALLOC (chan_size);
- ERR_ABORT (trans->buf->data);
- trans->buf->len = chan_size;
- trans->buf->is_locked = 1;
- }
- } else {
- transport_disconnect (trans);
- }
-
- /*
- if (fuse_session_exited (priv->se)) {
- transport_destroy (trans);
- res = -1;
- }*/
-
- return res >= 0 ? 0 : res;
-}
-
-static void
-fuse_transport_fini (transport_t *this)
-{
-
-}
-
-static struct transport_ops fuse_transport_ops = {
- .disconnect = fuse_transport_disconnect,
-};
-
-static transport_t fuse_transport = {
- .ops = &fuse_transport_ops,
- .private = NULL,
- .xl = NULL,
- .init = fuse_transport_init,
- .fini = fuse_transport_fini,
- .notify = fuse_transport_notify
-};
-
-
-transport_t *
-glusterfs_mount (glusterfs_ctx_t *ctx,
- const char *mount_point)
-{
- dict_t *options = get_new_dict ();
- transport_t *new_fuse = CALLOC (1, sizeof (*new_fuse));
- ERR_ABORT (new_fuse);
-
- memcpy (new_fuse, &fuse_transport, sizeof (*new_fuse));
- new_fuse->ops = &fuse_transport_ops;
- new_fuse->xl_private = ctx;
-
- dict_set (options,
- "mountpoint",
- str_to_data ((char *)mount_point));
-
- return (new_fuse->init (new_fuse,
- options,
- fuse_transport_notify) == 0 ? new_fuse : NULL);
-}
-
-int32_t
-fuse_thread (pthread_t *thread, void *data)
-{
- return pthread_create (thread, NULL, fuse_thread_proc, data);
-}
-
-