diff options
Diffstat (limited to 'glusterfs-guts/src')
-rw-r--r-- | glusterfs-guts/src/Makefile.am | 17 | ||||
-rw-r--r-- | glusterfs-guts/src/fuse-bridge.c | 2725 | ||||
-rw-r--r-- | glusterfs-guts/src/fuse-extra.c | 137 | ||||
-rw-r--r-- | glusterfs-guts/src/fuse-extra.h | 38 | ||||
-rw-r--r-- | glusterfs-guts/src/fuse_kernel.h | 380 | ||||
-rw-r--r-- | glusterfs-guts/src/glusterfs-fuse.h | 58 | ||||
-rw-r--r-- | glusterfs-guts/src/glusterfs-guts.c | 400 | ||||
-rw-r--r-- | glusterfs-guts/src/glusterfs-guts.h | 62 | ||||
-rw-r--r-- | glusterfs-guts/src/guts-extra.c | 18 | ||||
-rw-r--r-- | glusterfs-guts/src/guts-lowlevel.h | 86 | ||||
-rw-r--r-- | glusterfs-guts/src/guts-parse.c | 217 | ||||
-rw-r--r-- | glusterfs-guts/src/guts-parse.h | 140 | ||||
-rw-r--r-- | glusterfs-guts/src/guts-replay.c | 834 | ||||
-rw-r--r-- | glusterfs-guts/src/guts-replay.h | 33 | ||||
-rw-r--r-- | glusterfs-guts/src/guts-tables.c | 248 | ||||
-rw-r--r-- | glusterfs-guts/src/guts-tables.h | 80 | ||||
-rw-r--r-- | glusterfs-guts/src/guts-trace.c | 650 | ||||
-rw-r--r-- | glusterfs-guts/src/guts-trace.h | 54 |
18 files changed, 0 insertions, 6177 deletions
diff --git a/glusterfs-guts/src/Makefile.am b/glusterfs-guts/src/Makefile.am deleted file mode 100644 index bb8c7b17680..00000000000 --- a/glusterfs-guts/src/Makefile.am +++ /dev/null @@ -1,17 +0,0 @@ -sbin_PROGRAMS = glusterfs-guts - -glusterfs_guts_SOURCES = glusterfs-guts.c fuse-bridge.c guts-replay.c guts-trace.c \ - fuse-extra.c guts-extra.c guts-parse.c guts-tables.c - -noinst_HEADERS = fuse_kernel.h fuse-extra.h glusterfs-guts.h glusterfs-fuse.h guts-lowlevel.h \ - guts-parse.h guts-replay.h guts-tables.h guts-trace.h - -glusterfs_guts_LDADD = $(top_builddir)/libglusterfs/src/libglusterfs.la -lfuse - -AM_CFLAGS = -fPIC -Wall -pthread - -AM_CPPFLAGS = -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE -DFUSE_USE_VERSION=26 \ - -I$(top_srcdir)/libglusterfs/src -DDATADIR=\"$(localstatedir)\" \ - -DCONFDIR=\"$(sysconfdir)/glusterfs\" - -CLEANFILES = 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); -} - - diff --git a/glusterfs-guts/src/fuse-extra.c b/glusterfs-guts/src/fuse-extra.c deleted file mode 100644 index 19c2e1145e9..00000000000 --- a/glusterfs-guts/src/fuse-extra.c +++ /dev/null @@ -1,137 +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/>. -*/ - -#ifndef _CONFIG_H -#define _CONFIG_H -#include "config.h" -#endif /* _CONFIG_H */ - -#include "fuse-extra.h" -#include "common-utils.h" -#include <stdio.h> -#include <pthread.h> -#include <stdlib.h> -#include <string.h> -#include "common-utils.h" - -struct fuse_req; -struct fuse_ll; - -struct fuse_req { - struct fuse_ll *f; - uint64_t unique; - int ctr; - pthread_mutex_t lock; - struct fuse_ctx ctx; - struct fuse_chan *ch; - int interrupted; - union { - struct { - uint64_t unique; - } i; - struct { - fuse_interrupt_func_t func; - void *data; - } ni; - } u; - struct fuse_req *next; - struct fuse_req *prev; -}; - -struct fuse_ll { - int debug; - int allow_root; - struct fuse_lowlevel_ops op; - int got_init; - void *userdata; - uid_t owner; - struct fuse_conn_info conn; - struct fuse_req list; - struct fuse_req interrupts; - pthread_mutex_t lock; - int got_destroy; -}; - -struct fuse_out_header { - uint32_t len; - int32_t error; - uint64_t unique; -}; - -uint64_t req_callid (fuse_req_t req) -{ - return req->unique; -} - -static void destroy_req(fuse_req_t req) -{ - pthread_mutex_destroy (&req->lock); - FREE (req); -} - -static void list_del_req(struct fuse_req *req) -{ - struct fuse_req *prev = req->prev; - struct fuse_req *next = req->next; - prev->next = next; - next->prev = prev; -} - -static void -free_req (fuse_req_t req) -{ - int ctr; - struct fuse_ll *f = req->f; - - pthread_mutex_lock(&req->lock); - req->u.ni.func = NULL; - req->u.ni.data = NULL; - pthread_mutex_unlock(&req->lock); - - pthread_mutex_lock(&f->lock); - list_del_req(req); - ctr = --req->ctr; - pthread_mutex_unlock(&f->lock); - if (!ctr) - destroy_req(req); -} - -int32_t -fuse_reply_vec (fuse_req_t req, - struct iovec *vector, - int32_t count) -{ - int32_t error = 0; - struct fuse_out_header out; - struct iovec *iov; - int res; - - iov = alloca ((count + 1) * sizeof (*vector)); - out.unique = req->unique; - out.error = error; - iov[0].iov_base = &out; - iov[0].iov_len = sizeof(struct fuse_out_header); - memcpy (&iov[1], vector, count * sizeof (*vector)); - count++; - out.len = iov_length(iov, count); - res = fuse_chan_send(req->ch, iov, count); - free_req(req); - - return res; -} diff --git a/glusterfs-guts/src/fuse-extra.h b/glusterfs-guts/src/fuse-extra.h deleted file mode 100644 index 7839bd72e08..00000000000 --- a/glusterfs-guts/src/fuse-extra.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - Copyright (c) 2007-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/>. -*/ - -#ifndef _FUSE_EXTRA_H -#define _FUSE_EXTRA_H - -#ifndef _CONFIG_H -#define _CONFIG_H -#include "config.h" -#endif /* _CONFIG_H */ - -#include <stdlib.h> -#include <fuse/fuse_lowlevel.h> - -uint64_t req_callid (fuse_req_t req); - -int32_t -fuse_reply_vec (fuse_req_t req, - struct iovec *vector, - int32_t count); - -#endif /* _FUSE_EXTRA_H */ diff --git a/glusterfs-guts/src/fuse_kernel.h b/glusterfs-guts/src/fuse_kernel.h deleted file mode 100644 index 7ebff8b22f9..00000000000 --- a/glusterfs-guts/src/fuse_kernel.h +++ /dev/null @@ -1,380 +0,0 @@ -/* - FUSE: Filesystem in Userspace - Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu> - - This program can be distributed under the terms of the GNU GPL. - See the file COPYING. -*/ - -/* This file defines the kernel interface of FUSE */ - -#ifdef __FreeBSD__ -/* - This -- and only this -- header file may also be distributed under - the terms of the BSD Licence as follows: - - Copyright (C) 2001-2006 Miklos Szeredi. All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - SUCH DAMAGE. -*/ - -#include <sys/types.h> -#define __u64 uint64_t -#define __u32 uint32_t -#define __s32 int32_t -#else -#include <asm/types.h> -#include <linux/major.h> -#endif - -/** Version number of this interface */ -#define FUSE_KERNEL_VERSION 7 - -/** Minor version number of this interface */ -#define FUSE_KERNEL_MINOR_VERSION 8 - -/** The node ID of the root inode */ -#define FUSE_ROOT_ID 1 - -/** The major number of the fuse character device */ -#define FUSE_MAJOR MISC_MAJOR - -/** The minor number of the fuse character device */ -#define FUSE_MINOR 229 - -/* Make sure all structures are padded to 64bit boundary, so 32bit - userspace works under 64bit kernels */ - -struct fuse_attr { - __u64 ino; - __u64 size; - __u64 blocks; - __u64 atime; - __u64 mtime; - __u64 ctime; - __u32 atimensec; - __u32 mtimensec; - __u32 ctimensec; - __u32 mode; - __u32 nlink; - __u32 uid; - __u32 gid; - __u32 rdev; -}; - -struct fuse_kstatfs { - __u64 blocks; - __u64 bfree; - __u64 bavail; - __u64 files; - __u64 ffree; - __u32 bsize; - __u32 namelen; - __u32 frsize; - __u32 padding; - __u32 spare[6]; -}; - -struct fuse_file_lock { - __u64 start; - __u64 end; - __u32 type; - __u32 pid; /* tgid */ -}; - -/** - * Bitmasks for fuse_setattr_in.valid - */ -#define FATTR_MODE (1 << 0) -#define FATTR_UID (1 << 1) -#define FATTR_GID (1 << 2) -#define FATTR_SIZE (1 << 3) -#define FATTR_ATIME (1 << 4) -#define FATTR_MTIME (1 << 5) -#define FATTR_FH (1 << 6) - -/** - * Flags returned by the OPEN request - * - * FOPEN_DIRECT_IO: bypass page cache for this open file - * FOPEN_KEEP_CACHE: don't invalidate the data cache on open - */ -#define FOPEN_DIRECT_IO (1 << 0) -#define FOPEN_KEEP_CACHE (1 << 1) - -/** - * INIT request/reply flags - */ -#define FUSE_ASYNC_READ (1 << 0) -#define FUSE_POSIX_LOCKS (1 << 1) - -/** - * Release flags - */ -#define FUSE_RELEASE_FLUSH (1 << 0) - -enum fuse_opcode { - FUSE_LOOKUP = 1, - FUSE_FORGET = 2, /* no reply */ - FUSE_GETATTR = 3, - FUSE_SETATTR = 4, - FUSE_READLINK = 5, - FUSE_SYMLINK = 6, - FUSE_MKNOD = 8, - FUSE_MKDIR = 9, - FUSE_UNLINK = 10, - FUSE_RMDIR = 11, - FUSE_RENAME = 12, - FUSE_LINK = 13, - FUSE_OPEN = 14, - FUSE_READ = 15, - FUSE_WRITE = 16, - FUSE_STATFS = 17, - FUSE_RELEASE = 18, - FUSE_FSYNC = 20, - FUSE_SETXATTR = 21, - FUSE_GETXATTR = 22, - FUSE_LISTXATTR = 23, - FUSE_REMOVEXATTR = 24, - FUSE_FLUSH = 25, - FUSE_INIT = 26, - FUSE_OPENDIR = 27, - FUSE_READDIR = 28, - FUSE_RELEASEDIR = 29, - FUSE_FSYNCDIR = 30, - FUSE_GETLK = 31, - FUSE_SETLK = 32, - FUSE_SETLKW = 33, - FUSE_ACCESS = 34, - FUSE_CREATE = 35, - FUSE_INTERRUPT = 36, - FUSE_BMAP = 37, - FUSE_DESTROY = 38, -}; - -/* The read buffer is required to be at least 8k, but may be much larger */ -#define FUSE_MIN_READ_BUFFER 8192 - -struct fuse_entry_out { - __u64 nodeid; /* Inode ID */ - __u64 generation; /* Inode generation: nodeid:gen must - be unique for the fs's lifetime */ - __u64 entry_valid; /* Cache timeout for the name */ - __u64 attr_valid; /* Cache timeout for the attributes */ - __u32 entry_valid_nsec; - __u32 attr_valid_nsec; - struct fuse_attr attr; -}; - -struct fuse_forget_in { - __u64 nlookup; -}; - -struct fuse_attr_out { - __u64 attr_valid; /* Cache timeout for the attributes */ - __u32 attr_valid_nsec; - __u32 dummy; - struct fuse_attr attr; -}; - -struct fuse_mknod_in { - __u32 mode; - __u32 rdev; -}; - -struct fuse_mkdir_in { - __u32 mode; - __u32 padding; -}; - -struct fuse_rename_in { - __u64 newdir; -}; - -struct fuse_link_in { - __u64 oldnodeid; -}; - -struct fuse_setattr_in { - __u32 valid; - __u32 padding; - __u64 fh; - __u64 size; - __u64 unused1; - __u64 atime; - __u64 mtime; - __u64 unused2; - __u32 atimensec; - __u32 mtimensec; - __u32 unused3; - __u32 mode; - __u32 unused4; - __u32 uid; - __u32 gid; - __u32 unused5; -}; - -struct fuse_open_in { - __u32 flags; - __u32 mode; -}; - -struct fuse_open_out { - __u64 fh; - __u32 open_flags; - __u32 padding; -}; - -struct fuse_release_in { - __u64 fh; - __u32 flags; - __u32 release_flags; - __u64 lock_owner; -}; - -struct fuse_flush_in { - __u64 fh; - __u32 unused; - __u32 padding; - __u64 lock_owner; -}; - -struct fuse_read_in { - __u64 fh; - __u64 offset; - __u32 size; - __u32 padding; -}; - -struct fuse_write_in { - __u64 fh; - __u64 offset; - __u32 size; - __u32 write_flags; -}; - -struct fuse_write_out { - __u32 size; - __u32 padding; -}; - -#define FUSE_COMPAT_STATFS_SIZE 48 - -struct fuse_statfs_out { - struct fuse_kstatfs st; -}; - -struct fuse_fsync_in { - __u64 fh; - __u32 fsync_flags; - __u32 padding; -}; - -struct fuse_setxattr_in { - __u32 size; - __u32 flags; -}; - -struct fuse_getxattr_in { - __u32 size; - __u32 padding; -}; - -struct fuse_getxattr_out { - __u32 size; - __u32 padding; -}; - -struct fuse_lk_in { - __u64 fh; - __u64 owner; - struct fuse_file_lock lk; -}; - -struct fuse_lk_out { - struct fuse_file_lock lk; -}; - -struct fuse_access_in { - __u32 mask; - __u32 padding; -}; - -struct fuse_init_in { - __u32 major; - __u32 minor; - __u32 max_readahead; - __u32 flags; -}; - -struct fuse_init_out { - __u32 major; - __u32 minor; - __u32 max_readahead; - __u32 flags; - __u32 unused; - __u32 max_write; -}; - -struct fuse_interrupt_in { - __u64 unique; -}; - -struct fuse_bmap_in { - __u64 block; - __u32 blocksize; - __u32 padding; -}; - -struct fuse_bmap_out { - __u64 block; -}; - -struct fuse_in_header { - __u32 len; - __u32 opcode; - __u64 unique; - __u64 nodeid; - __u32 uid; - __u32 gid; - __u32 pid; - __u32 padding; -}; - -struct fuse_out_header { - __u32 len; - __s32 error; - __u64 unique; -}; - -struct fuse_dirent { - __u64 ino; - __u64 off; - __u32 namelen; - __u32 type; - char name[0]; -}; - -#define FUSE_NAME_OFFSET offsetof(struct fuse_dirent, name) -#define FUSE_DIRENT_ALIGN(x) (((x) + sizeof(__u64) - 1) & ~(sizeof(__u64) - 1)) -#define FUSE_DIRENT_SIZE(d) \ - FUSE_DIRENT_ALIGN(FUSE_NAME_OFFSET + (d)->namelen) diff --git a/glusterfs-guts/src/glusterfs-fuse.h b/glusterfs-guts/src/glusterfs-fuse.h deleted file mode 100644 index a10bfa7f6dc..00000000000 --- a/glusterfs-guts/src/glusterfs-fuse.h +++ /dev/null @@ -1,58 +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/>. -*/ - -#ifndef __GLUSTERFS_FUSE_H__ -#define __GLUSTERFS_FUSE_H__ - -#ifndef _CONFIG_H -#define _CONFIG_H -#include "config.h" -#endif /* _CONFIG_H */ - -#define DEFAULT_LOG_FILE DATADIR"/log/glusterfs/glusterfs.log" -#define DEFAULT_GLUSTERFS_CLIENT_VOL CONFDIR "/glusterfs-client.vol" - -#define SPEC_LOCAL_FILE 1 -#define SPEC_REMOTE_FILE 2 - -#if 0 -#define GF_YES 1 -#define GF_NO 0 -#endif - -#ifdef GF_LOG_FUSE_ARGS -#undef GF_LOG_FUSE_ARGS -#endif - -struct gf_spec_location { - int32_t where; - union { - char *file; - struct { - char *ip; - char *port; - char *transport; - }server; - }spec; -}; - -transport_t * glusterfs_mount (glusterfs_ctx_t *ctx, - const char *mount_point); - -#endif /* __GLUSTERFS_FUSE_H__ */ diff --git a/glusterfs-guts/src/glusterfs-guts.c b/glusterfs-guts/src/glusterfs-guts.c deleted file mode 100644 index 4b0a1b3750a..00000000000 --- a/glusterfs-guts/src/glusterfs-guts.c +++ /dev/null @@ -1,400 +0,0 @@ -/* - Copyright (c) 2008-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 <stdio.h> -#include <stdlib.h> -#include <argp.h> -#include <string.h> - -#include "glusterfs.h" -#include "xlator.h" -#include "glusterfs-guts.h" - -/* argp initializations */ -static char doc[] = "glusterfs-guts is unit testing suite for glusterfs"; -static char argp_doc[] = ""; -const char *argp_program_version = PACKAGE_NAME " " PACKAGE_VERSION " built on " __DATE__; -const char *argp_program_bug_address = PACKAGE_BUGREPORT; - -guts_ctx_t guts_ctx; -error_t parse_opts (int32_t key, char *arg, struct argp_state *_state); - -static struct argp_option options[] = { - {"spec-file", 'f', "VOLUMESPEC-FILE", 0,\ - "Load VOLUMESPEC-FILE."}, - {"threads", 't', "NUMBER", 0,\ - "Load NUMBER of threads."}, - {"tio-file", 'i', "FILE", 0,\ - "Replay fops from FILE."}, - {"tio-directory", 'I', "DIRECTORY", 0,\ - "Replay fops from files in DIRECTORY. Valid option only when using more than one thread."}, - {"log-level", 'L', "LOGLEVEL", 0, - "LOGLEVEL should be one of DEBUG, WARNING, [ERROR], CRITICAL, NONE"}, - {"log-file", 'l', "LOGFILE", 0, \ - "Specify the file to redirect logs"}, - {"trace", 'T', "MOUNTPOINT", 0, \ - "Run guts in trace mode. Guts mounts glusterfs on MOUNTPOINT specified"}, - {"output", 'o', "OUTPUT-TIOFILE", 0, \ - "Write trace io output to OUTPUT-TIOFILE. Valid only when run in trace(-T) mode."}, - {"version", 'V', 0, 0,\ - "print version information"}, - { 0, } -}; - -static struct argp argp = { options, parse_opts, argp_doc, doc }; - -/* guts_print_version - used by argument parser routine to print version information for guts */ -static int32_t -guts_print_version (void) -{ - printf ("%s\n", argp_program_version); - printf ("Copyright (c) 2006-2009 Gluster Inc. <http://www.gluster.com>\n"); - printf ("GlusterFS comes with ABSOLUTELY NO WARRANTY.\nYou may redistribute copies of GlusterFS under the terms of the GNU General Public License.\n"); - exit (0); -} - -/* parse_opts - argument parsing helper routine for argp library */ -error_t -parse_opts (int32_t key, char *arg, struct argp_state *_state) -{ - guts_ctx_t *state = _state->input; - - switch (key) { - case 'f': - if (!state->specfile) { - state->specfile = strdup (arg); - } - break; - - case 't': - if (!state->threads) { - state->threads = strtol (arg, NULL, 0); - } - break; - - case 'i': - if (state->threads == 1) { - state->file = strdup (arg); - } else { - fprintf (stderr, "glusterfs-guts: -i option is valid only when guts is running single thread\n"); - exit (1); - } - break; - - case 'I': - if (state->threads > 1) { - state->directory = strdup (arg); - } else { - fprintf (stderr, "glusterfs-guts: -I option is valid only when guts is running multiple threads\n"); - exit (1); - } - break; - - case 'L': - /* set log level */ - if (!strncasecmp (arg, "DEBUG", strlen ("DEBUG"))) { - state->loglevel = GF_LOG_DEBUG; - } else if (!strncasecmp (arg, "WARNING", strlen ("WARNING"))) { - state->loglevel = GF_LOG_WARNING; - } else if (!strncasecmp (arg, "CRITICAL", strlen ("CRITICAL"))) { - state->loglevel = GF_LOG_CRITICAL; - } else if (!strncasecmp (arg, "NONE", strlen ("NONE"))) { - state->loglevel = GF_LOG_NONE; - } else if (!strncasecmp (arg, "ERROR", strlen ("ERROR"))) { - state->loglevel = GF_LOG_ERROR; - } else { - fprintf (stderr, "glusterfs-guts: Unrecognized log-level \"%s\", possible values are \"DEBUG|WARNING|[ERROR]|CRITICAL|NONE\"\n", arg); - exit (EXIT_FAILURE); - } - break; - case 'l': - /* set log file */ - state->logfile = strdup (arg); - break; - - case 'T': - state->trace = 1; - state->mountpoint = strdup (arg); - break; - - case 'o': - state->file = strdup (arg); - break; - - case 'V': - guts_print_version (); - break; - - } - return 0; -} - -/* get_xlator_graph - creates a translator graph and returns the pointer to the root of the xlator tree - * - * @ctx: guts context structure - * @conf: file handle to volume specfile - * - * returns pointer to the root of the translator tree - */ -static xlator_t * -get_xlator_graph (glusterfs_ctx_t *ctx, - FILE *conf) -{ - xlator_t *tree, *trav = NULL; - - tree = file_to_xlator_tree (ctx, conf); - trav = tree; - - if (tree == NULL) { - gf_log ("glusterfs-guts", - GF_LOG_ERROR, - "specification file parsing failed, exiting"); - return NULL; - } - - tree = trav; - - return tree; -} - -/* get_spec_fp - get file handle to volume spec file specified. - * - * @ctx: guts context structure - * - * returns FILE pointer to the volume spec file. - */ -static FILE * -get_spec_fp (guts_ctx_t *ctx) -{ - char *specfile = ctx->specfile; - FILE *conf = NULL; - - specfile = ctx->specfile; - - conf = fopen (specfile, "r"); - - if (!conf) { - perror (specfile); - return NULL; - } - gf_log ("glusterfs-guts", - GF_LOG_DEBUG, - "loading spec from %s", - specfile); - - return conf; -} - -static void * -guts_thread_main (void *ctx) -{ - guts_thread_ctx_t *tctx = (guts_thread_ctx_t *) ctx; - - printf ("starting thread main with %s:\n", tctx->file); - guts_replay (tctx); - printf ("ending thread main.\n"); - - return NULL; -} - -/* guts_create_threads - creates different threads based on thread number specified in ctx and assigns a - * tio file to each thread and attaches each thread to the graph created by main(). - * @ctx: guts_ctx_t which contains the context corresponding to the current run of guts - * - * returns the guts_threads_t structure which contains handles to the different threads created. - * - */ -static guts_threads_t * -guts_create_threads (guts_ctx_t *ctx) -{ - guts_threads_t *threads = NULL; - int32_t thread_count = ctx->threads; - - threads = CALLOC (1, sizeof (*threads)); - ERR_ABORT (threads); - - - INIT_LIST_HEAD (&(threads->threads)); - - if (thread_count == 1) { - /* special case: we have only one thread and we are given a tio-file as argument instead of a directory. - * handling differently */ - guts_thread_ctx_t *thread = NULL; - thread = CALLOC (1, sizeof (*thread)); - ERR_ABORT (thread); - list_add (&thread->threads, &threads->threads); - thread->file = strdup (ctx->file); - thread->ctx = ctx; - } else { - /* look for .tio files in the directory given and assign to each of the threads */ - DIR *dir = opendir (ctx->directory); - - if (!dir) { - gf_log ("guts", - GF_LOG_ERROR, - "failed to open directory %s", ctx->directory); - } else { - guts_thread_ctx_t *thread = NULL; - struct dirent *dirp = NULL; - /* to pass through "." and ".." */ - readdir (dir); - readdir (dir); - - while (thread_count > 0) { - char pathname[256] = {0,}; - - thread = CALLOC (1, sizeof (*thread)); - ERR_ABORT (thread); - dirp = NULL; - - list_add (&thread->threads, &threads->threads); - dirp = readdir (dir); - if (dirp) { - sprintf (pathname, "%s/%s", ctx->directory, dirp->d_name); - printf ("file name for thread(%d) is %s\n", thread_count, pathname); - thread->file = strdup (pathname); - thread->ctx = ctx; - } else if (thread_count > 0) { - gf_log ("guts", - GF_LOG_ERROR, - "number of tio files less than %d, number of threads specified", ctx->threads); - /* TODO: cleanup */ - return NULL; - } - --thread_count; - } - } - } - return threads; -} - -/* guts_start_threads - starts all the threads in @threads. - * - * @threads: guts_threads_t structure containing the handles to threads created by guts_create_threads. - * - * returns <0 on error. - * - */ -static void -guts_start_threads (guts_threads_t *gthreads) -{ - guts_thread_ctx_t *thread = NULL; - list_for_each_entry (thread, >hreads->threads, threads) { - if (pthread_create (&thread->pthread, NULL, guts_thread_main, (void *)thread) < 0) { - gf_log ("guts", - GF_LOG_ERROR, - "failed to start thread"); - } else { - gf_log ("guts", - GF_LOG_DEBUG, - "started thread with file %s", thread->file); - } - } -} - -static int32_t -guts_join_threads (guts_threads_t *gthreads) -{ - guts_thread_ctx_t *thread = NULL; - list_for_each_entry (thread, >hreads->threads, threads) { - if (pthread_join (thread->pthread, NULL) < 0) { - gf_log ("guts", - GF_LOG_ERROR, - "failed to join thread"); - } else { - gf_log ("guts", - GF_LOG_DEBUG, - "joined thread with file %s", thread->file); - } - } - return 0; -} - - -int32_t -main (int32_t argc, char *argv[]) -{ - /* glusterfs_ctx_t is required to be passed to - * 1. get_xlator_graph - * 2. glusterfs_mount - */ - glusterfs_ctx_t gfs_ctx = { - .logfile = DATADIR "/log/glusterfs/glusterfs-guts.log", - .loglevel = GF_LOG_DEBUG, - .poll_type = SYS_POLL_TYPE_EPOLL, - }; - - guts_ctx_t guts_ctx = {0,}; - FILE *specfp = NULL; - xlator_t *graph = NULL; - guts_threads_t *threads = NULL; - - argp_parse (&argp, argc, argv, 0, 0, &guts_ctx); - - if (gf_log_init (gfs_ctx.logfile) == -1 ) { - fprintf (stderr, - "glusterfs-guts: failed to open logfile \"%s\"\n", - gfs_ctx.logfile); - return -1; - } - gf_log_set_loglevel (gfs_ctx.loglevel); - - specfp = get_spec_fp (&guts_ctx); - if (!specfp) { - fprintf (stderr, - "glusterfs-guts: could not open specfile\n"); - return -1; - } - - graph = get_xlator_graph (&gfs_ctx, specfp); - if (!graph) { - gf_log ("guts", GF_LOG_ERROR, - "Unable to get xlator graph"); - return -1; - } - fclose (specfp); - - guts_ctx.graph = graph; - - if (guts_ctx.trace) { - return guts_trace (&guts_ctx); - } else { - /* now that we have the xlator graph, we need to create as many threads as requested and assign a tio file - * to each of the threads and tell each thread to attach to the graph we just created. */ - - if (!guts_ctx.file && !guts_ctx.directory) { - fprintf (stderr, - "glusterfs-guts: no tio file specified"); - return -1; - } - - threads = guts_create_threads (&guts_ctx); - - if (threads) { - guts_start_threads (threads); - guts_join_threads (threads); - } else { - gf_log ("guts", GF_LOG_ERROR, - "unable to create threads"); - return 0; - } - } - - return 0; -} - diff --git a/glusterfs-guts/src/glusterfs-guts.h b/glusterfs-guts/src/glusterfs-guts.h deleted file mode 100644 index 4614379f73e..00000000000 --- a/glusterfs-guts/src/glusterfs-guts.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - Copyright (c) 2008-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/>. -*/ - -#ifndef __GLUSTERFS_GUTS_H -#define __GLUSTERFS_GUTS_H - -#include "xlator.h" -#include "transport.h" -#include "glusterfs.h" -#include "glusterfs-fuse.h" -#include "timer.h" - -#ifdef DEFAULT_LOG_FILE -#undef DEFAULT_LOG_FILE -#endif - -#define DEFAULT_LOG_FILE DATADIR"/log/glusterfs/glusterfs-guts.log" - - -typedef struct { - int32_t threads; /* number of threads to start in replay mode */ - char *logfile; /* logfile path */ - int32_t loglevel; /* logging level */ - char *directory; /* path to directory containing tio files, when threads > 1 */ - char *file; /* path to tio file, when threads == 1 during replay. in trace mode, path to tio output */ - char *specfile; /* path to specfile to load translator tree */ - xlator_t *graph; /* translator tree after the specfile is loaded */ - int32_t trace; /* if trace == 1, glusterfs-guts runs in trace mode, otherwise in replay mode */ - char *mountpoint; /* valid only when trace == 1, mounpoint to mount glusterfs */ -} guts_ctx_t; - - -typedef struct { - struct list_head threads; - pthread_t pthread; - xlator_t *tree; - char *file; - guts_ctx_t *ctx; -} guts_thread_ctx_t; - -typedef struct { - struct list_head threads; -} guts_threads_t; - -int32_t guts_replay (guts_thread_ctx_t *); -int32_t guts_trace (guts_ctx_t *); -#endif diff --git a/glusterfs-guts/src/guts-extra.c b/glusterfs-guts/src/guts-extra.c deleted file mode 100644 index 6411ec57fce..00000000000 --- a/glusterfs-guts/src/guts-extra.c +++ /dev/null @@ -1,18 +0,0 @@ -/* - Copyright (c) 2007-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/>. -*/ diff --git a/glusterfs-guts/src/guts-lowlevel.h b/glusterfs-guts/src/guts-lowlevel.h deleted file mode 100644 index fc765068603..00000000000 --- a/glusterfs-guts/src/guts-lowlevel.h +++ /dev/null @@ -1,86 +0,0 @@ -/* - Copyright (c) 2008-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/>. -*/ - -#ifndef _GUTS_LOWLEVEL_H_ -#define _GUTS_LOWLEVEL_H_ - -int -guts_reply_err (fuse_req_t req, - int err); - -int -guts_reply_none (fuse_req_t req); - -int -guts_reply_entry (fuse_req_t req, - const struct fuse_entry_param *e); - -int -guts_reply_create (fuse_req_t req, - const struct fuse_entry_param *e, - const struct fuse_file_info *f); - -int -guts_reply_attr (fuse_req_t req, - const struct stat *attr, - double attr_timeout); - -int -guts_reply_readlink (fuse_req_t req, - const char *linkname); - -int -guts_reply_open (fuse_req_t req, - const struct fuse_file_info *f); - -int -guts_reply_write (fuse_req_t req, - size_t count); - -int -guts_reply_buf (fuse_req_t req, - const char *buf, - size_t size); - -int -guts_reply_statfs (fuse_req_t req, - const struct statvfs *stbuf); - -int -guts_reply_xattr (fuse_req_t req, - size_t count); - -int -guts_reply_lock (fuse_req_t req, - struct flock *lock); - -/* exploiting the macros to reduce coding work ;) */ -#define fuse_reply_entry guts_reply_entry -#define fuse_reply_err guts_reply_err -#define fuse_reply_none guts_reply_none -#define fuse_reply_attr guts_reply_attr -#define fuse_reply_open guts_reply_open -#define fuse_reply_readlink guts_reply_readlink -#define fuse_reply_create guts_reply_create -#define fuse_reply_write guts_reply_write -#define fuse_reply_buf guts_reply_buf -#define fuse_reply_statfs guts_reply_statfs -#define fuse_reply_xattr guts_reply_xattr -#define fuse_reply_lock guts_reply_lock - -#endif diff --git a/glusterfs-guts/src/guts-parse.c b/glusterfs-guts/src/guts-parse.c deleted file mode 100644 index 1503b737fe4..00000000000 --- a/glusterfs-guts/src/guts-parse.c +++ /dev/null @@ -1,217 +0,0 @@ -/* - Copyright (c) 2008-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 "guts-parse.h" -#include "guts-tables.h" - -/* unavoidable usage of global data.. :'( */ -static int32_t tio_fd = 0; - -int32_t -guts_tio_init (const char *filename) -{ - tio_fd = open (filename, O_WRONLY | O_CREAT); - - if (tio_fd < 0) { - gf_log ("guts", - GF_LOG_ERROR, - "failed to open tio file %s", filename); - } - - return tio_fd; -} - -void -guts_reply_dump (fuse_req_t req, - const void *arg, - int32_t len) -{ - uint8_t *buf = NULL; - uint8_t *ibuf = NULL; - uint32_t buf_size = REP_HEADER_FULL_LEN + len; - - ibuf = buf = CALLOC (1, buf_size); - - /* being paranoid, checking for both ibuf and buf.. ;) */ - if (ibuf && buf) { - memcpy (ibuf, REP_BEGIN, strlen (REP_BEGIN)); - ibuf += strlen (REP_BEGIN); - memcpy (ibuf, req, sizeof (struct fuse_req)); - ibuf += sizeof (struct fuse_req); - memcpy (ibuf, &len, sizeof (len)); - ibuf += sizeof (len); - memcpy (ibuf, arg, len); - - gf_full_write (tio_fd, buf, buf_size); - - free (buf); - } else { - gf_log ("glusterfs-guts", GF_LOG_DEBUG, - "failed to allocate memory while dumping reply"); - } -} - -void -guts_req_dump (struct fuse_in_header *in, - const void *arg, - int32_t len) -{ - /* GUTS_REQUEST_BEGIN:<fuse_in_header>:<arg-len>:<args>:GUTS_REQUEST_END */ - uint8_t *buf = NULL; - uint8_t *ibuf = NULL; - uint32_t buf_size = REQ_HEADER_FULL_LEN + len; - - ibuf = buf = CALLOC (1, buf_size); - - if (ibuf && buf) { - memcpy (ibuf, REQ_BEGIN, strlen (REQ_BEGIN)); - ibuf += strlen (REQ_BEGIN); - memcpy (ibuf, in, sizeof (*in)); - ibuf += sizeof (*in); - memcpy (ibuf, &len, sizeof (len)); - ibuf += sizeof (len); - memcpy (ibuf, arg, len); - - gf_full_write (tio_fd, buf, buf_size); - - free (buf); - } else { - gf_log ("glusterfs-guts", GF_LOG_DEBUG, - "failed to allocate memory while dumping reply"); - } -} - - - -guts_req_t * -guts_read_entry (guts_replay_ctx_t *ctx) -{ - guts_req_t *req = NULL; - guts_reply_t *reply = NULL; - uint8_t begin[256] = {0,}; - int32_t ret = 0; - int32_t fd = ctx->tio_fd; - - while (!req) { - req = guts_get_request (ctx); - - if (!req) { - ret = read (fd, begin, strlen (REQ_BEGIN)); - - if (ret == 0) { - gf_log ("glusterfs-guts", GF_LOG_DEBUG, - "guts replay finished"); - req = NULL; - } - - if (is_request (begin)) { - req = CALLOC (1, sizeof (*req)); - ERR_ABORT (req); - gf_full_read (fd, (char *)req, REQ_HEADER_LEN); - - req->arg = CALLOC (1, req->arg_len + 1); - ERR_ABORT (req->arg); - gf_full_read (fd, req->arg, req->arg_len); - gf_log ("guts", - GF_LOG_DEBUG, - "%s: fop %s (%d)\n", - begin, guts_log[req->header.opcode].name, req->header.opcode); - guts_add_request (ctx, req); - req = guts_get_request (ctx); - } else { - /* whenever a reply is read, we put it to a hash table and we would like to retrieve it whenever - * we get a reply for any call - */ - reply = CALLOC (1, sizeof (*reply)); - ERR_ABORT (reply); - gf_full_read (fd, (char *)reply, REP_HEADER_LEN); - - reply->arg = CALLOC (1, reply->arg_len + 1); - ERR_ABORT (reply->arg); - gf_full_read (fd, reply->arg, reply->arg_len); - - /* add a new reply to */ - ret = guts_add_reply (ctx, reply); - gf_log ("guts", - GF_LOG_DEBUG, - "got a reply with unique: %ld", reply->req.unique); - } - } - } - return req; -} - -guts_reply_t * -guts_read_reply (guts_replay_ctx_t *ctx, - uint64_t unique) -{ - guts_req_t *req = NULL; - guts_reply_t *reply = NULL, *rep = NULL; - uint8_t begin[256] = {0,}; - int32_t ret = 0; - int32_t fd = ctx->tio_fd; - - while (!rep) { - - ret = read (fd, begin, strlen (REQ_BEGIN)); - - if (ret == 0) { - printf ("\ndone\n"); - return NULL; - } - - if (is_request (begin)) { - req = CALLOC (1, sizeof (*req)); - ERR_ABORT (req); - gf_full_read (fd, (char *)req, REQ_HEADER_LEN); - - req->arg = CALLOC (1, req->arg_len + 1); - ERR_ABORT (req->arg); - gf_full_read (fd, req->arg, req->arg_len); - gf_log ("guts", - GF_LOG_DEBUG, - "%s: fop %s (%d)\n", - begin, guts_log[req->header.opcode].name, req->header.opcode); - - ret = guts_add_request (ctx, req); - - } else { - /* whenever a reply is read, we put it to a hash table and we would like to retrieve it whenever - * we get a reply for any call - */ - reply = CALLOC (1, sizeof (*reply)); - ERR_ABORT (reply); - gf_full_read (fd, (char *)reply, REP_HEADER_LEN); - - reply->arg = CALLOC (1, reply->arg_len + 1); - ERR_ABORT (reply->arg); - gf_full_read (fd, reply->arg, reply->arg_len); - - /* add a new reply to */ - if (reply->req.unique == unique) { - return reply; - } else { - ret = guts_add_reply (ctx, reply); - gf_log ("guts", - GF_LOG_DEBUG, - "got a reply with unique: %ld", reply->req.unique); - } - } - } - return NULL; -} diff --git a/glusterfs-guts/src/guts-parse.h b/glusterfs-guts/src/guts-parse.h deleted file mode 100644 index 1eb5f3ecfb9..00000000000 --- a/glusterfs-guts/src/guts-parse.h +++ /dev/null @@ -1,140 +0,0 @@ -/* - Copyright (c) 2008-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/>. -*/ - -#ifndef _GUTS_PARSE_H_ -#define _GUTS_PARSE_H_ - -#include "glusterfs.h" -#include "glusterfs-guts.h" -#include "fuse_kernel.h" -#include <fuse/fuse_lowlevel.h> -#include "list.h" - -#ifndef _FUSE_OPAQUE_ -#define _FUSE_OPAQUE_ - -struct fuse_private { - int fd; - struct fuse *fuse; - struct fuse_session *se; - struct fuse_chan *ch; - char *mountpoint; -}; - -struct fuse_req { - struct fuse_ll *f; - uint64_t unique; - int ctr; - pthread_mutex_t lock; - struct fuse_ctx ctx; - struct fuse_chan *ch; - int interrupted; - union { - struct { - uint64_t unique; - } i; - struct { - fuse_interrupt_func_t func; - void *data; - } ni; - } u; - struct fuse_req *next; - struct fuse_req *prev; -}; - -struct fuse_ll { - int debug; - int allow_root; - struct fuse_lowlevel_ops op; - int got_init; - void *userdata; - uid_t owner; - struct fuse_conn_info conn; - struct fuse_req list; - struct fuse_req interrupts; - pthread_mutex_t lock; - int got_destroy; -}; -#endif - -#define REQ_BEGIN "GUTS_REQ_BEGIN:" -#define REQ_HEADER_FULL_LEN (strlen(REQ_BEGIN) + sizeof (struct fuse_in_header) + sizeof (int32_t)) - -#define REP_BEGIN "GUTS_REP_BEGIN:" -#define REP_HEADER_FULL_LEN (strlen(REP_BEGIN) + sizeof (struct fuse_req) + sizeof (int32_t)) - -#define REQ_HEADER_LEN (sizeof (struct fuse_in_header) + sizeof (int32_t)) -#define REP_HEADER_LEN (sizeof (struct fuse_req) + sizeof (int32_t)) - -#define is_request(begin) (0==strcmp(begin, REQ_BEGIN)?1:0) - -typedef void (*func_t)(struct fuse_in_header *, const void *); - -typedef struct { - func_t func; - const char *name; -} guts_log_t; - -typedef struct { - struct fuse_in_header header; - int32_t arg_len; - struct list_head list; - void *arg; -} guts_req_t; - -typedef struct { - struct fuse_req req; - int32_t arg_len; - void *arg; -} guts_reply_t; - -struct guts_replay_ctx { - int32_t tio_fd; - struct fuse_ll *guts_ll; - dict_t *replies; - dict_t *inodes; - dict_t *fds; - struct list_head requests; - dict_t *requests_dict; -}; - -typedef struct guts_replay_ctx guts_replay_ctx_t; - -extern guts_log_t guts_log[]; - -int32_t -guts_tio_init (const char *); - -void -guts_req_dump (struct fuse_in_header *, - const void *, - int32_t); - -guts_req_t * -guts_read_entry (guts_replay_ctx_t *ctx); - -void -guts_reply_dump (fuse_req_t, - const void *, - int32_t); - -guts_reply_t * -guts_read_reply (guts_replay_ctx_t *ctx, - uint64_t unique); - -#endif /* _GUTS_PARSE_H_ */ diff --git a/glusterfs-guts/src/guts-replay.c b/glusterfs-guts/src/guts-replay.c deleted file mode 100644 index 777480a96b9..00000000000 --- a/glusterfs-guts/src/guts-replay.c +++ /dev/null @@ -1,834 +0,0 @@ -/* - Copyright (c) 2008-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 "glusterfs-guts.h" -#include "guts-parse.h" -#include <signal.h> -#include "guts-tables.h" -#include "guts-replay.h" -#include "guts-trace.h" - -static void -convert_attr (const struct fuse_setattr_in *attr, - struct stat *stbuf) -{ - stbuf->st_mode = attr->mode; - stbuf->st_uid = attr->uid; - stbuf->st_gid = attr->gid; - stbuf->st_size = attr->size; - stbuf->st_atime = attr->atime; - /* - ST_ATIM_NSEC_SET (stbuf, attr->atimensec); - ST_MTIM_NSEC_SET (stbuf, attr->mtimensec);*/ -} - -static void -guts_replay_lookup (fuse_req_t req, - fuse_ino_t ino, - const void *inargs) -{ - char *name = (char *) inargs; - - if (req->f->op.lookup) - req->f->op.lookup(req, ino, name); - else - guts_reply_err (req, ENOSYS); - -} - -static void -guts_replay_forget (fuse_req_t req, - fuse_ino_t ino, - const void *inargs) -{ - struct fuse_forget_in *arg = (struct fuse_forget_in *) inargs; - - if (req->f->op.forget) - req->f->op.forget (req, ino, arg->nlookup); - -} - -static void -guts_replay_getattr (fuse_req_t req, - fuse_ino_t ino, - const void *inargs) -{ - (void) inargs; - - if (req->f->op.getattr) - req->f->op.getattr (req, ino, NULL); - else - guts_reply_err (req, ENOSYS); -} - -static void -guts_replay_setattr (fuse_req_t req, - fuse_ino_t ino, - const void *inargs) -{ - struct fuse_setattr_in *arg = (struct fuse_setattr_in *)inargs; - - if (req->f->op.setattr) { - struct fuse_file_info *fi = NULL; - struct fuse_file_info fi_store; - struct stat stbuf; - memset (&stbuf, 0, sizeof (stbuf)); - convert_attr (arg, &stbuf); - if (arg->valid & FATTR_FH) { - arg->valid &= ~FATTR_FH; - memset (&fi_store, 0, sizeof (fi_store)); - fi = &fi_store; - fi->fh = arg->fh; - fi->fh_old = fi->fh; - } - req->f->op.setattr (req, ino, &stbuf, arg->valid, fi); - } else - guts_reply_err (req, ENOSYS); -} - -static void -guts_replay_access (fuse_req_t req, - fuse_ino_t ino, - const void *inargs) -{ - struct fuse_access_in *arg = (struct fuse_access_in *)inargs; - - if (req->f->op.access) - req->f->op.access (req, ino, arg->mask); - else - guts_reply_err (req, ENOSYS); -} - -static void -guts_replay_readlink (fuse_req_t req, - fuse_ino_t ino, - const void *inargs) -{ - (void) inargs; - - if (req->f->op.readlink) - req->f->op.readlink (req, ino); - else - guts_reply_err (req, ENOSYS); -} - - -static void -guts_replay_mknod (fuse_req_t req, - fuse_ino_t ino, - const void *inargs) -{ - struct fuse_mknod_in *arg = (struct fuse_mknod_in *) inargs; - - if (req->f->op.mknod) - req->f->op.mknod (req, ino, PARAM(arg), arg->mode, arg->rdev); - else - guts_reply_err (req, ENOSYS); -} - -static void -guts_replay_mkdir (fuse_req_t req, - fuse_ino_t ino, - const void *inargs) -{ - struct fuse_mkdir_in *arg = (struct fuse_mkdir_in *) inargs; - - if (req->f->op.mkdir) - req->f->op.mkdir (req, ino, PARAM(arg), arg->mode); - else - guts_reply_err (req, ENOSYS); -} - -static void -guts_replay_unlink (fuse_req_t req, - fuse_ino_t ino, - const void *inargs) -{ - char *name = (char *)inargs; - - if (req->f->op.unlink) { - - req->f->op.unlink (req, ino, name); - } else - guts_reply_err (req, ENOSYS); -} - -static void -guts_replay_rmdir (fuse_req_t req, - fuse_ino_t ino, - const void *inargs) -{ - char *name = (char *)inargs; - - if (req->f->op.rmdir) { - req->f->op.rmdir (req, ino, name); - } else - guts_reply_err (req, ENOSYS); -} - -static void -guts_replay_symlink (fuse_req_t req, - fuse_ino_t ino, - const void *inargs) -{ - char *name = (char *) inargs; - char *linkname = ((char *) inargs) + strlen ((char *) inargs) + 1; - - if (req->f->op.symlink) { - req->f->op.symlink (req, linkname, ino, name); - } else - guts_reply_err (req, ENOSYS); -} - - - -static void -guts_replay_rename (fuse_req_t req, - fuse_ino_t ino, - const void *inargs) -{ - struct fuse_rename_in *arg = (struct fuse_rename_in *) inargs; - char *oldname = PARAM(arg); - char *newname = oldname + strlen (oldname) + 1; - - if (req->f->op.rename) { - req->f->op.rename (req, ino, oldname, arg->newdir, newname); - } else - guts_reply_err (req, ENOSYS); - -} - -static void -guts_replay_link (fuse_req_t req, - fuse_ino_t ino, - const void *inargs) -{ - struct fuse_link_in *arg = (struct fuse_link_in *) inargs; - - if (req->f->op.link) { - guts_replay_ctx_t *ctx = (guts_replay_ctx_t *) req->u.ni.data; - fuse_ino_t old_ino = guts_inode_search (ctx, arg->oldnodeid); - - req->f->op.link (req, old_ino, ino, PARAM(arg)); - } else - guts_reply_err (req, ENOSYS); -} - - -static void -guts_replay_create (fuse_req_t req, - fuse_ino_t ino, - const void *inargs) -{ - struct guts_create_in *arg = (struct guts_create_in *) inargs; - - if (req->f->op.create) { - struct fuse_file_info fi; - memset (&fi, 0, sizeof (fi)); - fi.flags = arg->open_in.flags; - - req->f->op.create (req, ino, arg->name, arg->open_in.mode, &fi); - } else - guts_reply_err (req, ENOSYS); - -} - -static void -guts_replay_open (fuse_req_t req, - fuse_ino_t ino, - const void *inargs) -{ - struct fuse_open_in *arg = (struct fuse_open_in *) inargs; - struct fuse_file_info fi; - - memset (&fi, 0, sizeof (fi)); - fi.flags = arg->flags; - - if (req->f->op.open) { - /* TODO: how efficient is using dict_get here?? */ - req->f->op.open (req, ino, &fi); - } else - guts_reply_open (req, &fi); -} - - -static void -guts_replay_read(fuse_req_t req, - fuse_ino_t ino, - const void *inarg) -{ - struct fuse_read_in *arg = (struct fuse_read_in *) inarg; - - if (req->f->op.read){ - struct fuse_file_info fi; - guts_replay_ctx_t *ctx = req->u.ni.data; - - memset (&fi, 0, sizeof (fi)); - /* TODO: how efficient is using dict_get here?? */ - fi.fh = (unsigned long) guts_fd_search (ctx, arg->fh); - if (!fi.fh) { - /* TODO: make it more meaningful and organized */ - printf ("readv called without opening the file\n"); - guts_reply_err (req, EBADFD); - } else { - fi.fh_old = fi.fh; - req->f->op.read (req, ino, arg->size, arg->offset, &fi); - } - } else - guts_reply_err (req, ENOSYS); -} - -static void -guts_replay_write(fuse_req_t req, - fuse_ino_t ino, - const void *inarg) -{ - struct fuse_write_in *arg = (struct fuse_write_in *) inarg; - struct fuse_file_info fi; - guts_replay_ctx_t *ctx = (guts_replay_ctx_t *) req->u.ni.data; - - memset (&fi, 0, sizeof (fi)); - fi.fh = (unsigned long) guts_fd_search (ctx, arg->fh); - - if (!fi.fh) { - /* TODO: make it more meaningful and organized */ - printf ("writev called without opening the file\n"); - guts_reply_err (req, EBADFD); - } else { - fi.fh_old = fi.fh; - fi.writepage = arg->write_flags & 1; - if (req->f->op.write) - req->f->op.write (req, ino, PARAM(arg), arg->size, arg->offset, &fi); - else - guts_reply_err (req, ENOSYS); - } -} - -static void -guts_replay_flush(fuse_req_t req, - fuse_ino_t ino, - const void *inarg) -{ - struct fuse_flush_in *arg = (struct fuse_flush_in *) inarg; - struct fuse_file_info fi; - guts_replay_ctx_t *ctx = (guts_replay_ctx_t *) req->u.ni.data; - - memset (&fi, 0, sizeof (fi)); - fi.fh = (unsigned long) guts_fd_search (ctx, arg->fh); - if (!fi.fh) { - printf ("flush called without calling open\n"); - guts_reply_err (req, EBADFD); - } else { - fi.fh_old = fi.fh; - fi.flush = 1; - - if (req->f->conn.proto_minor >= 7) - fi.lock_owner = arg->lock_owner; - - if (req->f->op.flush) - req->f->op.flush (req, ino, &fi); - else - guts_reply_err (req, ENOSYS); - } -} - -static void -guts_replay_release(fuse_req_t req, - fuse_ino_t ino, - const void *inarg) -{ - struct fuse_release_in *arg = (struct fuse_release_in *) inarg; - struct fuse_file_info fi; - guts_replay_ctx_t *ctx = (guts_replay_ctx_t *) req->u.ni.data; - - memset (&fi, 0, sizeof (fi)); - fi.flags = arg->flags; - fi.fh = (unsigned long) guts_fd_search (ctx, arg->fh); - - if (!fi.fh) { - printf ("release called without calling open\n"); - guts_reply_err (req, EBADFD); - } else { - fi.fh_old = fi.fh; - if (req->f->conn.proto_minor >= 8) { - fi.flush = (arg->release_flags & FUSE_RELEASE_FLUSH) ? 1 : 0; - fi.lock_owner = arg->lock_owner; - } - if (req->f->op.release) - req->f->op.release (req, ino, &fi); - else - guts_reply_err (req, ENOSYS); - } -} - -static void -guts_replay_fsync(fuse_req_t req, - fuse_ino_t ino, - const void *inarg) -{ - struct fuse_fsync_in *arg = (struct fuse_fsync_in *) inarg; - struct fuse_file_info fi; - guts_replay_ctx_t *ctx = (guts_replay_ctx_t *) req->u.ni.data; - - memset (&fi, 0, sizeof (fi)); - fi.fh = (unsigned long) guts_fd_search (ctx, arg->fh); - fi.fh_old = fi.fh; - - if (req->f->op.fsync) - req->f->op.fsync (req, ino, arg->fsync_flags & 1, &fi); - else - guts_reply_err (req, ENOSYS); -} - -static void -guts_replay_opendir (fuse_req_t req, - fuse_ino_t ino, - const void *inarg) -{ - struct fuse_open_in *arg = (struct fuse_open_in *) inarg; - struct fuse_file_info fi; - - memset (&fi, 0, sizeof (fi)); - fi.flags = arg->flags; - - if (req->f->op.opendir) { - req->f->op.opendir (req, ino, &fi); - } else - guts_reply_open (req, &fi); -} - -static void -guts_replay_readdir(fuse_req_t req, - fuse_ino_t ino, - const void *inarg) -{ - struct fuse_read_in *arg = (struct fuse_read_in *) inarg; - struct fuse_file_info fi; - guts_replay_ctx_t *ctx = (guts_replay_ctx_t *) req->u.ni.data; - - memset (&fi, 0, sizeof (fi)); - fi.fh = (unsigned long) guts_fd_search (ctx, arg->fh); - - if (!fi.fh) { - /* TODO: make it more meaningful and organized */ - printf ("readdir called without opening the file\n"); - guts_reply_err (req, EBADFD); - } else { - fi.fh_old = fi.fh; - - if (req->f->op.readdir) - req->f->op.readdir (req, ino, arg->size, arg->offset, &fi); - else - guts_reply_err (req, ENOSYS); - } - -} - -static void -guts_replay_releasedir(fuse_req_t req, - fuse_ino_t ino, - const void *inarg) -{ - struct fuse_release_in *arg = (struct fuse_release_in *) inarg; - struct fuse_file_info fi; - guts_replay_ctx_t *ctx = (guts_replay_ctx_t *) req->u.ni.data; - - memset (&fi, 0, sizeof (fi)); - fi.flags = arg->flags; - fi.fh = (unsigned long) guts_fd_search (ctx, arg->fh); - if (!fi.fh) { - printf ("releasedir called without calling opendir\n"); - guts_reply_err (req, EBADFD); - } else { - - fi.fh_old = fi.fh; - if (req->f->op.releasedir) - req->f->op.releasedir (req, ino, &fi); - else - guts_reply_err (req, ENOSYS); - } -} - -static void -guts_replay_fsyncdir(fuse_req_t req, - fuse_ino_t ino, - const void *inarg) -{ - struct fuse_fsync_in *arg = (struct fuse_fsync_in *) inarg; - struct fuse_file_info fi; - guts_replay_ctx_t *ctx = (guts_replay_ctx_t *) req->u.ni.data; - - memset (&fi, 0, sizeof (fi)); - fi.fh = (unsigned long) guts_fd_search (ctx, arg->fh); - fi.fh_old = fi.fh; - - if (req->f->op.fsyncdir) - req->f->op.fsyncdir (req, ino, arg->fsync_flags & 1, &fi); - else - guts_reply_err (req, ENOSYS); -} - -static void -guts_replay_statfs (fuse_req_t req, - fuse_ino_t ino, - const void *inargs) -{ - (void) ino; - (void) inargs; - - if (req->f->op.statfs) { - req->f->op.statfs (req, ino); - } else { - struct statvfs buf = { - .f_namemax = 255, - .f_bsize = 512, - }; - guts_reply_statfs (req, &buf); - } -} - -static void -guts_replay_setxattr(fuse_req_t req, - fuse_ino_t ino, - const void *inarg) -{ - struct fuse_setxattr_in *arg = (struct fuse_setxattr_in *) inarg; - char *name = PARAM(arg); - char *value = name + strlen(name) + 1; - - if (req->f->op.setxattr) - req->f->op.setxattr (req, ino, name, value, arg->size, arg->flags); - else - guts_reply_err (req, ENOSYS); -} - -static void -guts_replay_getxattr(fuse_req_t req, - fuse_ino_t ino, - const void *inarg) -{ - struct fuse_getxattr_in *arg = (struct fuse_getxattr_in *) inarg; - - if (req->f->op.getxattr) - req->f->op.getxattr (req, ino, PARAM(arg), arg->size); - else - guts_reply_err (req, ENOSYS); -} - -static void -guts_replay_listxattr (fuse_req_t req, - fuse_ino_t ino, - const void *inargs) -{ - struct fuse_getxattr_in *arg = (struct fuse_getxattr_in *) inargs; - - if (req->f->op.listxattr) - req->f->op.listxattr (req, ino, arg->size); - else - guts_reply_err (req, ENOSYS); -} - -static void -guts_replay_removexattr(fuse_req_t req, - fuse_ino_t ino, - const void *inargs) -{ - char *name = (char *)inargs; - - if (req->f->op.removexattr) - req->f->op.removexattr (req, ino, name); - else - guts_reply_err (req, ENOSYS); -} - -guts_replay_t guts_replay_fop[] = { - [FUSE_LOOKUP] = { guts_replay_lookup, "lookup" }, - [FUSE_FORGET] = { guts_replay_forget, "forget" }, - [FUSE_GETATTR] = { guts_replay_getattr, "getattr" }, - [FUSE_SETATTR] = { guts_replay_setattr, "setattr" }, - [FUSE_ACCESS] = { guts_replay_access, "access" }, - [FUSE_READLINK] = { guts_replay_readlink, "readlink" }, - [FUSE_MKNOD] = { guts_replay_mknod, "mknod" }, - [FUSE_MKDIR] = { guts_replay_mkdir, "mkdir" }, - [FUSE_UNLINK] = { guts_replay_unlink, "unlink" }, - [FUSE_RMDIR] = { guts_replay_rmdir, "rmdir" }, - [FUSE_SYMLINK] = { guts_replay_symlink, "symlink" }, - [FUSE_RENAME] = { guts_replay_rename, "rename" }, - [FUSE_LINK] = { guts_replay_link, "link" }, - [FUSE_CREATE] = { guts_replay_create, "create" }, - [FUSE_OPEN] = { guts_replay_open, "open" }, - [FUSE_READ] = { guts_replay_read, "read" }, - [FUSE_WRITE] = { guts_replay_write, "write" }, - [FUSE_FLUSH] = { guts_replay_flush, "flush" }, - [FUSE_RELEASE] = { guts_replay_release, "release" }, - [FUSE_FSYNC] = { guts_replay_fsync, "fsync" }, - [FUSE_OPENDIR] = { guts_replay_opendir, "opendir" }, - [FUSE_READDIR] = { guts_replay_readdir, "readdir" }, - [FUSE_RELEASEDIR] = { guts_replay_releasedir, "releasedir" }, - [FUSE_FSYNCDIR] = { guts_replay_fsyncdir, "fsyncdir" }, - [FUSE_STATFS] = { guts_replay_statfs, "statfs" }, - [FUSE_SETXATTR] = { guts_replay_setxattr, "setxattr" }, - [FUSE_GETXATTR] = { guts_replay_getxattr, "getxattr" }, - [FUSE_LISTXATTR] = { guts_replay_listxattr, "listxattr" }, - [FUSE_REMOVEXATTR] = { guts_replay_removexattr, "removexattr" }, -}; - -static inline void -list_init_req (struct fuse_req *req) -{ - req->next = req; - req->prev = req; -} - - -static int32_t -guts_transport_notify (xlator_t *xl, - int32_t event, - void *data, - ...) -{ - /* dummy, nobody has got anything to notify me.. ;) */ - return 0; -} - -static int32_t -guts_transport_init (transport_t *this, - dict_t *options, - event_notify_fn_t notify) -{ - struct fuse_private *priv = CALLOC (1, sizeof (*priv)); - ERR_ABORT (priv); - - this->notify = NULL; - this->private = (void *)priv; - - /* fuse channel */ - priv->ch = NULL; - - /* fuse session */ - priv->se = NULL; - - /* fuse channel fd */ - priv->fd = -1; - - this->buf = data_ref (data_from_dynptr (NULL, 0)); - this->buf->is_locked = 1; - - priv->mountpoint = NULL; - - transport_ref (this); - - return 0; -} - -static void -guts_transport_fini (transport_t *this) -{ - -} - -static int32_t -guts_transport_disconnect (transport_t *this) -{ - struct fuse_private *priv = this->private; - - gf_log ("glusterfs-guts", - GF_LOG_DEBUG, - "cleaning up fuse transport in disconnect handler"); - - 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 - */ - return -1; -} - -static struct transport_ops guts_transport_ops = { - .disconnect = guts_transport_disconnect, -}; - -static transport_t guts_transport = { - .ops = &guts_transport_ops, - .private = NULL, - .xl = NULL, - .init = guts_transport_init, - .fini = guts_transport_fini, - .notify = guts_transport_notify -}; - -static inline xlator_t * -fuse_graph (xlator_t *graph) -{ - xlator_t *top = NULL; - xlator_list_t *xlchild; - - top = CALLOC (1, sizeof (*top)); - ERR_ABORT (top); - - xlchild = CALLOC (1, sizeof(*xlchild)); - ERR_ABORT (xlchild); - xlchild->xlator = graph; - top->children = xlchild; - top->ctx = graph->ctx; - top->next = graph; - graph->parent = top; - - return top; -} - -static guts_replay_ctx_t * -guts_replay_init (guts_thread_ctx_t *thread) -{ - guts_replay_ctx_t *ctx = NULL; - int32_t fd = open (thread->file, O_RDONLY); - - if (fd < 0) { - gf_log ("glusterfs-guts", GF_LOG_DEBUG, - "failed to open tio_file %s", thread->file); - return ctx; - } else { - struct fuse_ll *guts_ll = CALLOC (1, sizeof (*guts_ll)); - ERR_ABORT (guts_ll); - - ctx = CALLOC (1, sizeof (*ctx)); - ERR_ABORT (ctx); - - if (ctx) { - /* equivalent to fuse_new_session () */ - guts_ll->conn.async_read = 1; - guts_ll->conn.max_write = UINT_MAX; - guts_ll->conn.max_readahead = UINT_MAX; - memcpy (&guts_ll->op, &fuse_ops, sizeof (struct fuse_lowlevel_ops)); - list_init_req (&guts_ll->list); - list_init_req (&guts_ll->interrupts); - guts_ll->owner = getuid (); - guts_ll->userdata = thread; - - /* TODO: need to create transport_t object which whole of the glusterfs - * so desperately depends on */ - transport_t *guts_trans = CALLOC (1, sizeof (*guts_trans)); - - if (guts_trans) { - memcpy (guts_trans, &guts_transport, sizeof (*guts_trans)); - guts_trans->ops = &guts_transport_ops; - } else { - gf_log ("glusterfs-guts", GF_LOG_ERROR, - "failed to allocate memory for guts transport object"); - return NULL; - } - - glusterfs_ctx_t *glfs_ctx = CALLOC (1, sizeof (*glfs_ctx));; - if (glfs_ctx) { - guts_trans->xl_private = glfs_ctx; - guts_trans->xl = fuse_graph (thread->ctx->graph); - }else { - gf_log ("glusterfs-guts", GF_LOG_ERROR, - "failed to allocate memory for glusterfs_ctx_t object"); - return NULL; - } - - call_pool_t *pool = CALLOC (1, sizeof (call_pool_t)); - if (pool) { - glfs_ctx->pool = pool; - LOCK_INIT (&pool->lock); - INIT_LIST_HEAD (&pool->all_frames); - } else { - gf_log ("glusterfs-guts", GF_LOG_ERROR, - "failed to allocate memory for guts call pool"); - return NULL; - } - - guts_trans->xl->ctx = glfs_ctx; - guts_trans->init (guts_trans, NULL, guts_transport_notify); - guts_ll->userdata = guts_trans; - - /* call fuse_init */ - guts_ll->op.init (guts_trans, NULL); - - { - ctx->guts_ll = guts_ll; - ctx->tio_fd = fd; - ctx->inodes = get_new_dict (); - ctx->fds = get_new_dict (); - ctx->replies = get_new_dict (); - INIT_LIST_HEAD(&ctx->requests); - ctx->requests_dict = get_new_dict (); - } - } else { - gf_log ("glusterfs-guts", GF_LOG_ERROR, - "failed to allocate memory for guts_ctx_t object"); - return NULL; - } - } - - return ctx; -} - -int32_t -guts_replay (guts_thread_ctx_t *thread) -{ - guts_req_t *entry = NULL; - guts_replay_ctx_t *ctx = guts_replay_init (thread); - - if (!ctx) { - gf_log ("glusterfs-guts", GF_LOG_ERROR, - "failed to initialize guts_replay"); - return -1; - } else { - while ((entry = guts_read_entry (ctx))) { - /* here we go ... execute the request */ - fuse_req_t req = CALLOC (1, sizeof (struct fuse_req)); - ino_t ino = entry->header.nodeid; - void *arg = entry->arg; - - if (req) { - req->f = ctx->guts_ll; - req->unique = entry->header.unique; - req->ctx.uid = entry->header.uid; - req->ctx.pid = entry->header.pid; - - /* req->u.ni.data is unused void *, while running in replay mode. Making use of available real-estate - * to store useful information of thread specific guts_replay_ctx */ - req->u.ni.data = (void *) ctx; - /* req->ch is of type 'struct fuse_chan', which fuse uses only at the - * time of the response it gets and is useful in sending the reply data to correct channel - * in /dev/fuse. This is not useful for us, so we ignore it by keeping it NULL */ - list_init_req (req); - - fuse_ino_t new_ino = guts_inode_search (ctx, ino); - - if (guts_replay_fop[entry->header.opcode].func) { - printf ("operation: %s && inode: %ld\n", guts_replay_fop[entry->header.opcode].name, new_ino); - guts_replay_fop[entry->header.opcode].func (req, new_ino, arg); - } - - if (entry->arg) - free (entry->arg); - free (entry); - } else { - gf_log ("glusterfs-guts", GF_LOG_ERROR, - "failed to allocate memory for fuse_req_t object"); - return -1; - } - } - } - return 0; -} diff --git a/glusterfs-guts/src/guts-replay.h b/glusterfs-guts/src/guts-replay.h deleted file mode 100644 index e4b4a2b733f..00000000000 --- a/glusterfs-guts/src/guts-replay.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - Copyright (c) 2008-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/>. -*/ - -#define PARAM(inarg) (((char *)(inarg)) + sizeof(*(inarg))) - -void guts_reply_err (fuse_req_t, error_t); -void guts_reply_open (fuse_req_t, struct fuse_file_info *); -void guts_reply_statfs (fuse_req_t, struct statvfs *); - -typedef void (*guts_replay_fop_t)(fuse_req_t, fuse_ino_t, const void *); - -typedef struct { - guts_replay_fop_t func; - const char *name; -} guts_replay_t; - -extern struct fuse_lowlevel_ops fuse_ops; - diff --git a/glusterfs-guts/src/guts-tables.c b/glusterfs-guts/src/guts-tables.c deleted file mode 100644 index 357b055d143..00000000000 --- a/glusterfs-guts/src/guts-tables.c +++ /dev/null @@ -1,248 +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 "guts-parse.h" -#include "dict.h" -#include "guts-tables.h" - - -int32_t -guts_attr_cmp (const struct stat *attr, - const struct stat *old_attr) -{ - return 0; -} - -int32_t -guts_statvfs_cmp (const struct statvfs *stbuf, - const struct statvfs *old_stbuf) -{ - return 0; -} - -int32_t -guts_flock_cmp (struct flock *lock, - struct flock *old_lock) -{ - return 0; -} - - -guts_req_t * -guts_lookup_request (guts_replay_ctx_t *ctx, uint64_t unique) -{ - guts_req_t *req = NULL; - - if (unique == 0) { - if (list_empty (&ctx->requests)) - req = NULL; - else { - /* pick an entry from list, move it out of the list and return it to the caller */ - char *key = NULL; - - req = list_entry (ctx->requests.next, guts_req_t, list); - list_del (&req->list); - - asprintf (&key, "%llu", req->header.unique); - - dict_set (ctx->requests_dict, key, data_from_static_ptr (req)); - - if (key) - free (key); - } - } else { - char *key = NULL; - data_t *req_data = NULL; - - asprintf (&key, "%llu", unique); - - req_data = dict_get (ctx->requests_dict, key); - - if (req_data) - req = data_to_ptr (req_data); - - if (key) - free (key); - } - return req; -} - -guts_req_t * -guts_get_request (guts_replay_ctx_t *ctx) -{ - return guts_lookup_request (ctx, 0); -} - -int32_t -guts_add_request (guts_replay_ctx_t *ctx, - guts_req_t *req) -{ - list_add_tail (&req->list, &ctx->requests); - return 0; -} - -int32_t -guts_add_reply (guts_replay_ctx_t *ctx, - guts_reply_t *reply) -{ - char *key = NULL; - asprintf (&key, "%llu", reply->req.unique); - - dict_set (ctx->replies, key, data_from_static_ptr(reply)); - - if (key) - free(key); - - return 0; -} - - -guts_reply_t * -guts_lookup_reply (guts_replay_ctx_t *ctx, - uint64_t unique) -{ - char *key = NULL; - data_t *reply_data = NULL; - guts_reply_t *new_reply = NULL; - - asprintf (&key, "%llu", unique); - reply_data = dict_get (ctx->replies, key); - - if (reply_data) { - new_reply = data_to_ptr (reply_data); - dict_del (ctx->replies, key); - } else { - /* reply has not yet been read from tio file */ - new_reply = guts_read_reply (ctx, unique); - - if (!new_reply) { - /* failed to fetch reply for 'unique' from tio file */ - new_reply; - } - } - - if (key) - free(key); - - return new_reply; - -} - -int32_t -guts_inode_update (guts_replay_ctx_t *ctx, - fuse_ino_t old_ino, - fuse_ino_t new_ino) -{ - char *key = NULL; - asprintf (&key, "%ld", old_ino); - dict_set (ctx->inodes, key, data_from_uint64 (new_ino)); - - if (key) - free(key); - - return 0; -} - -fuse_ino_t -guts_inode_search (guts_replay_ctx_t *ctx, - fuse_ino_t old_ino) -{ - char *key = NULL; - data_t *ino_data = NULL; - fuse_ino_t new_ino = 0; - - asprintf (&key, "%ld", old_ino); - ino_data = dict_get (ctx->inodes, key); - - if (ino_data) - new_ino = data_to_uint64 (ino_data); - else if (old_ino != /* TODO: FIXME */1 ) { - new_ino = 0; - } else - new_ino = old_ino; - - if (key) - free(key); - - return new_ino; -} - -int32_t -guts_fd_add (guts_replay_ctx_t *ctx, - unsigned long old_fd, - fd_t *new_fd) -{ - char *key = NULL; - asprintf (&key, "%ld", old_fd); - dict_set (ctx->fds, key, data_from_static_ptr (new_fd)); - - if (key) - free(key); - - return 0; -} - -fd_t * -guts_fd_search (guts_replay_ctx_t *ctx, - unsigned long old_fd) -{ - char *key = NULL; - data_t *fd_data = NULL; - fd_t *new_fd = NULL; - - asprintf (&key, "%ld", old_fd); - fd_data = dict_get (ctx->fds, key); - - if (fd_data) - new_fd = data_to_ptr (fd_data); - - if (key) - free(key); - - return new_fd; -} - -int32_t -guts_delete_fd (guts_replay_ctx_t *ctx, - unsigned long old_fd) -{ - char *key = NULL; - data_t *fd_data = NULL; - - asprintf (&key, "%ld", old_fd); - fd_data = dict_get (ctx->fds, key); - - if (fd_data) - dict_del (ctx->fds, key); - - if (key) - free(key); - - return 0; -} - -inline int32_t -guts_get_opcode (guts_replay_ctx_t *ctx, - uint64_t unique) -{ - guts_req_t *req = guts_lookup_request (ctx, unique); - - return ((req == NULL) ? -1 : req->header.opcode); - -} diff --git a/glusterfs-guts/src/guts-tables.h b/glusterfs-guts/src/guts-tables.h deleted file mode 100644 index 482751f338a..00000000000 --- a/glusterfs-guts/src/guts-tables.h +++ /dev/null @@ -1,80 +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/>. -*/ - -#ifndef _GUTS_TABLES_H_ -#define _GUTS_TABLES_H_ - - -int32_t -guts_attr_cmp (const struct stat *attr, - const struct stat *old_attr); - -int32_t -guts_statvfs_cmp (const struct statvfs *stbuf, - const struct statvfs *old_stbuf); - -int32_t -guts_inode_update (guts_replay_ctx_t *ctx, - fuse_ino_t old_ino, - fuse_ino_t new_ino); - -fuse_ino_t -guts_inode_search (guts_replay_ctx_t *ctx, - fuse_ino_t old_ino); - -int32_t -guts_add_request (guts_replay_ctx_t *, - guts_req_t *); - -guts_req_t * -guts_get_request (guts_replay_ctx_t *ctx); - -guts_req_t * -guts_lookup_request (guts_replay_ctx_t *ctx, - uint64_t unique); - -guts_reply_t * -guts_lookup_reply (guts_replay_ctx_t *ctx, - uint64_t unique); - -int32_t -guts_add_reply (guts_replay_ctx_t *ctx, - guts_reply_t *reply); - -int32_t -guts_flock_cmp (struct flock *lock, - struct flock *old_lock); - -fd_t * -guts_fd_search (guts_replay_ctx_t *ctx, - unsigned long old_fd); - -int32_t -guts_delete_fd (guts_replay_ctx_t *, - unsigned long); - -int32_t -guts_get_opcode (guts_replay_ctx_t *ctx, - uint64_t unique); -int32_t -guts_fd_add (guts_replay_ctx_t *ctx, - unsigned long old_fd, - fd_t *new_fd); - -#endif diff --git a/glusterfs-guts/src/guts-trace.c b/glusterfs-guts/src/guts-trace.c deleted file mode 100644 index a69aa16b96b..00000000000 --- a/glusterfs-guts/src/guts-trace.c +++ /dev/null @@ -1,650 +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 "glusterfs-guts.h" -#include <signal.h> - -#include "guts-parse.h" -#include "guts-tables.h" -#include "guts-trace.h" - -static xlator_t * -fuse_graph (xlator_t *graph) -{ - xlator_t *top = NULL; - xlator_list_t *xlchild; - - top = CALLOC (1, sizeof (*top)); - ERR_ABORT (top); - xlchild = CALLOC (1, sizeof(*xlchild)); - ERR_ABORT (xlchild); - xlchild->xlator = graph; - top->children = xlchild; - top->ctx = graph->ctx; - top->next = graph; - graph->parent = top; - - return top; -} - -int32_t -fuse_thread (pthread_t *thread, void *data); - -int32_t -guts_trace (guts_ctx_t *guts_ctx) -{ - transport_t *mp = NULL; - glusterfs_ctx_t ctx = { - .poll_type = SYS_POLL_TYPE_EPOLL, - }; - xlator_t *graph = NULL; - call_pool_t *pool = NULL; - int32_t ret = -1; - pthread_t thread; - /* Ignore SIGPIPE */ - signal (SIGPIPE, SIG_IGN); - -#if HAVE_BACKTRACE - /* Handle SIGABORT and SIGSEGV */ - signal (SIGSEGV, gf_print_trace); - signal (SIGABRT, gf_print_trace); -#endif /* HAVE_BACKTRACE */ - - ret = guts_tio_init (guts_ctx->file); - - if (ret < 0) { - gf_log ("glusterfs-guts", GF_LOG_ERROR, - "running in trace mode: failed to open tio file %s", guts_ctx->file); - return -1; - } - - pool = ctx.pool = CALLOC (1, sizeof (call_pool_t)); - ERR_ABORT (ctx.pool); - LOCK_INIT (&pool->lock); - INIT_LIST_HEAD (&pool->all_frames); - - /* glusterfs_mount has to be ideally placed after all the initialisation stuff */ - if (!(mp = glusterfs_mount (&ctx, guts_ctx->mountpoint))) { - gf_log ("glusterfs-guts", GF_LOG_ERROR, "Unable to mount glusterfs"); - return -1; - } - - gf_timer_registry_init (&ctx); - graph = guts_ctx->graph; - - if (!graph) { - gf_log ("glusterfs-guts", GF_LOG_ERROR, - "Unable to get xlator graph for mount_point %s", guts_ctx->mountpoint); - transport_disconnect (mp); - return -1; - } - - ctx.graph = graph; - - mp->xl = fuse_graph (graph); - mp->xl->ctx = &ctx; - - fuse_thread (&thread, mp); - - while (!poll_iteration (&ctx)); - - return 0; -} - - - -static void -guts_name (struct fuse_in_header *in, - const void *inargs) -{ - char *name = (char *) inargs; - - guts_req_dump (in, name, strlen (name)); -} - -static void -guts_noarg (struct fuse_in_header *in, - const void *inargs) -{ - guts_req_dump (in, NULL, 0); -} - - -static void -guts_setattr (struct fuse_in_header *in, - const void *inargs) -{ - struct fuse_setattr_in *arg = (struct fuse_setattr_in *)inargs; - guts_req_dump (in, arg, sizeof (*arg)); -} - -static void -guts_access (struct fuse_in_header *in, - const void *inargs) -{ - struct fuse_access_in *arg = (struct fuse_access_in *)inargs; - guts_req_dump (in, arg, sizeof (*arg)); -} - - -static void -guts_mknod (struct fuse_in_header *in, - const void *inargs) -{ - struct fuse_mknod_in *arg = (struct fuse_mknod_in *) inargs; - guts_req_dump (in, arg, sizeof (*arg)); -} - -static void -guts_mkdir (struct fuse_in_header *in, - const void *inargs) -{ - struct fuse_mkdir_in *arg = (struct fuse_mkdir_in *) inargs; - guts_req_dump (in, arg, sizeof (*arg)); -} - - -static void -guts_symlink (struct fuse_in_header *in, - const void *inargs) -{ - char *name = (char *) inargs; - char *linkname = ((char *) inargs) + strlen ((char *) inargs) + 1; - struct guts_symlink_in symlink_in; - - strcpy (symlink_in.name, name); - strcpy (symlink_in.linkname, linkname); - guts_req_dump (in, &symlink_in, sizeof (symlink_in)); -} - -static void -guts_rename (struct fuse_in_header *in, - const void *inargs) -{ - struct fuse_rename_in *arg = (struct fuse_rename_in *) inargs; - char *oldname = PARAM(arg); - char *newname = oldname + strlen (oldname) + 1; - struct guts_rename_in rename_in; - - memset (&rename_in, 0, sizeof (rename_in)); - memcpy (&rename_in, arg, sizeof (*arg)); - strcpy (rename_in.oldname, oldname); - strcpy (rename_in.newname, newname); - - guts_req_dump (in, &rename_in, sizeof (rename_in)); - -} - -static void -guts_link (struct fuse_in_header *in, - const void *inargs) -{ - struct fuse_link_in *arg = (struct fuse_link_in *) inargs; - - guts_req_dump (in, arg, sizeof (*arg)); -} - - -static void -guts_open (struct fuse_in_header *in, - const void *inargs) -{ - struct fuse_open_in *arg = (struct fuse_open_in *) inargs; - - guts_req_dump (in, arg, sizeof (*arg)); -} - -static void -guts_create (struct fuse_in_header *in, - const void *inargs) -{ - struct guts_create_in create_in; - struct fuse_open_in *arg = (struct fuse_open_in *) inargs; - char *name = PARAM (arg); - - memset (&create_in, 0, sizeof (create_in)); - memcpy (&create_in.open_in, arg, sizeof (*arg)); - memcpy (&create_in.name, name, strlen (name)); - - guts_req_dump (in, &create_in, sizeof (create_in)); -} - - -static void -guts_read(struct fuse_in_header *in, - const void *inarg) -{ - struct fuse_read_in *arg = (struct fuse_read_in *) inarg; - guts_req_dump (in, arg, sizeof (*arg)); -} - -static void -guts_write(struct fuse_in_header *in, - const void *inarg) -{ - /* TODO: where the hell is the data to be written??? */ - struct fuse_write_in *arg = (struct fuse_write_in *) inarg; - guts_req_dump (in, arg, sizeof (*arg)); -} - -static void -guts_flush(struct fuse_in_header *in, - const void *inarg) -{ - struct fuse_flush_in *arg = (struct fuse_flush_in *) inarg; - guts_req_dump (in, arg, sizeof (*arg)); -} - -static void -guts_release(struct fuse_in_header *in, - const void *inarg) -{ - struct fuse_release_in *arg = (struct fuse_release_in *) inarg; - guts_req_dump (in, arg, sizeof (*arg)); -} - -static void -guts_fsync(struct fuse_in_header *in, - const void *inarg) -{ - struct fuse_fsync_in *arg = (struct fuse_fsync_in *) inarg; - guts_req_dump (in, arg, sizeof (*arg)); -} - - -static void -guts_readdir(struct fuse_in_header *in, - const void *inarg) -{ - struct fuse_read_in *arg = (struct fuse_read_in *) inarg; - guts_req_dump (in, arg, sizeof (*arg)); -} - -static void -guts_releasedir(struct fuse_in_header *in, - const void *inarg) -{ - struct fuse_release_in *arg = (struct fuse_release_in *) inarg; - guts_req_dump (in, arg, sizeof (*arg)); -} - -static void -guts_fsyncdir(struct fuse_in_header *in, - const void *inarg) -{ - struct fuse_fsync_in *arg = (struct fuse_fsync_in *) inarg; - guts_req_dump (in, arg, sizeof (*arg)); -} - - -static void -guts_setxattr(struct fuse_in_header *in, - const void *inarg) -{ - struct fuse_setxattr_in *arg = (struct fuse_setxattr_in *) inarg; - char *name = PARAM(arg); - char *value = name + strlen(name) + 1; - struct guts_xattr_in setxattr_in; - - memset (&setxattr_in, 0, sizeof (setxattr_in)); - memcpy (&setxattr_in, arg, sizeof (*arg)); - strcpy (setxattr_in.name, name); - strcpy (setxattr_in.value, value); - - guts_req_dump (in, &setxattr_in, sizeof (setxattr_in)); - -} - -static void -guts_getxattr(struct fuse_in_header *in, - const void *inarg) -{ - struct fuse_getxattr_in *arg = (struct fuse_getxattr_in *) inarg; - guts_req_dump (in, arg, sizeof (*arg)); -} - -guts_log_t guts_log[] = { - [FUSE_LOOKUP] = { guts_name, "lookup" }, - [FUSE_GETATTR] = { guts_noarg, "getattr" }, - [FUSE_SETATTR] = { guts_setattr, "setattr" }, - [FUSE_ACCESS] = { guts_access, "access" }, - [FUSE_READLINK] = { guts_noarg, "readlink" }, - [FUSE_MKNOD] = { guts_mknod, "mknod" }, - [FUSE_MKDIR] = { guts_mkdir, "mkdir" }, - [FUSE_UNLINK] = { guts_name, "unlink" }, - [FUSE_RMDIR] = { guts_name, "rmdir" }, - [FUSE_SYMLINK] = { guts_symlink, "symlink" }, - [FUSE_RENAME] = { guts_rename, "rename" }, - [FUSE_LINK] = { guts_link, "link" }, - [FUSE_CREATE] = { guts_create, "create" }, - [FUSE_OPEN] = { guts_open, "open" }, - [FUSE_READ] = { guts_read, "read" }, - [FUSE_WRITE] = { guts_write, "write" }, - [FUSE_FLUSH] = { guts_flush, "flush" }, - [FUSE_RELEASE] = { guts_release, "release" }, - [FUSE_FSYNC] = { guts_fsync, "fsync" }, - [FUSE_OPENDIR] = { guts_open, "opendir" }, - [FUSE_READDIR] = { guts_readdir, "readdir" }, - [FUSE_RELEASEDIR] = { guts_releasedir, "releasedir" }, - [FUSE_FSYNCDIR] = { guts_fsyncdir, "fsyncdir" }, - [FUSE_STATFS] = { guts_noarg, "statfs" }, - [FUSE_SETXATTR] = { guts_setxattr, "setxattr" }, - [FUSE_GETXATTR] = { guts_getxattr, "getxattr" }, - [FUSE_LISTXATTR] = { guts_getxattr, "listxattr" }, - [FUSE_REMOVEXATTR] = { guts_name, "removexattr" }, -}; - -/* used for actual tracing task */ - -int32_t -guts_log_req (void *buf, - int32_t len) -{ - struct fuse_in_header *in = buf; - const void *inargs = NULL; - int32_t header_len = sizeof (struct fuse_in_header); - - if (header_len < len ) { - inargs = buf + header_len; - gf_log ("guts-gimmik", GF_LOG_ERROR, - "unique: %llu, opcode: %s (%i), nodeid: %lu, insize: %zu\n", - (unsigned long long) in->unique, "<null>", - /*opname((enum fuse_opcode) in->opcode),*/ in->opcode, - (unsigned long) in->nodeid, len); - if (guts_log[in->opcode].func) - guts_log[in->opcode].func (in, inargs); - - } else { - gf_log ("guts", GF_LOG_ERROR, - "header is longer than the buffer passed"); - } - - return 0; -} - - -int -guts_reply_err (fuse_req_t req, int err) -{ - if (IS_TRACE(req)) { - /* we are tracing calls, just dump the reply to file and continue with fuse_reply_err() */ - guts_reply_dump (req, &err, sizeof (err)); - return fuse_reply_err (req, err); - } else { - /* we are replaying. ;) */ - guts_replay_ctx_t *ctx = (guts_replay_ctx_t *) req->u.ni.data; - int32_t opcode = guts_get_opcode (ctx, req->unique); - - /* see if we are called by close/closedir, if yes remove do a guts_fd_delete () */ - if (opcode == FUSE_RELEASEDIR || opcode == FUSE_RELEASE) { - guts_req_t *request = guts_lookup_request (ctx, req->unique); - struct fuse_release_in *arg = request->arg; - - guts_delete_fd (ctx, arg->fh); - } else if (err == -1) { - /* error while replaying?? just quit as of now - * TODO: this is not the right way */ - printf (":O - glusterfs-guts: replay failed\n"); - exit (0); - } - - return 0; - } -} - -void -guts_reply_none (fuse_req_t req) -{ - if (IS_TRACE(req)) { - guts_reply_dump (req, NULL, 0); - fuse_reply_none (req); - } else { - return; - } -} - -int -guts_reply_entry (fuse_req_t req, - const struct fuse_entry_param *e) -{ - if (IS_TRACE(req)) { - guts_reply_dump (req, e, sizeof (*e)); - return fuse_reply_entry (req, e); - } else { - /* TODO: is dict_set() the best solution for this case?? */ - guts_replay_ctx_t *ctx = (guts_replay_ctx_t *) req->u.ni.data; - guts_reply_t *reply = guts_lookup_reply (ctx, req->unique); - struct fuse_entry_param *old_entry = (struct fuse_entry_param *)reply->arg; - guts_inode_update (ctx, old_entry->ino, e->ino); - return 0; - } -} - -int -guts_reply_create (fuse_req_t req, - const struct fuse_entry_param *e, - const struct fuse_file_info *f) -{ - if (IS_TRACE(req)) { - struct guts_create_out create_out; - - memset (&create_out, 0, sizeof (create_out)); - memcpy (&create_out.e, e, sizeof (*e)); - memcpy (&create_out.f, f, sizeof (*f)); - - guts_reply_dump (req, &create_out, sizeof (create_out)); - return fuse_reply_create (req, e, f); - } else { - guts_replay_ctx_t *ctx = (guts_replay_ctx_t *) req->u.ni.data; - guts_reply_t *reply = guts_lookup_reply (ctx, req->unique); - struct guts_create_out *old_createout = (struct guts_create_out *) reply->arg; - struct fuse_file_info *old_f = &old_createout->f; - - /* add a new fd and map it to the file handle, as stored in tio file */ - guts_fd_add (ctx, old_f->fh, (fd_t *)(long)f->fh); - - return 0; - } -} - - -int -guts_reply_attr (fuse_req_t req, - const struct stat *attr, - double attr_timeout) -{ - if (IS_TRACE(req)) { - struct guts_attr_out attr_out; - - memcpy (&attr_out.attr, attr, sizeof (*attr)); - attr_out.attr_timeout = attr_timeout; - - guts_reply_dump (req, &attr_out, sizeof (attr_out)); - return fuse_reply_attr (req, attr, attr_timeout); - } else { - guts_replay_ctx_t *ctx = (guts_replay_ctx_t *) req->u.ni.data; - guts_reply_t *reply = guts_lookup_reply (ctx, req->unique); - struct guts_attr_out *old_attrout = (struct guts_attr_out *) reply->arg; - - if (!guts_attr_cmp (attr, &old_attrout->attr)) - return 0; - else { - gf_log ("glusterfs-guts", GF_LOG_ERROR, - "attr failed."); - return -1; - } - } -} - -int -guts_reply_readlink (fuse_req_t req, - const char *linkname) -{ - if (IS_TRACE(req)) { - guts_reply_dump (req, linkname, strlen (linkname)); - return fuse_reply_readlink (req, linkname); - } else { - guts_replay_ctx_t *ctx = (guts_replay_ctx_t *) req->u.ni.data; - guts_reply_t *reply = guts_lookup_reply (ctx, req->unique); - char *old_linkname = (char *) reply->arg; - if (!strcmp (linkname, old_linkname)) - return 0; - else { - gf_log ("glusterfs-guts", GF_LOG_ERROR, - "readlink failed. linkname in tio file: %s \n linkname recieved on replay: %s", - old_linkname, linkname); - return -1; - } - } -} - -int -guts_reply_open (fuse_req_t req, - const struct fuse_file_info *f) -{ - if (IS_TRACE(req)) { - guts_reply_dump (req, f, sizeof (*f)); - return fuse_reply_open (req, f); - } else { - /* the fd we recieve here is the valid fd for our current session, map the indicative number we have - * in mapping */ - guts_replay_ctx_t *ctx = (guts_replay_ctx_t *) req->u.ni.data; - guts_reply_t *reply = guts_lookup_reply (ctx, req->unique); - - if (reply) { - struct fuse_file_info *old_f = reply->arg; - - /* add a new fd and map it to the file handle, as stored in tio file */ - guts_fd_add (ctx, old_f->fh, (fd_t *)(long)f->fh); - } - - return 0; - } -} - -int -guts_reply_write (fuse_req_t req, - size_t count) -{ - if (IS_TRACE(req)) { - guts_reply_dump (req, &count, sizeof (count)); - return fuse_reply_write (req, count); - } else { - guts_replay_ctx_t *ctx = (guts_replay_ctx_t *) req->u.ni.data; - guts_reply_t *reply = guts_lookup_reply (ctx, req->unique); - size_t *old_count = reply->arg; - if (count == *old_count) - return 0; - else { - gf_log ("glusterfs-guts", GF_LOG_ERROR, - "writev failed. old writev count: %d \n writev count on replay: %d", - old_count, count); - return -1; - } - } -} - -int -guts_reply_buf (fuse_req_t req, - const char *buf, - size_t size) -{ - if (IS_TRACE(req)) { - guts_reply_dump (req, buf, size); - return fuse_reply_buf (req, buf, size); - } else { - guts_replay_ctx_t *ctx = (guts_replay_ctx_t *) req->u.ni.data; - guts_reply_t *reply = guts_lookup_reply (ctx, req->unique); - char *old_buf = reply->arg; - size_t old_size = reply->arg_len; - if ((size == old_size) && (!memcmp (buf, old_buf, size))) - return 0; - else { - gf_log ("glusterfs-guts", GF_LOG_ERROR, - "readv failed. old readv size: %d \n readv size on replay: %d", - old_size, size); - return -1; - } - } -} - -int -guts_reply_statfs (fuse_req_t req, - const struct statvfs *stbuf) -{ - if (IS_TRACE(req)) { - guts_reply_dump (req, stbuf, sizeof (*stbuf)); - return fuse_reply_statfs (req, stbuf); - } else { - guts_replay_ctx_t *ctx = (guts_replay_ctx_t *) req->u.ni.data; - guts_reply_t *reply = guts_lookup_reply (ctx, req->unique); - struct statvfs *old_stbuf = reply->arg; - - if (!guts_statvfs_cmp (old_stbuf, stbuf)) - return 0; - else { - gf_log ("glusterfs-guts", GF_LOG_ERROR, - "statfs failed."); - return -1; - } - } -} - -int -guts_reply_xattr (fuse_req_t req, - size_t count) -{ - if (IS_TRACE(req)) { - guts_reply_dump (req, &count, sizeof (count)); - return fuse_reply_xattr (req, count); - } else { - guts_replay_ctx_t *ctx = (guts_replay_ctx_t *) req->u.ni.data; - guts_reply_t *reply = guts_lookup_reply (ctx, req->unique); - size_t *old_count = reply->arg; - if (count == *old_count) - return 0; - else { - gf_log ("glusterfs-guts", GF_LOG_ERROR, - "xattr failed. old xattr count: %d \n xattr count on replay: %d", - old_count, count); - return -1; - } - } -} - -int -guts_reply_lock (fuse_req_t req, - struct flock *lock) -{ - if (IS_TRACE(req)) { - guts_reply_dump (req, lock , sizeof (*lock)); - return fuse_reply_lock (req, lock); - } else { - guts_replay_ctx_t *ctx = (guts_replay_ctx_t *) req->u.ni.data; - guts_reply_t *reply = guts_lookup_reply (ctx, req->unique); - struct flock *old_lock = (struct flock *)reply->arg; - if (!guts_flock_cmp (lock, old_lock)) - return 0; - else { - gf_log ("glusterfs-guts", GF_LOG_ERROR, - "lock failed."); - return -1; - } - } -} diff --git a/glusterfs-guts/src/guts-trace.h b/glusterfs-guts/src/guts-trace.h deleted file mode 100644 index 2428e599b8a..00000000000 --- a/glusterfs-guts/src/guts-trace.h +++ /dev/null @@ -1,54 +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/>. -*/ - -#define IS_TRACE(req) (req->ch != NULL) - -#define PARAM(inarg) (((char *)(inarg)) + sizeof(*(inarg))) - -struct guts_symlink_in { - char name[NAME_MAX]; - char linkname[NAME_MAX]; -}; - -struct guts_create_in { - struct fuse_open_in open_in; - char name[NAME_MAX]; -}; - -struct guts_xattr_in { - struct fuse_setxattr_in xattr; - char name[NAME_MAX]; - char value[NAME_MAX]; -}; - -struct guts_rename_in { - struct fuse_rename_in rename; - char oldname[NAME_MAX]; - char newname[NAME_MAX]; -}; - -struct guts_create_out { - struct fuse_entry_param e; - struct fuse_file_info f; -}; - -struct guts_attr_out { - struct stat attr; - double attr_timeout; -}; |