diff options
author | Vijay Bellur <vijay@gluster.com> | 2010-03-24 04:22:33 +0000 |
---|---|---|
committer | Anand V. Avati <avati@dev.gluster.com> | 2010-03-24 05:42:29 -0700 |
commit | bd1242b66da347e61db5f2e51638eca9e641b20d (patch) | |
tree | 5202f5c7a93b2521ebef63b6ff69db932ab47cdb /glusterfs-guts/src/fuse-bridge.c | |
parent | 08fd3a63f56c3bae0cbf57d59a3e4c32da791312 (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.c | 2725 |
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); -} - - |