summaryrefslogtreecommitdiffstats
path: root/xlators/protocol/server/src
diff options
context:
space:
mode:
Diffstat (limited to 'xlators/protocol/server/src')
-rw-r--r--xlators/protocol/server/src/Makefile.am28
-rw-r--r--xlators/protocol/server/src/authenticate.c253
-rw-r--r--xlators/protocol/server/src/authenticate.h51
-rw-r--r--xlators/protocol/server/src/server-dentry.c414
-rw-r--r--xlators/protocol/server/src/server-handshake.c781
-rw-r--r--xlators/protocol/server/src/server-helpers.c1831
-rw-r--r--xlators/protocol/server/src/server-helpers.h101
-rw-r--r--xlators/protocol/server/src/server-mem-types.h30
-rw-r--r--xlators/protocol/server/src/server-protocol.c7898
-rw-r--r--xlators/protocol/server/src/server-protocol.h155
-rw-r--r--xlators/protocol/server/src/server-resolve.c598
-rw-r--r--xlators/protocol/server/src/server-rpc-fops.c6179
-rw-r--r--xlators/protocol/server/src/server.c1214
-rw-r--r--xlators/protocol/server/src/server.h196
14 files changed, 10484 insertions, 9245 deletions
diff --git a/xlators/protocol/server/src/Makefile.am b/xlators/protocol/server/src/Makefile.am
index dcd92aeed..6a18bf025 100644
--- a/xlators/protocol/server/src/Makefile.am
+++ b/xlators/protocol/server/src/Makefile.am
@@ -1,18 +1,26 @@
-
xlator_LTLIBRARIES = server.la
xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/protocol
-server_la_LDFLAGS = -module -avoidversion
+server_la_LDFLAGS = -module -avoid-version
+
+server_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la \
+ $(top_builddir)/rpc/rpc-lib/src/libgfrpc.la \
+ $(top_builddir)/rpc/xdr/src/libgfxdr.la
-server_la_SOURCES = server-protocol.c server-dentry.c server-helpers.c
-server_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la
+server_la_SOURCES = server.c server-resolve.c server-helpers.c \
+ server-rpc-fops.c server-handshake.c authenticate.c
-noinst_HEADERS = server-protocol.h server-helpers.h
+noinst_HEADERS = server.h server-helpers.h server-mem-types.h authenticate.h
-AM_CFLAGS = -fPIC -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE -Wall -D$(GF_HOST_OS) \
- -I$(top_srcdir)/libglusterfs/src -shared -nostartfiles \
- -DDATADIR=\"$(localstatedir)\" -DCONFDIR=\"$(sysconfdir)/glusterfs\" \
- $(GF_CFLAGS)
+AM_CPPFLAGS = $(GF_CPPFLAGS) \
+ -I$(top_srcdir)/libglusterfs/src \
+ -DCONFDIR=\"$(sysconfdir)/glusterfs\" \
+ -DLIBDIR=\"$(libdir)/glusterfs/$(PACKAGE_VERSION)/auth\" \
+ -I$(top_srcdir)/xlators/protocol/lib/src \
+ -I$(top_srcdir)/rpc/rpc-lib/src \
+ -I$(top_srcdir)/rpc/xdr/src
-CLEANFILES =
+AM_CFLAGS = -Wall $(GF_CFLAGS) \
+ -DDATADIR=\"$(localstatedir)\"
+CLEANFILES = *~
diff --git a/xlators/protocol/server/src/authenticate.c b/xlators/protocol/server/src/authenticate.c
new file mode 100644
index 000000000..d8d138a84
--- /dev/null
+++ b/xlators/protocol/server/src/authenticate.c
@@ -0,0 +1,253 @@
+/*
+ Copyright (c) 2007-2013 Red Hat, Inc. <http://www.redhat.com>
+ This file is part of GlusterFS.
+
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
+*/
+
+
+
+#ifndef _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+
+#include <stdio.h>
+#include <dlfcn.h>
+#include <errno.h>
+#include "authenticate.h"
+
+static int
+init (dict_t *this, char *key, data_t *value, void *data)
+{
+ void *handle = NULL;
+ char *auth_file = NULL;
+ auth_handle_t *auth_handle = NULL;
+ auth_fn_t authenticate = NULL;
+ int *error = NULL;
+ int ret = 0;
+
+ /* It gets over written */
+ error = data;
+
+ if (!strncasecmp (key, "ip", strlen ("ip"))) {
+ gf_log ("authenticate", GF_LOG_ERROR,
+ "AUTHENTICATION MODULE \"IP\" HAS BEEN REPLACED "
+ "BY \"ADDR\"");
+ dict_set (this, key, data_from_dynptr (NULL, 0));
+ /* TODO: 1.3.x backword compatibility */
+ // *error = -1;
+ // return;
+ key = "addr";
+ }
+
+ ret = gf_asprintf (&auth_file, "%s/%s.so", LIBDIR, key);
+ if (-1 == ret) {
+ dict_set (this, key, data_from_dynptr (NULL, 0));
+ *error = -1;
+ return -1;
+ }
+
+ handle = dlopen (auth_file, RTLD_LAZY);
+ if (!handle) {
+ gf_log ("authenticate", GF_LOG_ERROR, "dlopen(%s): %s\n",
+ auth_file, dlerror ());
+ dict_set (this, key, data_from_dynptr (NULL, 0));
+ GF_FREE (auth_file);
+ *error = -1;
+ return -1;
+ }
+ GF_FREE (auth_file);
+
+ authenticate = dlsym (handle, "gf_auth");
+ if (!authenticate) {
+ gf_log ("authenticate", GF_LOG_ERROR,
+ "dlsym(gf_auth) on %s\n", dlerror ());
+ dict_set (this, key, data_from_dynptr (NULL, 0));
+ dlclose (handle);
+ *error = -1;
+ return -1;
+ }
+
+ auth_handle = GF_CALLOC (1, sizeof (*auth_handle),
+ gf_common_mt_auth_handle_t);
+ if (!auth_handle) {
+ dict_set (this, key, data_from_dynptr (NULL, 0));
+ *error = -1;
+ dlclose (handle);
+ return -1;
+ }
+ auth_handle->vol_opt = GF_CALLOC (1, sizeof (volume_opt_list_t),
+ gf_common_mt_volume_opt_list_t);
+ if (!auth_handle->vol_opt) {
+ dict_set (this, key, data_from_dynptr (NULL, 0));
+ *error = -1;
+ GF_FREE (auth_handle);
+ dlclose (handle);
+ return -1;
+ }
+ auth_handle->vol_opt->given_opt = dlsym (handle, "options");
+ if (auth_handle->vol_opt->given_opt == NULL) {
+ gf_log ("authenticate", GF_LOG_DEBUG,
+ "volume option validation not specified");
+ }
+
+ auth_handle->authenticate = authenticate;
+ auth_handle->handle = handle;
+
+ dict_set (this, key,
+ data_from_dynptr (auth_handle, sizeof (*auth_handle)));
+ return 0;
+}
+
+static int
+fini (dict_t *this, char *key, data_t *value, void *data)
+{
+ auth_handle_t *handle = data_to_ptr (value);
+ if (handle) {
+ dlclose (handle->handle);
+ }
+ return 0;
+}
+
+static int
+_gf_auth_option_validate (dict_t *d, char *k, data_t *v, void *tmp)
+{
+ auth_handle_t *handle = NULL;
+ xlator_t *xl = NULL;
+ int ret = 0;
+
+ xl = tmp;
+
+ handle = data_to_ptr (v);
+ if (!handle)
+ return 0;
+
+ list_add_tail (&(handle->vol_opt->list), &(xl->volume_options));
+
+ ret = xlator_options_validate_list (xl, xl->options,
+ handle->vol_opt, NULL);
+ if (ret) {
+ gf_log ("authenticate", GF_LOG_ERROR,
+ "volume option validation failed");
+ return -1;
+ }
+ return 0;
+}
+
+int32_t
+gf_auth_init (xlator_t *xl, dict_t *auth_modules)
+{
+ int ret = 0;
+
+ dict_foreach (auth_modules, init, &ret);
+ if (ret)
+ goto out;
+
+ ret = dict_foreach (auth_modules, _gf_auth_option_validate, xl);
+
+out:
+ if (ret) {
+ gf_log (xl->name, GF_LOG_ERROR, "authentication init failed");
+ dict_foreach (auth_modules, fini, &ret);
+ ret = -1;
+ }
+ return ret;
+}
+
+static dict_t *__input_params;
+static dict_t *__config_params;
+
+int
+map (dict_t *this, char *key, data_t *value, void *data)
+{
+ dict_t *res = data;
+ auth_fn_t authenticate;
+ auth_handle_t *handle = NULL;
+
+ if (value && (handle = data_to_ptr (value)) &&
+ (authenticate = handle->authenticate)) {
+ dict_set (res, key,
+ int_to_data (authenticate (__input_params,
+ __config_params)));
+ } else {
+ dict_set (res, key, int_to_data (AUTH_DONT_CARE));
+ }
+ return 0;
+}
+
+int
+reduce (dict_t *this, char *key, data_t *value, void *data)
+{
+ int64_t val = 0;
+ int64_t *res = data;
+ if (!data)
+ return 0;
+
+ val = data_to_int64 (value);
+ switch (val)
+ {
+ case AUTH_ACCEPT:
+ if (AUTH_DONT_CARE == *res)
+ *res = AUTH_ACCEPT;
+ break;
+
+ case AUTH_REJECT:
+ *res = AUTH_REJECT;
+ break;
+
+ case AUTH_DONT_CARE:
+ break;
+ }
+ return 0;
+}
+
+
+auth_result_t
+gf_authenticate (dict_t *input_params,
+ dict_t *config_params,
+ dict_t *auth_modules)
+{
+ char *name = NULL;
+ dict_t *results = NULL;
+ int64_t result = AUTH_DONT_CARE;
+ data_t *peerinfo_data = NULL;
+
+ results = get_new_dict ();
+ __input_params = input_params;
+ __config_params = config_params;
+
+ dict_foreach (auth_modules, map, results);
+
+ dict_foreach (results, reduce, &result);
+ if (AUTH_DONT_CARE == result) {
+ peerinfo_data = dict_get (input_params, "peer-info-name");
+
+ if (peerinfo_data) {
+ name = peerinfo_data->data;
+ }
+
+ gf_log ("auth", GF_LOG_ERROR,
+ "no authentication module is interested in "
+ "accepting remote-client %s", name);
+ result = AUTH_REJECT;
+ }
+
+ dict_destroy (results);
+ return result;
+}
+
+void
+gf_auth_fini (dict_t *auth_modules)
+{
+ int32_t dummy;
+
+ dict_foreach (auth_modules, fini, &dummy);
+}
diff --git a/xlators/protocol/server/src/authenticate.h b/xlators/protocol/server/src/authenticate.h
new file mode 100644
index 000000000..d4d43e498
--- /dev/null
+++ b/xlators/protocol/server/src/authenticate.h
@@ -0,0 +1,51 @@
+/*
+ Copyright (c) 2007-2013 Red Hat, Inc. <http://www.redhat.com>
+ This file is part of GlusterFS.
+
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
+*/
+
+#ifndef _AUTHENTICATE_H
+#define _AUTHENTICATE_H
+
+#ifndef _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+
+#include <stdio.h>
+#include <fnmatch.h>
+#include "dict.h"
+#include "compat.h"
+#include "list.h"
+#include "xlator.h"
+
+typedef enum {
+ AUTH_ACCEPT,
+ AUTH_REJECT,
+ AUTH_DONT_CARE
+} auth_result_t;
+
+typedef auth_result_t (*auth_fn_t) (dict_t *input_params,
+ dict_t *config_params);
+
+typedef struct {
+ void *handle;
+ auth_fn_t authenticate;
+ volume_opt_list_t *vol_opt;
+} auth_handle_t;
+
+auth_result_t gf_authenticate (dict_t *input_params,
+ dict_t *config_params,
+ dict_t *auth_modules);
+int32_t gf_auth_init (xlator_t *xl, dict_t *auth_modules);
+void gf_auth_fini (dict_t *auth_modules);
+
+#endif /* _AUTHENTICATE_H */
diff --git a/xlators/protocol/server/src/server-dentry.c b/xlators/protocol/server/src/server-dentry.c
deleted file mode 100644
index 940bc3bee..000000000
--- a/xlators/protocol/server/src/server-dentry.c
+++ /dev/null
@@ -1,414 +0,0 @@
-#include "glusterfs.h"
-#include "xlator.h"
-#include "server-protocol.h"
-#include "server-helpers.h"
-#include <libgen.h>
-
-/* SERVER_DENTRY_STATE_PREPARE - prepare a fresh state for use
- *
- * @state - an empty state
- * @loc - loc_t which needs to resolved
- * @parent - most immediate parent of @loc available in dentry cache
- * @resolved - component of @loc->path which has been resolved
- * through dentry cache
- */
-#define SERVER_DENTRY_STATE_PREPARE(_state,_loc,_parent,_resolved) do { \
- size_t pathlen = 0; \
- size_t resolvedlen = 0; \
- char *path = NULL; \
- int pad = 0; \
- pathlen = strlen (_loc->path) + 1; \
- path = CALLOC (1, pathlen); \
- _state->loc.parent = inode_ref (_parent); \
- _state->loc.inode = inode_new (_state->itable); \
- if (_resolved) { \
- resolvedlen = strlen (_resolved); \
- strncpy (path, _resolved, resolvedlen); \
- _state->resolved = memdup (path, pathlen); \
- if (resolvedlen == 1) /* only root resolved */ \
- pad = 0; \
- else { \
- pad = 1; \
- path[resolvedlen] = '/'; \
- } \
- strcpy_till (path + resolvedlen + pad, loc->path + resolvedlen + pad, '/'); \
- } else { \
- strncpy (path, _loc->path, pathlen); \
- } \
- _state->loc.path = path; \
- _state->loc.name = strrchr (path, '/'); \
- if (_state->loc.name) \
- _state->loc.name++; \
- _state->path = strdup (_loc->path); \
- }while (0);
-
-/* SERVER_DENTRY_UPDATE_STATE - update a server_state_t, to prepare state
- * for new lookup
- *
- * @state - state to be updated.
- */
-#define SERVER_DENTRY_UPDATE_STATE(_state) do { \
- char *path = NULL; \
- size_t pathlen = 0; \
- strcpy (_state->resolved, _state->loc.path); \
- pathlen = strlen (_state->loc.path); \
- if (!strcmp (_state->resolved, _state->path)) { \
- free (_state->resolved); \
- _state->resolved = NULL; \
- goto resume; \
- } \
- \
- path = (char *)(_state->loc.path + pathlen); \
- path[0] = '/'; \
- strcpy_till (path + 1, \
- _state->path + pathlen + 1, '/'); \
- _state->loc.name = strrchr (_state->loc.path, '/'); \
- if (_state->loc.name) \
- _state->loc.name++; \
- inode_unref (_state->loc.parent); \
- _state->loc.parent = inode_ref (_state->loc.inode); \
- inode_unref (_state->loc.inode); \
- _state->loc.inode = inode_new (_state->itable); \
- }while (0);
-
-/* NOTE: should be used only for a state which was created by __do_path_resolve
- * using any other state will result in double free corruption.
- */
-#define SERVER_STATE_CLEANUP(_state) do { \
- if (_state->resolved) \
- free (_state->resolved); \
- if (_state->path) \
- free (_state->path); \
- server_loc_wipe (&_state->loc); \
- free_state (_state); \
- } while (0);
-
-/* strcpy_till - copy @dname to @dest, until 'delim' is encountered in @dest
- * @dest - destination string
- * @dname - source string
- * @delim - delimiter character
- *
- * return - NULL is returned if '0' is encountered in @dname, otherwise returns
- * a pointer to remaining string begining in @dest.
- */
-static char *
-strcpy_till (char *dest, const char *dname, char delim)
-{
- char *src = NULL;
- int idx = 0;
- char *ret = NULL;
-
- src = (char *)dname;
- while (src[idx] && (src[idx] != delim)) {
- dest[idx] = src[idx];
- idx++;
- }
-
- dest[idx] = 0;
-
- if (src[idx] == 0)
- ret = NULL;
- else
- ret = &(src[idx]);
-
- return ret;
-}
-
-/* __server_path_to_parenti - derive parent inode for @path. if immediate parent is
- * not available in the dentry cache, return nearest
- * available parent inode and set @reslv to the path of
- * the returned directory.
- *
- * @itable - inode table
- * @path - path whose parent has to be looked up.
- * @reslv - if immediate parent is not available, reslv will be set to path of the
- * resolved parent.
- *
- * return - should never return NULL. should at least return '/' inode.
- */
-static inode_t *
-__server_path_to_parenti (inode_table_t *itable,
- const char *path,
- char **reslv)
-{
- char *resolved_till = NULL;
- char *strtokptr = NULL;
- char *component = NULL;
- char *next_component = NULL;
- char *pathdup = NULL;
- inode_t *curr = NULL;
- inode_t *parent = NULL;
- size_t pathlen = 0;
-
-
- pathlen = STRLEN_0 (path);
- resolved_till = CALLOC (1, pathlen);
-
- GF_VALIDATE_OR_GOTO("server-dentry", resolved_till, out);
- pathdup = strdup (path);
- GF_VALIDATE_OR_GOTO("server-dentry", pathdup, out);
-
- parent = inode_ref (itable->root);
- curr = NULL;
-
- component = strtok_r (pathdup, "/", &strtokptr);
-
- while (component) {
- curr = inode_search (itable, parent->ino, component);
- if (!curr) {
- /* if current component was the last component
- set it to NULL
- */
- component = strtok_r (NULL, "/", &strtokptr);
- break;
- }
-
- /* It is OK to append the component even if it is the
- last component in the path, because, if 'next_component'
- returns NULL, @parent will remain the same and
- @resolved_till will not be sent back
- */
-
- strcat (resolved_till, "/");
- strcat (resolved_till, component);
-
- next_component = strtok_r (NULL, "/", &strtokptr);
-
- if (next_component) {
- inode_unref (parent);
- parent = curr;
- curr = NULL;
- } else {
- /* will break */
- inode_unref (curr);
- }
-
- component = next_component;
- }
-
- free (pathdup);
-
- if (component) {
- *reslv = resolved_till;
- } else {
- free (resolved_till);
- }
-out:
- return parent;
-}
-
-
-/* __do_path_resolve_cbk -
- *
- * @frame -
- * @cookie -
- * @this -
- * @op_ret -
- * @op_errno -
- * @inode -
- * @stbuf -
- * @dict -
- *
- */
-static int32_t
-__do_path_resolve_cbk (call_frame_t *frame,
- void *cookie,
- xlator_t *this,
- int32_t op_ret,
- int32_t op_errno,
- inode_t *inode,
- struct stat *stbuf,
- dict_t *dict,
- struct stat *postparent)
-{
- server_state_t *state = NULL;
- call_stub_t *stub = NULL;
- inode_t *parent = NULL;
-
- stub = frame->local;
- state = CALL_STATE(frame);
-
- parent = state->loc.parent;
-
- if (op_ret == -1) {
- if (strcmp (state->path, state->loc.path))
- parent = NULL;
-
- server_stub_resume (stub, op_ret, op_errno, NULL, parent);
- goto cleanup;
- } else {
- if (inode->ino == 0) {
- gf_log (BOUND_XL(frame)->name, GF_LOG_DEBUG,
- "looked up for %s (%"PRId64"/%s)",
- state->loc.path, state->loc.parent->ino, state->loc.name);
- inode_link (inode, state->loc.parent, state->loc.name, stbuf);
- inode_lookup (inode);
- }
-
- if (state->resolved) {
- SERVER_DENTRY_UPDATE_STATE(state);
-
- gf_log (BOUND_XL(frame)->name, GF_LOG_DEBUG,
- "looking up for %s (%"PRId64"/%s)",
- state->loc.path, state->loc.parent->ino, state->loc.name);
-
- STACK_WIND (frame,
- __do_path_resolve_cbk,
- BOUND_XL(frame),
- BOUND_XL(frame)->fops->lookup,
- &(state->loc),
- 0);
-
- goto out;
- }
- resume:
- /* we are done, call stub_resume() to do rest of the job */
- server_stub_resume (stub, op_ret, op_errno, inode, parent);
- cleanup:
- SERVER_STATE_CLEANUP(state);
- /* stub will be freed by stub_resume, leave no traces */
- frame->local = NULL;
- STACK_DESTROY (frame->root);
- }
-out:
- return 0;
-}
-
-/* __do_path_resolve - resolve @loc->path into @loc->inode and @loc->parent. also
- * update the dentry cache
- *
- * @stub - call stub to resume after resolving @loc->path
- * @loc - loc to resolve before resuming @stub.
- *
- * return - return value of __do_path_resolve doesn't matter to the caller, if @stub
- * is not NULL.
- */
-static int32_t
-__do_path_resolve (call_stub_t *stub,
- const loc_t *loc)
-{
- int32_t ret = -1;
- char *resolved = NULL;
- call_frame_t *new_frame = NULL;
- server_state_t *state = NULL, *new_state = NULL;
- inode_t *parent = NULL;
-
- state = CALL_STATE(stub->frame);
- parent = loc->parent;
- if (parent) {
- inode_ref (parent);
- gf_log (BOUND_XL(stub->frame)->name, GF_LOG_DEBUG,
- "loc->parent(%"PRId64") already present. sending lookup "
- "for %"PRId64"/%s", parent->ino, parent->ino, loc->name);
- resolved = strdup (loc->path);
- resolved = dirname (resolved);
- } else {
- parent = __server_path_to_parenti (state->itable, loc->path, &resolved);
- }
-
- if (parent == NULL) {
- /* fire in the bush.. run! run!! run!!! */
- gf_log ("server",
- GF_LOG_CRITICAL,
- "failed to get parent inode number");
- goto panic;
- }
-
- if (resolved) {
- gf_log (BOUND_XL(stub->frame)->name,
- GF_LOG_DEBUG,
- "resolved path(%s) till %"PRId64"(%s). "
- "sending lookup for remaining path",
- loc->path, parent->ino, resolved);
- }
-
- {
- new_frame = server_copy_frame (stub->frame);
- new_state = CALL_STATE(new_frame);
-
- SERVER_DENTRY_STATE_PREPARE(new_state, loc, parent, resolved);
-
- if (parent)
- inode_unref (parent); /* __server_path_to_parenti()'s inode_ref */
- free (resolved);
- /* now interpret state as:
- * state->path - compelete pathname to resolve
- * state->resolved - pathname resolved from dentry cache
- */
- new_frame->local = stub;
- STACK_WIND (new_frame,
- __do_path_resolve_cbk,
- BOUND_XL(new_frame),
- BOUND_XL(new_frame)->fops->lookup,
- &(new_state->loc),
- 0);
- goto out;
- }
-panic:
- server_stub_resume (stub, -1, ENOENT, NULL, NULL);
-out:
- return ret;
-}
-
-
-/*
- * do_path_lookup - transform a pathname into inode, with the compelete
- * dentry tree upto inode built.
- *
- * @stub - call stub to resume after completing pathname to inode transform
- * @loc - location. valid fields that do_path_lookup() uses in @loc are
- * @loc->path - pathname
- * @loc->ino - inode number
- *
- * return - do_path_lookup returns only after complete dentry tree is built
- * upto @loc->path.
- */
-int32_t
-do_path_lookup (call_stub_t *stub,
- const loc_t *loc)
-{
- char *pathname = NULL;
- char *directory = NULL;
- inode_t *inode = NULL;
- inode_t *parent = NULL;
- server_state_t *state = NULL;
-
- state = CALL_STATE(stub->frame);
-
- inode = inode_from_path (state->itable, loc->path);
- pathname = strdup (loc->path);
- directory = dirname (pathname);
- parent = inode_from_path (state->itable, directory);
-
- if (inode && parent) {
- gf_log (BOUND_XL(stub->frame)->name,
- GF_LOG_DEBUG,
- "resolved path(%s) to %"PRId64"/%"PRId64"(%s)",
- loc->path, parent->ino, inode->ino, loc->name);
- server_stub_resume (stub, 0, 0, inode, parent);
- inode_unref (inode);
- inode_unref (parent);
- } else {
- gf_log (BOUND_XL(stub->frame)->name,
- GF_LOG_DEBUG,
- "resolved path(%s) to %p(%"PRId64")/%p(%"PRId64")",
- loc->path, parent, (parent ? parent->ino : 0),
- inode, (inode ? inode->ino : 0));
- if (parent) {
- inode_unref (parent);
- } else if (inode) {
- inode_unref (inode);
- gf_log (BOUND_XL(stub->frame)->name,
- GF_LOG_ERROR,
- "undesired behaviour. inode(%"PRId64") for %s "
- "exists without parent (%s)",
- inode->ino, loc->path, directory);
- }
- __do_path_resolve (stub, loc);
- }
-
- if (pathname)
- free (pathname);
-
- return 0;
-}
diff --git a/xlators/protocol/server/src/server-handshake.c b/xlators/protocol/server/src/server-handshake.c
new file mode 100644
index 000000000..d4941011d
--- /dev/null
+++ b/xlators/protocol/server/src/server-handshake.c
@@ -0,0 +1,781 @@
+/*
+ Copyright (c) 2010-2013 Red Hat, Inc. <http://www.redhat.com>
+ This file is part of GlusterFS.
+
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
+*/
+
+
+#ifndef _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+#include "server.h"
+#include "server-helpers.h"
+#include "glusterfs3-xdr.h"
+#include "compat-errno.h"
+#include "glusterfs3.h"
+#include "authenticate.h"
+
+struct __get_xl_struct {
+ const char *name;
+ xlator_t *reply;
+};
+int
+gf_compare_client_version (rpcsvc_request_t *req, int fop_prognum,
+ int mgmt_prognum)
+{
+ int ret = -1;
+ /* TODO: think.. */
+ if (glusterfs3_3_fop_prog.prognum == fop_prognum)
+ ret = 0;
+
+ return ret;
+}
+
+void __check_and_set (xlator_t *each, void *data)
+{
+ if (!strcmp (each->name,
+ ((struct __get_xl_struct *) data)->name))
+ ((struct __get_xl_struct *) data)->reply = each;
+}
+
+static xlator_t *
+get_xlator_by_name (xlator_t *some_xl, const char *name)
+{
+ struct __get_xl_struct get = {
+ .name = name,
+ .reply = NULL
+ };
+
+ xlator_foreach (some_xl, __check_and_set, &get);
+
+ return get.reply;
+}
+
+
+int
+_volfile_update_checksum (xlator_t *this, char *key, uint32_t checksum)
+{
+ server_conf_t *conf = NULL;
+ struct _volfile_ctx *temp_volfile = NULL;
+
+ conf = this->private;
+ temp_volfile = conf->volfile;
+
+ while (temp_volfile) {
+ if ((NULL == key) && (NULL == temp_volfile->key))
+ break;
+ if ((NULL == key) || (NULL == temp_volfile->key)) {
+ temp_volfile = temp_volfile->next;
+ continue;
+ }
+ if (strcmp (temp_volfile->key, key) == 0)
+ break;
+ temp_volfile = temp_volfile->next;
+ }
+
+ if (!temp_volfile) {
+ temp_volfile = GF_CALLOC (1, sizeof (struct _volfile_ctx),
+ gf_server_mt_volfile_ctx_t);
+ if (!temp_volfile)
+ goto out;
+ temp_volfile->next = conf->volfile;
+ temp_volfile->key = (key)? gf_strdup (key): NULL;
+ temp_volfile->checksum = checksum;
+
+ conf->volfile = temp_volfile;
+ goto out;
+ }
+
+ if (temp_volfile->checksum != checksum) {
+ gf_log (this->name, GF_LOG_INFO,
+ "the volume file was modified between a prior access "
+ "and now. This may lead to inconsistency between "
+ "clients, you are advised to remount client");
+ temp_volfile->checksum = checksum;
+ }
+
+out:
+ return 0;
+}
+
+
+static size_t
+getspec_build_volfile_path (xlator_t *this, const char *key, char *path,
+ size_t path_len)
+{
+ char *filename = NULL;
+ server_conf_t *conf = NULL;
+ int ret = -1;
+ int free_filename = 0;
+ char data_key[256] = {0,};
+
+ conf = this->private;
+
+ /* Inform users that this option is changed now */
+ ret = dict_get_str (this->options, "client-volume-filename",
+ &filename);
+ if (ret == 0) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "option 'client-volume-filename' is changed to "
+ "'volume-filename.<key>' which now takes 'key' as an "
+ "option to choose/fetch different files from server. "
+ "Refer documentation or contact developers for more "
+ "info. Currently defaulting to given file '%s'",
+ filename);
+ }
+
+ if (key && !filename) {
+ sprintf (data_key, "volume-filename.%s", key);
+ ret = dict_get_str (this->options, data_key, &filename);
+ if (ret < 0) {
+ /* Make sure that key doesn't contain "../" in path */
+ if ((gf_strstr (key, "/", "..")) == -1) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "%s: invalid key", key);
+ goto out;
+ }
+ }
+ }
+
+ if (!filename) {
+ ret = dict_get_str (this->options,
+ "volume-filename.default", &filename);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "no default volume filename given, "
+ "defaulting to %s", DEFAULT_VOLUME_FILE_PATH);
+ }
+ }
+
+ if (!filename && key) {
+ ret = gf_asprintf (&filename, "%s/%s.vol", conf->conf_dir, key);
+ if (-1 == ret)
+ goto out;
+
+ free_filename = 1;
+ }
+ if (!filename)
+ filename = DEFAULT_VOLUME_FILE_PATH;
+
+ ret = -1;
+
+ if ((filename) && (path_len > strlen (filename))) {
+ strcpy (path, filename);
+ ret = strlen (filename);
+ }
+
+out:
+ if (free_filename)
+ GF_FREE (filename);
+
+ return ret;
+}
+
+int
+_validate_volfile_checksum (xlator_t *this, char *key,
+ uint32_t checksum)
+{
+ char filename[PATH_MAX] = {0,};
+ server_conf_t *conf = NULL;
+ struct _volfile_ctx *temp_volfile = NULL;
+ int ret = 0;
+ int fd = 0;
+ uint32_t local_checksum = 0;
+
+ conf = this->private;
+ temp_volfile = conf->volfile;
+
+ if (!checksum)
+ goto out;
+
+ if (!temp_volfile) {
+ ret = getspec_build_volfile_path (this, key, filename,
+ sizeof (filename));
+ if (ret <= 0)
+ goto out;
+ fd = open (filename, O_RDONLY);
+ if (-1 == fd) {
+ ret = 0;
+ gf_log (this->name, GF_LOG_INFO,
+ "failed to open volume file (%s) : %s",
+ filename, strerror (errno));
+ goto out;
+ }
+ get_checksum_for_file (fd, &local_checksum);
+ _volfile_update_checksum (this, key, local_checksum);
+ close (fd);
+ }
+
+ temp_volfile = conf->volfile;
+ while (temp_volfile) {
+ if ((NULL == key) && (NULL == temp_volfile->key))
+ break;
+ if ((NULL == key) || (NULL == temp_volfile->key)) {
+ temp_volfile = temp_volfile->next;
+ continue;
+ }
+ if (strcmp (temp_volfile->key, key) == 0)
+ break;
+ temp_volfile = temp_volfile->next;
+ }
+
+ if (!temp_volfile)
+ goto out;
+
+ if ((temp_volfile->checksum) &&
+ (checksum != temp_volfile->checksum))
+ ret = -1;
+
+out:
+ return ret;
+}
+
+
+int
+server_getspec (rpcsvc_request_t *req)
+{
+ int32_t ret = -1;
+ int32_t op_errno = ENOENT;
+ int32_t spec_fd = -1;
+ size_t file_len = 0;
+ char filename[PATH_MAX] = {0,};
+ struct stat stbuf = {0,};
+ uint32_t checksum = 0;
+ char *key = NULL;
+ server_conf_t *conf = NULL;
+ xlator_t *this = NULL;
+ gf_getspec_req args = {0,};
+ gf_getspec_rsp rsp = {0,};
+
+ this = req->svc->mydata;
+ conf = this->private;
+ ret = xdr_to_generic (req->msg[0], &args,
+ (xdrproc_t)xdr_gf_getspec_req);
+ if (ret < 0) {
+ //failed to decode msg;
+ req->rpc_err = GARBAGE_ARGS;
+ op_errno = EINVAL;
+ goto fail;
+ }
+
+ ret = getspec_build_volfile_path (this, args.key,
+ filename, sizeof (filename));
+ if (ret > 0) {
+ /* to allocate the proper buffer to hold the file data */
+ ret = stat (filename, &stbuf);
+ if (ret < 0){
+ gf_log (this->name, GF_LOG_ERROR,
+ "Unable to stat %s (%s)",
+ filename, strerror (errno));
+ op_errno = errno;
+ goto fail;
+ }
+
+ spec_fd = open (filename, O_RDONLY);
+ if (spec_fd < 0) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Unable to open %s (%s)",
+ filename, strerror (errno));
+ op_errno = errno;
+ goto fail;
+ }
+ ret = file_len = stbuf.st_size;
+
+ if (conf->verify_volfile) {
+ get_checksum_for_file (spec_fd, &checksum);
+ _volfile_update_checksum (this, key, checksum);
+ }
+ } else {
+ op_errno = ENOENT;
+ }
+
+ if (file_len) {
+ rsp.spec = GF_CALLOC (file_len, sizeof (char),
+ gf_server_mt_rsp_buf_t);
+ if (!rsp.spec) {
+ ret = -1;
+ op_errno = ENOMEM;
+ goto fail;
+ }
+ ret = read (spec_fd, rsp.spec, file_len);
+ }
+
+ /* convert to XDR */
+ op_errno = errno;
+fail:
+ if (!rsp.spec)
+ rsp.spec = "";
+ rsp.op_errno = gf_errno_to_error (op_errno);
+ rsp.op_ret = ret;
+
+ if (spec_fd != -1)
+ close (spec_fd);
+
+ server_submit_reply (NULL, req, &rsp, NULL, 0, NULL,
+ (xdrproc_t)xdr_gf_getspec_rsp);
+
+ return 0;
+}
+
+
+int
+server_setvolume (rpcsvc_request_t *req)
+{
+ gf_setvolume_req args = {{0,},};
+ gf_setvolume_rsp rsp = {0,};
+ client_t *client = NULL;
+ server_ctx_t *serv_ctx = NULL;
+ server_conf_t *conf = NULL;
+ peer_info_t *peerinfo = NULL;
+ dict_t *reply = NULL;
+ dict_t *config_params = NULL;
+ dict_t *params = NULL;
+ char *name = NULL;
+ char *client_uid = NULL;
+ char *clnt_version = NULL;
+ xlator_t *xl = NULL;
+ char *msg = NULL;
+ char *volfile_key = NULL;
+ xlator_t *this = NULL;
+ uint32_t checksum = 0;
+ int32_t ret = -1;
+ int32_t op_ret = -1;
+ int32_t op_errno = EINVAL;
+ int32_t fop_version = 0;
+ int32_t mgmt_version = 0;
+ uint32_t lk_version = 0;
+ char *buf = NULL;
+ gf_boolean_t cancelled = _gf_false;
+
+ params = dict_new ();
+ reply = dict_new ();
+ ret = xdr_to_generic (req->msg[0], &args,
+ (xdrproc_t)xdr_gf_setvolume_req);
+ if (ret < 0) {
+ //failed to decode msg;
+ req->rpc_err = GARBAGE_ARGS;
+ goto fail;
+ }
+
+ this = req->svc->mydata;
+
+ config_params = dict_copy_with_ref (this->options, NULL);
+ conf = this->private;
+
+ buf = memdup (args.dict.dict_val, args.dict.dict_len);
+ if (buf == NULL) {
+ op_ret = -1;
+ op_errno = ENOMEM;
+ goto fail;
+ }
+
+ ret = dict_unserialize (buf, args.dict.dict_len, &params);
+ if (ret < 0) {
+ ret = dict_set_str (reply, "ERROR",
+ "Internal error: failed to unserialize "
+ "request dictionary");
+ if (ret < 0)
+ gf_log (this->name, GF_LOG_DEBUG,
+ "failed to set error msg \"%s\"",
+ "Internal error: failed to unserialize "
+ "request dictionary");
+
+ op_ret = -1;
+ op_errno = EINVAL;
+ goto fail;
+ }
+
+ params->extra_free = buf;
+ buf = NULL;
+
+ ret = dict_get_str (params, "process-uuid", &client_uid);
+ if (ret < 0) {
+ ret = dict_set_str (reply, "ERROR",
+ "UUID not specified");
+ if (ret < 0)
+ gf_log (this->name, GF_LOG_DEBUG,
+ "failed to set error msg");
+
+ op_ret = -1;
+ op_errno = EINVAL;
+ goto fail;
+ }
+
+ /*lk_verion :: [1..2^31-1]*/
+ ret = dict_get_uint32 (params, "clnt-lk-version", &lk_version);
+ if (ret < 0) {
+ ret = dict_set_str (reply, "ERROR",
+ "lock state version not supplied");
+ if (ret < 0)
+ gf_log (this->name, GF_LOG_DEBUG,
+ "failed to set error msg");
+
+ op_ret = -1;
+ op_errno = EINVAL;
+ goto fail;
+ }
+
+ client = gf_client_get (this, &req->cred, client_uid);
+ if (client == NULL) {
+ op_ret = -1;
+ op_errno = ENOMEM;
+ goto fail;
+ }
+
+ gf_log (this->name, GF_LOG_DEBUG, "Connected to %s", client->client_uid);
+ cancelled = server_cancel_grace_timer (this, client);
+ if (cancelled)//Do gf_client_put on behalf of grace-timer-handler.
+ gf_client_put (client, NULL);
+
+ serv_ctx = server_ctx_get (client, client->this);
+ if (serv_ctx == NULL) {
+ gf_log (this->name, GF_LOG_INFO, "server_ctx_get() failed");
+ goto fail;
+ }
+
+ if (serv_ctx->lk_version != 0 &&
+ serv_ctx->lk_version != lk_version) {
+ (void) server_connection_cleanup (this, client,
+ INTERNAL_LOCKS | POSIX_LOCKS);
+ }
+
+ if (req->trans->xl_private != client)
+ req->trans->xl_private = client;
+
+ ret = dict_get_int32 (params, "fops-version", &fop_version);
+ if (ret < 0) {
+ ret = dict_set_str (reply, "ERROR",
+ "No FOP version number specified");
+ if (ret < 0)
+ gf_log (this->name, GF_LOG_DEBUG,
+ "failed to set error msg");
+ }
+
+ ret = dict_get_int32 (params, "mgmt-version", &mgmt_version);
+ if (ret < 0) {
+ ret = dict_set_str (reply, "ERROR",
+ "No MGMT version number specified");
+ if (ret < 0)
+ gf_log (this->name, GF_LOG_DEBUG,
+ "failed to set error msg");
+ }
+
+ ret = gf_compare_client_version (req, fop_version, mgmt_version);
+ if (ret != 0) {
+ ret = gf_asprintf (&msg, "version mismatch: client(%d)"
+ " - client-mgmt(%d)",
+ fop_version, mgmt_version);
+ /* get_supported_version (req)); */
+ if (-1 == ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "asprintf failed while setting up error msg");
+ goto fail;
+ }
+ ret = dict_set_dynstr (reply, "ERROR", msg);
+ if (ret < 0)
+ gf_log (this->name, GF_LOG_DEBUG,
+ "failed to set error msg");
+
+ op_ret = -1;
+ op_errno = EINVAL;
+ goto fail;
+ }
+
+ ret = dict_get_str (params, "remote-subvolume", &name);
+ if (ret < 0) {
+ ret = dict_set_str (reply, "ERROR",
+ "No remote-subvolume option specified");
+ if (ret < 0)
+ gf_log (this->name, GF_LOG_DEBUG,
+ "failed to set error msg");
+
+ op_ret = -1;
+ op_errno = EINVAL;
+ goto fail;
+ }
+
+ xl = get_xlator_by_name (this, name);
+ if (xl == NULL) {
+ ret = gf_asprintf (&msg, "remote-subvolume \"%s\" is not found",
+ name);
+ if (-1 == ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "asprintf failed while setting error msg");
+ goto fail;
+ }
+ ret = dict_set_dynstr (reply, "ERROR", msg);
+ if (ret < 0)
+ gf_log (this->name, GF_LOG_DEBUG,
+ "failed to set error msg");
+
+ op_ret = -1;
+ op_errno = ENOENT;
+ goto fail;
+ }
+
+ if (conf->verify_volfile) {
+ ret = dict_get_uint32 (params, "volfile-checksum", &checksum);
+ if (ret == 0) {
+ ret = dict_get_str (params, "volfile-key",
+ &volfile_key);
+ if (ret)
+ gf_log (this->name, GF_LOG_DEBUG,
+ "failed to set 'volfile-key'");
+
+ ret = _validate_volfile_checksum (this, volfile_key,
+ checksum);
+ if (-1 == ret) {
+ ret = dict_set_str (reply, "ERROR",
+ "volume-file checksum "
+ "varies from earlier "
+ "access");
+ if (ret < 0)
+ gf_log (this->name, GF_LOG_DEBUG,
+ "failed to set error msg");
+
+ op_ret = -1;
+ op_errno = ESTALE;
+ goto fail;
+ }
+ }
+ }
+
+
+ peerinfo = &req->trans->peerinfo;
+ if (peerinfo) {
+ ret = dict_set_static_ptr (params, "peer-info", peerinfo);
+ if (ret < 0)
+ gf_log (this->name, GF_LOG_DEBUG,
+ "failed to set peer-info");
+ }
+ if (conf->auth_modules == NULL) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Authentication module not initialized");
+ }
+
+ ret = dict_get_str (params, "client-version", &clnt_version);
+ if (ret)
+ gf_log (this->name, GF_LOG_INFO, "client-version not set, "
+ "may be of older version");
+
+ ret = gf_authenticate (params, config_params,
+ conf->auth_modules);
+
+ if (ret == AUTH_ACCEPT) {
+
+ gf_log (this->name, GF_LOG_INFO,
+ "accepted client from %s (version: %s)",
+ client->client_uid,
+ (clnt_version) ? clnt_version : "old");
+ op_ret = 0;
+ client->bound_xl = xl;
+ ret = dict_set_str (reply, "ERROR", "Success");
+ if (ret < 0)
+ gf_log (this->name, GF_LOG_DEBUG,
+ "failed to set error msg");
+ } else {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Cannot authenticate client from %s %s",
+ client->client_uid,
+ (clnt_version) ? clnt_version : "old");
+
+ op_ret = -1;
+ op_errno = EACCES;
+ ret = dict_set_str (reply, "ERROR", "Authentication failed");
+ if (ret < 0)
+ gf_log (this->name, GF_LOG_DEBUG,
+ "failed to set error msg");
+ goto fail;
+ }
+
+ if (client->bound_xl == NULL) {
+ ret = dict_set_str (reply, "ERROR",
+ "Check volfile and handshake "
+ "options in protocol/client");
+ if (ret < 0)
+ gf_log (this->name, GF_LOG_DEBUG,
+ "failed to set error msg");
+
+ op_ret = -1;
+ op_errno = EACCES;
+ goto fail;
+ }
+
+ if ((client->bound_xl != NULL) &&
+ (ret >= 0) &&
+ (client->bound_xl->itable == NULL)) {
+ /* create inode table for this bound_xl, if one doesn't
+ already exist */
+
+ gf_log (this->name, GF_LOG_TRACE,
+ "creating inode table with lru_limit=%"PRId32", "
+ "xlator=%s", conf->inode_lru_limit,
+ client->bound_xl->name);
+
+ /* TODO: what is this ? */
+ client->bound_xl->itable =
+ inode_table_new (conf->inode_lru_limit,
+ client->bound_xl);
+ }
+
+ ret = dict_set_str (reply, "process-uuid",
+ this->ctx->process_uuid);
+ if (ret)
+ gf_log (this->name, GF_LOG_DEBUG,
+ "failed to set 'process-uuid'");
+
+ ret = dict_set_uint32 (reply, "clnt-lk-version", serv_ctx->lk_version);
+ if (ret)
+ gf_log (this->name, GF_LOG_WARNING,
+ "failed to set 'clnt-lk-version'");
+
+ ret = dict_set_uint64 (reply, "transport-ptr",
+ ((uint64_t) (long) req->trans));
+ if (ret)
+ gf_log (this->name, GF_LOG_DEBUG,
+ "failed to set 'transport-ptr'");
+
+fail:
+ rsp.dict.dict_len = dict_serialized_length (reply);
+ if (rsp.dict.dict_len < 0) {
+ gf_log ("server-handshake", GF_LOG_DEBUG,
+ "failed to get serialized length of reply dict");
+ op_ret = -1;
+ op_errno = EINVAL;
+ rsp.dict.dict_len = 0;
+ }
+
+ if (rsp.dict.dict_len) {
+ rsp.dict.dict_val = GF_CALLOC (1, rsp.dict.dict_len,
+ gf_server_mt_rsp_buf_t);
+ if (rsp.dict.dict_val) {
+ ret = dict_serialize (reply, rsp.dict.dict_val);
+ if (ret < 0) {
+ gf_log ("server-handshake", GF_LOG_DEBUG,
+ "failed to serialize reply dict");
+ op_ret = -1;
+ op_errno = -ret;
+ }
+ }
+ }
+ rsp.op_ret = op_ret;
+ rsp.op_errno = gf_errno_to_error (op_errno);
+
+ /* if bound_xl is NULL or something fails, then put the connection
+ * back. Otherwise the connection would have been added to the
+ * list of connections the server is maintaining and might segfault
+ * during statedump when bound_xl of the connection is accessed.
+ */
+ if (op_ret && !xl) {
+ /* We would have set the xl_private of the transport to the
+ * @conn. But if we have put the connection i.e shutting down
+ * the connection, then we should set xl_private to NULL as it
+ * would be pointing to a freed memory and would segfault when
+ * accessed upon getting DISCONNECT.
+ */
+ gf_client_put (client, NULL);
+ req->trans->xl_private = NULL;
+ }
+ server_submit_reply (NULL, req, &rsp, NULL, 0, NULL,
+ (xdrproc_t)xdr_gf_setvolume_rsp);
+
+
+ free (args.dict.dict_val);
+
+ GF_FREE (rsp.dict.dict_val);
+
+ dict_unref (params);
+ dict_unref (reply);
+ dict_unref (config_params);
+
+ GF_FREE (buf);
+
+ return 0;
+}
+
+
+int
+server_ping (rpcsvc_request_t *req)
+{
+ gf_common_rsp rsp = {0,};
+
+ /* Accepted */
+ rsp.op_ret = 0;
+
+ server_submit_reply (NULL, req, &rsp, NULL, 0, NULL,
+ (xdrproc_t)xdr_gf_common_rsp);
+
+ return 0;
+}
+
+int
+server_set_lk_version (rpcsvc_request_t *req)
+{
+ int op_ret = -1;
+ int op_errno = EINVAL;
+ gf_set_lk_ver_req args = {0,};
+ gf_set_lk_ver_rsp rsp = {0,};
+ client_t *client = NULL;
+ server_ctx_t *serv_ctx = NULL;
+ xlator_t *this = NULL;
+
+ this = req->svc->mydata;
+ //TODO: Decide on an appropriate errno for the error-path
+ //below
+ if (!this)
+ goto fail;
+
+ op_ret = xdr_to_generic (req->msg[0], &args,
+ (xdrproc_t)xdr_gf_set_lk_ver_req);
+ if (op_ret < 0) {
+ //failed to decode msg;
+ req->rpc_err = GARBAGE_ARGS;
+ goto fail;
+ }
+
+ client = gf_client_get (this, &req->cred, args.uid);
+ serv_ctx = server_ctx_get (client, client->this);
+ if (serv_ctx == NULL) {
+ gf_log (this->name, GF_LOG_INFO, "server_ctx_get() failed");
+ goto fail;
+ }
+
+ serv_ctx->lk_version = args.lk_ver;
+ gf_client_put (client, NULL);
+
+ rsp.lk_ver = args.lk_ver;
+
+ op_ret = 0;
+fail:
+ rsp.op_ret = op_ret;
+ rsp.op_errno = op_errno;
+ server_submit_reply (NULL, req, &rsp, NULL, 0, NULL,
+ (xdrproc_t)xdr_gf_set_lk_ver_rsp);
+
+ free (args.uid);
+
+ return 0;
+}
+
+rpcsvc_actor_t gluster_handshake_actors[] = {
+ [GF_HNDSK_NULL] = {"NULL", GF_HNDSK_NULL, server_null, NULL, 0, DRC_NA},
+ [GF_HNDSK_SETVOLUME] = {"SETVOLUME", GF_HNDSK_SETVOLUME, server_setvolume, NULL, 0, DRC_NA},
+ [GF_HNDSK_GETSPEC] = {"GETSPEC", GF_HNDSK_GETSPEC, server_getspec, NULL, 0, DRC_NA},
+ [GF_HNDSK_PING] = {"PING", GF_HNDSK_PING, server_ping, NULL, 0, DRC_NA},
+ [GF_HNDSK_SET_LK_VER] = {"SET_LK_VER", GF_HNDSK_SET_LK_VER, server_set_lk_version, NULL, 0, DRC_NA},
+};
+
+
+struct rpcsvc_program gluster_handshake_prog = {
+ .progname = "GlusterFS Handshake",
+ .prognum = GLUSTER_HNDSK_PROGRAM,
+ .progver = GLUSTER_HNDSK_VERSION,
+ .actors = gluster_handshake_actors,
+ .numactors = GF_HNDSK_MAXVALUE,
+};
diff --git a/xlators/protocol/server/src/server-helpers.c b/xlators/protocol/server/src/server-helpers.c
index 14797508d..f0b040c74 100644
--- a/xlators/protocol/server/src/server-helpers.c
+++ b/xlators/protocol/server/src/server-helpers.c
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2006-2009 Z RESEARCH, Inc. <http://www.zresearch.com>
+ Copyright (c) 2010-2013 Red Hat, Inc. <http://www.redhat.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/>.
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
*/
#ifndef _CONFIG_H
@@ -22,841 +13,1249 @@
#include "config.h"
#endif
-#include "server-protocol.h"
+#include "server.h"
#include "server-helpers.h"
+#include <fnmatch.h>
-/* server_loc_fill - derive a loc_t for a given inode number
- *
- * NOTE: make sure that @loc is empty, because any pointers it holds with reference will
- * be leaked after returning from here.
- */
int
-server_loc_fill (loc_t *loc, server_state_t *state,
- ino_t ino, ino_t par,
- const char *name, const char *path)
-{
- inode_t *inode = NULL;
- inode_t *parent = NULL;
- int32_t ret = -1;
- char *dentry_path = NULL;
-
-
- GF_VALIDATE_OR_GOTO ("server", loc, out);
- GF_VALIDATE_OR_GOTO ("server", state, out);
- GF_VALIDATE_OR_GOTO ("server", path, out);
-
- /* anything beyond this point is success */
- ret = 0;
- loc->ino = ino;
- inode = loc->inode;
- if (inode == NULL) {
- if (ino)
- inode = inode_search (state->itable, ino, NULL);
-
- if ((inode == NULL) &&
- (par && name))
- inode = inode_search (state->itable, par, name);
-
- loc->inode = inode;
- if (inode)
- loc->ino = inode->ino;
- }
-
- parent = loc->parent;
- if (parent == NULL) {
- if (inode)
- parent = inode_parent (inode, par, name);
- else
- parent = inode_search (state->itable, par, NULL);
- loc->parent = parent;
- }
-
- if (name && parent) {
- ret = inode_path (parent, name, &dentry_path);
- if (ret < 0) {
- gf_log (state->bound_xl->name, GF_LOG_DEBUG,
- "failed to build path for %"PRId64"/%s: %s",
- parent->ino, name, strerror (-ret));
- }
- } else if (inode) {
- ret = inode_path (inode, NULL, &dentry_path);
- if (ret < 0) {
- gf_log (state->bound_xl->name, GF_LOG_DEBUG,
- "failed to build path for %"PRId64": %s",
- inode->ino, strerror (-ret));
- }
- }
-
- if (dentry_path) {
- if (strcmp (dentry_path, path)) {
- gf_log (state->bound_xl->name, GF_LOG_DEBUG,
- "paths differ for inode(%"PRId64"): "
- "client path = %s. dentry path = %s",
- ino, path, dentry_path);
- }
-
- loc->path = dentry_path;
- loc->name = strrchr (loc->path, '/');
- if (loc->name)
- loc->name++;
- } else {
- loc->path = strdup (path);
- loc->name = strrchr (loc->path, '/');
- if (loc->name)
- loc->name++;
- }
+server_decode_groups (call_frame_t *frame, rpcsvc_request_t *req)
+{
+ int i = 0;
-out:
- return ret;
-}
+ GF_VALIDATE_OR_GOTO ("server", frame, out);
+ GF_VALIDATE_OR_GOTO ("server", req, out);
-/*
- * stat_to_str - convert struct stat to a ASCII string
- * @stbuf: struct stat pointer
- *
- * not for external reference
- */
-char *
-stat_to_str (struct stat *stbuf)
-{
- int ret = 0;
- char *tmp_buf = NULL;
-
- uint64_t dev = stbuf->st_dev;
- uint64_t ino = stbuf->st_ino;
- uint32_t mode = stbuf->st_mode;
- uint32_t nlink = stbuf->st_nlink;
- uint32_t uid = stbuf->st_uid;
- uint32_t gid = stbuf->st_gid;
- uint64_t rdev = stbuf->st_rdev;
- uint64_t size = stbuf->st_size;
- uint32_t blksize = stbuf->st_blksize;
- uint64_t blocks = stbuf->st_blocks;
- uint32_t atime = stbuf->st_atime;
- uint32_t mtime = stbuf->st_mtime;
- uint32_t ctime = stbuf->st_ctime;
-
- uint32_t atime_nsec = ST_ATIM_NSEC(stbuf);
- uint32_t mtime_nsec = ST_MTIM_NSEC(stbuf);
- uint32_t ctime_nsec = ST_CTIM_NSEC(stbuf);
-
-
- ret = asprintf (&tmp_buf,
- GF_STAT_PRINT_FMT_STR,
- dev,
- ino,
- mode,
- nlink,
- uid,
- gid,
- rdev,
- size,
- blksize,
- blocks,
- atime,
- atime_nsec,
- mtime,
- mtime_nsec,
- ctime,
- ctime_nsec);
- if (-1 == ret) {
- gf_log ("protocol/server", GF_LOG_DEBUG,
- "asprintf failed while setting up stat buffer string");
- return NULL;
- }
- return tmp_buf;
+ if (call_stack_alloc_groups (frame->root, req->auxgidcount) != 0)
+ return -1;
+
+ frame->root->ngrps = req->auxgidcount;
+ if (frame->root->ngrps == 0)
+ return 0;
+
+ if (frame->root->ngrps > GF_MAX_AUX_GROUPS)
+ return -1;
+
+ for (; i < frame->root->ngrps; ++i)
+ frame->root->groups[i] = req->auxgids[i];
+out:
+ return 0;
}
void
server_loc_wipe (loc_t *loc)
{
- if (loc->parent)
- inode_unref (loc->parent);
- if (loc->inode)
- inode_unref (loc->inode);
- if (loc->path)
- free ((char *)loc->path);
-}
+ if (loc->parent) {
+ inode_unref (loc->parent);
+ loc->parent = NULL;
+ }
-void
-free_state (server_state_t *state)
-{
- transport_t *trans = NULL;
+ if (loc->inode) {
+ inode_unref (loc->inode);
+ loc->inode = NULL;
+ }
- trans = state->trans;
+ GF_FREE ((void *)loc->path);
+}
- if (state->fd)
- fd_unref (state->fd);
- transport_unref (trans);
-
- if (state->xattr_req)
- dict_unref (state->xattr_req);
+void
+server_resolve_wipe (server_resolve_t *resolve)
+{
+ GF_FREE ((void *)resolve->path);
- if (state->volume)
- FREE (state->volume);
+ GF_FREE ((void *)resolve->bname);
- FREE (state);
+ loc_wipe (&resolve->resolve_loc);
}
-call_frame_t *
-server_copy_frame (call_frame_t *frame)
+void
+free_state (server_state_t *state)
{
- call_frame_t *new_frame = NULL;
- server_state_t *state = NULL, *new_state = NULL;
+ if (state->xprt) {
+ rpc_transport_unref (state->xprt);
+ state->xprt = NULL;
+ }
+ if (state->fd) {
+ fd_unref (state->fd);
+ state->fd = NULL;
+ }
- state = frame->root->state;
+ if (state->params) {
+ dict_unref (state->params);
+ state->params = NULL;
+ }
- new_frame = copy_frame (frame);
+ if (state->iobref) {
+ iobref_unref (state->iobref);
+ state->iobref = NULL;
+ }
- new_state = CALLOC (1, sizeof (server_state_t));
+ if (state->iobuf) {
+ iobuf_unref (state->iobuf);
+ state->iobuf = NULL;
+ }
- new_frame->root->op = frame->root->op;
- new_frame->root->type = frame->root->type;
- new_frame->root->trans = state->trans;
- new_frame->root->state = new_state;
+ if (state->dict) {
+ dict_unref (state->dict);
+ state->dict = NULL;
+ }
- new_state->bound_xl = state->bound_xl;
- new_state->trans = transport_ref (state->trans);
- new_state->itable = state->itable;
+ if (state->xdata) {
+ dict_unref (state->xdata);
+ state->xdata = NULL;
+ }
- return new_frame;
-}
+ GF_FREE ((void *)state->volume);
-int32_t
-gf_add_locker (struct _lock_table *table,
- const char *volume,
- loc_t *loc,
- fd_t *fd,
- pid_t pid)
-{
- int32_t ret = -1;
- struct _locker *new = NULL;
- uint8_t dir = 0;
-
- new = CALLOC (1, sizeof (struct _locker));
- if (new == NULL) {
- gf_log ("server", GF_LOG_ERROR,
- "failed to allocate memory for \'struct _locker\'");
- goto out;
- }
- INIT_LIST_HEAD (&new->lockers);
-
- new->volume = strdup (volume);
-
- if (fd == NULL) {
- loc_copy (&new->loc, loc);
- dir = S_ISDIR (new->loc.inode->st_mode);
- } else {
- new->fd = fd_ref (fd);
- dir = S_ISDIR (fd->inode->st_mode);
- }
-
- new->pid = pid;
-
- LOCK (&table->lock);
- {
- if (dir)
- list_add_tail (&new->lockers, &table->dir_lockers);
- else
- list_add_tail (&new->lockers, &table->file_lockers);
- }
- UNLOCK (&table->lock);
-out:
- return ret;
-}
+ GF_FREE ((void *)state->name);
-int32_t
-gf_del_locker (struct _lock_table *table,
- const char *volume,
- loc_t *loc,
- fd_t *fd,
- pid_t pid)
-{
- struct _locker *locker = NULL, *tmp = NULL;
- int32_t ret = 0;
- uint8_t dir = 0;
- struct list_head *head = NULL;
- struct list_head del;
-
- INIT_LIST_HEAD (&del);
-
- if (fd) {
- dir = S_ISDIR (fd->inode->st_mode);
- } else {
- dir = S_ISDIR (loc->inode->st_mode);
- }
-
- LOCK (&table->lock);
- {
- if (dir) {
- head = &table->dir_lockers;
- } else {
- head = &table->file_lockers;
- }
-
- list_for_each_entry_safe (locker, tmp, head, lockers) {
- if (locker->fd &&
- fd &&
- (locker->fd == fd) && (locker->pid == pid)
- && !strcmp (locker->volume, volume)) {
- list_move_tail (&locker->lockers, &del);
- } else if (locker->loc.inode &&
- loc &&
- (locker->loc.inode == loc->inode) &&
- (locker->pid == pid)
- && !strcmp (locker->volume, volume)) {
- list_move_tail (&locker->lockers, &del);
- }
- }
- }
- UNLOCK (&table->lock);
-
- tmp = NULL;
- locker = NULL;
-
- list_for_each_entry_safe (locker, tmp, &del, lockers) {
- list_del_init (&locker->lockers);
- if (locker->fd)
- fd_unref (locker->fd);
- else
- loc_wipe (&locker->loc);
-
- free (locker->volume);
- free (locker);
- }
-
- return ret;
-}
-
-int32_t
-gf_direntry_to_bin (dir_entry_t *head,
- char *buffer)
-{
- dir_entry_t *trav = NULL;
- uint32_t len = 0;
- uint32_t this_len = 0;
- size_t buflen = -1;
- char *ptr = NULL;
- char *tmp_buf = NULL;
-
- trav = head->next;
- while (trav) {
- len += strlen (trav->name);
- len += 1;
- len += strlen (trav->link);
- len += 1; /* for '\n' */
- len += 256; // max possible for statbuf;
- trav = trav->next;
- }
-
- ptr = buffer;
- trav = head->next;
- while (trav) {
- tmp_buf = stat_to_str (&trav->buf);
- /* tmp_buf will have \n before \0 */
-
- this_len = sprintf (ptr, "%s/%s%s\n",
- trav->name, tmp_buf,
- trav->link);
-
- FREE (tmp_buf);
- trav = trav->next;
- ptr += this_len;
- }
-
- buflen = strlen (buffer);
-
- return buflen;
-}
-
-
-static struct _lock_table *
-gf_lock_table_new (void)
-{
- struct _lock_table *new = NULL;
-
- new = CALLOC (1, sizeof (struct _lock_table));
- if (new == NULL) {
- gf_log ("server-protocol", GF_LOG_CRITICAL,
- "failed to allocate memory for new lock table");
- goto out;
- }
- INIT_LIST_HEAD (&new->dir_lockers);
- INIT_LIST_HEAD (&new->file_lockers);
- LOCK_INIT (&new->lock);
-out:
- return new;
-}
-
-
-int
-do_lock_table_cleanup (xlator_t *this, server_connection_t *conn,
- call_frame_t *frame, struct _lock_table *ltable)
-{
- struct list_head file_lockers, dir_lockers;
- call_frame_t *tmp_frame = NULL;
- struct flock flock = {0, };
- xlator_t *bound_xl = NULL;
- struct _locker *locker = NULL, *tmp = NULL;
- int ret = -1;
-
- bound_xl = conn->bound_xl;
- INIT_LIST_HEAD (&file_lockers);
- INIT_LIST_HEAD (&dir_lockers);
-
- LOCK (&ltable->lock);
- {
- list_splice_init (&ltable->file_lockers,
- &file_lockers);
-
- list_splice_init (&ltable->dir_lockers, &dir_lockers);
- }
- UNLOCK (&ltable->lock);
-
- free (ltable);
-
- flock.l_type = F_UNLCK;
- flock.l_start = 0;
- flock.l_len = 0;
- list_for_each_entry_safe (locker,
- tmp, &file_lockers, lockers) {
- tmp_frame = copy_frame (frame);
- if (tmp_frame == NULL) {
- gf_log (this->name, GF_LOG_ERROR,
- "out of memory");
- goto out;
- }
- /*
- pid = 0 is a special case that tells posix-locks
- to release all locks from this transport
- */
- tmp_frame->root->pid = 0;
- tmp_frame->root->trans = conn;
-
- if (locker->fd) {
- STACK_WIND (tmp_frame, server_nop_cbk,
- bound_xl,
- bound_xl->fops->finodelk,
- locker->volume,
- locker->fd, F_SETLK, &flock);
- fd_unref (locker->fd);
- } else {
- STACK_WIND (tmp_frame, server_nop_cbk,
- bound_xl,
- bound_xl->fops->inodelk,
- locker->volume,
- &(locker->loc), F_SETLK, &flock);
- loc_wipe (&locker->loc);
- }
-
- free (locker->volume);
-
- list_del_init (&locker->lockers);
- free (locker);
- }
-
- tmp = NULL;
- locker = NULL;
- list_for_each_entry_safe (locker, tmp, &dir_lockers, lockers) {
- tmp_frame = copy_frame (frame);
-
- tmp_frame->root->pid = 0;
- tmp_frame->root->trans = conn;
-
- if (locker->fd) {
- STACK_WIND (tmp_frame, server_nop_cbk,
- bound_xl,
- bound_xl->fops->fentrylk,
- locker->volume,
- locker->fd, NULL,
- ENTRYLK_UNLOCK, ENTRYLK_WRLCK);
- fd_unref (locker->fd);
- } else {
- STACK_WIND (tmp_frame, server_nop_cbk,
- bound_xl,
- bound_xl->fops->entrylk,
- locker->volume,
- &(locker->loc), NULL,
- ENTRYLK_UNLOCK, ENTRYLK_WRLCK);
- loc_wipe (&locker->loc);
- }
+ server_loc_wipe (&state->loc);
+ server_loc_wipe (&state->loc2);
- free (locker->volume);
-
- list_del_init (&locker->lockers);
- free (locker);
- }
- ret = 0;
+ server_resolve_wipe (&state->resolve);
+ server_resolve_wipe (&state->resolve2);
-out:
- return ret;
+ GF_FREE (state);
}
-static int32_t
-server_connection_cleanup_flush_cbk (call_frame_t *frame,
- void *cookie,
- xlator_t *this,
- int32_t op_ret,
- int32_t op_errno)
+static int
+server_connection_cleanup_flush_cbk (call_frame_t *frame, void *cookie,
+ xlator_t *this, int32_t op_ret,
+ int32_t op_errno, dict_t *xdata)
{
- fd_t *fd = NULL;
+ int32_t ret = -1;
+ fd_t *fd = NULL;
+ client_t *client = NULL;
+
+ GF_VALIDATE_OR_GOTO ("server", this, out);
+ GF_VALIDATE_OR_GOTO ("server", cookie, out);
+ GF_VALIDATE_OR_GOTO ("server", frame, out);
fd = frame->local;
+ client = frame->root->client;
fd_unref (fd);
frame->local = NULL;
+ gf_client_unref (client);
STACK_DESTROY (frame->root);
- return 0;
+
+ ret = 0;
+out:
+ return ret;
}
-int
-do_fd_cleanup (xlator_t *this, server_connection_t *conn, call_frame_t *frame,
- fdentry_t *fdentries, int fd_count)
+static int
+do_fd_cleanup (xlator_t *this, client_t* client, fdentry_t *fdentries, int fd_count)
{
fd_t *fd = NULL;
int i = 0, ret = -1;
call_frame_t *tmp_frame = NULL;
xlator_t *bound_xl = NULL;
-
- bound_xl = conn->bound_xl;
+ char *path = NULL;
+
+ GF_VALIDATE_OR_GOTO ("server", this, out);
+ GF_VALIDATE_OR_GOTO ("server", fdentries, out);
+
+ bound_xl = client->bound_xl;
for (i = 0;i < fd_count; i++) {
fd = fdentries[i].fd;
-
+
if (fd != NULL) {
- tmp_frame = copy_frame (frame);
+ tmp_frame = create_frame (this, this->ctx->pool);
if (tmp_frame == NULL) {
- gf_log (this->name, GF_LOG_ERROR,
- "out of memory");
goto out;
}
+
+ GF_ASSERT (fd->inode);
+
+ ret = inode_path (fd->inode, NULL, &path);
+
+ if (ret > 0) {
+ gf_log (this->name, GF_LOG_INFO,
+ "fd cleanup on %s", path);
+ GF_FREE (path);
+ } else {
+
+ gf_log (this->name, GF_LOG_INFO,
+ "fd cleanup on inode with gfid %s",
+ uuid_utoa (fd->inode->gfid));
+ }
+
tmp_frame->local = fd;
-
+
tmp_frame->root->pid = 0;
- tmp_frame->root->trans = conn;
+ gf_client_ref (client);
+ memset (&tmp_frame->root->lk_owner, 0,
+ sizeof (gf_lkowner_t));
+
STACK_WIND (tmp_frame,
server_connection_cleanup_flush_cbk,
- bound_xl,
- bound_xl->fops->flush,
- fd);
+ bound_xl, bound_xl->fops->flush, fd, NULL);
}
}
- FREE (fdentries);
+
+ GF_FREE (fdentries);
ret = 0;
out:
return ret;
}
+
int
-do_connection_cleanup (xlator_t *this, server_connection_t *conn,
- struct _lock_table *ltable, fdentry_t *fdentries, int fd_count)
+server_connection_cleanup (xlator_t *this, client_t *client,
+ int32_t flags)
{
- int32_t ret = 0, saved_ret = 0;
- call_frame_t *frame = NULL;
- server_state_t *state = NULL;
+ server_ctx_t *serv_ctx = NULL;
+ fdentry_t *fdentries = NULL;
+ uint32_t fd_count = 0;
+ int cd_ret = 0;
+ int ret = 0;
+
+ GF_VALIDATE_OR_GOTO (this->name, this, out);
+ GF_VALIDATE_OR_GOTO (this->name, client, out);
+ GF_VALIDATE_OR_GOTO (this->name, flags, out);
+
+ serv_ctx = server_ctx_get (client, client->this);
- frame = create_frame (this, this->ctx->pool);
- if (frame == NULL) {
- gf_log (this->name, GF_LOG_ERROR, "out of memory");
+ if (serv_ctx == NULL) {
+ gf_log (this->name, GF_LOG_INFO, "server_ctx_get() failed");
goto out;
}
- saved_ret = do_lock_table_cleanup (this, conn, frame, ltable);
-
- if (fdentries != NULL) {
- ret = do_fd_cleanup (this, conn, frame, fdentries, fd_count);
+ LOCK (&serv_ctx->fdtable_lock);
+ {
+ if (serv_ctx->fdtable && (flags & POSIX_LOCKS))
+ fdentries = gf_fd_fdtable_get_all_fds (serv_ctx->fdtable,
+ &fd_count);
}
+ UNLOCK (&serv_ctx->fdtable_lock);
- state = CALL_STATE (frame);
- if (state)
- free (state);
+ if (client->bound_xl == NULL)
+ goto out;
- STACK_DESTROY (frame->root);
+ if (flags & INTERNAL_LOCKS) {
+ cd_ret = gf_client_disconnect (client);
+ }
+
+ if (fdentries != NULL)
+ ret = do_fd_cleanup (this, client, fdentries, fd_count);
+ else
+ gf_log (this->name, GF_LOG_INFO, "no fdentries to clean");
- if (saved_ret || ret) {
+ if (cd_ret || ret)
ret = -1;
+
+out:
+ return ret;
+}
+
+
+static call_frame_t *
+server_alloc_frame (rpcsvc_request_t *req)
+{
+ call_frame_t *frame = NULL;
+ server_state_t *state = NULL;
+ client_t *client = NULL;
+
+ GF_VALIDATE_OR_GOTO ("server", req, out);
+ GF_VALIDATE_OR_GOTO ("server", req->trans, out);
+ GF_VALIDATE_OR_GOTO ("server", req->svc, out);
+ GF_VALIDATE_OR_GOTO ("server", req->svc->ctx, out);
+
+ client = req->trans->xl_private;
+ GF_VALIDATE_OR_GOTO ("server", client, out);
+
+ frame = create_frame (client->this, req->svc->ctx->pool);
+ if (!frame)
+ goto out;
+
+ state = GF_CALLOC (1, sizeof (*state), gf_server_mt_state_t);
+ if (!state)
+ goto out;
+
+ if (client->bound_xl)
+ state->itable = client->bound_xl->itable;
+
+ state->xprt = rpc_transport_ref (req->trans);
+ state->resolve.fd_no = -1;
+ state->resolve2.fd_no = -1;
+
+ frame->root->client = client;
+ frame->root->state = state; /* which socket */
+ frame->root->unique = 0; /* which call */
+
+ frame->this = client->this;
+out:
+ return frame;
+}
+
+
+call_frame_t *
+get_frame_from_request (rpcsvc_request_t *req)
+{
+ call_frame_t *frame = NULL;
+ client_t *client = NULL;
+
+ GF_VALIDATE_OR_GOTO ("server", req, out);
+
+ client = req->trans->xl_private;
+
+ frame = server_alloc_frame (req);
+ if (!frame)
+ goto out;
+
+ frame->root->op = req->procnum;
+
+ frame->root->unique = req->xid;
+
+ frame->root->uid = req->uid;
+ frame->root->gid = req->gid;
+ frame->root->pid = req->pid;
+ gf_client_ref (client);
+ frame->root->client = client;
+ frame->root->lk_owner = req->lk_owner;
+
+ server_decode_groups (frame, req);
+
+ frame->local = req;
+out:
+ return frame;
+}
+
+
+int
+server_build_config (xlator_t *this, server_conf_t *conf)
+{
+ data_t *data = NULL;
+ int ret = -1;
+ struct stat buf = {0,};
+
+ GF_VALIDATE_OR_GOTO ("server", this, out);
+ GF_VALIDATE_OR_GOTO ("server", conf, out);
+
+ ret = dict_get_int32 (this->options, "inode-lru-limit",
+ &conf->inode_lru_limit);
+ if (ret < 0) {
+ conf->inode_lru_limit = 16384;
+ }
+
+ conf->verify_volfile = 1;
+ data = dict_get (this->options, "verify-volfile-checksum");
+ if (data) {
+ ret = gf_string2boolean(data->data, &conf->verify_volfile);
+ if (ret != 0) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "wrong value for 'verify-volfile-checksum', "
+ "Neglecting option");
+ }
}
-
+
+ data = dict_get (this->options, "trace");
+ if (data) {
+ ret = gf_string2boolean (data->data, &conf->trace);
+ if (ret != 0) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "'trace' takes on only boolean values. "
+ "Neglecting option");
+ }
+ }
+
+ /* TODO: build_rpc_config (); */
+ ret = dict_get_int32 (this->options, "limits.transaction-size",
+ &conf->rpc_conf.max_block_size);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_TRACE,
+ "defaulting limits.transaction-size to %d",
+ DEFAULT_BLOCK_SIZE);
+ conf->rpc_conf.max_block_size = DEFAULT_BLOCK_SIZE;
+ }
+
+ data = dict_get (this->options, "config-directory");
+ if (data) {
+ /* Check whether the specified directory exists,
+ or directory specified is non standard */
+ ret = stat (data->data, &buf);
+ if ((ret != 0) || !S_ISDIR (buf.st_mode)) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Directory '%s' doesn't exist, exiting.",
+ data->data);
+ ret = -1;
+ goto out;
+ }
+ /* Make sure that conf-dir doesn't contain ".." in path */
+ if ((gf_strstr (data->data, "/", "..")) == -1) {
+ ret = -1;
+ gf_log (this->name, GF_LOG_ERROR,
+ "%s: invalid conf_dir", data->data);
+ goto out;
+ }
+
+ conf->conf_dir = gf_strdup (data->data);
+ }
+ ret = 0;
out:
return ret;
}
+
+void
+print_caller (char *str, int size, call_frame_t *frame)
+{
+ server_state_t *state = NULL;
+
+ GF_VALIDATE_OR_GOTO ("server", str, out);
+ GF_VALIDATE_OR_GOTO ("server", frame, out);
+
+ state = CALL_STATE (frame);
+
+ snprintf (str, size,
+ " Callid=%"PRId64", Client=%s",
+ frame->root->unique,
+ state->xprt->peerinfo.identifier);
+
+out:
+ return;
+}
+
+
+void
+server_print_resolve (char *str, int size, server_resolve_t *resolve)
+{
+ int filled = 0;
+
+ GF_VALIDATE_OR_GOTO ("server", str, out);
+
+ if (!resolve) {
+ snprintf (str, size, "<nul>");
+ return;
+ }
+
+ filled += snprintf (str + filled, size - filled,
+ " Resolve={");
+ if (resolve->fd_no != -1)
+ filled += snprintf (str + filled, size - filled,
+ "fd=%"PRId64",", (uint64_t) resolve->fd_no);
+ if (resolve->bname)
+ filled += snprintf (str + filled, size - filled,
+ "bname=%s,", resolve->bname);
+ if (resolve->path)
+ filled += snprintf (str + filled, size - filled,
+ "path=%s", resolve->path);
+
+ snprintf (str + filled, size - filled, "}");
+out:
+ return;
+}
+
+
+void
+server_print_loc (char *str, int size, loc_t *loc)
+{
+ int filled = 0;
+
+ GF_VALIDATE_OR_GOTO ("server", str, out);
+
+ if (!loc) {
+ snprintf (str, size, "<nul>");
+ return;
+ }
+
+ filled += snprintf (str + filled, size - filled,
+ " Loc={");
+
+ if (loc->path)
+ filled += snprintf (str + filled, size - filled,
+ "path=%s,", loc->path);
+ if (loc->inode)
+ filled += snprintf (str + filled, size - filled,
+ "inode=%p,", loc->inode);
+ if (loc->parent)
+ filled += snprintf (str + filled, size - filled,
+ "parent=%p", loc->parent);
+
+ snprintf (str + filled, size - filled, "}");
+out:
+ return;
+}
+
+
+void
+server_print_params (char *str, int size, server_state_t *state)
+{
+ int filled = 0;
+
+ GF_VALIDATE_OR_GOTO ("server", str, out);
+
+ filled += snprintf (str + filled, size - filled,
+ " Params={");
+
+ if (state->fd)
+ filled += snprintf (str + filled, size - filled,
+ "fd=%p,", state->fd);
+ if (state->valid)
+ filled += snprintf (str + filled, size - filled,
+ "valid=%d,", state->valid);
+ if (state->flags)
+ filled += snprintf (str + filled, size - filled,
+ "flags=%d,", state->flags);
+ if (state->wbflags)
+ filled += snprintf (str + filled, size - filled,
+ "wbflags=%d,", state->wbflags);
+ if (state->size)
+ filled += snprintf (str + filled, size - filled,
+ "size=%zu,", state->size);
+ if (state->offset)
+ filled += snprintf (str + filled, size - filled,
+ "offset=%"PRId64",", state->offset);
+ if (state->cmd)
+ filled += snprintf (str + filled, size - filled,
+ "cmd=%d,", state->cmd);
+ if (state->type)
+ filled += snprintf (str + filled, size - filled,
+ "type=%d,", state->type);
+ if (state->name)
+ filled += snprintf (str + filled, size - filled,
+ "name=%s,", state->name);
+ if (state->mask)
+ filled += snprintf (str + filled, size - filled,
+ "mask=%d,", state->mask);
+ if (state->volume)
+ filled += snprintf (str + filled, size - filled,
+ "volume=%s,", state->volume);
+
+/* FIXME
+ snprintf (str + filled, size - filled,
+ "bound_xl=%s}", state->client->bound_xl->name);
+*/
+out:
+ return;
+}
+
+
int
-server_connection_cleanup (xlator_t *this, server_connection_t *conn)
+server_resolve_is_empty (server_resolve_t *resolve)
+{
+ if (resolve->fd_no != -1)
+ return 0;
+
+ if (resolve->path != 0)
+ return 0;
+
+ if (resolve->bname != 0)
+ return 0;
+
+ return 1;
+}
+
+
+void
+server_print_reply (call_frame_t *frame, int op_ret, int op_errno)
+{
+ server_conf_t *conf = NULL;
+ server_state_t *state = NULL;
+ xlator_t *this = NULL;
+ char caller[512];
+ char fdstr[32];
+ char *op = "UNKNOWN";
+
+ GF_VALIDATE_OR_GOTO ("server", frame, out);
+
+ this = frame->this;
+ conf = this->private;
+
+ GF_VALIDATE_OR_GOTO ("server", conf, out);
+ GF_VALIDATE_OR_GOTO ("server", conf->trace, out);
+
+ state = CALL_STATE (frame);
+
+ print_caller (caller, 256, frame);
+
+ switch (frame->root->type) {
+ case GF_OP_TYPE_FOP:
+ op = (char *)gf_fop_list[frame->root->op];
+ break;
+ default:
+ op = "";
+ }
+
+ fdstr[0] = '\0';
+ if (state->fd)
+ snprintf (fdstr, 32, " fd=%p", state->fd);
+
+ gf_log (this->name, GF_LOG_INFO,
+ "%s%s => (%d, %d)%s",
+ op, caller, op_ret, op_errno, fdstr);
+out:
+ return;
+}
+
+
+void
+server_print_request (call_frame_t *frame)
{
- char do_cleanup = 0;
- struct _lock_table *ltable = NULL;
- fdentry_t *fdentries = NULL;
- uint32_t fd_count = 0;
- int ret = 0;
+ server_conf_t *conf = NULL;
+ xlator_t *this = NULL;
+ server_state_t *state = NULL;
+ char *op = "UNKNOWN";
+ char resolve_vars[256];
+ char resolve2_vars[256];
+ char loc_vars[256];
+ char loc2_vars[256];
+ char other_vars[512];
+ char caller[512];
+
+ GF_VALIDATE_OR_GOTO ("server", frame, out);
+
+ this = frame->this;
+ conf = this->private;
- if (conn == NULL) {
+ GF_VALIDATE_OR_GOTO ("server", conf, out);
+
+ if (!conf->trace)
goto out;
+
+ state = CALL_STATE (frame);
+
+ memset (resolve_vars, '\0', 256);
+ memset (resolve2_vars, '\0', 256);
+ memset (loc_vars, '\0', 256);
+ memset (loc2_vars, '\0', 256);
+ memset (other_vars, '\0', 256);
+
+ print_caller (caller, 256, frame);
+
+ if (!server_resolve_is_empty (&state->resolve)) {
+ server_print_resolve (resolve_vars, 256, &state->resolve);
+ server_print_loc (loc_vars, 256, &state->loc);
}
- pthread_mutex_lock (&conn->lock);
- {
- conn->active_transports--;
- if (conn->active_transports == 0) {
- if (conn->ltable) {
- ltable = conn->ltable;
- conn->ltable = gf_lock_table_new ();
- }
-
- if (conn->fdtable) {
- fdentries = gf_fd_fdtable_get_all_fds (conn->fdtable,
- &fd_count);
+ if (!server_resolve_is_empty (&state->resolve2)) {
+ server_print_resolve (resolve2_vars, 256, &state->resolve2);
+ server_print_loc (loc2_vars, 256, &state->loc2);
+ }
+
+ server_print_params (other_vars, 512, state);
+
+ switch (frame->root->type) {
+ case GF_OP_TYPE_FOP:
+ op = (char *)gf_fop_list[frame->root->op];
+ break;
+ default:
+ op = "";
+ break;
+ }
+
+ gf_log (this->name, GF_LOG_INFO,
+ "%s%s%s%s%s%s%s",
+ op, caller,
+ resolve_vars, loc_vars, resolve2_vars, loc2_vars, other_vars);
+out:
+ return;
+}
+
+
+int
+serialize_rsp_direntp (gf_dirent_t *entries, gfs3_readdirp_rsp *rsp)
+{
+ gf_dirent_t *entry = NULL;
+ gfs3_dirplist *trav = NULL;
+ gfs3_dirplist *prev = NULL;
+ int ret = -1;
+
+ GF_VALIDATE_OR_GOTO ("server", entries, out);
+ GF_VALIDATE_OR_GOTO ("server", rsp, out);
+
+ list_for_each_entry (entry, &entries->list, list) {
+ trav = GF_CALLOC (1, sizeof (*trav), gf_server_mt_dirent_rsp_t);
+ if (!trav)
+ goto out;
+
+ trav->d_ino = entry->d_ino;
+ trav->d_off = entry->d_off;
+ trav->d_len = entry->d_len;
+ trav->d_type = entry->d_type;
+ trav->name = entry->d_name;
+
+ gf_stat_from_iatt (&trav->stat, &entry->d_stat);
+
+ /* if 'dict' is present, pack it */
+ if (entry->dict) {
+ trav->dict.dict_len = dict_serialized_length (entry->dict);
+ if (trav->dict.dict_len < 0) {
+ gf_log (THIS->name, GF_LOG_ERROR,
+ "failed to get serialized length "
+ "of reply dict");
+ errno = EINVAL;
+ trav->dict.dict_len = 0;
+ goto out;
+ }
+
+ trav->dict.dict_val = GF_CALLOC (1, trav->dict.dict_len,
+ gf_server_mt_rsp_buf_t);
+ if (!trav->dict.dict_val) {
+ errno = ENOMEM;
+ trav->dict.dict_len = 0;
+ goto out;
+ }
+
+ ret = dict_serialize (entry->dict, trav->dict.dict_val);
+ if (ret < 0) {
+ gf_log (THIS->name, GF_LOG_ERROR,
+ "failed to serialize reply dict");
+ errno = -ret;
+ trav->dict.dict_len = 0;
+ goto out;
}
- do_cleanup = 1;
}
+
+ if (prev)
+ prev->nextentry = trav;
+ else
+ rsp->reply = trav;
+
+ prev = trav;
+ trav = NULL;
}
- pthread_mutex_unlock (&conn->lock);
- if (do_cleanup && conn->bound_xl)
- ret = do_connection_cleanup (this, conn, ltable, fdentries, fd_count);
+ ret = 0;
+out:
+ GF_FREE (trav);
+
+ return ret;
+}
+
+
+int
+serialize_rsp_dirent (gf_dirent_t *entries, gfs3_readdir_rsp *rsp)
+{
+ gf_dirent_t *entry = NULL;
+ gfs3_dirlist *trav = NULL;
+ gfs3_dirlist *prev = NULL;
+ int ret = -1;
+
+ GF_VALIDATE_OR_GOTO ("server", entries, out);
+ GF_VALIDATE_OR_GOTO ("server", rsp, out);
+
+ list_for_each_entry (entry, &entries->list, list) {
+ trav = GF_CALLOC (1, sizeof (*trav), gf_server_mt_dirent_rsp_t);
+ if (!trav)
+ goto out;
+ trav->d_ino = entry->d_ino;
+ trav->d_off = entry->d_off;
+ trav->d_len = entry->d_len;
+ trav->d_type = entry->d_type;
+ trav->name = entry->d_name;
+ if (prev)
+ prev->nextentry = trav;
+ else
+ rsp->reply = trav;
+
+ prev = trav;
+ }
+ ret = 0;
out:
return ret;
}
int
-server_connection_destroy (xlator_t *this, server_connection_t *conn)
-{
- call_frame_t *frame = NULL, *tmp_frame = NULL;
- xlator_t *bound_xl = NULL;
- int32_t ret = -1;
- server_state_t *state = NULL;
- struct list_head file_lockers;
- struct list_head dir_lockers;
- struct _lock_table *ltable = NULL;
- struct _locker *locker = NULL, *tmp = NULL;
- struct flock flock = {0,};
- fd_t *fd = NULL;
- int32_t i = 0;
- fdentry_t *fdentries = NULL;
- uint32_t fd_count = 0;
-
- if (conn == NULL) {
- ret = 0;
- goto out;
+readdir_rsp_cleanup (gfs3_readdir_rsp *rsp)
+{
+ gfs3_dirlist *prev = NULL;
+ gfs3_dirlist *trav = NULL;
+
+ trav = rsp->reply;
+ prev = trav;
+ while (trav) {
+ trav = trav->nextentry;
+ GF_FREE (prev);
+ prev = trav;
}
- bound_xl = (xlator_t *) (conn->bound_xl);
-
- if (bound_xl) {
- /* trans will have ref_count = 1 after this call, but its
- ok since this function is called in
- GF_EVENT_TRANSPORT_CLEANUP */
- frame = create_frame (this, this->ctx->pool);
-
- pthread_mutex_lock (&(conn->lock));
- {
- if (conn->ltable) {
- ltable = conn->ltable;
- conn->ltable = NULL;
- }
- }
- pthread_mutex_unlock (&conn->lock);
-
- INIT_LIST_HEAD (&file_lockers);
- INIT_LIST_HEAD (&dir_lockers);
-
- LOCK (&ltable->lock);
- {
- list_splice_init (&ltable->file_lockers,
- &file_lockers);
-
- list_splice_init (&ltable->dir_lockers, &dir_lockers);
- }
- UNLOCK (&ltable->lock);
- free (ltable);
-
- flock.l_type = F_UNLCK;
- flock.l_start = 0;
- flock.l_len = 0;
- list_for_each_entry_safe (locker,
- tmp, &file_lockers, lockers) {
- tmp_frame = copy_frame (frame);
- /*
- pid = 0 is a special case that tells posix-locks
- to release all locks from this transport
- */
- tmp_frame->root->pid = 0;
- tmp_frame->root->trans = conn;
-
- if (locker->fd) {
- STACK_WIND (tmp_frame, server_nop_cbk,
- bound_xl,
- bound_xl->fops->finodelk,
- locker->volume,
- locker->fd, F_SETLK, &flock);
- fd_unref (locker->fd);
- } else {
- STACK_WIND (tmp_frame, server_nop_cbk,
- bound_xl,
- bound_xl->fops->inodelk,
- locker->volume,
- &(locker->loc), F_SETLK, &flock);
- loc_wipe (&locker->loc);
- }
-
- free (locker->volume);
-
- list_del_init (&locker->lockers);
- free (locker);
- }
-
- tmp = NULL;
- locker = NULL;
- list_for_each_entry_safe (locker, tmp, &dir_lockers, lockers) {
- tmp_frame = copy_frame (frame);
-
- tmp_frame->root->pid = 0;
- tmp_frame->root->trans = conn;
-
- if (locker->fd) {
- STACK_WIND (tmp_frame, server_nop_cbk,
- bound_xl,
- bound_xl->fops->fentrylk,
- locker->volume,
- locker->fd, NULL,
- ENTRYLK_UNLOCK, ENTRYLK_WRLCK);
- fd_unref (locker->fd);
- } else {
- STACK_WIND (tmp_frame, server_nop_cbk,
- bound_xl,
- bound_xl->fops->entrylk,
- locker->volume,
- &(locker->loc), NULL,
- ENTRYLK_UNLOCK, ENTRYLK_WRLCK);
- loc_wipe (&locker->loc);
- }
-
- free (locker->volume);
-
- list_del_init (&locker->lockers);
- free (locker);
- }
-
- state = CALL_STATE (frame);
- if (state)
- free (state);
- STACK_DESTROY (frame->root);
-
- pthread_mutex_lock (&(conn->lock));
- {
- if (conn->fdtable) {
- fdentries = gf_fd_fdtable_get_all_fds (conn->fdtable,
- &fd_count);
- gf_fd_fdtable_destroy (conn->fdtable);
- conn->fdtable = NULL;
- }
- }
- pthread_mutex_unlock (&conn->lock);
-
- if (fdentries != NULL) {
- for (i = 0; i < fd_count; i++) {
- fd = fdentries[i].fd;
- if (fd != NULL) {
- tmp_frame = copy_frame (frame);
- tmp_frame->local = fd;
-
- STACK_WIND (tmp_frame,
- server_connection_cleanup_flush_cbk,
- bound_xl,
- bound_xl->fops->flush,
- fd);
- }
+ return 0;
+}
+
+
+int
+readdirp_rsp_cleanup (gfs3_readdirp_rsp *rsp)
+{
+ gfs3_dirplist *prev = NULL;
+ gfs3_dirplist *trav = NULL;
+
+ trav = rsp->reply;
+ prev = trav;
+ while (trav) {
+ trav = trav->nextentry;
+ GF_FREE (prev->dict.dict_val);
+ GF_FREE (prev);
+ prev = trav;
+ }
+
+ return 0;
+}
+
+
+int
+gf_server_check_getxattr_cmd (call_frame_t *frame, const char *key)
+{
+
+ server_conf_t *conf = NULL;
+ rpc_transport_t *xprt = NULL;
+
+ conf = frame->this->private;
+ if (!conf)
+ return 0;
+
+ if (fnmatch ("*list*mount*point*", key, 0) == 0) {
+ /* list all the client protocol connecting to this process */
+ pthread_mutex_lock (&conf->mutex);
+ {
+ list_for_each_entry (xprt, &conf->xprt_list, list) {
+ gf_log ("mount-point-list", GF_LOG_INFO,
+ "%s", xprt->peerinfo.identifier);
}
- FREE (fdentries);
}
- }
+ pthread_mutex_unlock (&conf->mutex);
+ }
+
+ /* Add more options/keys here */
- gf_log (this->name, GF_LOG_INFO, "destroyed connection of %s",
- conn->id);
+ return 0;
+}
- FREE (conn->id);
- FREE (conn);
-out:
- return ret;
+int
+gf_server_check_setxattr_cmd (call_frame_t *frame, dict_t *dict)
+{
+
+ server_conf_t *conf = NULL;
+ rpc_transport_t *xprt = NULL;
+ uint64_t total_read = 0;
+ uint64_t total_write = 0;
+
+ conf = frame->this->private;
+ if (!conf || !dict)
+ return 0;
+
+ if (dict_foreach_fnmatch (dict, "*io*stat*dump",
+ dict_null_foreach_fn, NULL ) > 0) {
+ list_for_each_entry (xprt, &conf->xprt_list, list) {
+ total_read += xprt->total_bytes_read;
+ total_write += xprt->total_bytes_write;
+ }
+ gf_log ("stats", GF_LOG_INFO,
+ "total-read %"PRIu64", total-write %"PRIu64,
+ total_read, total_write);
+ }
+
+ return 0;
}
-server_connection_t *
-server_connection_get (xlator_t *this, const char *id)
+gf_boolean_t
+server_cancel_grace_timer (xlator_t *this, client_t *client)
{
- server_connection_t *conn = NULL;
- server_connection_t *trav = NULL;
- server_conf_t *conf = NULL;
+ server_ctx_t *serv_ctx = NULL;
+ gf_timer_t *timer = NULL;
+ gf_boolean_t cancelled = _gf_false;
+
+ if (!this || !client) {
+ gf_log (THIS->name, GF_LOG_ERROR,
+ "Invalid arguments to cancel connection timer");
+ return cancelled;
+ }
+
+ serv_ctx = server_ctx_get (client, client->this);
+
+ if (serv_ctx == NULL) {
+ gf_log (this->name, GF_LOG_INFO, "server_ctx_get() failed");
+ goto out;
+ }
+
+ LOCK (&serv_ctx->fdtable_lock);
+ {
+ if (serv_ctx->grace_timer) {
+ timer = serv_ctx->grace_timer;
+ serv_ctx->grace_timer = NULL;
+ }
+ }
+ UNLOCK (&serv_ctx->fdtable_lock);
+
+ if (timer) {
+ gf_timer_call_cancel (this->ctx, timer);
+ cancelled = _gf_true;
+ }
+out:
+ return cancelled;
+}
+
+server_ctx_t*
+server_ctx_get (client_t *client, xlator_t *xlator)
+{
+ void *tmp = NULL;
+ server_ctx_t *ctx = NULL;
+
+ client_ctx_get (client, xlator, &tmp);
- conf = this->private;
+ ctx = tmp;
- pthread_mutex_lock (&conf->mutex);
- {
- list_for_each_entry (trav, &conf->conns, list) {
- if (!strcmp (id, trav->id)) {
- conn = trav;
- break;
- }
- }
+ if (ctx != NULL)
+ goto out;
+
+ ctx = GF_CALLOC (1, sizeof (server_ctx_t), gf_server_mt_server_conf_t);
+
+ if (ctx == NULL)
+ goto out;
- if (!conn) {
- conn = (void *) CALLOC (1, sizeof (*conn));
+ /* ctx->lk_version = 0; redundant */
+ ctx->fdtable = gf_fd_fdtable_alloc ();
+
+ if (ctx->fdtable == NULL) {
+ GF_FREE (ctx);
+ ctx = NULL;
+ goto out;
+ }
- conn->id = strdup (id);
- conn->fdtable = gf_fd_fdtable_alloc ();
- conn->ltable = gf_lock_table_new ();
+ LOCK_INIT (&ctx->fdtable_lock);
- pthread_mutex_init (&conn->lock, NULL);
+ if (client_ctx_set (client, xlator, ctx) != 0) {
+ LOCK_DESTROY (&ctx->fdtable_lock);
+ GF_FREE (ctx);
+ ctx = NULL;
+ }
+
+out:
+ return ctx;
+}
+
+int32_t
+gf_barrier_transmit (server_conf_t *conf, gf_barrier_payload_t *payload)
+{
+ gf_barrier_t *barrier = NULL;
+ int32_t ret = -1;
+ client_t *client = NULL;
+ gf_boolean_t lk_heal = _gf_false;
+ call_frame_t *frame = NULL;
+ server_state_t *state = NULL;
+
+ GF_VALIDATE_OR_GOTO ("barrier", conf, out);
+ GF_VALIDATE_OR_GOTO ("barrier", conf->barrier, out);
+ GF_VALIDATE_OR_GOTO ("barrier", payload, out);
+
+ barrier = conf->barrier;
+
+ frame = payload->frame;
+ if (frame) {
+ state = CALL_STATE (frame);
+ frame->local = NULL;
+ client = frame->root->client;
+ }
+ /* currently lk fops are not barrier'ed. This is reflecting code in
+ * server_submit_reply */
+ if (client)
+ lk_heal = ((server_conf_t *) client->this->private)->lk_heal;
+
+ ret = rpcsvc_submit_generic (payload->req, &payload->rsp, 1,
+ payload->payload, payload->payload_count,
+ payload->iobref);
+ iobuf_unref (payload->iob);
+ if (ret == -1) {
+ gf_log_callingfn ("", GF_LOG_ERROR, "Reply submission failed");
+ if (frame && client && !lk_heal) {
+ server_connection_cleanup (frame->this, client,
+ INTERNAL_LOCKS | POSIX_LOCKS);
+ } else {
+ /* TODO: Failure of open(dir), create, inodelk, entrylk
+ or lk fops send failure must be handled specially. */
+ }
+ goto ret;
+ }
- list_add (&conn->list, &conf->conns);
- }
+ ret = 0;
+ret:
+ if (state) {
+ free_state (state);
+ }
- conn->ref++;
- conn->active_transports++;
- }
- pthread_mutex_unlock (&conf->mutex);
+ if (frame) {
+ gf_client_unref (client);
+ STACK_DESTROY (frame->root);
+ }
- return conn;
+ if (payload->free_iobref) {
+ iobref_unref (payload->iobref);
+ }
+out:
+ return ret;
}
+gf_barrier_payload_t *
+gf_barrier_dequeue (gf_barrier_t *barrier)
+{
+ gf_barrier_payload_t *payload = NULL;
+
+ if (!barrier || list_empty (&barrier->queue))
+ return NULL;
+
+ payload = list_entry (barrier->queue.next,
+ gf_barrier_payload_t, list);
+ if (payload) {
+ list_del_init (&payload->list);
+ barrier->cur_size--;
+ }
+
+ return payload;
+}
+
+
+void*
+gf_barrier_dequeue_start (void *data)
+{
+ server_conf_t *conf = NULL;
+ gf_barrier_t *barrier = NULL;
+ gf_barrier_payload_t *payload = NULL;
+
+ conf = (server_conf_t *)data;
+ if (!conf || !conf->barrier)
+ return NULL;
+ barrier = conf->barrier;
+
+ LOCK (&barrier->lock);
+ {
+ while (barrier->cur_size) {
+ payload = gf_barrier_dequeue (barrier);
+ if (payload) {
+ if (gf_barrier_transmit (conf, payload)) {
+ gf_log ("server", GF_LOG_WARNING,
+ "Failed to transmit");
+ }
+ GF_FREE (payload);
+ }
+ }
+ }
+ UNLOCK (&barrier->lock);
+ return NULL;
+}
void
-server_connection_put (xlator_t *this, server_connection_t *conn)
+gf_barrier_timeout (void *data)
{
- server_conf_t *conf = NULL;
- server_connection_t *todel = NULL;
+ server_conf_t *conf = NULL;
+ gf_barrier_t *barrier = NULL;
+ gf_boolean_t need_dequeue = _gf_false;
- if (conn == NULL) {
+ conf = (server_conf_t *)data;
+ if (!conf || !conf->barrier)
goto out;
+ barrier = conf->barrier;
+
+ gf_log ("", GF_LOG_INFO, "barrier timed-out");
+ LOCK (&barrier->lock);
+ {
+ need_dequeue = barrier->on;
+ barrier->on = _gf_false;
+ }
+ UNLOCK (&barrier->lock);
+
+ if (need_dequeue == _gf_true)
+ gf_barrier_dequeue_start (data);
+out:
+ return;
+}
+
+
+int32_t
+gf_barrier_start (xlator_t *this)
+{
+ server_conf_t *conf = NULL;
+ gf_barrier_t *barrier = NULL;
+ int32_t ret = -1;
+ struct timespec time = {0,};
+
+ conf = this->private;
+
+ GF_VALIDATE_OR_GOTO ("server", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, conf, out);
+ GF_VALIDATE_OR_GOTO (this->name, conf->barrier, out);
+
+ barrier = conf->barrier;
+
+ gf_log (this->name, GF_LOG_INFO, "barrier start called");
+ LOCK (&barrier->lock);
+ {
+ /* if barrier is on, reset timer */
+ if (barrier->on == _gf_true) {
+ ret = gf_timer_call_cancel (this->ctx, barrier->timer);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR, "Failed to "
+ "unset timer, failing barrier start");
+ goto unlock;
+ }
+ }
+
+ barrier->on = _gf_true;
+ time.tv_sec = barrier->time_out;
+ time.tv_nsec = 0;
+
+ barrier->timer = gf_timer_call_after (this->ctx, time,
+ gf_barrier_timeout,
+ (void *)conf);
+ if (!barrier->timer) {
+ gf_log (this->name, GF_LOG_ERROR, "Failed to set "
+ "timer, failing barrier start");
+ barrier->on = _gf_false;
+ }
}
+unlock:
+ UNLOCK (&barrier->lock);
+
+ ret = 0;
+out:
+ return ret;
+}
- conf = this->private;
+int32_t
+gf_barrier_stop (xlator_t *this)
+{
+ server_conf_t *conf = NULL;
+ gf_barrier_t *barrier = NULL;
+ int32_t ret = -1;
+ gf_boolean_t need_dequeue = _gf_false;
- pthread_mutex_lock (&conf->mutex);
- {
- conn->ref--;
+ conf = this->private;
- if (!conn->ref) {
- list_del_init (&conn->list);
- todel = conn;
- }
- }
- pthread_mutex_unlock (&conf->mutex);
+ GF_VALIDATE_OR_GOTO ("server", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, conf, out);
+ GF_VALIDATE_OR_GOTO (this->name, conf->barrier, out);
- if (todel) {
- server_connection_destroy (this, todel);
- }
+ barrier = conf->barrier;
+ gf_log (this->name, GF_LOG_INFO, "barrier stop called");
+ LOCK (&barrier->lock);
+ {
+ need_dequeue = barrier->on;
+ barrier->on = _gf_false;
+ }
+ UNLOCK (&barrier->lock);
+
+ if (need_dequeue == _gf_true) {
+ gf_timer_call_cancel (this->ctx, barrier->timer);
+ ret = gf_thread_create (&conf->barrier_th, NULL,
+ gf_barrier_dequeue_start,
+ conf);
+ if (ret) {
+ gf_log (this->name, GF_LOG_CRITICAL,
+ "Failed to start un-barriering");
+ goto out;
+ }
+ }
+ ret = 0;
out:
- return;
+ return ret;
+}
+
+int32_t
+gf_barrier_fops_configure (xlator_t *this, gf_barrier_t *barrier, char *str)
+{
+ int32_t ret = -1;
+ char *dup_str = NULL;
+ char *str_tok = NULL;
+ char *save_ptr = NULL;
+ uint64_t fops = 0;
+
+ /* by defaul fsync & flush needs to be barriered */
+
+ fops |= 1 << GFS3_OP_FSYNC;
+ fops |= 1 << GFS3_OP_FLUSH;
+
+ if (!str)
+ goto done;
+
+ dup_str = gf_strdup (str);
+ if (!dup_str)
+ goto done;
+
+ str_tok = strtok_r (dup_str, ",", &save_ptr);
+ if (!str_tok)
+ goto done;
+
+ fops = 0;
+ while (str_tok) {
+ if (!strcmp(str_tok, "writev")) {
+ fops |= ((uint64_t)1 << GFS3_OP_WRITE);
+ } else if (!strcmp(str_tok, "fsync")) {
+ fops |= ((uint64_t)1 << GFS3_OP_FSYNC);
+ } else if (!strcmp(str_tok, "read")) {
+ fops |= ((uint64_t)1 << GFS3_OP_READ);
+ } else if (!strcmp(str_tok, "rename")) {
+ fops |= ((uint64_t)1 << GFS3_OP_RENAME);
+ } else if (!strcmp(str_tok, "flush")) {
+ fops |= ((uint64_t)1 << GFS3_OP_FLUSH);
+ } else if (!strcmp(str_tok, "ftruncate")) {
+ fops |= ((uint64_t)1 << GFS3_OP_FTRUNCATE);
+ } else if (!strcmp(str_tok, "fallocate")) {
+ fops |= ((uint64_t)1 << GFS3_OP_FALLOCATE);
+ } else if (!strcmp(str_tok, "rmdir")) {
+ fops |= ((uint64_t)1 << GFS3_OP_RMDIR);
+ } else {
+ gf_log ("barrier", GF_LOG_ERROR,
+ "Invalid barrier fop %s", str_tok);
+ }
+
+ str_tok = strtok_r (NULL, ",", &save_ptr);
+ }
+done:
+ LOCK (&barrier->lock);
+ {
+ barrier->fops = fops;
+ }
+ UNLOCK (&barrier->lock);
+ ret = 0;
+
+ GF_FREE (dup_str);
+ return ret;
+}
+
+void
+gf_barrier_enqueue (gf_barrier_t *barrier, gf_barrier_payload_t *payload)
+{
+ list_add_tail (&payload->list, &barrier->queue);
+ barrier->cur_size++;
+}
+
+gf_barrier_payload_t *
+gf_barrier_payload (rpcsvc_request_t *req, struct iovec *rsp,
+ call_frame_t *frame, struct iovec *payload_orig,
+ int payloadcount, struct iobref *iobref,
+ struct iobuf *iob, gf_boolean_t free_iobref)
+{
+ gf_barrier_payload_t *payload = NULL;
+
+ if (!rsp)
+ return NULL;
+
+ payload = GF_CALLOC (1, sizeof (*payload),1);
+ if (!payload)
+ return NULL;
+
+ INIT_LIST_HEAD (&payload->list);
+
+ payload->req = req;
+ memcpy (&payload->rsp, rsp, sizeof (struct iovec));
+ payload->frame = frame;
+ payload->payload = payload_orig;
+ payload->payload_count = payloadcount;
+ payload->iobref = iobref;
+ payload->iob = iob;
+ payload->free_iobref = free_iobref;
+
+ return payload;
}
diff --git a/xlators/protocol/server/src/server-helpers.h b/xlators/protocol/server/src/server-helpers.h
index 48f5f4a6d..b455aa6df 100644
--- a/xlators/protocol/server/src/server-helpers.h
+++ b/xlators/protocol/server/src/server-helpers.h
@@ -1,77 +1,74 @@
/*
- Copyright (c) 2006-2009 Z RESEARCH, Inc. <http://www.zresearch.com>
+ Copyright (c) 2010-2013 Red Hat, Inc. <http://www.redhat.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/>.
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
*/
-#ifndef __SERVER_HELPERS_H__
-#define __SERVER_HELPERS_H__
-
-#define CALL_STATE(frame) ((server_state_t *)frame->root->state)
+#ifndef _SERVER_HELPERS_H
+#define _SERVER_HELPERS_H
-#define BOUND_XL(frame) ((xlator_t *) CALL_STATE(frame)->bound_xl)
+#include "server.h"
-#define TRANSPORT_FROM_FRAME(frame) ((transport_t *) CALL_STATE(frame)->trans)
+#define CALL_STATE(frame) ((server_state_t *)frame->root->state)
-#define SERVER_CONNECTION(frame) \
- ((server_connection_t *) TRANSPORT_FROM_FRAME(frame)->xl_private)
+#define XPRT_FROM_FRAME(frame) ((rpc_transport_t *) CALL_STATE(frame)->xprt)
-#define SERVER_CONF(frame) \
- ((server_conf_t *)TRANSPORT_FROM_FRAME(frame)->xl->private)
+#define SERVER_CONF(frame) \
+ ((server_conf_t *)XPRT_FROM_FRAME(frame)->this->private)
-#define TRANSPORT_FROM_XLATOR(this) ((((server_conf_t *)this->private))->trans)
+#define XPRT_FROM_XLATOR(this) ((((server_conf_t *)this->private))->listen)
-#define INODE_LRU_LIMIT(this) \
- (((server_conf_t *)(this->private))->inode_lru_limit)
+#define INODE_LRU_LIMIT(this) \
+ (((server_conf_t *)(this->private))->config.inode_lru_limit)
#define IS_ROOT_INODE(inode) (inode == inode->table->root)
#define IS_NOT_ROOT(pathlen) ((pathlen > 2)? 1 : 0)
-int32_t
-server_loc_fill (loc_t *loc,
- server_state_t *state,
- ino_t ino,
- ino_t par,
- const char *name,
- const char *path);
-
-char *
-stat_to_str (struct stat *stbuf);
+#define is_fop_barriered(fops, procnum) (fops & ((uint64_t)1 << procnum))
-call_frame_t *
-server_copy_frame (call_frame_t *frame);
+#define barrier_add_to_queue(barrier) (barrier->on || barrier->cur_size)
void free_state (server_state_t *state);
void server_loc_wipe (loc_t *loc);
-int32_t
-gf_add_locker (struct _lock_table *table, const char *volume,
- loc_t *loc,
- fd_t *fd,
- pid_t pid);
+void
+server_print_request (call_frame_t *frame);
+
+call_frame_t *
+get_frame_from_request (rpcsvc_request_t *req);
+
+int
+server_connection_cleanup (xlator_t *this, struct _client_t *client,
+ int32_t flags);
+
+gf_boolean_t
+server_cancel_grace_timer (xlator_t *this, struct _client_t *client);
+
+int
+server_build_config (xlator_t *this, server_conf_t *conf);
+
+int serialize_rsp_dirent (gf_dirent_t *entries, gfs3_readdir_rsp *rsp);
+int serialize_rsp_direntp (gf_dirent_t *entries, gfs3_readdirp_rsp *rsp);
+int readdirp_rsp_cleanup (gfs3_readdirp_rsp *rsp);
+int readdir_rsp_cleanup (gfs3_readdir_rsp *rsp);
-int32_t
-gf_del_locker (struct _lock_table *table, const char *volume,
- loc_t *loc,
- fd_t *fd,
- pid_t pid);
+server_ctx_t *server_ctx_get (client_t *client, xlator_t *xlator);
-int32_t
-gf_direntry_to_bin (dir_entry_t *head, char *bufferp);
+int32_t gf_barrier_start (xlator_t *this);
+int32_t gf_barrier_stop (xlator_t *this);
+int32_t gf_barrier_fops_configure (xlator_t *this, gf_barrier_t *barrier,
+ char *str);
+void gf_barrier_enqueue (gf_barrier_t *barrier, gf_barrier_payload_t *stub);
+gf_barrier_payload_t *
+gf_barrier_payload (rpcsvc_request_t *req, struct iovec *rsp,
+ call_frame_t *frame, struct iovec *payload,
+ int payloadcount, struct iobref *iobref,
+ struct iobuf *iob, gf_boolean_t free_iobref);
-#endif /* __SERVER_HELPERS_H__ */
+#endif /* !_SERVER_HELPERS_H */
diff --git a/xlators/protocol/server/src/server-mem-types.h b/xlators/protocol/server/src/server-mem-types.h
new file mode 100644
index 000000000..19c3466d3
--- /dev/null
+++ b/xlators/protocol/server/src/server-mem-types.h
@@ -0,0 +1,30 @@
+/*
+ Copyright (c) 2010-2013 Red Hat, Inc. <http://www.redhat.com>
+ This file is part of GlusterFS.
+
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
+*/
+
+
+#ifndef __SERVER_MEM_TYPES_H__
+#define __SERVER_MEM_TYPES_H__
+
+#include "mem-types.h"
+
+enum gf_server_mem_types_ {
+ gf_server_mt_server_conf_t = gf_common_mt_end + 1,
+ gf_server_mt_resolv_comp_t,
+ gf_server_mt_state_t,
+ gf_server_mt_locker_t,
+ gf_server_mt_lock_table_t,
+ gf_server_mt_conn_t,
+ gf_server_mt_dirent_rsp_t,
+ gf_server_mt_rsp_buf_t,
+ gf_server_mt_volfile_ctx_t,
+ gf_server_mt_timer_data_t,
+ gf_server_mt_end,
+};
+#endif /* __SERVER_MEM_TYPES_H__ */
diff --git a/xlators/protocol/server/src/server-protocol.c b/xlators/protocol/server/src/server-protocol.c
deleted file mode 100644
index 56c65bec7..000000000
--- a/xlators/protocol/server/src/server-protocol.c
+++ /dev/null
@@ -1,7898 +0,0 @@
-/*
- Copyright (c) 2006-2009 Z RESEARCH, Inc. <http://www.zresearch.com>
- This file is part of GlusterFS.
-
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
-*/
-
-
-#ifndef _CONFIG_H
-#define _CONFIG_H
-#include "config.h"
-#endif
-#include <time.h>
-#include <sys/uio.h>
-#include <sys/resource.h>
-
-#include <libgen.h>
-
-#include "transport.h"
-#include "fnmatch.h"
-#include "xlator.h"
-#include "protocol.h"
-#include "server-protocol.h"
-#include "server-helpers.h"
-#include "call-stub.h"
-#include "defaults.h"
-#include "list.h"
-#include "dict.h"
-#include "compat.h"
-#include "compat-errno.h"
-#include "statedump.h"
-#include "md5.h"
-
-static void
-protocol_server_reply (call_frame_t *frame, int type, int op,
- gf_hdr_common_t *hdr, size_t hdrlen,
- struct iovec *vector, int count,
- struct iobref *iobref)
-{
- server_state_t *state = NULL;
- xlator_t *bound_xl = NULL;
- transport_t *trans = NULL;
- int ret = 0;
-
- bound_xl = BOUND_XL (frame);
- state = CALL_STATE (frame);
- trans = state->trans;
-
- hdr->callid = hton64 (frame->root->unique);
- hdr->type = hton32 (type);
- hdr->op = hton32 (op);
-
- ret = transport_submit (trans, (char *)hdr, hdrlen, vector,
- count, iobref);
- if (ret < 0) {
- gf_log ("protocol/server", GF_LOG_ERROR,
- "frame %"PRId64": failed to submit. op= %d, type= %d",
- frame->root->unique, op, type);
- }
-
- STACK_DESTROY (frame->root);
-
- if (state)
- free_state (state);
-
-}
-
-
-/*
- * server_setdents_cbk - writedir callback for server protocol
- * @frame: call frame
- * @cookie:
- * @this:
- * @op_ret: return value
- * @op_errno: errno
- *
- * not for external reference
- */
-int
-server_setdents_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno)
-{
- gf_hdr_common_t *hdr = NULL;
- gf_fop_setdents_rsp_t *rsp = NULL;
- size_t hdrlen = 0;
- int32_t gf_errno = 0;
-
- hdrlen = gf_hdr_len (rsp, 0);
- hdr = gf_hdr_new (rsp, 0);
- rsp = gf_param (hdr);
-
- hdr->rsp.op_ret = hton32 (op_ret);
- gf_errno = gf_errno_to_error (op_errno);
- hdr->rsp.op_errno = hton32 (gf_errno);
-
- protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_FOP_SETDENTS,
- hdr, hdrlen, NULL, 0, NULL);
-
- return 0;
-}
-
-/*
- * server_lk_cbk - lk callback for server protocol
- * @frame: call frame
- * @cookie:
- * @this:
- * @op_ret:
- * @op_errno:
- * @lock:
- *
- * not for external reference
- */
-int
-server_lk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct flock *lock)
-{
- gf_hdr_common_t *hdr = NULL;
- gf_fop_lk_rsp_t *rsp = NULL;
- size_t hdrlen = 0;
- int32_t gf_errno = 0;
- server_state_t *state = NULL;
-
- hdrlen = gf_hdr_len (rsp, 0);
- hdr = gf_hdr_new (rsp, 0);
- rsp = gf_param (hdr);
-
- hdr->rsp.op_ret = hton32 (op_ret);
- gf_errno = gf_errno_to_error (op_errno);
- hdr->rsp.op_errno = hton32 (gf_errno);
-
- if (op_ret == 0) {
- gf_flock_from_flock (&rsp->flock, lock);
- } else if (op_errno != ENOSYS) {
- state = CALL_STATE(frame);
-
- gf_log (this->name, GF_LOG_TRACE,
- "%"PRId64": LK %"PRId64" (%"PRId64") ==> %"PRId32" (%s)",
- frame->root->unique, state->fd_no,
- state->fd ? state->fd->inode->ino : 0, op_ret,
- strerror (op_errno));
- }
-
- protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_FOP_LK,
- hdr, hdrlen, NULL, 0, NULL);
-
- return 0;
-}
-
-
-int
-server_inodelk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno)
-{
- server_connection_t *conn = NULL;
- gf_hdr_common_t *hdr = NULL;
- gf_fop_inodelk_rsp_t *rsp = NULL;
- server_state_t *state = NULL;
- size_t hdrlen = 0;
- int32_t gf_errno = 0;
-
- conn = SERVER_CONNECTION(frame);
-
- state = CALL_STATE(frame);
-
- hdrlen = gf_hdr_len (rsp, 0);
- hdr = gf_hdr_new (rsp, 0);
- rsp = gf_param (hdr);
-
- hdr->rsp.op_ret = hton32 (op_ret);
- gf_errno = gf_errno_to_error (op_errno);
- hdr->rsp.op_errno = hton32 (gf_errno);
-
- if (op_ret >= 0) {
- if (state->flock.l_type == F_UNLCK)
- gf_del_locker (conn->ltable, state->volume,
- &state->loc, NULL, frame->root->pid);
- else
- gf_add_locker (conn->ltable, state->volume,
- &state->loc, NULL, frame->root->pid);
- } else if (op_errno != ENOSYS) {
- gf_log (this->name, GF_LOG_TRACE,
- "%"PRId64": INODELK %s (%"PRId64") ==> %"PRId32" (%s)",
- frame->root->unique, state->loc.path,
- state->loc.inode ? state->loc.inode->ino : 0, op_ret,
- strerror (op_errno));
- }
-
- server_loc_wipe (&state->loc);
-
- protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_FOP_INODELK,
- hdr, hdrlen, NULL, 0, NULL);
-
- return 0;
-}
-
-
-int
-server_finodelk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno)
-{
- server_connection_t *conn = NULL;
- gf_hdr_common_t *hdr = NULL;
- gf_fop_finodelk_rsp_t *rsp = NULL;
- server_state_t *state = NULL;
- size_t hdrlen = 0;
- int32_t gf_errno = 0;
-
- conn = SERVER_CONNECTION(frame);
-
- hdrlen = gf_hdr_len (rsp, 0);
- hdr = gf_hdr_new (rsp, 0);
- rsp = gf_param (hdr);
-
- hdr->rsp.op_ret = hton32 (op_ret);
- gf_errno = gf_errno_to_error (op_errno);
- hdr->rsp.op_errno = hton32 (gf_errno);
-
- state = CALL_STATE(frame);
-
- if (op_ret >= 0) {
- if (state->flock.l_type == F_UNLCK)
- gf_del_locker (conn->ltable, state->volume,
- NULL, state->fd,
- frame->root->pid);
- else
- gf_add_locker (conn->ltable, state->volume,
- NULL, state->fd,
- frame->root->pid);
- } else if (op_errno != ENOSYS) {
- gf_log (this->name, GF_LOG_TRACE,
- "%"PRId64": FINODELK %"PRId64" (%"PRId64") ==> %"PRId32" (%s)",
- frame->root->unique, state->fd_no,
- state->fd ? state->fd->inode->ino : 0, op_ret,
- strerror (op_errno));
- }
-
- protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_FOP_FINODELK,
- hdr, hdrlen, NULL, 0, NULL);
-
- return 0;
-}
-
-
-/*
- * server_entrylk_cbk -
- * @frame: call frame
- * @cookie:
- * @this:
- * @op_ret:
- * @op_errno:
- * @lock:
- *
- * not for external reference
- */
-int
-server_entrylk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno)
-{
- server_connection_t *conn = NULL;
- gf_hdr_common_t *hdr = NULL;
- gf_fop_entrylk_rsp_t *rsp = NULL;
- server_state_t *state = NULL;
- size_t hdrlen = 0;
- int32_t gf_errno = 0;
-
- conn = SERVER_CONNECTION(frame);
-
- state = CALL_STATE(frame);
-
- hdrlen = gf_hdr_len (rsp, 0);
- hdr = gf_hdr_new (rsp, 0);
- rsp = gf_param (hdr);
-
- hdr->rsp.op_ret = hton32 (op_ret);
- gf_errno = gf_errno_to_error (op_errno);
- hdr->rsp.op_errno = hton32 (gf_errno);
-
- if (op_ret >= 0) {
- if (state->cmd == ENTRYLK_UNLOCK)
- gf_del_locker (conn->ltable, state->volume,
- &state->loc, NULL, frame->root->pid);
- else
- gf_add_locker (conn->ltable, state->volume,
- &state->loc, NULL, frame->root->pid);
- } else if (op_errno != ENOSYS) {
- gf_log (this->name, GF_LOG_TRACE,
- "%"PRId64": INODELK %s (%"PRId64") ==> %"PRId32" (%s)",
- frame->root->unique, state->loc.path,
- state->loc.inode ? state->loc.inode->ino : 0, op_ret,
- strerror (op_errno));
- }
-
- server_loc_wipe (&state->loc);
-
- protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_FOP_ENTRYLK,
- hdr, hdrlen, NULL, 0, NULL);
-
- return 0;
-}
-
-
-int
-server_fentrylk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno)
-{
- server_connection_t *conn = NULL;
- gf_hdr_common_t *hdr = NULL;
- gf_fop_fentrylk_rsp_t *rsp = NULL;
- server_state_t *state = NULL;
- size_t hdrlen = 0;
- int32_t gf_errno = 0;
-
- conn = SERVER_CONNECTION(frame);
-
- hdrlen = gf_hdr_len (rsp, 0);
- hdr = gf_hdr_new (rsp, 0);
- rsp = gf_param (hdr);
-
- hdr->rsp.op_ret = hton32 (op_ret);
- gf_errno = gf_errno_to_error (op_errno);
- hdr->rsp.op_errno = hton32 (gf_errno);
-
- if (op_ret >= 0) {
- state = CALL_STATE(frame);
- if (state->cmd == ENTRYLK_UNLOCK)
- gf_del_locker (conn->ltable, state->volume,
- NULL, state->fd, frame->root->pid);
- else
- gf_add_locker (conn->ltable, state->volume,
- NULL, state->fd, frame->root->pid);
- } else if (op_errno != ENOSYS) {
- gf_log (this->name, GF_LOG_TRACE,
- "%"PRId64": FENTRYLK %"PRId64" (%"PRId64") ==> %"PRId32" (%s)",
- frame->root->unique, state->fd_no,
- state->fd ? state->fd->inode->ino : 0, op_ret,
- strerror (op_errno));
- }
-
- protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_FOP_FENTRYLK,
- hdr, hdrlen, NULL, 0, NULL);
-
- return 0;
-}
-
-
-/*
- * server_access_cbk - access callback for server protocol
- * @frame: call frame
- * @cookie:
- * @this:
- * @op_ret:
- * @op_errno:
- *
- * not for external reference
- */
-int
-server_access_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno)
-{
- gf_hdr_common_t *hdr = NULL;
- gf_fop_access_rsp_t *rsp = NULL;
- server_state_t *state = NULL;
- size_t hdrlen = 0;
- int32_t gf_errno = 0;
-
- state = CALL_STATE(frame);
-
- hdrlen = gf_hdr_len (rsp, 0);
- hdr = gf_hdr_new (rsp, 0);
- rsp = gf_param (hdr);
-
- hdr->rsp.op_ret = hton32 (op_ret);
- gf_errno = gf_errno_to_error (op_errno);
- hdr->rsp.op_errno = hton32 (gf_errno);
-
- server_loc_wipe (&(state->loc));
-
- protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_FOP_ACCESS,
- hdr, hdrlen, NULL, 0, NULL);
-
- return 0;
-}
-
-/*
- * server_rmdir_cbk - rmdir callback for server protocol
- * @frame: call frame
- * @cookie:
- * @this:
- * @op_ret:
- * @op_errno:
- *
- * not for external reference
- */
-int
-server_rmdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct stat *preparent,
- struct stat *postparent)
-{
- gf_hdr_common_t *hdr = NULL;
- gf_fop_rmdir_rsp_t *rsp = NULL;
- server_state_t *state = NULL;
- int32_t gf_errno = 0;
- size_t hdrlen = 0;
-
- state = CALL_STATE(frame);
-
- if (op_ret == 0) {
- inode_unlink (state->loc.inode, state->loc.parent,
- state->loc.name);
- inode_forget (state->loc.inode, 0);
- } else {
- gf_log (this->name, GF_LOG_TRACE,
- "%"PRId64": RMDIR %s (%"PRId64") ==> %"PRId32" (%s)",
- frame->root->unique, state->loc.path,
- state->loc.inode ? state->loc.inode->ino : 0,
- op_ret, strerror (op_errno));
- }
-
- hdrlen = gf_hdr_len (rsp, 0);
- hdr = gf_hdr_new (rsp, 0);
- rsp = gf_param (hdr);
-
- hdr->rsp.op_ret = hton32 (op_ret);
- gf_errno = gf_errno_to_error (op_errno);
- hdr->rsp.op_errno = hton32 (gf_errno);
-
- if (op_ret == 0) {
- gf_stat_from_stat (&rsp->preparent, preparent);
- gf_stat_from_stat (&rsp->postparent, postparent);
- }
-
- server_loc_wipe (&(state->loc));
-
- protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_FOP_RMDIR,
- hdr, hdrlen, NULL, 0, NULL);
-
- return 0;
-}
-
-/*
- * server_mkdir_cbk - mkdir callback for server protocol
- * @frame: call frame
- * @cookie:
- * @this:
- * @op_ret:
- * @op_errno:
- * @stbuf:
- *
- * not for external reference
- */
-int
-server_mkdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, inode_t *inode,
- struct stat *stbuf, struct stat *preparent,
- struct stat *postparent)
-{
- gf_hdr_common_t *hdr = NULL;
- gf_fop_mkdir_rsp_t *rsp = NULL;
- server_state_t *state = NULL;
- size_t hdrlen = 0;
- int32_t gf_errno = 0;
-
- state = CALL_STATE(frame);
-
- hdrlen = gf_hdr_len (rsp, 0);
- hdr = gf_hdr_new (rsp, 0);
- rsp = gf_param (hdr);
-
- hdr->rsp.op_ret = hton32 (op_ret);
- gf_errno = gf_errno_to_error (op_errno);
- hdr->rsp.op_errno = hton32 (gf_errno);
-
- if (op_ret >= 0) {
- gf_stat_from_stat (&rsp->stat, stbuf);
- inode_link (inode, state->loc.parent, state->loc.name, stbuf);
- inode_lookup (inode);
- } else {
- gf_log (this->name, GF_LOG_TRACE,
- "%"PRId64": MKDIR %s ==> %"PRId32" (%s)",
- frame->root->unique, state->loc.path,
- op_ret, strerror (op_errno));
- }
-
- server_loc_wipe (&(state->loc));
-
- protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_FOP_MKDIR,
- hdr, hdrlen, NULL, 0, NULL);
-
- return 0;
-}
-
-/*
- * server_mknod_cbk - mknod callback for server protocol
- * @frame: call frame
- * @cookie:
- * @this:
- * @op_ret:
- * @op_errno:
- * @stbuf:
- *
- * not for external reference
- */
-int
-server_mknod_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno,
- inode_t *inode, struct stat *stbuf, struct stat *preparent,
- struct stat *postparent)
-{
- gf_hdr_common_t *hdr = NULL;
- gf_fop_mknod_rsp_t *rsp = NULL;
- server_state_t *state = NULL;
- int32_t gf_errno = 0;
- size_t hdrlen = 0;
-
- state = CALL_STATE(frame);
-
- hdrlen = gf_hdr_len (rsp, 0);
- hdr = gf_hdr_new (rsp, 0);
- rsp = gf_param (hdr);
-
- hdr->rsp.op_ret = hton32 (op_ret);
- gf_errno = gf_errno_to_error (op_errno);
- hdr->rsp.op_errno = hton32 (gf_errno);
-
- if (op_ret >= 0) {
- gf_stat_from_stat (&rsp->stat, stbuf);
- inode_link (inode, state->loc.parent, state->loc.name, stbuf);
- inode_lookup (inode);
- } else {
- gf_log (this->name, GF_LOG_TRACE,
- "%"PRId64": MKNOD %s ==> %"PRId32" (%s)",
- frame->root->unique, state->loc.path,
- op_ret, strerror (op_errno));
- }
-
- server_loc_wipe (&(state->loc));
-
- protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_FOP_MKNOD,
- hdr, hdrlen, NULL, 0, NULL);
-
- return 0;
-}
-
-/*
- * server_fsyncdir_cbk - fsyncdir callback for server protocol
- * @frame: call frame
- * @cookie:
- * @this:
- * @op_ret:
- * @op_errno:
- *
- * not for external reference
- */
-int
-server_fsyncdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno)
-{
- gf_hdr_common_t *hdr = NULL;
- gf_fop_fsyncdir_rsp_t *rsp = NULL;
- size_t hdrlen = 0;
- int32_t gf_errno = 0;
- server_state_t *state = NULL;
-
- hdrlen = gf_hdr_len (rsp, 0);
- hdr = gf_hdr_new (rsp, 0);
- rsp = gf_param (hdr);
-
- if (op_ret < 0) {
- state = CALL_STATE(frame);
-
- gf_log (this->name, GF_LOG_TRACE,
- "%"PRId64": FSYNCDIR %"PRId64" (%"PRId64") ==> %"PRId32" (%s)",
- frame->root->unique, state->fd_no,
- state->fd ? state->fd->inode->ino : 0, op_ret,
- strerror (op_errno));
- }
-
- hdr->rsp.op_ret = hton32 (op_ret);
- gf_errno = gf_errno_to_error (op_errno);
- hdr->rsp.op_errno = hton32 (gf_errno);
-
- protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_FOP_FSYNCDIR,
- hdr, hdrlen, NULL, 0, NULL);
-
- return 0;
-}
-
-
-/*
- * server_getdents_cbk - readdir callback for server protocol
- * @frame: call frame
- * @cookie:
- * @this:
- * @op_ret: return value
- * @op_errno: errno
- * @entries:
- * @count:
- *
- * not for external reference
- */
-int
-server_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)
-{
- gf_hdr_common_t *hdr = NULL;
- gf_fop_getdents_rsp_t *rsp = NULL;
- size_t hdrlen = 0;
- int32_t vec_count = 0;
- int32_t gf_errno = 0;
- struct iobref *iobref = NULL;
- struct iobuf *iobuf = NULL;
- size_t buflen = 0;
- struct iovec vector[1];
- server_state_t *state = NULL;
-
- state = CALL_STATE(frame);
-
- if (op_ret >= 0) {
- iobuf = iobuf_get (this->ctx->iobuf_pool);
- if (!iobuf) {
- op_ret = -1;
- op_errno = ENOMEM;
- goto out;
- }
-
- buflen = gf_direntry_to_bin (entries, iobuf->ptr);
- if (buflen < 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "fd - %"PRId64" (%"PRId64"): failed to convert "
- "entries list to string buffer",
- state->fd_no, state->fd->inode->ino);
- op_ret = -1;
- op_errno = EINVAL;
- goto out;
- }
-
- iobref = iobref_new ();
- if (iobref == NULL) {
- gf_log (this->name, GF_LOG_ERROR,
- "fd - %"PRId64" (%"PRId64"): failed to get iobref",
- state->fd_no, state->fd->inode->ino);
- op_ret = -1;
- op_errno = ENOMEM;
- goto out;
- }
-
- iobref_add (iobref, iobuf);
-
- vector[0].iov_base = iobuf->ptr;
- vector[0].iov_len = buflen;
- vec_count = 1;
- } else {
- gf_log (this->name, GF_LOG_TRACE,
- "%"PRId64": GETDENTS %"PRId64" (%"PRId64"): %"PRId32" (%s)",
- frame->root->unique,
- state->fd_no,
- state->fd ? state->fd->inode->ino : 0,
- op_ret, strerror (op_errno));
- vector[0].iov_base = NULL;
- vector[0].iov_len = 0;
- }
-
-out:
- hdrlen = gf_hdr_len (rsp, 0);
- hdr = gf_hdr_new (rsp, 0);
- rsp = gf_param (hdr);
-
- rsp->count = hton32 (count);
-
- hdr->rsp.op_ret = hton32 (op_ret);
- gf_errno = gf_errno_to_error (op_errno);
- hdr->rsp.op_errno = hton32 (gf_errno);
-
- protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_FOP_GETDENTS,
- hdr, hdrlen, vector, vec_count, iobref);
-
- if (iobref)
- iobref_unref (iobref);
- if (iobuf)
- iobuf_unref (iobuf);
-
- return 0;
-}
-
-
-/*
- * server_readdir_cbk - getdents callback for server protocol
- * @frame: call frame
- * @cookie:
- * @this:
- * @op_ret:
- * @op_errno:
- *
- * not for external reference
- */
-int
-server_readdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, gf_dirent_t *entries)
-{
- gf_hdr_common_t *hdr = NULL;
- gf_fop_readdir_rsp_t *rsp = NULL;
- size_t hdrlen = 0;
- size_t buf_size = 0;
- int32_t gf_errno = 0;
- server_state_t *state = NULL;
-
- if (op_ret > 0)
- buf_size = gf_dirent_serialize (entries, NULL, 0);
-
- hdrlen = gf_hdr_len (rsp, buf_size);
- hdr = gf_hdr_new (rsp, buf_size);
- rsp = gf_param (hdr);
-
- hdr->rsp.op_ret = hton32 (op_ret);
- gf_errno = gf_errno_to_error (op_errno);
- hdr->rsp.op_errno = hton32 (gf_errno);
-
- if (op_ret > 0) {
- rsp->size = hton32 (buf_size);
- gf_dirent_serialize (entries, rsp->buf, buf_size);
- } else {
- state = CALL_STATE(frame);
-
- gf_log (this->name, GF_LOG_TRACE,
- "%"PRId64": READDIR %"PRId64" (%"PRId64") ==> %"PRId32" (%s)",
- frame->root->unique, state->fd_no,
- state->fd ? state->fd->inode->ino : 0, op_ret,
- strerror (op_errno));
- }
-
- protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_FOP_READDIR,
- hdr, hdrlen, NULL, 0, NULL);
-
- return 0;
-}
-
-
-/*
- * server_releasedir_cbk - releasedir callback for server protocol
- * @frame: call frame
- * @cookie:
- * @this:
- * @op_ret: return value
- * @op_errno: errno
- *
- * not for external reference
- */
-int
-server_releasedir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno)
-{
- gf_hdr_common_t *hdr = NULL;
- gf_cbk_releasedir_rsp_t *rsp = NULL;
- size_t hdrlen = 0;
- int32_t gf_errno = 0;
-
- hdrlen = gf_hdr_len (rsp, 0);
- hdr = gf_hdr_new (rsp, 0);
- rsp = gf_param (hdr);
-
- hdr->rsp.op_ret = hton32 (op_ret);
- gf_errno = gf_errno_to_error (op_errno);
- hdr->rsp.op_errno = hton32 (gf_errno);
-
- protocol_server_reply (frame, GF_OP_TYPE_CBK_REPLY, GF_CBK_RELEASEDIR,
- hdr, hdrlen, NULL, 0, NULL);
-
- return 0;
-}
-
-
-/*
- * server_opendir_cbk - opendir callback for server protocol
- * @frame: call frame
- * @cookie:
- * @this:
- * @op_ret: return value
- * @op_errno: errno
- * @fd: file descriptor structure of opened directory
- *
- * not for external reference
- */
-int
-server_opendir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, fd_t *fd)
-{
- server_connection_t *conn = NULL;
- gf_hdr_common_t *hdr = NULL;
- gf_fop_opendir_rsp_t *rsp = NULL;
- server_state_t *state = NULL;
- size_t hdrlen = 0;
- int32_t gf_errno = 0;
-
- conn = SERVER_CONNECTION (frame);
-
- state = CALL_STATE (frame);
-
- if (op_ret >= 0) {
- fd_bind (fd);
-
- state->fd_no = gf_fd_unused_get (conn->fdtable, fd);
- } else {
- gf_log (this->name, GF_LOG_TRACE,
- "%"PRId64": OPENDIR %s (%"PRId64") ==> %"PRId32" (%s)",
- frame->root->unique, state->loc.path,
- state->loc.inode ? state->loc.inode->ino : 0,
- op_ret, strerror (op_errno));
-
- /* NOTE: corresponding to fd_create()'s ref */
- if (state->fd)
- fd_unref (state->fd);
- }
-
- hdrlen = gf_hdr_len (rsp, 0);
- hdr = gf_hdr_new (rsp, 0);
- rsp = gf_param (hdr);
-
- hdr->rsp.op_ret = hton32 (op_ret);
- gf_errno = gf_errno_to_error (op_errno);
- hdr->rsp.op_errno = hton32 (gf_errno);
- rsp->fd = hton64 (state->fd_no);
-
- server_loc_wipe (&(state->loc));
-
- protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_FOP_OPENDIR,
- hdr, hdrlen, NULL, 0, NULL);
-
- return 0;
-}
-
-/*
- * server_statfs_cbk - statfs callback for server protocol
- * @frame: call frame
- * @cookie:
- * @this:
- * @op_ret: return value
- * @op_errno: errno
- * @buf:
- *
- * not for external reference
- */
-int
-server_statfs_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct statvfs *buf)
-{
- gf_hdr_common_t *hdr = NULL;
- gf_fop_statfs_rsp_t *rsp = NULL;
- server_state_t *state = NULL;
- size_t hdrlen = 0;
- int32_t gf_errno = 0;
-
- state = CALL_STATE (frame);
-
- hdrlen = gf_hdr_len (rsp, 0);
- hdr = gf_hdr_new (rsp, 0);
- rsp = gf_param (hdr);
-
- hdr->rsp.op_ret = hton32 (op_ret);
- gf_errno = gf_errno_to_error (op_errno);
- hdr->rsp.op_errno = hton32 (gf_errno);
-
- if (op_ret >= 0) {
- gf_statfs_from_statfs (&rsp->statfs, buf);
- }
-
- server_loc_wipe (&(state->loc));
-
- protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_FOP_STATFS,
- hdr, hdrlen, NULL, 0, NULL);
-
- return 0;
-}
-
-/*
- * server_removexattr_cbk - removexattr callback for server protocol
- * @frame: call frame
- * @cookie:
- * @this:
- * @op_ret: return value
- * @op_errno: errno
- *
- * not for external reference
- */
-int
-server_removexattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno)
-{
- gf_hdr_common_t *hdr = NULL;
- gf_fop_removexattr_rsp_t *rsp = NULL;
- server_state_t *state = NULL;
- size_t hdrlen = 0;
- int32_t gf_errno = 0;
-
- state = CALL_STATE (frame);
-
- hdrlen = gf_hdr_len (rsp, 0);
- hdr = gf_hdr_new (rsp, 0);
- rsp = gf_param (hdr);
-
- hdr->rsp.op_ret = hton32 (op_ret);
- gf_errno = gf_errno_to_error (op_errno);
- hdr->rsp.op_errno = hton32 (gf_errno);
-
- server_loc_wipe (&(state->loc));
-
- protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_FOP_REMOVEXATTR,
- hdr, hdrlen, NULL, 0, NULL);
-
- return 0;
-}
-
-/*
- * server_getxattr_cbk - getxattr callback for server protocol
- * @frame: call frame
- * @cookie:
- * @this:
- * @op_ret: return value
- * @op_errno: errno
- * @value:
- *
- * not for external reference
- */
-int
-server_getxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *dict)
-{
- gf_hdr_common_t *hdr = NULL;
- gf_fop_getxattr_rsp_t *rsp = NULL;
- server_state_t *state = NULL;
- size_t hdrlen = 0;
- int32_t len = 0;
- int32_t gf_errno = 0;
- int32_t ret = -1;
-
- state = CALL_STATE (frame);
-
- if (op_ret >= 0) {
- len = dict_serialized_length (dict);
- if (len < 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "%s (%"PRId64"): failed to get serialized length of "
- "reply dict",
- state->loc.path, state->ino);
- op_ret = -1;
- op_errno = EINVAL;
- len = 0;
- }
- }
-
- hdrlen = gf_hdr_len (rsp, len + 1);
- hdr = gf_hdr_new (rsp, len + 1);
- rsp = gf_param (hdr);
-
- if (op_ret >= 0) {
- ret = dict_serialize (dict, rsp->dict);
- if (len < 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "%s (%"PRId64"): failed to serialize reply dict",
- state->loc.path, state->ino);
- op_ret = -1;
- op_errno = -ret;
- }
- }
- rsp->dict_len = hton32 (len);
-
- hdr->rsp.op_ret = hton32 (op_ret);
- gf_errno = gf_errno_to_error (op_errno);
- hdr->rsp.op_errno = hton32 (gf_errno);
-
-
- server_loc_wipe (&(state->loc));
-
- protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_FOP_GETXATTR,
- hdr, hdrlen, NULL, 0, NULL);
-
- return 0;
-}
-
-
-int
-server_fgetxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *dict)
-{
- gf_hdr_common_t *hdr = NULL;
- gf_fop_fgetxattr_rsp_t *rsp = NULL;
- server_state_t *state = NULL;
- size_t hdrlen = 0;
- int32_t len = 0;
- int32_t gf_errno = 0;
- int32_t ret = -1;
-
- state = CALL_STATE (frame);
-
- if (op_ret >= 0) {
- len = dict_serialized_length (dict);
- if (len < 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "%s (%"PRId64"): failed to get serialized length of "
- "reply dict",
- state->loc.path, state->ino);
- op_ret = -1;
- op_errno = EINVAL;
- len = 0;
- }
- }
-
- hdrlen = gf_hdr_len (rsp, len + 1);
- hdr = gf_hdr_new (rsp, len + 1);
- rsp = gf_param (hdr);
-
- if (op_ret >= 0) {
- ret = dict_serialize (dict, rsp->dict);
- if (len < 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "%s (%"PRId64"): failed to serialize reply dict",
- state->loc.path, state->ino);
- op_ret = -1;
- op_errno = -ret;
- }
- }
- rsp->dict_len = hton32 (len);
-
- hdr->rsp.op_ret = hton32 (op_ret);
- gf_errno = gf_errno_to_error (op_errno);
- hdr->rsp.op_errno = hton32 (gf_errno);
-
- fd_unref (state->fd);
-
- protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_FOP_FGETXATTR,
- hdr, hdrlen, NULL, 0, NULL);
-
- return 0;
-}
-
-
-/*
- * server_setxattr_cbk - setxattr callback for server protocol
- * @frame: call frame
- * @cookie:
- * @this:
- * @op_ret: return value
- * @op_errno: errno
- *
- * not for external reference
- */
-int
-server_setxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno)
-{
- gf_hdr_common_t *hdr = NULL;
- gf_fop_setxattr_rsp_t *rsp = NULL;
- server_state_t *state = NULL;
- size_t hdrlen = 0;
- int32_t gf_errno = 0;
-
- state = CALL_STATE (frame);
-
- hdrlen = gf_hdr_len (rsp, 0);
- hdr = gf_hdr_new (rsp, 0);
- rsp = gf_param (hdr);
-
- hdr->rsp.op_ret = hton32 (op_ret);
- gf_errno = gf_errno_to_error (op_errno);
- hdr->rsp.op_errno = hton32 (gf_errno);
-
- server_loc_wipe (&(state->loc));
-
- protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_FOP_SETXATTR,
- hdr, hdrlen, NULL, 0, NULL);
-
- return 0;
-}
-
-
-int
-server_fsetxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno)
-{
- gf_hdr_common_t *hdr = NULL;
- gf_fop_fsetxattr_rsp_t *rsp = NULL;
- server_state_t *state = NULL;
- size_t hdrlen = 0;
- int32_t gf_errno = 0;
-
- state = CALL_STATE(frame);
-
- hdrlen = gf_hdr_len (rsp, 0);
- hdr = gf_hdr_new (rsp, 0);
- rsp = gf_param (hdr);
-
- hdr->rsp.op_ret = hton32 (op_ret);
- gf_errno = gf_errno_to_error (op_errno);
- hdr->rsp.op_errno = hton32 (gf_errno);
-
- protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_FOP_FSETXATTR,
- hdr, hdrlen, NULL, 0, NULL);
-
- return 0;
-}
-
-
-/*
- * server_rename_cbk - rename callback for server protocol
- * @frame: call frame
- * @cookie:
- * @this:
- * @op_ret: return value
- * @op_errno: errno
- *
- * not for external reference
- */
-int
-server_rename_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct stat *stbuf,
- struct stat *preoldparent, struct stat *postoldparent,
- struct stat *prenewparent, struct stat *postnewparent)
-{
- gf_hdr_common_t *hdr = NULL;
- gf_fop_rename_rsp_t *rsp = NULL;
- server_state_t *state = NULL;
- size_t hdrlen = 0;
- int32_t gf_errno = 0;
-
- state = CALL_STATE(frame);
-
- hdrlen = gf_hdr_len (rsp, 0);
- hdr = gf_hdr_new (rsp, 0);
- rsp = gf_param (hdr);
-
- hdr->rsp.op_ret = hton32 (op_ret);
- gf_errno = gf_errno_to_error (op_errno);
- hdr->rsp.op_errno = hton32 (gf_errno);
-
- if (op_ret == 0) {
- stbuf->st_ino = state->loc.inode->ino;
- stbuf->st_mode = state->loc.inode->st_mode;
-
- gf_log (state->bound_xl->name, GF_LOG_TRACE,
- "%"PRId64": RENAME_CBK (%"PRId64") %"PRId64"/%s "
- "==> %"PRId64"/%s",
- frame->root->unique, state->loc.inode->ino,
- state->loc.parent->ino, state->loc.name,
- state->loc2.parent->ino, state->loc2.name);
-
- inode_rename (state->itable,
- state->loc.parent, state->loc.name,
- state->loc2.parent, state->loc2.name,
- state->loc.inode, stbuf);
- gf_stat_from_stat (&rsp->stat, stbuf);
-
- gf_stat_from_stat (&rsp->preoldparent, preoldparent);
- gf_stat_from_stat (&rsp->postoldparent, postoldparent);
-
- gf_stat_from_stat (&rsp->prenewparent, prenewparent);
- gf_stat_from_stat (&rsp->postnewparent, postnewparent);
- }
-
- server_loc_wipe (&(state->loc));
- server_loc_wipe (&(state->loc2));
-
- protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_FOP_RENAME,
- hdr, hdrlen, NULL, 0, NULL);
-
- return 0;
-}
-
-
-/*
- * server_unlink_cbk - unlink callback for server protocol
- * @frame: call frame
- * @cookie:
- * @this:
- * @op_ret: return value
- * @op_errno: errno
- *
- * not for external reference
- */
-int
-server_unlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct stat *preparent,
- struct stat *postparent)
-{
- gf_hdr_common_t *hdr = NULL;
- gf_fop_unlink_rsp_t *rsp = NULL;
- server_state_t *state = NULL;
- size_t hdrlen = 0;
- int32_t gf_errno = 0;
-
- state = CALL_STATE(frame);
-
- if (op_ret == 0) {
- gf_log (state->bound_xl->name, GF_LOG_TRACE,
- "%"PRId64": UNLINK_CBK %"PRId64"/%s (%"PRId64")",
- frame->root->unique, state->loc.parent->ino,
- state->loc.name, state->loc.inode->ino);
-
- inode_unlink (state->loc.inode, state->loc.parent,
- state->loc.name);
-
- inode_forget (state->loc.inode, 0);
- } else {
- gf_log (this->name, GF_LOG_DEBUG,
- "%"PRId64": UNLINK %s (%"PRId64") ==> %"PRId32" (%s)",
- frame->root->unique, state->loc.path,
- state->loc.inode ? state->loc.inode->ino : 0,
- op_ret, strerror (op_errno));
- }
-
- hdrlen = gf_hdr_len (rsp, 0);
- hdr = gf_hdr_new (rsp, 0);
- rsp = gf_param (hdr);
-
- hdr->rsp.op_ret = hton32 (op_ret);
- gf_errno = gf_errno_to_error (op_errno);
- hdr->rsp.op_errno = hton32 (gf_errno);
-
- if (op_ret == 0) {
- gf_stat_from_stat (&rsp->preparent, preparent);
- gf_stat_from_stat (&rsp->postparent, postparent);
- }
-
- server_loc_wipe (&(state->loc));
-
- protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_FOP_UNLINK,
- hdr, hdrlen, NULL, 0, NULL);
-
- return 0;
-}
-
-/*
- * server_symlink_cbk - symlink callback for server protocol
- * @frame: call frame
- * @cookie:
- * @this:
- * @op_ret: return value
- * @op_errno: errno
- *
- * not for external reference
- */
-int
-server_symlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, inode_t *inode,
- struct stat *stbuf, struct stat *preparent,
- struct stat *postparent)
-{
- gf_hdr_common_t *hdr = NULL;
- gf_fop_symlink_rsp_t *rsp = NULL;
- server_state_t *state = NULL;
- size_t hdrlen = 0;
- int32_t gf_errno = 0;
-
- state = CALL_STATE(frame);
-
- hdrlen = gf_hdr_len (rsp, 0);
- hdr = gf_hdr_new (rsp, 0);
- rsp = gf_param (hdr);
-
- hdr->rsp.op_ret = hton32 (op_ret);
- gf_errno = gf_errno_to_error (op_errno);
- hdr->rsp.op_errno = hton32 (gf_errno_to_error (op_errno));
-
- if (op_ret >= 0) {
- gf_stat_from_stat (&rsp->stat, stbuf);
- inode_link (inode, state->loc.parent, state->loc.name, stbuf);
- inode_lookup (inode);
- } else {
- gf_log (this->name, GF_LOG_DEBUG,
- "%"PRId64": SYMLINK %s (%"PRId64") ==> %"PRId32" (%s)",
- frame->root->unique, state->loc.path,
- state->loc.inode ? state->loc.inode->ino : 0,
- op_ret, strerror (op_errno));
- }
-
- server_loc_wipe (&(state->loc));
-
- protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_FOP_SYMLINK,
- hdr, hdrlen, NULL, 0, NULL);
-
- return 0;
-}
-
-
-/*
- * server_link_cbk - link callback for server protocol
- * @frame: call frame
- * @this:
- * @op_ret:
- * @op_errno:
- * @stbuf:
- *
- * not for external reference
- */
-int
-server_link_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, inode_t *inode,
- struct stat *stbuf, struct stat *preparent,
- struct stat *postparent)
-{
- gf_hdr_common_t *hdr = NULL;
- gf_fop_link_rsp_t *rsp = NULL;
- server_state_t *state = NULL;
- int32_t gf_errno = 0;
- size_t hdrlen = 0;
-
- state = CALL_STATE(frame);
-
- hdrlen = gf_hdr_len (rsp, 0);
- hdr = gf_hdr_new (rsp, 0);
- rsp = gf_param (hdr);
-
- hdr->rsp.op_ret = hton32 (op_ret);
- gf_errno = gf_errno_to_error (op_errno);
- hdr->rsp.op_errno = hton32 (gf_errno);
-
- if (op_ret == 0) {
- stbuf->st_ino = state->loc.inode->ino;
- gf_stat_from_stat (&rsp->stat, stbuf);
- gf_log (state->bound_xl->name, GF_LOG_TRACE,
- "%"PRId64": LINK (%"PRId64") %"PRId64"/%s ==> %"PRId64"/%s",
- frame->root->unique, inode->ino,
- state->loc2.parent->ino,
- state->loc2.name, state->loc.parent->ino,
- state->loc.name);
-
- inode_link (inode, state->loc2.parent,
- state->loc2.name, stbuf);
- } else {
- gf_log (state->bound_xl->name, GF_LOG_DEBUG,
- "%"PRId64": LINK (%"PRId64") %"PRId64"/%s ==> %"PRId64"/%s "
- " ==> %"PRId32" (%s)",
- frame->root->unique, inode->ino,
- state->loc2.parent->ino,
- state->loc2.name, state->loc.parent->ino,
- state->loc.name,
- op_ret, strerror (op_errno));
- }
-
- server_loc_wipe (&(state->loc));
- server_loc_wipe (&(state->loc2));
-
- protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_FOP_LINK,
- hdr, hdrlen, NULL, 0, NULL);
-
- return 0;
-}
-
-
-/*
- * server_truncate_cbk - truncate callback for server protocol
- * @frame: call frame
- * @cookie:
- * @this:
- * @op_ret:
- * @op_errno:
- * @stbuf:
- *
- * not for external reference
- */
-int
-server_truncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct stat *prebuf,
- struct stat *postbuf)
-{
- gf_hdr_common_t *hdr = NULL;
- gf_fop_truncate_rsp_t *rsp = NULL;
- server_state_t *state = NULL;
- size_t hdrlen = 0;
- int32_t gf_errno = 0;
-
- state = CALL_STATE (frame);
-
- hdrlen = gf_hdr_len (rsp, 0);
- hdr = gf_hdr_new (rsp, 0);
- rsp = gf_param (hdr);
-
- hdr->rsp.op_ret = hton32 (op_ret);
- gf_errno = gf_errno_to_error (op_errno);
- hdr->rsp.op_errno = hton32 (gf_errno);
-
- if (op_ret == 0) {
- gf_stat_from_stat (&rsp->prestat, prebuf);
- gf_stat_from_stat (&rsp->poststat, postbuf);
- } else {
- gf_log (this->name, GF_LOG_DEBUG,
- "%"PRId64": TRUNCATE %s (%"PRId64") ==> %"PRId32" (%s)",
- frame->root->unique, state->loc.path,
- state->loc.inode ? state->loc.inode->ino : 0,
- op_ret, strerror (op_errno));
- }
-
- server_loc_wipe (&(state->loc));
-
- protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_FOP_TRUNCATE,
- hdr, hdrlen, NULL, 0, NULL);
-
- return 0;
-}
-
-/*
- * server_fstat_cbk - fstat callback for server protocol
- * @frame: call frame
- * @cookie:
- * @this:
- * @op_ret:
- * @op_errno:
- * @stbuf:
- *
- * not for external reference
- */
-int
-server_fstat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct stat *stbuf)
-{
- gf_hdr_common_t *hdr = NULL;
- gf_fop_fstat_rsp_t *rsp = NULL;
- size_t hdrlen = 0;
- int32_t gf_errno = 0;
- server_state_t *state = NULL;
-
- hdrlen = gf_hdr_len (rsp, 0);
- hdr = gf_hdr_new (rsp, 0);
- rsp = gf_param (hdr);
-
- hdr->rsp.op_ret = hton32 (op_ret);
- gf_errno = gf_errno_to_error (op_errno);
- hdr->rsp.op_errno = hton32 (gf_errno);
-
- if (op_ret == 0) {
- gf_stat_from_stat (&rsp->stat, stbuf);
- } else {
- state = CALL_STATE(frame);
-
- gf_log (this->name, GF_LOG_DEBUG,
- "%"PRId64": FSTAT %"PRId64" (%"PRId64") ==> %"PRId32" (%s)",
- frame->root->unique, state->fd_no,
- state->fd ? state->fd->inode->ino : 0, op_ret,
- strerror (op_errno));
- }
-
- protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_FOP_FSTAT,
- hdr, hdrlen, NULL, 0, NULL);
-
- return 0;
-}
-
-/*
- * server_ftruncate_cbk - ftruncate callback for server protocol
- * @frame: call frame
- * @cookie:
- * @this:
- * @op_ret:
- * @op_errno:
- * @stbuf:
- *
- * not for external reference
- */
-int
-server_ftruncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct stat *prebuf,
- struct stat *postbuf)
-{
- gf_hdr_common_t *hdr = NULL;
- gf_fop_ftruncate_rsp_t *rsp = NULL;
- size_t hdrlen = 0;
- int32_t gf_errno = 0;
- server_state_t *state = NULL;
-
- hdrlen = gf_hdr_len (rsp, 0);
- hdr = gf_hdr_new (rsp, 0);
- rsp = gf_param (hdr);
-
- hdr->rsp.op_ret = hton32 (op_ret);
- gf_errno = gf_errno_to_error (op_errno);
- hdr->rsp.op_errno = hton32 (gf_errno);
-
- if (op_ret == 0) {
- gf_stat_from_stat (&rsp->prestat, prebuf);
- gf_stat_from_stat (&rsp->poststat, postbuf);
- } else {
- state = CALL_STATE (frame);
-
- gf_log (this->name, GF_LOG_DEBUG,
- "%"PRId64": FTRUNCATE %"PRId64" (%"PRId64") ==> %"PRId32" (%s)",
- frame->root->unique, state->fd_no,
- state->fd ? state->fd->inode->ino : 0, op_ret,
- strerror (op_errno));
- }
-
- protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_FOP_FTRUNCATE,
- hdr, hdrlen, NULL, 0, NULL);
-
- return 0;
-}
-
-
-/*
- * server_flush_cbk - flush callback for server protocol
- * @frame: call frame
- * @cookie:
- * @this:
- * @op_ret:
- * @op_errno:
- *
- * not for external reference
- */
-int
-server_flush_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno)
-{
- gf_hdr_common_t *hdr = NULL;
- gf_fop_flush_rsp_t *rsp = NULL;
- size_t hdrlen = 0;
- int32_t gf_errno = 0;
- server_state_t *state = NULL;
-
- if (op_ret < 0) {
- state = CALL_STATE(frame);
-
- gf_log (this->name, GF_LOG_DEBUG,
- "%"PRId64": FLUSH %"PRId64" (%"PRId64") ==> %"PRId32" (%s)",
- frame->root->unique, state->fd_no,
- state->fd ? state->fd->inode->ino : 0, op_ret,
- strerror (op_errno));
- }
-
- hdrlen = gf_hdr_len (rsp, 0);
- hdr = gf_hdr_new (rsp, 0);
-
- hdr->rsp.op_ret = hton32 (op_ret);
- gf_errno = gf_errno_to_error (op_errno);
- hdr->rsp.op_errno = hton32 (gf_errno);
-
- protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_FOP_FLUSH,
- hdr, hdrlen, NULL, 0, NULL);
-
- return 0;
-}
-
-/*
- * server_fsync_cbk - fsync callback for server protocol
- * @frame: call frame
- * @cookie:
- * @this:
- * @op_ret:
- * @op_errno:
- *
- * not for external reference
- */
-int
-server_fsync_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct stat *prebuf,
- struct stat *postbuf)
-{
- gf_hdr_common_t *hdr = NULL;
- gf_fop_fsync_rsp_t *rsp = NULL;
- size_t hdrlen = 0;
- int32_t gf_errno = 0;
- server_state_t *state = NULL;
-
- if (op_ret < 0) {
- state = CALL_STATE(frame);
-
- gf_log (this->name, GF_LOG_DEBUG,
- "%"PRId64": FSYNC %"PRId64" (%"PRId64") ==> %"PRId32" (%s)",
- frame->root->unique, state->fd_no,
- state->fd ? state->fd->inode->ino : 0, op_ret,
- strerror (op_errno));
- }
-
- hdrlen = gf_hdr_len (rsp, 0);
- hdr = gf_hdr_new (rsp, 0);
- rsp = gf_param (hdr);
-
- hdr->rsp.op_ret = hton32 (op_ret);
- gf_errno = gf_errno_to_error (op_errno);
- hdr->rsp.op_errno = hton32 (gf_errno);
-
- if (op_ret >= 0) {
- gf_stat_from_stat (&(rsp->prestat), prebuf);
- gf_stat_from_stat (&(rsp->poststat), postbuf);
- }
-
- protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_FOP_FSYNC,
- hdr, hdrlen, NULL, 0, NULL);
-
- return 0;
-}
-
-/*
- * server_release_cbk - rleease callback for server protocol
- * @frame: call frame
- * @cookie:
- * @this:
- * @op_ret:
- * @op_errno:
- *
- * not for external reference
- */
-int
-server_release_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno)
-{
- gf_hdr_common_t *hdr = NULL;
- gf_cbk_release_rsp_t *rsp = NULL;
- size_t hdrlen = 0;
- int32_t gf_errno = 0;
-
- hdrlen = gf_hdr_len (rsp, 0);
- hdr = gf_hdr_new (rsp, 0);
-
- hdr->rsp.op_ret = hton32 (op_ret);
- gf_errno = gf_errno_to_error (op_errno);
- hdr->rsp.op_errno = hton32 (gf_errno);
-
- protocol_server_reply (frame, GF_OP_TYPE_CBK_REPLY, GF_CBK_RELEASE,
- hdr, hdrlen, NULL, 0, NULL);
-
- return 0;
-}
-
-
-/*
- * server_writev_cbk - writev callback for server protocol
- * @frame: call frame
- * @cookie:
- * @this:
- * @op_ret:
- * @op_errno:
- *
- * not for external reference
- */
-
-int
-server_writev_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct stat *prebuf,
- struct stat *postbuf)
-{
- gf_hdr_common_t *hdr = NULL;
- gf_fop_write_rsp_t *rsp = NULL;
- size_t hdrlen = 0;
- int32_t gf_errno = 0;
- server_state_t *state = NULL;
-
- hdrlen = gf_hdr_len (rsp, 0);
- hdr = gf_hdr_new (rsp, 0);
- rsp = gf_param (hdr);
-
- hdr->rsp.op_ret = hton32 (op_ret);
- gf_errno = gf_errno_to_error (op_errno);
- hdr->rsp.op_errno = hton32 (gf_errno_to_error (op_errno));
-
- if (op_ret >= 0) {
- gf_stat_from_stat (&rsp->prestat, prebuf);
- gf_stat_from_stat (&rsp->poststat, postbuf);
- } else {
- state = CALL_STATE(frame);
-
- gf_log (this->name, GF_LOG_DEBUG,
- "%"PRId64": WRITEV %"PRId64" (%"PRId64") ==> %"PRId32" (%s)",
- frame->root->unique, state->fd_no,
- state->fd ? state->fd->inode->ino : 0, op_ret,
- strerror (op_errno));
- }
-
- protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_FOP_WRITE,
- hdr, hdrlen, NULL, 0, NULL);
-
- return 0;
-}
-
-
-/*
- * server_readv_cbk - readv callback for server protocol
- * @frame: call frame
- * @cookie:
- * @this:
- * @op_ret:
- * @op_errno:
- * @vector:
- * @count:
- *
- * not for external reference
- */
-int
-server_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, struct iobref *iobref)
-{
- gf_hdr_common_t *hdr = NULL;
- gf_fop_read_rsp_t *rsp = NULL;
- size_t hdrlen = 0;
- int32_t gf_errno = 0;
- server_state_t *state = NULL;
-
- hdrlen = gf_hdr_len (rsp, 0);
- hdr = gf_hdr_new (rsp, 0);
- rsp = gf_param (hdr);
-
- hdr->rsp.op_ret = hton32 (op_ret);
- gf_errno = gf_errno_to_error (op_errno);
- hdr->rsp.op_errno = hton32 (gf_errno);
-
- if (op_ret >= 0) {
- gf_stat_from_stat (&rsp->stat, stbuf);
- } else {
- state = CALL_STATE(frame);
-
- gf_log (this->name, GF_LOG_DEBUG,
- "%"PRId64": READV %"PRId64" (%"PRId64") ==> %"PRId32" (%s)",
- frame->root->unique, state->fd_no,
- state->fd ? state->fd->inode->ino : 0, op_ret,
- strerror (op_errno));
- }
-
- protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_FOP_READ,
- hdr, hdrlen, vector, count, iobref);
-
- return 0;
-}
-
-
-/*
- * server_open_cbk - open callback for server protocol
- * @frame: call frame
- * @cookie:
- * @this:
- * @op_ret:
- * @op_errno:
- * @fd:
- *
- * not for external reference
- */
-int
-server_open_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, fd_t *fd)
-{
- server_connection_t *conn = NULL;
- gf_hdr_common_t *hdr = NULL;
- gf_fop_open_rsp_t *rsp = NULL;
- server_state_t *state = NULL;
- size_t hdrlen = 0;
- int32_t gf_errno = 0;
-
- conn = SERVER_CONNECTION (frame);
-
- state = CALL_STATE (frame);
-
- if (op_ret >= 0) {
- fd_bind (fd);
-
- state->fd_no = gf_fd_unused_get (conn->fdtable, fd);
- } else {
- gf_log (this->name, GF_LOG_DEBUG,
- "%"PRId64": OPEN %s (%"PRId64") ==> %"PRId32" (%s)",
- frame->root->unique, state->loc.path,
- state->loc.inode ? state->loc.inode->ino : 0,
- op_ret, strerror (op_errno));
-
- /* NOTE: corresponding to fd_create()'s ref */
- if (state->fd)
- fd_unref (state->fd);
- }
-
- hdrlen = gf_hdr_len (rsp, 0);
- hdr = gf_hdr_new (rsp, 0);
- rsp = gf_param (hdr);
-
- hdr->rsp.op_ret = hton32 (op_ret);
- gf_errno = gf_errno_to_error (op_errno);
- hdr->rsp.op_errno = hton32 (gf_errno);
- rsp->fd = hton64 (state->fd_no);
-
- server_loc_wipe (&(state->loc));
-
- protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_FOP_OPEN,
- hdr, hdrlen, NULL, 0, NULL);
-
- return 0;
-}
-
-
-/*
- * server_create_cbk - create callback for server
- * @frame: call frame
- * @cookie:
- * @this: translator structure
- * @op_ret:
- * @op_errno:
- * @fd: file descriptor
- * @inode: inode structure
- * @stbuf: struct stat of created file
- *
- * not for external reference
- */
-int
-server_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 *stbuf,
- struct stat *preparent, struct stat *postparent)
-{
- server_connection_t *conn = NULL;
- gf_hdr_common_t *hdr = NULL;
- gf_fop_create_rsp_t *rsp = NULL;
- server_state_t *state = NULL;
- size_t hdrlen = 0;
- int32_t gf_errno = 0;
-
- conn = SERVER_CONNECTION (frame);
-
- state = CALL_STATE (frame);
-
- if (op_ret >= 0) {
- gf_log (state->bound_xl->name, GF_LOG_TRACE,
- "%"PRId64": CREATE %"PRId64"/%s (%"PRId64")",
- frame->root->unique, state->loc.parent->ino,
- state->loc.name, stbuf->st_ino);
-
- inode_link (inode, state->loc.parent, state->loc.name, stbuf);
- inode_lookup (inode);
-
- fd_bind (fd);
-
- state->fd_no = gf_fd_unused_get (conn->fdtable, fd);
-
- if ((state->fd_no < 0) || (fd == 0)) {
- op_ret = state->fd_no;
- op_errno = errno;
- }
- } else {
- gf_log (this->name, GF_LOG_DEBUG,
- "%"PRId64": CREATE %s (%"PRId64") ==> %"PRId32" (%s)",
- frame->root->unique, state->loc.path,
- state->loc.inode ? state->loc.inode->ino : 0,
- op_ret, strerror (op_errno));
-
- /* NOTE: corresponding to fd_create()'s ref */
- if (state->fd)
- fd_unref (state->fd);
-
- }
-
- hdrlen = gf_hdr_len (rsp, 0);
- hdr = gf_hdr_new (rsp, 0);
- rsp = gf_param (hdr);
-
- hdr->rsp.op_ret = hton32 (op_ret);
- gf_errno = gf_errno_to_error (op_errno);
- hdr->rsp.op_errno = hton32 (gf_errno);
- rsp->fd = hton64 (state->fd_no);
-
- if (op_ret >= 0)
- gf_stat_from_stat (&rsp->stat, stbuf);
-
- server_loc_wipe (&(state->loc));
-
- protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_FOP_CREATE,
- hdr, hdrlen, NULL, 0, NULL);
-
- return 0;
-}
-
-/*
- * server_readlink_cbk - readlink callback for server protocol
- * @frame: call frame
- * @cookie:
- * @this:
- * @op_ret:
- * @op_errno:
- * @buf:
- *
- * not for external reference
- */
-int
-server_readlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, const char *buf,
- struct stat *sbuf)
-{
- gf_hdr_common_t *hdr = NULL;
- gf_fop_readlink_rsp_t *rsp = NULL;
- server_state_t *state = NULL;
- size_t hdrlen = 0;
- size_t linklen = 0;
- int32_t gf_errno = 0;
-
- state = CALL_STATE(frame);
-
- if (op_ret >= 0) {
- linklen = strlen (buf) + 1;
- } else {
- gf_log (this->name, GF_LOG_DEBUG,
- "%"PRId64": READLINK %s (%"PRId64") ==> %"PRId32" (%s)",
- frame->root->unique, state->loc.path,
- state->loc.inode ? state->loc.inode->ino : 0,
- op_ret, strerror (op_errno));
- }
-
- hdrlen = gf_hdr_len (rsp, linklen);
- hdr = gf_hdr_new (rsp, linklen);
- rsp = gf_param (hdr);
-
- hdr->rsp.op_ret = hton32 (op_ret);
- gf_errno = gf_errno_to_error (op_errno);
- hdr->rsp.op_errno = hton32 (gf_errno_to_error (op_errno));
-
- if (op_ret >= 0) {
- gf_stat_from_stat (&(rsp->buf), sbuf);
- strcpy (rsp->path, buf);
- }
-
- server_loc_wipe (&(state->loc));
-
- protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_FOP_READLINK,
- hdr, hdrlen, NULL, 0, NULL);
-
- return 0;
-}
-
-/*
- * server_stat_cbk - stat callback for server protocol
- * @frame: call frame
- * @cookie:
- * @this:
- * @op_ret:
- * @op_errno:
- * @stbuf:
- *
- * not for external reference
- */
-int
-server_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct stat *stbuf)
-{
- gf_hdr_common_t *hdr = NULL;
- gf_fop_stat_rsp_t *rsp = NULL;
- server_state_t *state = NULL;
- size_t hdrlen = 0;
- int32_t gf_errno = 0;
-
- state = CALL_STATE (frame);
-
- hdrlen = gf_hdr_len (rsp, 0);
- hdr = gf_hdr_new (rsp, 0);
- rsp = gf_param (hdr);
-
- hdr->rsp.op_ret = hton32 (op_ret);
- gf_errno = gf_errno_to_error (op_errno);
- hdr->rsp.op_errno = hton32 (gf_errno_to_error (op_errno));
-
- if (op_ret == 0) {
- gf_stat_from_stat (&rsp->stat, stbuf);
- } else {
- gf_log (this->name, GF_LOG_DEBUG,
- "%"PRId64": STAT %s (%"PRId64") ==> %"PRId32" (%s)",
- frame->root->unique, state->loc.path,
- state->loc.inode ? state->loc.inode->ino : 0,
- op_ret, strerror (op_errno));
- }
-
- server_loc_wipe (&(state->loc));
-
- protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_FOP_STAT,
- hdr, hdrlen, NULL, 0, NULL);
-
- return 0;
-}
-
-/*
- * server_setattr_cbk - setattr callback for server protocol
- * @frame: call frame
- * @cookie:
- * @this:
- * @op_ret:
- * @op_errno:
- * @stbuf:
- *
- * not for external reference
- */
-int
-server_setattr_cbk (call_frame_t *frame,
- void *cookie,
- xlator_t *this,
- int32_t op_ret,
- int32_t op_errno,
- struct stat *statpre,
- struct stat *statpost)
-{
- gf_hdr_common_t *hdr = NULL;
- gf_fop_setattr_rsp_t *rsp = NULL;
- server_state_t *state = NULL;
- size_t hdrlen = 0;
- int32_t gf_errno = 0;
-
- state = CALL_STATE (frame);
-
- hdrlen = gf_hdr_len (rsp, 0);
- hdr = gf_hdr_new (rsp, 0);
- rsp = gf_param (hdr);
-
- hdr->rsp.op_ret = hton32 (op_ret);
- gf_errno = gf_errno_to_error (op_errno);
- hdr->rsp.op_errno = hton32 (gf_errno_to_error (op_errno));
-
- if (op_ret == 0) {
- gf_stat_from_stat (&rsp->statpre, statpre);
- gf_stat_from_stat (&rsp->statpost, statpost);
- } else {
- gf_log (this->name, GF_LOG_DEBUG,
- "%"PRId64": SETATTR %s (%"PRId64") ==> %"PRId32" (%s)",
- frame->root->unique, state->loc.path,
- state->loc.inode ? state->loc.inode->ino : 0,
- op_ret, strerror (op_errno));
- }
-
- server_loc_wipe (&(state->loc));
-
- protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_FOP_SETATTR,
- hdr, hdrlen, NULL, 0, NULL);
-
- return 0;
-}
-
-/*
- * server_setattr_cbk - setattr callback for server protocol
- * @frame: call frame
- * @cookie:
- * @this:
- * @op_ret:
- * @op_errno:
- * @stbuf:
- *
- * not for external reference
- */
-int
-server_fsetattr_cbk (call_frame_t *frame,
- void *cookie,
- xlator_t *this,
- int32_t op_ret,
- int32_t op_errno,
- struct stat *statpre,
- struct stat *statpost)
-{
- gf_hdr_common_t *hdr = NULL;
- gf_fop_fsetattr_rsp_t *rsp = NULL;
- server_state_t *state = NULL;
- size_t hdrlen = 0;
- int32_t gf_errno = 0;
-
- state = CALL_STATE (frame);
-
- hdrlen = gf_hdr_len (rsp, 0);
- hdr = gf_hdr_new (rsp, 0);
- rsp = gf_param (hdr);
-
- hdr->rsp.op_ret = hton32 (op_ret);
- gf_errno = gf_errno_to_error (op_errno);
- hdr->rsp.op_errno = hton32 (gf_errno_to_error (op_errno));
-
- if (op_ret == 0) {
- gf_stat_from_stat (&rsp->statpre, statpre);
- gf_stat_from_stat (&rsp->statpost, statpost);
- } else {
- gf_log (this->name, GF_LOG_DEBUG,
- "%"PRId64": FSETATTR %"PRId64" (%"PRId64") ==> "
- "%"PRId32" (%s)",
- frame->root->unique, state->fd_no,
- state->fd ? state->fd->inode->ino : 0,
- op_ret, strerror (op_errno));
- }
-
- server_loc_wipe (&(state->loc));
-
- protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_FOP_FSETATTR,
- hdr, hdrlen, NULL, 0, NULL);
-
- return 0;
-}
-
-
-/*
- * server_lookup_cbk - lookup callback for server protocol
- * @frame: call frame
- * @cookie:
- * @this:
- * @op_ret:
- * @op_errno:
- * @inode:
- * @stbuf:
- *
- * not for external reference
- */
-int
-server_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno,
- inode_t *inode, struct stat *stbuf, dict_t *dict,
- struct stat *postparent)
-{
- gf_hdr_common_t *hdr = NULL;
- gf_fop_lookup_rsp_t *rsp = NULL;
- server_state_t *state = NULL;
- inode_t *root_inode = NULL;
- int32_t dict_len = 0;
- size_t hdrlen = 0;
- int32_t gf_errno = 0;
- int32_t ret = -1;
- loc_t loc = {0,};
-
- state = CALL_STATE(frame);
- if ((op_errno == ESTALE) && (op_ret == -1)) {
- /* Send lookup again with new ctx dictionary */
-
- root_inode = BOUND_XL(frame)->itable->root;
- if (state->loc.inode != root_inode) {
- if (state->loc.inode)
- inode_unref (state->loc.inode);
- state->loc.inode = inode_new (BOUND_XL(frame)->itable);
- }
- loc.inode = state->loc.inode;
- loc.path = state->path;
- state->is_revalidate = 2;
-
- STACK_WIND (frame, server_lookup_cbk,
- BOUND_XL(frame),
- BOUND_XL(frame)->fops->lookup,
- &loc,
- state->xattr_req);
- return 0;
- }
-
- if (dict) {
- dict_len = dict_serialized_length (dict);
- if (dict_len < 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "%s (%"PRId64"): failed to get serialized "
- "length of reply dict",
- state->loc.path, state->loc.inode->ino);
- op_ret = -1;
- op_errno = EINVAL;
- dict_len = 0;
- }
- }
-
- hdrlen = gf_hdr_len (rsp, dict_len);
- hdr = gf_hdr_new (rsp, dict_len);
- rsp = gf_param (hdr);
-
- if ((op_ret >= 0) && dict) {
- ret = dict_serialize (dict, rsp->dict);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "%s (%"PRId64"): failed to serialize reply dict",
- state->loc.path, state->loc.inode->ino);
- op_ret = -1;
- op_errno = -ret;
- dict_len = 0;
- }
- }
- rsp->dict_len = hton32 (dict_len);
-
- hdr->rsp.op_ret = hton32 (op_ret);
- gf_errno = gf_errno_to_error (op_errno);
- hdr->rsp.op_errno = hton32 (gf_errno);
-
- if (op_ret == 0) {
- root_inode = BOUND_XL(frame)->itable->root;
- if (inode == root_inode) {
- /* we just looked up root ("/") */
- stbuf->st_ino = 1;
- if (inode->st_mode == 0)
- inode->st_mode = stbuf->st_mode;
- }
-
- gf_stat_from_stat (&rsp->stat, stbuf);
- gf_stat_from_stat (&rsp->postparent, postparent);
-
- if (inode->ino == 0) {
- inode_link (inode, state->loc.parent,
- state->loc.name, stbuf);
- inode_lookup (inode);
- }
- } else {
- gf_log (this->name,
- (op_errno == ENOENT ? GF_LOG_TRACE : GF_LOG_DEBUG),
- "%"PRId64": LOOKUP %s (%"PRId64") ==> %"PRId32" (%s)",
- frame->root->unique, state->loc.path,
- state->loc.inode ? state->loc.inode->ino : 0,
- op_ret, strerror (op_errno));
- }
-
- server_loc_wipe (&state->loc);
- protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_FOP_LOOKUP,
- hdr, hdrlen, NULL, 0, NULL);
-
- return 0;
-}
-
-int
-server_xattrop_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *dict)
-{
- gf_hdr_common_t *hdr = NULL;
- gf_fop_xattrop_rsp_t *rsp = NULL;
- server_state_t *state = NULL;
- size_t hdrlen = 0;
- int32_t len = 0;
- int32_t gf_errno = 0;
- int32_t ret = -1;
-
- state = CALL_STATE (frame);
-
- if (op_ret < 0) {
- gf_log (this->name, GF_LOG_DEBUG,
- "%"PRId64": XATTROP %s (%"PRId64") ==> %"PRId32" (%s)",
- frame->root->unique, state->loc.path,
- state->loc.inode ? state->loc.inode->ino : 0,
- op_ret, strerror (op_errno));
- }
-
- if ((op_ret >= 0) && dict) {
- len = dict_serialized_length (dict);
- if (len < 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "%s (%"PRId64"): failed to get serialized length"
- " for reply dict",
- state->loc.path, state->loc.inode->ino);
- op_ret = -1;
- op_errno = EINVAL;
- len = 0;
- }
- }
-
- hdrlen = gf_hdr_len (rsp, len + 1);
- hdr = gf_hdr_new (rsp, len + 1);
- rsp = gf_param (hdr);
-
- if ((op_ret >= 0) && dict) {
- ret = dict_serialize (dict, rsp->dict);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "%s (%"PRId64"): failed to serialize reply dict",
- state->loc.path, state->loc.inode->ino);
- op_ret = -1;
- op_errno = -ret;
- len = 0;
- }
- }
- rsp->dict_len = hton32 (len);
-
- hdr->rsp.op_ret = hton32 (op_ret);
- gf_errno = gf_errno_to_error (op_errno);
- hdr->rsp.op_errno = hton32 (gf_errno);
-
- server_loc_wipe (&(state->loc));
-
- protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_FOP_XATTROP,
- hdr, hdrlen, NULL, 0, NULL);
-
- return 0;
-}
-
-
-int
-server_fxattrop_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *dict)
-{
- gf_hdr_common_t *hdr = NULL;
- gf_fop_xattrop_rsp_t *rsp = NULL;
- size_t hdrlen = 0;
- int32_t len = 0;
- int32_t gf_errno = 0;
- int32_t ret = -1;
- server_state_t *state = NULL;
-
- state = CALL_STATE(frame);
-
- if (op_ret < 0) {
- gf_log (this->name, GF_LOG_DEBUG,
- "%"PRId64": FXATTROP %"PRId64" (%"PRId64") ==> %"PRId32" (%s)",
- frame->root->unique, state->fd_no,
- state->fd ? state->fd->inode->ino : 0, op_ret,
- strerror (op_errno));
- }
-
- if ((op_ret >= 0) && dict) {
- len = dict_serialized_length (dict);
- if (len < 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "fd - %"PRId64" (%"PRId64"): failed to get "
- "serialized length for reply dict",
- state->fd_no, state->fd->inode->ino);
- op_ret = -1;
- op_errno = EINVAL;
- len = 0;
- }
- }
-
- hdrlen = gf_hdr_len (rsp, len + 1);
- hdr = gf_hdr_new (rsp, len + 1);
- rsp = gf_param (hdr);
-
- if ((op_ret >= 0) && dict) {
- ret = dict_serialize (dict, rsp->dict);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "fd - %"PRId64" (%"PRId64"): failed to "
- "serialize reply dict",
- state->fd_no, state->fd->inode->ino);
- op_ret = -1;
- op_errno = -ret;
- len = 0;
- }
- }
- rsp->dict_len = hton32 (len);
-
- hdr->rsp.op_ret = hton32 (op_ret);
- gf_errno = gf_errno_to_error (op_errno);
- hdr->rsp.op_errno = hton32 (gf_errno);
-
-
- protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_FOP_FXATTROP,
- hdr, hdrlen, NULL, 0, NULL);
-
- return 0;
-}
-
-/*
- * server_stub_resume - this is callback function used whenever an fop does
- * STACK_WIND to fops->lookup in order to lookup the inode
- * for a pathname. this case of doing fops->lookup arises
- * when fop searches in inode table for pathname and search
- * fails.
- *
- * @stub: call stub
- * @op_ret:
- * @op_errno:
- * @inode:
- * @parent:
- *
- * not for external reference
- */
-int
-server_stub_resume (call_stub_t *stub, int32_t op_ret, int32_t op_errno,
- inode_t *inode, inode_t *parent)
-{
- inode_t *server_inode = NULL;
- loc_t *newloc = NULL;
- dict_t *dict = NULL;
-
- server_inode = inode;
-
- if (!stub) {
- return 0;
- }
-
- switch (stub->fop)
- {
- case GF_FOP_RENAME:
- if ((op_ret < 0 && stub->args.rename.old.inode == NULL) ||
- (op_ret < 0 && parent == NULL)) {
- /* Either oldloc lookup failed OR newloc lookup
- * failed and parent was not found
- */
- gf_log (stub->frame->this->name, GF_LOG_DEBUG,
- "%"PRId64": RENAME (%s -> %s) on %s "
- "returning error: "
- "%"PRId32" (%"PRId32")",
- stub->frame->root->unique,
- stub->args.rename.old.path,
- stub->args.rename.new.path,
- BOUND_XL(stub->frame)->name,
- op_ret, op_errno);
-
- /* lookup of oldpath failed, UNWIND to
- * server_rename_cbk with ret=-1 and
- * errno=ENOENT
- */
- server_rename_cbk (stub->frame, NULL,
- stub->frame->this,
- -1, ENOENT, NULL, NULL, NULL, NULL,
- NULL);
- server_loc_wipe (&stub->args.rename.old);
- server_loc_wipe (&stub->args.rename.new);
- FREE (stub);
- return 0;
- }
-
- if (stub->args.rename.old.inode == NULL) {
- /* now we are called by lookup of oldpath. */
- if (stub->args.rename.old.parent == NULL)
- stub->args.rename.old.parent =
- inode_ref (parent);
-
- /* store inode information of oldpath in our stub
- * and search for newpath in inode table.
- */
- if (server_inode) {
- stub->args.rename.old.inode =
- inode_ref (server_inode);
-
- stub->args.rename.old.ino =
- server_inode->ino;
- }
-
- /* now lookup for newpath */
- newloc = &stub->args.rename.new;
-
- if (newloc->parent == NULL) {
- /* lookup for newpath */
- do_path_lookup (stub, newloc);
- break;
- } else {
- /* found newpath in inode cache */
- call_resume (stub);
- break;
- }
- } else {
- /* we are called by the lookup of newpath */
- if (stub->args.rename.new.parent == NULL)
- stub->args.rename.new.parent =
- inode_ref (parent);
- }
-
- /* after looking up for oldpath as well as newpath,
- * we are ready to resume */
- {
- call_resume (stub);
- }
- break;
-
- case GF_FOP_OPEN:
- {
- if (op_ret < 0) {
- gf_log (stub->frame->this->name, GF_LOG_DEBUG,
- "%"PRId64": OPEN (%s) on %s returning error: "
- "%"PRId32" (%"PRId32")",
- stub->frame->root->unique,
- stub->args.open.loc.path,
- BOUND_XL(stub->frame)->name,
- op_ret, op_errno);
-
- server_open_cbk (stub->frame, NULL, stub->frame->this,
- -1, ENOENT, NULL);
- FREE (stub->args.open.loc.path);
- FREE (stub);
- return 0;
- }
- if (stub->args.open.loc.parent == NULL)
- stub->args.open.loc.parent = inode_ref (parent);
-
- if (server_inode && (stub->args.open.loc.inode == NULL)) {
- stub->args.open.loc.inode = inode_ref (server_inode);
- stub->args.open.loc.ino = server_inode->ino;
- }
- call_resume (stub);
- break;
- }
-
- case GF_FOP_LOOKUP:
- {
- if (op_ret < 0) {
- gf_log (stub->frame->this->name,
- GF_LOG_DEBUG,
- "%"PRId64": LOOKUP (%s) on %s returning error: "
- "%"PRId32" (%"PRId32")",
- stub->frame->root->unique,
- stub->args.lookup.loc.path,
- BOUND_XL(stub->frame)->name,
- op_ret, op_errno);
-
- server_lookup_cbk (stub->frame, NULL,
- stub->frame->this, -1, ENOENT,
- NULL, NULL, NULL, NULL);
- server_loc_wipe (&stub->args.lookup.loc);
- FREE (stub);
- return 0;
- }
-
- if (stub->args.lookup.loc.parent == NULL)
- stub->args.lookup.loc.parent = inode_ref (parent);
-
- if (server_inode && (stub->args.lookup.loc.inode == NULL)) {
- stub->args.lookup.loc.inode = inode_ref (server_inode);
- stub->args.lookup.loc.ino = server_inode->ino;
- }
-
- call_resume (stub);
-
- break;
- }
-
- case GF_FOP_STAT:
- {
- if (op_ret < 0) {
- gf_log (stub->frame->this->name, GF_LOG_DEBUG,
- "%"PRId64": STAT (%s) on %s returning error: "
- "%"PRId32" (%"PRId32")",
- stub->frame->root->unique,
- stub->args.stat.loc.path,
- BOUND_XL(stub->frame)->name,
- op_ret, op_errno);
- server_stat_cbk (stub->frame, NULL, stub->frame->this,
- -1, ENOENT, NULL);
- server_loc_wipe (&stub->args.stat.loc);
- FREE (stub);
- return 0;
- }
-
- /* TODO:reply from here only, we already have stat structure */
- if (stub->args.stat.loc.parent == NULL)
- stub->args.stat.loc.parent = inode_ref (parent);
-
- if (server_inode && (stub->args.stat.loc.inode == NULL)) {
- stub->args.stat.loc.inode = inode_ref (server_inode);
- stub->args.stat.loc.ino = server_inode->ino;
- }
- call_resume (stub);
- break;
- }
-
- case GF_FOP_XATTROP:
- {
- if (op_ret < 0) {
- gf_log (stub->frame->this->name, GF_LOG_DEBUG,
- "%"PRId64": XATTROP (%s) on %s returning error: "
- "%"PRId32" (%"PRId32")",
- stub->frame->root->unique,
- stub->args.xattrop.loc.path,
- BOUND_XL(stub->frame)->name,
- op_ret, op_errno);
- server_xattrop_cbk (stub->frame, NULL,
- stub->frame->this, -1, ENOENT,
- NULL);
- server_loc_wipe (&stub->args.xattrop.loc);
- FREE (stub);
- return 0;
- }
-
- if (stub->args.xattrop.loc.parent == NULL)
- stub->args.xattrop.loc.parent = inode_ref (parent);
-
- if (server_inode && (stub->args.xattrop.loc.inode == NULL)) {
- stub->args.xattrop.loc.inode =
- inode_ref (server_inode);
-
- stub->args.xattrop.loc.ino = server_inode->ino;
- }
- call_resume (stub);
- break;
- }
-
- case GF_FOP_UNLINK:
- {
- if (op_ret < 0) {
- gf_log (stub->frame->this->name, GF_LOG_DEBUG,
- "%"PRId64": UNLINK (%s) on %s returning error: "
- "%"PRId32" (%"PRId32")",
- stub->frame->root->unique,
- stub->args.unlink.loc.path,
- BOUND_XL(stub->frame)->name,
- op_ret, op_errno);
- server_unlink_cbk (stub->frame, NULL,
- stub->frame->this, -1, ENOENT, NULL,
- NULL);
- server_loc_wipe (&stub->args.unlink.loc);
- FREE (stub);
- return 0;
- }
-
- if (stub->args.unlink.loc.parent == NULL)
- stub->args.unlink.loc.parent = inode_ref (parent);
-
- if (server_inode && (stub->args.unlink.loc.inode == NULL)) {
- stub->args.unlink.loc.inode = inode_ref (server_inode);
- stub->args.unlink.loc.ino = server_inode->ino;
- }
- call_resume (stub);
- break;
- }
-
- case GF_FOP_SYMLINK:
- {
- if ((op_ret < 0) && (parent == NULL)) {
- gf_log (stub->frame->this->name, GF_LOG_DEBUG,
- "%"PRId64": SYMLINK (%s -> %s) on %s returning error: "
- "%"PRId32" (%"PRId32")",
- stub->frame->root->unique,
- stub->args.symlink.loc.path,
- stub->args.symlink.linkname,
- BOUND_XL(stub->frame)->name,
- op_ret, op_errno);
- server_symlink_cbk (stub->frame, NULL,
- stub->frame->this, -1, ENOENT,
- NULL, NULL, NULL, NULL);
- server_loc_wipe (&stub->args.symlink.loc);
- FREE (stub);
- return 0;
- }
-
- if (stub->args.symlink.loc.parent == NULL)
- stub->args.symlink.loc.parent = inode_ref (parent);
-
- if (server_inode && (stub->args.symlink.loc.inode == NULL)) {
- stub->args.symlink.loc.inode =
- inode_ref (server_inode);
- stub->args.symlink.loc.ino = server_inode->ino;
- }
- call_resume (stub);
- break;
- }
-
- case GF_FOP_RMDIR:
- {
- if (op_ret < 0) {
- gf_log (stub->frame->this->name, GF_LOG_DEBUG,
- "%"PRId64": RMDIR (%s) on %s returning error: "
- "%"PRId32" (%"PRId32")",
- stub->frame->root->unique,
- stub->args.rmdir.loc.path,
- BOUND_XL(stub->frame)->name,
- op_ret, op_errno);
- server_rmdir_cbk (stub->frame, NULL, stub->frame->this,
- -1, ENOENT, NULL, NULL);
- server_loc_wipe (&stub->args.rmdir.loc);
- FREE (stub);
- return 0;
- }
-
- if (stub->args.rmdir.loc.parent == NULL)
- stub->args.rmdir.loc.parent = inode_ref (parent);
-
- if (server_inode && (stub->args.rmdir.loc.inode == NULL)) {
- stub->args.rmdir.loc.inode = inode_ref (server_inode);
- stub->args.rmdir.loc.ino = server_inode->ino;
- }
- call_resume (stub);
- break;
- }
-
- case GF_FOP_LINK:
- {
- if ((stub->args.link.oldloc.inode == NULL)
- || (stub->args.link.oldloc.parent == NULL)) {
- if (op_ret < 0) {
- gf_log (stub->frame->this->name, GF_LOG_DEBUG,
- "%"PRId64": LINK (%s -> %s) on %s returning "
- "error for oldloc: "
- "%"PRId32" (%"PRId32")",
- stub->frame->root->unique,
- stub->args.link.oldloc.path,
- stub->args.link.newloc.path,
- BOUND_XL(stub->frame)->name,
- op_ret, op_errno);
-
- server_link_cbk (stub->frame, NULL,
- stub->frame->this, -1, ENOENT,
- NULL, NULL, NULL, NULL);
- server_loc_wipe (&stub->args.link.oldloc);
- server_loc_wipe (&stub->args.link.newloc);
- FREE (stub);
- return 0;
- }
-
- if (stub->args.link.oldloc.parent == NULL)
- stub->args.link.oldloc.parent =
- inode_ref (parent);
-
- if (server_inode &&
- (stub->args.link.oldloc.inode == NULL)) {
- stub->args.link.oldloc.inode =
- inode_ref (server_inode);
- stub->args.link.oldloc.ino = server_inode->ino;
- }
-
- if (stub->args.link.newloc.parent == NULL) {
- do_path_lookup (stub,
- &(stub->args.link.newloc));
- break;
- }
- } else {
- /* we are called by the lookup of newpath */
- if ((op_ret < 0) && (parent == NULL)) {
- gf_log (stub->frame->this->name, GF_LOG_DEBUG,
- "%"PRId64": LINK (%s -> %s) on %s returning "
- "error for newloc: "
- "%"PRId32" (%"PRId32")",
- stub->frame->root->unique,
- stub->args.link.oldloc.path,
- stub->args.link.newloc.path,
- BOUND_XL(stub->frame)->name,
- op_ret, op_errno);
-
- server_link_cbk (stub->frame, NULL,
- stub->frame->this, -1, ENOENT,
- NULL, NULL, NULL, NULL);
-
- server_loc_wipe (&stub->args.link.oldloc);
- server_loc_wipe (&stub->args.link.newloc);
- FREE (stub);
- break;
- }
-
- if (stub->args.link.newloc.parent == NULL) {
- stub->args.link.newloc.parent =
- inode_ref (parent);
- }
-
- if (server_inode &&
- (stub->args.link.newloc.inode == NULL)) {
- /* as new.inode doesn't get forget, it
- * needs to be unref'd here */
- stub->args.link.newloc.inode =
- inode_ref (server_inode);
- stub->args.link.newloc.ino = server_inode->ino;
- }
- }
- call_resume (stub);
- break;
- }
-
- case GF_FOP_TRUNCATE:
- {
- if (op_ret < 0) {
- gf_log (stub->frame->this->name, GF_LOG_DEBUG,
- "%"PRId64": TRUNCATE (%s) on %s returning error: "
- "%"PRId32" (%"PRId32")",
- stub->frame->root->unique,
- stub->args.truncate.loc.path,
- BOUND_XL(stub->frame)->name,
- op_ret, op_errno);
-
- server_truncate_cbk (stub->frame, NULL,
- stub->frame->this, -1, ENOENT,
- NULL, NULL);
- server_loc_wipe (&stub->args.truncate.loc);
- FREE (stub);
- return 0;
- }
-
- if (stub->args.truncate.loc.parent == NULL)
- stub->args.truncate.loc.parent = inode_ref (parent);
-
- if (server_inode && (stub->args.truncate.loc.inode == NULL)) {
- stub->args.truncate.loc.inode =
- inode_ref (server_inode);
- stub->args.truncate.loc.ino = server_inode->ino;
- }
- call_resume (stub);
- break;
- }
-
- case GF_FOP_STATFS:
- {
- if (op_ret < 0) {
- gf_log (stub->frame->this->name, GF_LOG_DEBUG,
- "%"PRId64": STATFS (%s) on %s returning ENOENT: "
- "%"PRId32" (%"PRId32")",
- stub->frame->root->unique,
- stub->args.statfs.loc.path,
- BOUND_XL(stub->frame)->name,
- op_ret, op_errno);
-
- server_statfs_cbk (stub->frame, NULL,
- stub->frame->this, -1, ENOENT,
- NULL);
- server_loc_wipe (&stub->args.statfs.loc);
- FREE (stub);
- return 0;
- }
-
- if (stub->args.statfs.loc.parent == NULL)
- stub->args.statfs.loc.parent = inode_ref (parent);
-
- if (server_inode && (stub->args.statfs.loc.inode == NULL)) {
- stub->args.statfs.loc.inode = inode_ref (server_inode);
- stub->args.statfs.loc.ino = server_inode->ino;
- }
- call_resume (stub);
- break;
- }
-
- case GF_FOP_SETXATTR:
- {
- dict = stub->args.setxattr.dict;
- if (op_ret < 0) {
- gf_log (stub->frame->this->name, GF_LOG_DEBUG,
- "%"PRId64": SETXATTR (%s) on %s returning error: "
- "%"PRId32" (%"PRId32")",
- stub->frame->root->unique,
- stub->args.setxattr.loc.path,
- BOUND_XL(stub->frame)->name,
- op_ret, op_errno);
-
- server_setxattr_cbk (stub->frame, NULL,
- stub->frame->this, -1, ENOENT);
-
- server_loc_wipe (&stub->args.setxattr.loc);
- dict_unref (dict);
- FREE (stub);
- return 0;
- }
-
- if (stub->args.setxattr.loc.parent == NULL)
- stub->args.setxattr.loc.parent = inode_ref (parent);
-
- if (server_inode && (stub->args.setxattr.loc.inode == NULL)) {
- stub->args.setxattr.loc.inode =
- inode_ref (server_inode);
- stub->args.setxattr.loc.ino = server_inode->ino;
- }
- call_resume (stub);
- break;
- }
-
- case GF_FOP_GETXATTR:
- {
- if (op_ret < 0) {
- gf_log (stub->frame->this->name, GF_LOG_DEBUG,
- "%"PRId64": GETXATTR (%s) on %s for key %s "
- "returning error: %"PRId32" (%"PRId32")",
- stub->frame->root->unique,
- stub->args.getxattr.loc.path,
- BOUND_XL(stub->frame)->name,
- stub->args.getxattr.name ?
- stub->args.getxattr.name : "<nul>",
- op_ret, op_errno);
-
- server_getxattr_cbk (stub->frame, NULL,
- stub->frame->this, -1, ENOENT,
- NULL);
- server_loc_wipe (&stub->args.getxattr.loc);
- FREE (stub);
- return 0;
- }
-
- if (stub->args.getxattr.loc.parent == NULL)
- stub->args.getxattr.loc.parent = inode_ref (parent);
-
- if (server_inode && (stub->args.getxattr.loc.inode == NULL)) {
- stub->args.getxattr.loc.inode =
- inode_ref (server_inode);
- stub->args.getxattr.loc.ino = server_inode->ino;
- }
- call_resume (stub);
- break;
- }
-
- case GF_FOP_REMOVEXATTR:
- {
- if (op_ret < 0) {
- gf_log (stub->frame->this->name, GF_LOG_DEBUG,
- "%"PRId64": REMOVEXATTR (%s) on %s for key %s "
- "returning error: %"PRId32" (%"PRId32")",
- stub->frame->root->unique,
- stub->args.removexattr.loc.path,
- BOUND_XL(stub->frame)->name,
- stub->args.removexattr.name,
- op_ret, op_errno);
-
- server_removexattr_cbk (stub->frame, NULL,
- stub->frame->this, -1,
- ENOENT);
- server_loc_wipe (&stub->args.removexattr.loc);
- FREE (stub);
- return 0;
- }
-
- if (stub->args.removexattr.loc.parent == NULL)
- stub->args.removexattr.loc.parent = inode_ref (parent);
-
- if (server_inode &&
- (stub->args.removexattr.loc.inode == NULL)) {
- stub->args.removexattr.loc.inode =
- inode_ref (server_inode);
- stub->args.removexattr.loc.ino = server_inode->ino;
- }
- call_resume (stub);
- break;
- }
-
- case GF_FOP_OPENDIR:
- {
- if (op_ret < 0) {
- gf_log (stub->frame->this->name, GF_LOG_DEBUG,
- "%"PRId64": OPENDIR (%s) on %s returning error: "
- "%"PRId32" (%"PRId32")",
- stub->frame->root->unique,
- stub->args.opendir.loc.path,
- BOUND_XL(stub->frame)->name,
- op_ret, op_errno);
-
- server_opendir_cbk (stub->frame, NULL,
- stub->frame->this, -1, ENOENT,
- NULL);
- server_loc_wipe (&stub->args.opendir.loc);
- FREE (stub);
- return 0;
- }
-
- if (stub->args.opendir.loc.parent == NULL)
- stub->args.opendir.loc.parent = inode_ref (parent);
-
- if (server_inode && (stub->args.opendir.loc.inode == NULL)) {
- stub->args.opendir.loc.inode =
- inode_ref (server_inode);
- stub->args.opendir.loc.ino = server_inode->ino;
- }
- call_resume (stub);
- break;
- }
-
- case GF_FOP_ACCESS:
- {
- if (op_ret < 0) {
- gf_log (stub->frame->this->name, GF_LOG_DEBUG,
- "%"PRId64": ACCESS (%s) on %s returning error: "
- "%"PRId32" (%"PRId32")",
- stub->frame->root->unique,
- stub->args.access.loc.path,
- BOUND_XL(stub->frame)->name,
- op_ret, op_errno);
-
- server_access_cbk (stub->frame, NULL,
- stub->frame->this, -1, ENOENT);
- server_loc_wipe (&stub->args.access.loc);
- FREE (stub);
- return 0;
- }
-
- if (stub->args.access.loc.parent == NULL)
- stub->args.access.loc.parent = inode_ref (parent);
-
- if (server_inode && (stub->args.access.loc.inode == NULL)) {
- stub->args.access.loc.inode = inode_ref (server_inode);
- stub->args.access.loc.ino = server_inode->ino;
- }
- call_resume (stub);
- break;
- }
-
- case GF_FOP_READLINK:
- {
- if (op_ret < 0) {
- gf_log (stub->frame->this->name, GF_LOG_DEBUG,
- "%"PRId64": READLINK (%s) on %s returning error: "
- "%"PRId32" (%"PRId32")",
- stub->frame->root->unique,
- stub->args.readlink.loc.path,
- BOUND_XL(stub->frame)->name,
- op_ret, op_errno);
-
- server_readlink_cbk (stub->frame, NULL,
- stub->frame->this, -1, ENOENT,
- NULL, NULL);
- server_loc_wipe (&stub->args.readlink.loc);
- FREE (stub);
- return 0;
- }
-
- if (stub->args.readlink.loc.parent == NULL)
- stub->args.readlink.loc.parent = inode_ref (parent);
-
- if (server_inode && (stub->args.readlink.loc.inode == NULL)) {
- stub->args.readlink.loc.inode =
- inode_ref (server_inode);
- stub->args.readlink.loc.ino = server_inode->ino;
- }
- call_resume (stub);
- break;
- }
- case GF_FOP_MKDIR:
- {
- if ((op_ret < 0) && (parent == NULL)) {
- gf_log (stub->frame->this->name, GF_LOG_DEBUG,
- "%"PRId64": MKDIR (%s) on %s returning error: "
- "%"PRId32" (%"PRId32")",
- stub->frame->root->unique,
- stub->args.mkdir.loc.path,
- BOUND_XL(stub->frame)->name,
- op_ret, op_errno);
-
- server_mkdir_cbk (stub->frame, NULL,
- stub->frame->this, -1, ENOENT,
- NULL, NULL, NULL, NULL);
- server_loc_wipe (&stub->args.mkdir.loc);
- FREE (stub);
- break;
- }
-
- if (stub->args.mkdir.loc.parent == NULL)
- stub->args.mkdir.loc.parent = inode_ref (parent);
-
- if (server_inode && (stub->args.mkdir.loc.inode == NULL)) {
- stub->args.mkdir.loc.inode = inode_ref (server_inode);
- stub->args.mkdir.loc.ino = server_inode->ino;
- }
-
- call_resume (stub);
- break;
- }
-
- case GF_FOP_CREATE:
- {
- if ((op_ret < 0) && (parent == NULL)) {
- gf_log (stub->frame->this->name, GF_LOG_DEBUG,
- "%"PRId64": CREATE (%s) on %s returning error: "
- "%"PRId32" (%"PRId32")",
- stub->frame->root->unique,
- stub->args.create.loc.path,
- BOUND_XL(stub->frame)->name,
- op_ret, op_errno);
-
- server_create_cbk (stub->frame, NULL,
- stub->frame->this, -1, ENOENT,
- NULL, NULL, NULL, NULL, NULL);
- if (stub->args.create.fd)
- fd_unref (stub->args.create.fd);
- server_loc_wipe (&stub->args.create.loc);
- FREE (stub);
- break;
- }
-
- if (stub->args.create.loc.parent == NULL)
- stub->args.create.loc.parent = inode_ref (parent);
-
- if (server_inode && (stub->args.create.loc.inode == NULL)) {
- stub->args.create.loc.inode = inode_ref (server_inode);
- stub->args.create.loc.ino = server_inode->ino;
- }
-
- call_resume (stub);
- break;
- }
-
- case GF_FOP_MKNOD:
- {
- if ((op_ret < 0) && (parent == NULL)) {
- gf_log (stub->frame->this->name, GF_LOG_DEBUG,
- "%"PRId64": MKNOD (%s) on %s returning error: "
- "%"PRId32" (%"PRId32")",
- stub->frame->root->unique,
- stub->args.mknod.loc.path,
- BOUND_XL(stub->frame)->name,
- op_ret, op_errno);
-
- server_mknod_cbk (stub->frame, NULL,
- stub->frame->this, -1, ENOENT, NULL,
- NULL, NULL, NULL);
- server_loc_wipe (&stub->args.mknod.loc);
- FREE (stub);
- break;
- }
-
- if (stub->args.mknod.loc.parent == NULL)
- stub->args.mknod.loc.parent = inode_ref (parent);
-
- if (server_inode && (stub->args.mknod.loc.inode == NULL)) {
- stub->args.mknod.loc.inode = inode_ref (server_inode);
- stub->args.mknod.loc.ino = server_inode->ino;
- }
- call_resume (stub);
- break;
- }
- case GF_FOP_ENTRYLK:
- {
- if (op_ret < 0) {
- gf_log (stub->frame->this->name, GF_LOG_DEBUG,
- "%"PRId64": ENTRYLK (%s) on %s for key %s returning "
- "error: %"PRId32" (%"PRId32")",
- stub->frame->root->unique,
- stub->args.entrylk.loc.path,
- BOUND_XL(stub->frame)->name,
- stub->args.entrylk.name ?
- stub->args.entrylk.name : "<nul>",
- op_ret, op_errno);
-
- server_entrylk_cbk (stub->frame, NULL,
- stub->frame->this, -1, ENOENT);
- server_loc_wipe (&stub->args.entrylk.loc);
- FREE (stub);
- break;
- }
-
- if (stub->args.entrylk.loc.parent == NULL)
- stub->args.entrylk.loc.parent = inode_ref (parent);
-
- if (server_inode && (stub->args.entrylk.loc.inode == NULL)) {
- stub->args.entrylk.loc.inode = inode_ref (server_inode);
- stub->args.entrylk.loc.ino = server_inode->ino;
- }
- call_resume (stub);
- break;
- }
- case GF_FOP_INODELK:
- {
- if (op_ret < 0) {
- gf_log (stub->frame->this->name, GF_LOG_DEBUG,
- "%"PRId64": INODELK (%s) on %s returning error: "
- "%"PRId32" (%"PRId32")",
- stub->frame->root->unique,
- stub->args.inodelk.loc.path,
- BOUND_XL(stub->frame)->name,
- op_ret, op_errno);
-
- server_inodelk_cbk (stub->frame, NULL,
- stub->frame->this, -1, ENOENT);
- server_loc_wipe (&stub->args.inodelk.loc);
- FREE (stub);
- break;
- }
-
- if (stub->args.inodelk.loc.parent == NULL)
- stub->args.inodelk.loc.parent = inode_ref (parent);
-
- if (server_inode && (stub->args.inodelk.loc.inode == NULL)) {
- stub->args.inodelk.loc.inode =
- inode_ref (server_inode);
- stub->args.inodelk.loc.ino = server_inode->ino;
- }
- call_resume (stub);
- break;
- }
- case GF_FOP_SETATTR:
- {
- if (op_ret < 0) {
- gf_log (stub->frame->this->name, GF_LOG_DEBUG,
- "%"PRId64": SETATTR (%s) on %s returning error:"
- " %"PRId32" (%"PRId32")",
- stub->frame->root->unique,
- stub->args.setattr.loc.path,
- BOUND_XL(stub->frame)->name,
- op_ret, op_errno);
- server_setattr_cbk (stub->frame, NULL,
- stub->frame->this,
- -1, ENOENT, NULL, NULL);
- server_loc_wipe (&stub->args.setattr.loc);
- FREE (stub);
- return 0;
- }
-
- if (stub->args.setattr.loc.parent == NULL)
- stub->args.setattr.loc.parent = inode_ref (parent);
-
- if (server_inode && (stub->args.setattr.loc.inode == NULL)) {
- stub->args.setattr.loc.inode = inode_ref (server_inode);
- stub->args.setattr.loc.ino = server_inode->ino;
- }
- call_resume (stub);
- break;
- }
- default:
- call_resume (stub);
- }
-
- return 0;
-}
-
-int
-server_lookup_resume (call_frame_t *frame, xlator_t *this, loc_t *loc,
- dict_t *xattr_req)
-{
- server_state_t *state = NULL;
-
- state = CALL_STATE(frame);
-
- if ((state->loc.parent == NULL) &&
- (loc->parent))
- state->loc.parent = inode_ref (loc->parent);
-
- if (state->loc.inode == NULL) {
- if (loc->inode == NULL)
- state->loc.inode = inode_new (state->itable);
- else
- /* FIXME: why another lookup? */
- state->loc.inode = inode_ref (loc->inode);
- } else {
- if (loc->inode && (state->loc.inode != loc->inode)) {
- if (state->loc.inode)
- inode_unref (state->loc.inode);
- state->loc.inode = inode_ref (loc->inode);
- }
- }
-
- gf_log (BOUND_XL(frame)->name, GF_LOG_TRACE,
- "%"PRId64": LOOKUP \'%"PRId64"/%s\'",
- frame->root->unique, state->par, state->bname);
-
- STACK_WIND (frame, server_lookup_cbk,
- BOUND_XL(frame),
- BOUND_XL(frame)->fops->lookup,
- &(state->loc), xattr_req);
- return 0;
-}
-
-/*
- * server_lookup - lookup function for server protocol
- * @frame: call frame
- * @bound_xl:
- * @params: parameter dictionary
- *
- * not for external reference
- */
-int
-server_lookup (call_frame_t *frame, xlator_t *bound_xl,
- gf_hdr_common_t *hdr, size_t hdrlen,
- struct iobuf *iobuf)
-{
- gf_fop_lookup_req_t *req = NULL;
- server_state_t *state = NULL;
- call_stub_t *lookup_stub = NULL;
- int32_t ret = -1;
- size_t pathlen = 0;
- size_t baselen = 0;
- size_t dictlen = 0;
- dict_t *xattr_req = NULL;
- char *req_dictbuf = NULL;
-
- req = gf_param (hdr);
-
- state = CALL_STATE(frame);
- {
-
- pathlen = STRLEN_0 (req->path);
- dictlen = ntoh32 (req->dictlen);
-
- /* NOTE: lookup() uses req->ino only to identify if a lookup()
- * is requested for 'root' or not
- */
- state->ino = ntoh64 (req->ino);
- if (state->ino != 1)
- state->ino = 0;
-
- state->par = ntoh64 (req->par);
- state->path = req->path;
- if (IS_NOT_ROOT(pathlen)) {
- state->bname = req->bname + pathlen;
- baselen = STRLEN_0 (state->bname);
- }
-
- if (dictlen) {
- /* Unserialize the dictionary */
- req_dictbuf = memdup (req->dict + pathlen + baselen,
- dictlen);
- GF_VALIDATE_OR_GOTO(bound_xl->name, req_dictbuf, fail);
-
- xattr_req = dict_new ();
- GF_VALIDATE_OR_GOTO(bound_xl->name, xattr_req, fail);
-
- ret = dict_unserialize (req_dictbuf, dictlen,
- &xattr_req);
- if (ret < 0) {
- gf_log (bound_xl->name, GF_LOG_ERROR,
- "%"PRId64": %s (%"PRId64"): failed to "
- "unserialize req-buffer to dictionary",
- frame->root->unique, state->path,
- state->ino);
- free (req_dictbuf);
- goto fail;
- } else{
- xattr_req->extra_free = req_dictbuf;
- state->xattr_req = xattr_req;
- xattr_req = NULL;
- }
- }
- }
-
- ret = server_loc_fill (&state->loc, state, state->ino, state->par,
- state->bname, state->path);
-
- if (state->loc.inode) {
- /* revalidate */
- state->is_revalidate = 1;
- } else {
- /* fresh lookup or inode was previously pruned out */
- state->is_revalidate = -1;
- }
-
- lookup_stub = fop_lookup_stub (frame, server_lookup_resume,
- &(state->loc), state->xattr_req);
- GF_VALIDATE_OR_GOTO(bound_xl->name, lookup_stub, fail);
-
- if ((state->loc.parent == NULL) &&
- IS_NOT_ROOT(pathlen))
- do_path_lookup (lookup_stub, &(state->loc));
- else
- call_resume (lookup_stub);
-
- return 0;
-fail:
- server_lookup_cbk (frame, NULL, frame->this, -1,EINVAL, NULL, NULL,
- NULL, NULL);
- if (xattr_req)
- dict_unref (xattr_req);
-
- return 0;
-}
-
-
-/*
- * server_forget - forget function for server protocol
- *
- * not for external reference
- */
-int
-server_forget (call_frame_t *frame, xlator_t *bound_xl,
- gf_hdr_common_t *hdr, size_t hdrlen,
- struct iobuf *iobuf)
-{
- gf_log ("forget", GF_LOG_CRITICAL, "function not implemented");
- return 0;
-}
-
-
-int
-server_stat_resume (call_frame_t *frame, xlator_t *this, loc_t *loc)
-{
- server_state_t *state = NULL;
-
- state = CALL_STATE(frame);
-
- gf_log (BOUND_XL(frame)->name, GF_LOG_TRACE,
- "%"PRId64": STAT \'%s (%"PRId64")\'",
- frame->root->unique, state->loc.path, state->loc.ino);
-
- STACK_WIND (frame, server_stat_cbk,
- BOUND_XL(frame),
- BOUND_XL(frame)->fops->stat,
- loc);
- return 0;
-}
-
-/*
- * server_stat - stat function for server
- * @frame: call frame
- * @bound_xl: translator this server is bound to
- * @params: parameters dictionary
- *
- * not for external reference
- */
-int
-server_stat (call_frame_t *frame, xlator_t *bound_xl,
- gf_hdr_common_t *hdr, size_t hdrlen,
- struct iobuf *iobuf)
-{
- call_stub_t *stat_stub = NULL;
- gf_fop_stat_req_t *req = NULL;
- server_state_t *state = NULL;
- int32_t ret = -1;
- size_t pathlen = 0;
-
- req = gf_param (hdr);
- state = CALL_STATE(frame);
-
- state->ino = ntoh64 (req->ino);
- state->path = req->path;
- pathlen = STRLEN_0(state->path);
-
- ret = server_loc_fill (&(state->loc), state, state->ino, state->par,
- state->bname, state->path);
-
- stat_stub = fop_stat_stub (frame, server_stat_resume,
- &(state->loc));
- GF_VALIDATE_OR_GOTO(bound_xl->name, stat_stub, fail);
-
- if (((state->loc.parent == NULL) && IS_NOT_ROOT(pathlen)) ||
- (state->loc.inode == NULL)) {
- do_path_lookup (stat_stub, &(state->loc));
- } else {
- call_resume (stat_stub);
- }
- return 0;
-fail:
- server_stat_cbk (frame, NULL, frame->this, -1, EINVAL, NULL);
- return 0;
-}
-
-int
-server_setattr_resume (call_frame_t *frame,
- xlator_t *this,
- loc_t *loc,
- struct stat *stbuf,
- int32_t valid)
-{
- server_state_t *state = NULL;
-
- state = CALL_STATE(frame);
-
- gf_log (BOUND_XL(frame)->name, GF_LOG_TRACE,
- "%"PRId64": SETATTR \'%s (%"PRId64")\'",
- frame->root->unique, state->loc.path, state->loc.ino);
-
- STACK_WIND (frame, server_setattr_cbk,
- BOUND_XL(frame),
- BOUND_XL(frame)->fops->setattr,
- loc,
- stbuf, valid);
- return 0;
-}
-
-/*
- * server_setattr - setattr function for server
- * @frame: call frame
- * @bound_xl: translator this server is bound to
- * @params: parameters dictionary
- *
- * not for external reference
- */
-int
-server_setattr (call_frame_t *frame, xlator_t *bound_xl,
- gf_hdr_common_t *hdr, size_t hdrlen,
- struct iobuf *iobuf)
-{
- call_stub_t *setattr_stub = NULL;
- gf_fop_setattr_req_t *req = NULL;
- server_state_t *state = NULL;
- int32_t ret = -1;
- size_t pathlen = 0;
- struct stat stbuf = {0,};
- int32_t valid = 0;
-
- req = gf_param (hdr);
-
- state = CALL_STATE(frame);
-
- state->ino = ntoh64 (req->ino);
- state->path = req->path;
- pathlen = STRLEN_0(state->path);
-
- gf_stat_to_stat (&req->stbuf, &stbuf);
-
- valid = ntoh32 (req->valid);
-
- ret = server_loc_fill (&(state->loc), state, state->ino, state->par,
- state->bname, state->path);
-
- setattr_stub = fop_setattr_stub (frame, server_setattr_resume,
- &(state->loc), &stbuf, valid);
- GF_VALIDATE_OR_GOTO(bound_xl->name, setattr_stub, fail);
-
- if (((state->loc.parent == NULL) && IS_NOT_ROOT(pathlen)) ||
- (state->loc.inode == NULL)) {
- do_path_lookup (setattr_stub, &(state->loc));
- } else {
- call_resume (setattr_stub);
- }
- return 0;
-fail:
- server_setattr_cbk (frame, NULL, frame->this, -1, EINVAL, NULL, NULL);
- return 0;
-}
-
-int
-server_fsetattr (call_frame_t *frame, xlator_t *bound_xl,
- gf_hdr_common_t *hdr, size_t hdrlen,
- struct iobuf *iobuf)
-{
- server_connection_t *conn = NULL;
- gf_fop_fsetattr_req_t *req = NULL;
- server_state_t *state = NULL;
- struct stat stbuf = {0,};
- int32_t valid = 0;
-
- conn = SERVER_CONNECTION(frame);
-
- req = gf_param (hdr);
- state = CALL_STATE (frame);
- {
- state->fd_no = ntoh64 (req->fd);
- if (state->fd_no >= 0)
- state->fd = gf_fd_fdptr_get (conn->fdtable,
- state->fd_no);
-
- gf_stat_to_stat (&req->stbuf, &stbuf);
-
- valid = ntoh32 (req->valid);
- }
-
- GF_VALIDATE_OR_GOTO(bound_xl->name, state->fd, fail);
-
- STACK_WIND (frame, server_fsetattr_cbk,
- BOUND_XL(frame),
- BOUND_XL(frame)->fops->fsetattr,
- state->fd, &stbuf, valid);
-
- return 0;
-fail:
- server_fsetattr_cbk (frame, NULL, frame->this, -1, EINVAL, NULL, NULL);
- return 0;
-}
-
-int
-server_readlink_resume (call_frame_t *frame, xlator_t *this, loc_t *loc,
- size_t size)
-{
- server_state_t *state = NULL;
-
- state = CALL_STATE(frame);
-
- gf_log (BOUND_XL(frame)->name, GF_LOG_TRACE,
- "%"PRId64": READLINK \'%s (%"PRId64")\'",
- frame->root->unique, state->loc.path, state->loc.ino);
-
- STACK_WIND (frame, server_readlink_cbk,
- BOUND_XL(frame),
- BOUND_XL(frame)->fops->readlink,
- loc, size);
- return 0;
-}
-
-/*
- * server_readlink - readlink function for server
- * @frame: call frame
- * @bound_xl: translator this server is bound to
- * @params: parameters dictionary
- *
- * not for external reference
- */
-int
-server_readlink (call_frame_t *frame, xlator_t *bound_xl,
- gf_hdr_common_t *hdr, size_t hdrlen,
- struct iobuf *iobuf)
-{
- call_stub_t *readlink_stub = NULL;
- gf_fop_readlink_req_t *req = NULL;
- server_state_t *state = NULL;
- int32_t ret = -1;
-
- req = gf_param (hdr);
- state = CALL_STATE(frame);
-
- state->size = ntoh32 (req->size);
-
- state->ino = ntoh64 (req->ino);
- state->path = req->path;
-
- ret = server_loc_fill (&(state->loc), state, state->ino, 0, NULL,
- state->path);
-
- readlink_stub = fop_readlink_stub (frame, server_readlink_resume,
- &(state->loc), state->size);
- GF_VALIDATE_OR_GOTO(bound_xl->name, readlink_stub, fail);
-
- if ((state->loc.parent == NULL) ||
- (state->loc.inode == NULL)) {
- do_path_lookup (readlink_stub, &(state->loc));
- } else {
- call_resume (readlink_stub);
- }
- return 0;
-fail:
- server_readlink_cbk (frame, NULL,frame->this, -1, EINVAL, NULL, NULL);
- return 0;
-}
-
-int
-server_create_resume (call_frame_t *frame, xlator_t *this, loc_t *loc,
- int32_t flags, mode_t mode, fd_t *fd)
-{
- server_state_t *state = NULL;
-
- state = CALL_STATE(frame);
-
- if (state->loc.parent == NULL)
- state->loc.parent = inode_ref (loc->parent);
-
- state->loc.inode = inode_new (state->itable);
- GF_VALIDATE_OR_GOTO(BOUND_XL(frame)->name, state->loc.inode, fail);
-
- state->fd = fd_create (state->loc.inode, frame->root->pid);
- GF_VALIDATE_OR_GOTO(BOUND_XL(frame)->name, state->fd, fail);
-
- state->fd->flags = flags;
- state->fd = fd_ref (state->fd);
-
- gf_log (BOUND_XL(frame)->name, GF_LOG_TRACE,
- "%"PRId64": CREATE \'%"PRId64"/%s\'",
- frame->root->unique, state->par, state->bname);
-
- STACK_WIND (frame, server_create_cbk,
- BOUND_XL(frame),
- BOUND_XL(frame)->fops->create,
- &(state->loc), flags, mode, state->fd);
-
- return 0;
-fail:
- server_create_cbk (frame, NULL, frame->this, -1, EINVAL, NULL, NULL,
- NULL, NULL, NULL);
- return 0;
-}
-
-
-/*
- * server_create - create function for server
- * @frame: call frame
- * @bound_xl: translator this server is bound to
- * @params: parameters dictionary
- *
- * not for external reference
- */
-int
-server_create (call_frame_t *frame, xlator_t *bound_xl,
- gf_hdr_common_t *hdr, size_t hdrlen,
- struct iobuf *iobuf)
-{
- gf_fop_create_req_t *req = NULL;
- server_state_t *state = NULL;
- call_stub_t *create_stub = NULL;
- int32_t ret = -1;
- size_t pathlen = 0;
-
- req = gf_param (hdr);
- state = CALL_STATE(frame);
- {
- pathlen = STRLEN_0(req->path);
-
- state->par = ntoh64 (req->par);
- state->path = req->path;
- if (IS_NOT_ROOT(pathlen))
- state->bname = req->bname + pathlen;
-
- state->mode = ntoh32 (req->mode);
- state->flags = gf_flags_to_flags (ntoh32 (req->flags));
- }
-
- ret = server_loc_fill (&(state->loc), state,
- 0, state->par, state->bname,
- state->path);
-
- create_stub = fop_create_stub (frame, server_create_resume,
- &(state->loc), state->flags,
- state->mode, state->fd);
- GF_VALIDATE_OR_GOTO(bound_xl->name, create_stub, fail);
-
- if (state->loc.parent == NULL) {
- do_path_lookup (create_stub, &state->loc);
- } else {
- call_resume (create_stub);
- }
- return 0;
-fail:
- server_create_cbk (frame, NULL, frame->this, -1, EINVAL, NULL, NULL,
- NULL, NULL, NULL);
- return 0;
-}
-
-
-int
-server_open_resume (call_frame_t *frame, xlator_t *this, loc_t *loc,
- int32_t flags, fd_t *fd, int32_t wbflags)
-{
- server_state_t *state = NULL;
- fd_t *new_fd = NULL;
-
- state = CALL_STATE(frame);
- new_fd = fd_create (loc->inode, frame->root->pid);
- GF_VALIDATE_OR_GOTO(BOUND_XL(frame)->name, new_fd, fail);
-
- new_fd->flags = flags;
-
- state->fd = fd_ref (new_fd);
-
- gf_log (BOUND_XL(frame)->name, GF_LOG_TRACE,
- "%"PRId64": OPEN \'%s (%"PRId64")\'",
- frame->root->unique, state->path, state->ino);
-
- STACK_WIND (frame, server_open_cbk,
- BOUND_XL(frame),
- BOUND_XL(frame)->fops->open,
- loc, flags, state->fd, wbflags);
-
- return 0;
-fail:
- server_open_cbk (frame, NULL, frame->this, -1, EINVAL, NULL);
- return 0;
-}
-
-/*
- * server_open - open function for server protocol
- * @frame: call frame
- * @bound_xl: translator this server protocol is bound to
- * @params: parameters dictionary
- *
- * not for external reference
- */
-int
-server_open (call_frame_t *frame, xlator_t *bound_xl,
- gf_hdr_common_t *hdr, size_t hdrlen,
- struct iobuf *iobuf)
-{
- call_stub_t *open_stub = NULL;
- gf_fop_open_req_t *req = NULL;
- server_state_t *state = NULL;
- int32_t ret = -1;
- size_t pathlen = 0;
-
- req = gf_param (hdr);
- state = CALL_STATE (frame);
- {
- state->ino = ntoh64 (req->ino);
- state->path = req->path;
- pathlen = STRLEN_0(state->path);
- state->flags = gf_flags_to_flags (ntoh32 (req->flags));
- }
- ret = server_loc_fill (&(state->loc), state,
- state->ino, 0, NULL, state->path);
-
- open_stub = fop_open_stub (frame,
- server_open_resume,
- &(state->loc), state->flags, NULL, 0);
- GF_VALIDATE_OR_GOTO(bound_xl->name, open_stub, fail);
-
- if (((state->loc.parent == NULL) && IS_NOT_ROOT(pathlen)) ||
- (state->loc.inode == NULL)) {
- do_path_lookup (open_stub, &state->loc);
- } else {
- call_resume (open_stub);
- }
- return 0;
-fail:
- server_open_cbk (frame, NULL, frame->this, -1, EINVAL, NULL);
- return 0;
-}
-
-
-/*
- * server_readv - readv function for server protocol
- * @frame: call frame
- * @bound_xl:
- * @params: parameter dictionary
- *
- * not for external reference
- */
-int
-server_readv (call_frame_t *frame, xlator_t *bound_xl,
- gf_hdr_common_t *hdr, size_t hdrlen,
- struct iobuf *iobuf)
-{
- gf_fop_read_req_t *req = NULL;
- server_state_t *state = NULL;
- server_connection_t *conn = NULL;
-
- conn = SERVER_CONNECTION (frame);
-
- req = gf_param (hdr);
-
- state = CALL_STATE(frame);
- {
- state->fd_no = ntoh64 (req->fd);
- if (state->fd_no >= 0)
- state->fd = gf_fd_fdptr_get (conn->fdtable,
- state->fd_no);
-
- state->size = ntoh32 (req->size);
- state->offset = ntoh64 (req->offset);
- }
-
- GF_VALIDATE_OR_GOTO(bound_xl->name, state->fd, fail);
-
- gf_log (bound_xl->name, GF_LOG_TRACE,
- "%"PRId64": READV \'fd=%"PRId64" (%"PRId64"); "
- "offset=%"PRId64"; size=%"PRId64,
- frame->root->unique, state->fd_no, state->fd->inode->ino,
- state->offset, (int64_t)state->size);
-
- STACK_WIND (frame, server_readv_cbk,
- BOUND_XL(frame),
- BOUND_XL(frame)->fops->readv,
- state->fd, state->size, state->offset);
- return 0;
-fail:
- server_readv_cbk (frame, NULL, frame->this, -1, EINVAL, NULL, 0,
- NULL, NULL);
- return 0;
-}
-
-
-/*
- * server_writev - writev function for server
- * @frame: call frame
- * @bound_xl:
- * @params: parameter dictionary
- *
- * not for external reference
- */
-int
-server_writev (call_frame_t *frame, xlator_t *bound_xl,
- gf_hdr_common_t *hdr, size_t hdrlen,
- struct iobuf *iobuf)
-{
- server_connection_t *conn = NULL;
- gf_fop_write_req_t *req = NULL;
- struct iovec iov = {0, };
- struct iobref *iobref = NULL;
- server_state_t *state = NULL;
-
- conn = SERVER_CONNECTION(frame);
-
- req = gf_param (hdr);
- state = CALL_STATE(frame);
- {
- state->fd_no = ntoh64 (req->fd);
- if (state->fd_no >= 0)
- state->fd = gf_fd_fdptr_get (conn->fdtable,
- state->fd_no);
-
- state->offset = ntoh64 (req->offset);
- state->size = ntoh32 (req->size);
- }
-
- GF_VALIDATE_OR_GOTO(bound_xl->name, state->fd, fail);
-
- if (iobuf)
- iov.iov_base = iobuf->ptr;
- iov.iov_len = state->size;
-
- iobref = iobref_new ();
- GF_VALIDATE_OR_GOTO(bound_xl->name, iobref, fail);
-
- iobref_add (iobref, iobuf);
-
- gf_log (bound_xl->name, GF_LOG_TRACE,
- "%"PRId64": WRITEV \'fd=%"PRId64" (%"PRId64"); "
- "offset=%"PRId64"; size=%"PRId32,
- frame->root->unique, state->fd_no, state->fd->inode->ino,
- state->offset, (int32_t)state->size);
-
- STACK_WIND (frame, server_writev_cbk,
- BOUND_XL(frame),
- BOUND_XL(frame)->fops->writev,
- state->fd, &iov, 1, state->offset, iobref);
-
- if (iobref)
- iobref_unref (iobref);
- if (iobuf)
- iobuf_unref (iobuf);
-
- return 0;
-fail:
- server_writev_cbk (frame, NULL, frame->this, -1, EINVAL, NULL, NULL);
-
- if (iobref)
- iobref_unref (iobref);
- if (iobuf)
- iobuf_unref (iobuf);
-
- return 0;
-}
-
-
-
-/*
- * server_release - release function for server protocol
- * @frame: call frame
- * @bound_xl:
- * @params: parameter dictionary
- *
- * not for external reference
- */
-int
-server_release (call_frame_t *frame, xlator_t *bound_xl,
- gf_hdr_common_t *hdr, size_t hdrlen,
- struct iobuf *iobuf)
-{
- gf_cbk_release_req_t *req = NULL;
- server_state_t *state = NULL;
- server_connection_t *conn = NULL;
-
- conn = SERVER_CONNECTION(frame);
-
- req = gf_param (hdr);
- state = CALL_STATE(frame);
-
- state->fd_no = ntoh64 (req->fd);
-
- gf_fd_put (conn->fdtable, state->fd_no);
-
- gf_log (bound_xl->name, GF_LOG_TRACE,
- "%"PRId64": RELEASE \'fd=%"PRId64"\'",
- frame->root->unique, state->fd_no);
-
- server_release_cbk (frame, NULL, frame->this, 0, 0);
- return 0;
-}
-
-
-/*
- * server_fsync - fsync function for server protocol
- * @frame: call frame
- * @bound_xl:
- * @params: parameters dictionary
- *
- * not for external reference
- */
-int
-server_fsync (call_frame_t *frame, xlator_t *bound_xl,
- gf_hdr_common_t *hdr, size_t hdrlen,
- struct iobuf *iobuf)
-{
- gf_fop_fsync_req_t *req = NULL;
- server_state_t *state = NULL;
- server_connection_t *conn = NULL;
-
- conn = SERVER_CONNECTION(frame);
-
- req = gf_param (hdr);
- state = CALL_STATE(frame);
- {
- state->fd_no = ntoh64 (req->fd);
- if (state->fd_no >= 0)
- state->fd = gf_fd_fdptr_get (conn->fdtable,
- state->fd_no);
-
- state->flags = ntoh32 (req->data);
- }
-
- GF_VALIDATE_OR_GOTO(bound_xl->name, state->fd, fail);
-
- gf_log (bound_xl->name, GF_LOG_TRACE,
- "%"PRId64": FSYNC \'fd=%"PRId64" (%"PRId64")\'",
- frame->root->unique, state->fd_no, state->fd->inode->ino);
-
- STACK_WIND (frame, server_fsync_cbk,
- BOUND_XL(frame),
- BOUND_XL(frame)->fops->fsync,
- state->fd, state->flags);
- return 0;
-fail:
- server_fsync_cbk (frame, NULL, frame->this, -1, EINVAL, NULL, NULL);
-
- return 0;
-}
-
-
-/*
- * server_flush - flush function for server protocol
- * @frame: call frame
- * @bound_xl:
- * @params: parameter dictionary
- *
- * not for external reference
- */
-int
-server_flush (call_frame_t *frame, xlator_t *bound_xl,
- gf_hdr_common_t *hdr, size_t hdrlen,
- struct iobuf *iobuf)
-{
- gf_fop_flush_req_t *req = NULL;
- server_state_t *state = NULL;
- server_connection_t *conn = NULL;
-
- conn = SERVER_CONNECTION (frame);
-
- req = gf_param (hdr);
- state = CALL_STATE(frame);
- {
- state->fd_no = ntoh64 (req->fd);
- if (state->fd_no >= 0)
- state->fd = gf_fd_fdptr_get (conn->fdtable,
- state->fd_no);
- }
-
- GF_VALIDATE_OR_GOTO (bound_xl->name, state->fd, fail);
-
- gf_log (bound_xl->name, GF_LOG_TRACE,
- "%"PRId64": FLUSH \'fd=%"PRId64" (%"PRId64")\'",
- frame->root->unique, state->fd_no, state->fd->inode->ino);
-
- STACK_WIND (frame, server_flush_cbk,
- BOUND_XL(frame),
- BOUND_XL(frame)->fops->flush,
- state->fd);
- return 0;
-
-fail:
- server_flush_cbk (frame, NULL, frame->this, -1, EINVAL);
-
- return 0;
-}
-
-
-/*
- * server_ftruncate - ftruncate function for server protocol
- * @frame: call frame
- * @bound_xl:
- * @params: parameters dictionary
- *
- * not for external reference
- */
-int
-server_ftruncate (call_frame_t *frame, xlator_t *bound_xl,
- gf_hdr_common_t *hdr, size_t hdrlen,
- struct iobuf *iobuf)
-{
- gf_fop_ftruncate_req_t *req = NULL;
- server_state_t *state = NULL;
- server_connection_t *conn = NULL;
-
- conn = SERVER_CONNECTION(frame);
-
- req = gf_param (hdr);
-
- state = CALL_STATE(frame);
- {
- state->fd_no = ntoh64 (req->fd);
- if (state->fd_no >= 0)
- state->fd = gf_fd_fdptr_get (conn->fdtable,
- state->fd_no);
-
- state->offset = ntoh64 (req->offset);
- }
-
- GF_VALIDATE_OR_GOTO(bound_xl->name, state->fd, fail);
-
- gf_log (bound_xl->name, GF_LOG_TRACE,
- "%"PRId64": FTRUNCATE \'fd=%"PRId64" (%"PRId64"); "
- "offset=%"PRId64"\'",
- frame->root->unique, state->fd_no, state->fd->inode->ino,
- state->offset);
-
- STACK_WIND (frame, server_ftruncate_cbk,
- bound_xl,
- bound_xl->fops->ftruncate,
- state->fd, state->offset);
- return 0;
-fail:
- server_ftruncate_cbk (frame, NULL, frame->this, -1, EINVAL, NULL, NULL);
-
- return 0;
-}
-
-
-/*
- * server_fstat - fstat function for server protocol
- * @frame: call frame
- * @bound_xl:
- * @params: parameter dictionary
- *
- * not for external reference
- */
-int
-server_fstat (call_frame_t *frame, xlator_t *bound_xl,
- gf_hdr_common_t *hdr, size_t hdrlen,
- struct iobuf *iobuf)
-{
- gf_fop_fstat_req_t *req = NULL;
- server_state_t *state = NULL;
- server_connection_t *conn = NULL;
-
- conn = SERVER_CONNECTION (frame);
-
- req = gf_param (hdr);
- state = CALL_STATE(frame);
- {
- state->fd_no = ntoh64 (req->fd);
- if (state->fd_no >= 0)
- state->fd = gf_fd_fdptr_get (conn->fdtable,
- state->fd_no);
- }
-
-
- if (state->fd == NULL) {
- gf_log (frame->this->name, GF_LOG_WARNING,
- "fd - %"PRId64": unresolved fd",
- state->fd_no);
-
- server_fstat_cbk (frame, NULL, frame->this,
- -1, EBADF, NULL);
-
- goto out;
- }
-
- gf_log (bound_xl->name, GF_LOG_TRACE,
- "%"PRId64": FSTAT \'fd=%"PRId64" (%"PRId64")\'",
- frame->root->unique, state->fd_no, state->fd->inode->ino);
-
- STACK_WIND (frame, server_fstat_cbk,
- bound_xl,
- bound_xl->fops->fstat,
- state->fd);
-out:
- return 0;
-}
-
-
-int
-server_truncate_resume (call_frame_t *frame, xlator_t *this, loc_t *loc,
- off_t offset)
-{
- server_state_t *state = NULL;
-
- state = CALL_STATE(frame);
-
- gf_log (BOUND_XL(frame)->name, GF_LOG_TRACE,
- "%"PRId64": TRUNCATE \'%s (%"PRId64")\'",
- frame->root->unique, state->path, state->ino);
-
- STACK_WIND (frame, server_truncate_cbk,
- BOUND_XL(frame),
- BOUND_XL(frame)->fops->truncate,
- loc, offset);
- return 0;
-}
-
-
-/*
- * server_truncate - truncate function for server protocol
- * @frame: call frame
- * @bound_xl:
- * @params:
- *
- * not for external reference
- */
-int
-server_truncate (call_frame_t *frame, xlator_t *bound_xl,
- gf_hdr_common_t *hdr, size_t hdrlen,
- struct iobuf *iobuf)
-{
- call_stub_t *truncate_stub = NULL;
- gf_fop_truncate_req_t *req = NULL;
- server_state_t *state = NULL;
- int32_t ret = -1;
- size_t pathlen = 0;
-
- req = gf_param (hdr);
- state = CALL_STATE(frame);
- {
- pathlen = STRLEN_0(req->path);
- state->offset = ntoh64 (req->offset);
-
- state->path = req->path;
- state->ino = ntoh64 (req->ino);
- }
-
-
- ret = server_loc_fill (&(state->loc), state,
- state->ino, 0, NULL, state->path);
-
- truncate_stub = fop_truncate_stub (frame, server_truncate_resume,
- &(state->loc),
- state->offset);
- if ((state->loc.parent == NULL) ||
- (state->loc.inode == NULL)) {
- do_path_lookup (truncate_stub, &(state->loc));
- } else {
- call_resume (truncate_stub);
- }
-
- return 0;
-}
-
-
-int
-server_unlink_resume (call_frame_t *frame, xlator_t *this, loc_t *loc)
-{
- server_state_t *state = NULL;
-
- state = CALL_STATE(frame);
-
- if (state->loc.parent == NULL)
- state->loc.parent = inode_ref (loc->parent);
-
- if (state->loc.inode == NULL)
- state->loc.inode = inode_ref (loc->inode);
-
- gf_log (BOUND_XL(frame)->name, GF_LOG_TRACE,
- "%"PRId64": UNLINK \'%"PRId64"/%s (%"PRId64")\'",
- frame->root->unique, state->par, state->path,
- state->loc.inode->ino);
-
- STACK_WIND (frame, server_unlink_cbk,
- BOUND_XL(frame),
- BOUND_XL(frame)->fops->unlink,
- loc);
- return 0;
-}
-
-/*
- * server_unlink - unlink function for server protocol
- * @frame: call frame
- * @bound_xl:
- * @params: parameter dictionary
- *
- * not for external reference
- */
-int
-server_unlink (call_frame_t *frame, xlator_t *bound_xl,
- gf_hdr_common_t *hdr, size_t hdrlen,
- struct iobuf *iobuf)
-{
- call_stub_t *unlink_stub = NULL;
- gf_fop_unlink_req_t *req = NULL;
- server_state_t *state = NULL;
- int32_t ret = -1;
- size_t pathlen = 0;
-
- req = gf_param (hdr);
- state = CALL_STATE (frame);
-
- pathlen = STRLEN_0(req->path);
-
- state->par = ntoh64 (req->par);
- state->path = req->path;
- if (IS_NOT_ROOT(pathlen))
- state->bname = req->bname + pathlen;
-
- ret = server_loc_fill (&(state->loc), state, 0, state->par,
- state->bname, state->path);
-
- unlink_stub = fop_unlink_stub (frame, server_unlink_resume,
- &(state->loc));
-
- if ((state->loc.parent == NULL) ||
- (state->loc.inode == NULL)) {
- do_path_lookup (unlink_stub, &state->loc);
- } else {
- call_resume (unlink_stub);
- }
-
- return 0;
-}
-
-
-int
-server_setxattr_resume (call_frame_t *frame, xlator_t *this, loc_t *loc,
- dict_t *dict, int32_t flags)
-{
- server_state_t *state = NULL;
-
- state = CALL_STATE(frame);
-
- gf_log (BOUND_XL(frame)->name, GF_LOG_TRACE,
- "%"PRId64": SETXATTR \'%s (%"PRId64")\'",
- frame->root->unique, state->path, state->ino);
-
- STACK_WIND (frame, server_setxattr_cbk,
- BOUND_XL(frame),
- BOUND_XL(frame)->fops->setxattr,
- loc, dict, flags);
- return 0;
-}
-
-/*
- * server_setxattr - setxattr function for server protocol
- * @frame: call frame
- * @bound_xl:
- * @params: parameter dictionary
- *
- * not for external reference
- */
-
-int
-server_setxattr (call_frame_t *frame, xlator_t *bound_xl,
- gf_hdr_common_t *hdr, size_t hdrlen,
- struct iobuf *iobuf)
-{
- call_stub_t *setxattr_stub = NULL;
- gf_fop_setxattr_req_t *req = NULL;
- dict_t *dict = NULL;
- server_state_t *state = NULL;
- int32_t ret = -1;
- size_t pathlen = 0;
- size_t dict_len = 0;
- char *req_dictbuf = NULL;
-
- req = gf_param (hdr);
- state = CALL_STATE(frame);
- {
- dict_len = ntoh32 (req->dict_len);
-
- state->path = req->path + dict_len;
-
- pathlen = STRLEN_0(state->path);
- state->ino = ntoh64 (req->ino);
-
- state->flags = ntoh32 (req->flags);
- }
-
- ret = server_loc_fill (&(state->loc), state, state->ino, 0, NULL,
- state->path);
- {
- /* Unserialize the dictionary */
- req_dictbuf = memdup (req->dict, dict_len);
- GF_VALIDATE_OR_GOTO(bound_xl->name, req_dictbuf, fail);
-
- dict = dict_new ();
- GF_VALIDATE_OR_GOTO(bound_xl->name, dict, fail);
-
- ret = dict_unserialize (req_dictbuf, dict_len, &dict);
- if (ret < 0) {
- gf_log (bound_xl->name, GF_LOG_ERROR,
- "%"PRId64": %s (%"PRId64"): failed to "
- "unserialize request buffer to dictionary",
- frame->root->unique, state->loc.path,
- state->ino);
- free (req_dictbuf);
- goto fail;
- } else{
- dict->extra_free = req_dictbuf;
- }
- }
-
- setxattr_stub = fop_setxattr_stub (frame, server_setxattr_resume,
- &(state->loc), dict, state->flags);
- GF_VALIDATE_OR_GOTO(bound_xl->name, setxattr_stub, fail);
-
- if (((state->loc.parent == NULL) && IS_NOT_ROOT(pathlen)) ||
- (state->loc.inode == NULL)) {
- do_path_lookup (setxattr_stub, &(state->loc));
- } else {
- call_resume (setxattr_stub);
- }
-
- if (dict)
- dict_unref (dict);
-
- return 0;
-fail:
- if (dict)
- dict_unref (dict);
-
- server_setxattr_cbk (frame, NULL, frame->this, -1, ENOENT);
- return 0;
-
-}
-
-
-int
-server_fsetxattr (call_frame_t *frame, xlator_t *bound_xl,
- gf_hdr_common_t *hdr, size_t hdrlen,
- struct iobuf *iobuf)
-{
- server_connection_t *conn = NULL;
- gf_fop_fsetxattr_req_t *req = NULL;
- dict_t *dict = NULL;
- server_state_t *state = NULL;
- int32_t ret = -1;
- size_t pathlen = 0;
- size_t dict_len = 0;
- char *req_dictbuf = NULL;
-
- conn = SERVER_CONNECTION (frame);
-
- req = gf_param (hdr);
- state = CALL_STATE(frame);
- {
- state->fd_no = ntoh64 (req->fd);
- if (state->fd_no >= 0)
- state->fd = gf_fd_fdptr_get (conn->fdtable,
- state->fd_no);
- dict_len = ntoh32 (req->dict_len);
-
- pathlen = STRLEN_0(state->path);
- state->ino = ntoh64 (req->ino);
-
- state->flags = ntoh32 (req->flags);
- }
-
- /* Unserialize the dictionary */
- req_dictbuf = memdup (req->dict, dict_len);
- GF_VALIDATE_OR_GOTO(bound_xl->name, req_dictbuf, fail);
-
- dict = dict_new ();
- GF_VALIDATE_OR_GOTO(bound_xl->name, dict, fail);
-
- ret = dict_unserialize (req_dictbuf, dict_len, &dict);
- if (ret < 0) {
- gf_log (bound_xl->name, GF_LOG_ERROR,
- "%"PRId64": %s (%"PRId64"): failed to "
- "unserialize request buffer to dictionary",
- frame->root->unique, state->loc.path,
- state->ino);
- free (req_dictbuf);
- goto fail;
- } else{
- dict->extra_free = req_dictbuf;
- }
-
- STACK_WIND (frame, server_setxattr_cbk,
- BOUND_XL(frame),
- BOUND_XL(frame)->fops->fsetxattr,
- state->fd, dict, state->flags);
-
- if (dict)
- dict_unref (dict);
-
- return 0;
-fail:
- if (dict)
- dict_unref (dict);
-
- server_fsetxattr_cbk (frame, NULL, frame->this,
- -1, ENOENT);
- return 0;
-}
-
-
-int
-server_fxattrop (call_frame_t *frame, xlator_t *bound_xl,
- gf_hdr_common_t *hdr, size_t hdrlen,
- struct iobuf *iobuf)
-{
- server_connection_t *conn = NULL;
- gf_fop_fxattrop_req_t *req = NULL;
- dict_t *dict = NULL;
- server_state_t *state = NULL;
- size_t dict_len = 0;
- char *req_dictbuf = NULL;
- int32_t ret = -1;
-
- conn = SERVER_CONNECTION(frame);
-
- req = gf_param (hdr);
- state = CALL_STATE(frame);
- {
- state->fd_no = ntoh64 (req->fd);
- if (state->fd_no >= 0)
- state->fd = gf_fd_fdptr_get (conn->fdtable,
- state->fd_no);
-
- dict_len = ntoh32 (req->dict_len);
- state->ino = ntoh64 (req->ino);
- state->flags = ntoh32 (req->flags);
- }
-
- if (dict_len) {
- /* Unserialize the dictionary */
- req_dictbuf = memdup (req->dict, dict_len);
- GF_VALIDATE_OR_GOTO(bound_xl->name, req_dictbuf, fail);
-
- dict = dict_new ();
- GF_VALIDATE_OR_GOTO(bound_xl->name, dict, fail);
-
- ret = dict_unserialize (req_dictbuf, dict_len, &dict);
- if (ret < 0) {
- gf_log (bound_xl->name, GF_LOG_ERROR,
- "fd - %"PRId64" (%"PRId64"): failed to unserialize "
- "request buffer to dictionary",
- state->fd_no, state->fd->inode->ino);
- free (req_dictbuf);
- goto fail;
- } else {
- dict->extra_free = req_dictbuf;
- }
- }
-
- gf_log (bound_xl->name, GF_LOG_TRACE,
- "%"PRId64": FXATTROP \'fd=%"PRId64" (%"PRId64")\'",
- frame->root->unique, state->fd_no, state->fd->inode->ino);
-
- STACK_WIND (frame, server_fxattrop_cbk,
- bound_xl,
- bound_xl->fops->fxattrop,
- state->fd, state->flags, dict);
- if (dict)
- dict_unref (dict);
- return 0;
-
-fail:
- if (dict)
- dict_unref (dict);
-
- server_fxattrop_cbk (frame, NULL, frame->this, -1, EINVAL, NULL);
- return 0;
-}
-
-
-int
-server_xattrop_resume (call_frame_t *frame, xlator_t *this,
- loc_t *loc, gf_xattrop_flags_t flags, dict_t *dict)
-{
- server_state_t *state = NULL;
-
- state = CALL_STATE(frame);
-
- gf_log (BOUND_XL(frame)->name, GF_LOG_TRACE,
- "%"PRId64": XATTROP \'%s (%"PRId64")\'",
- frame->root->unique, state->path, state->ino);
-
- STACK_WIND (frame, server_xattrop_cbk,
- BOUND_XL(frame),
- BOUND_XL(frame)->fops->xattrop,
- loc, flags, dict);
- return 0;
-}
-
-
-int
-server_xattrop (call_frame_t *frame, xlator_t *bound_xl,
- gf_hdr_common_t *hdr, size_t hdrlen,
- struct iobuf *iobuf)
-{
- gf_fop_xattrop_req_t *req = NULL;
- dict_t *dict = NULL;
- server_state_t *state = NULL;
- call_stub_t *xattrop_stub = NULL;
- int32_t ret = -1;
- size_t pathlen = 0;
- size_t dict_len = 0;
- char *req_dictbuf = NULL;
-
- req = gf_param (hdr);
- state = CALL_STATE(frame);
- {
- dict_len = ntoh32 (req->dict_len);
- state->ino = ntoh64 (req->ino);
- state->path = req->path + dict_len;
- pathlen = STRLEN_0(state->path);
- state->flags = ntoh32 (req->flags);
- }
-
- ret = server_loc_fill (&(state->loc), state,
- state->ino, 0, NULL, state->path);
-
- if (dict_len) {
- /* Unserialize the dictionary */
- req_dictbuf = memdup (req->dict, dict_len);
- GF_VALIDATE_OR_GOTO(bound_xl->name, req_dictbuf, fail);
-
- dict = dict_new ();
- GF_VALIDATE_OR_GOTO(bound_xl->name, dict, fail);
-
- ret = dict_unserialize (req_dictbuf, dict_len, &dict);
- if (ret < 0) {
- gf_log (bound_xl->name, GF_LOG_ERROR,
- "%s (%"PRId64"): failed to unserialize "
- "request buffer to dictionary",
- state->loc.path, state->ino);
- goto fail;
- } else {
- dict->extra_free = req_dictbuf;
- }
- }
- xattrop_stub = fop_xattrop_stub (frame, server_xattrop_resume,
- &(state->loc), state->flags, dict);
- GF_VALIDATE_OR_GOTO(bound_xl->name, xattrop_stub, fail);
-
- if (((state->loc.parent == NULL) && IS_NOT_ROOT(pathlen)) ||
- (state->loc.inode == NULL)) {
- do_path_lookup (xattrop_stub, &(state->loc));
- } else {
- call_resume (xattrop_stub);
- }
-
- if (dict)
- dict_unref (dict);
- return 0;
-fail:
- if (dict)
- dict_unref (dict);
-
- server_xattrop_cbk (frame, NULL, frame->this, -1, EINVAL, NULL);
- return 0;
-}
-
-
-int
-server_getxattr_resume (call_frame_t *frame, xlator_t *this, loc_t *loc,
- const char *name)
-{
- server_state_t *state = NULL;
-
- state = CALL_STATE(frame);
-
- gf_log (BOUND_XL(frame)->name, GF_LOG_TRACE,
- "%"PRId64": GETXATTR \'%s (%"PRId64")\'",
- frame->root->unique, state->path, state->ino);
-
- STACK_WIND (frame, server_getxattr_cbk,
- BOUND_XL(frame),
- BOUND_XL(frame)->fops->getxattr,
- loc, name);
- return 0;
-}
-
-/*
- * server_getxattr - getxattr function for server protocol
- * @frame: call frame
- * @bound_xl:
- * @params: parameter dictionary
- *
- * not for external reference
- */
-int
-server_getxattr (call_frame_t *frame, xlator_t *bound_xl,
- gf_hdr_common_t *hdr, size_t hdrlen,
- struct iobuf *iobuf)
-{
- gf_fop_getxattr_req_t *req = NULL;
- call_stub_t *getxattr_stub = NULL;
- server_state_t *state = NULL;
- int32_t ret = -1;
- size_t namelen = 0;
- size_t pathlen = 0;
-
- req = gf_param (hdr);
- state = CALL_STATE(frame);
- {
- pathlen = STRLEN_0(req->path);
-
- state->path = req->path;
- state->ino = ntoh64 (req->ino);
-
- namelen = ntoh32 (req->namelen);
- if (namelen)
- state->name = (req->name + pathlen);
- }
-
- ret = server_loc_fill (&(state->loc), state,
- state->ino, 0, NULL, state->path);
-
- getxattr_stub = fop_getxattr_stub (frame, server_getxattr_resume,
- &(state->loc), state->name);
-
- if (((state->loc.parent == NULL) && IS_NOT_ROOT(pathlen)) ||
- (state->loc.inode == NULL)) {
- do_path_lookup (getxattr_stub, &(state->loc));
- } else {
- call_resume (getxattr_stub);
- }
-
- return 0;
-}
-
-
-int
-server_fgetxattr (call_frame_t *frame, xlator_t *bound_xl,
- gf_hdr_common_t *hdr, size_t hdrlen,
- struct iobuf *iobuf)
-{
- server_connection_t *conn = NULL;
- gf_fop_fgetxattr_req_t *req = NULL;
- server_state_t *state = NULL;
- size_t namelen = 0;
-
- conn = SERVER_CONNECTION (frame);
-
- req = gf_param (hdr);
- state = CALL_STATE(frame);
- {
- state->fd_no = ntoh64 (req->fd);
- if (state->fd_no >= 0)
- state->fd = gf_fd_fdptr_get (conn->fdtable,
- state->fd_no);
-
- state->ino = ntoh64 (req->ino);
-
- namelen = ntoh32 (req->namelen);
- if (namelen)
- state->name = (req->name);
- }
-
- STACK_WIND (frame, server_fgetxattr_cbk,
- BOUND_XL(frame),
- BOUND_XL(frame)->fops->fgetxattr,
- state->fd, state->name);
- return 0;
-}
-
-
-int
-server_removexattr_resume (call_frame_t *frame, xlator_t *this,
- loc_t *loc, const char *name)
-{
- server_state_t *state = NULL;
-
- state = CALL_STATE (frame);
-
- gf_log (BOUND_XL(frame)->name, GF_LOG_TRACE,
- "%"PRId64": REMOVEXATTR \'%s (%"PRId64")\'",
- frame->root->unique, state->path, state->ino);
-
- STACK_WIND (frame, server_removexattr_cbk,
- BOUND_XL(frame),
- BOUND_XL(frame)->fops->removexattr,
- loc, name);
- return 0;
-}
-
-/*
- * server_removexattr - removexattr function for server protocol
- * @frame: call frame
- * @bound_xl:
- * @params: parameter dictionary
- *
- * not for external reference
- */
-int
-server_removexattr (call_frame_t *frame, xlator_t *bound_xl,
- gf_hdr_common_t *hdr, size_t hdrlen,
- struct iobuf *iobuf)
-{
- gf_fop_removexattr_req_t *req = NULL;
- call_stub_t *removexattr_stub = NULL;
- server_state_t *state = NULL;
- int32_t ret = -1;
- size_t pathlen = 0;
-
- req = gf_param (hdr);
- state = CALL_STATE(frame);
- {
- pathlen = STRLEN_0(req->path);
-
- state->path = req->path;
- state->ino = ntoh64 (req->ino);
-
- state->name = (req->name + pathlen);
- }
-
- ret = server_loc_fill (&(state->loc), state,
- state->ino, 0, NULL, state->path);
-
- removexattr_stub = fop_removexattr_stub (frame,
- server_removexattr_resume,
- &(state->loc),
- state->name);
-
- if (((state->loc.parent == NULL) && IS_NOT_ROOT(pathlen)) ||
- (state->loc.inode == NULL)) {
- do_path_lookup (removexattr_stub, &(state->loc));
- } else {
- call_resume (removexattr_stub);
- }
-
- return 0;
-}
-
-
-/*
- * server_statfs - statfs function for server protocol
- * @frame: call frame
- * @bound_xl:
- * @params: parameter dictionary
- *
- * not for external reference
- */
-int
-server_statfs (call_frame_t *frame, xlator_t *bound_xl,
- gf_hdr_common_t *hdr, size_t hdrlen,
- struct iobuf *iobuf)
-{
- gf_fop_statfs_req_t *req = NULL;
- server_state_t *state = NULL;
- int32_t ret = -1;
-
- req = gf_param (hdr);
-
- state = CALL_STATE(frame);
- state->ino = ntoh64 (req->ino);
- state->path = req->path;
-
- ret = server_loc_fill (&state->loc, state, state->ino, 0, NULL,
- state->path);
-
- gf_log (BOUND_XL(frame)->name, GF_LOG_TRACE,
- "%"PRId64": STATFS \'%s (%"PRId64")\'",
- frame->root->unique, state->path, state->ino);
-
- STACK_WIND (frame, server_statfs_cbk,
- BOUND_XL(frame),
- BOUND_XL(frame)->fops->statfs,
- &(state->loc));
-
- return 0;
-}
-
-
-int
-server_opendir_resume (call_frame_t *frame, xlator_t *this, loc_t *loc,
- fd_t *fd)
-{
- server_state_t *state = NULL;
- fd_t *new_fd = NULL;
-
- state = CALL_STATE (frame);
- new_fd = fd_create (loc->inode, frame->root->pid);
- state->fd = fd_ref (new_fd);
-
- gf_log (BOUND_XL(frame)->name, GF_LOG_TRACE,
- "%"PRId64": OPENDIR \'%s (%"PRId64")\'",
- frame->root->unique, state->path, state->ino);
-
- STACK_WIND (frame, server_opendir_cbk,
- BOUND_XL(frame),
- BOUND_XL(frame)->fops->opendir,
- loc, state->fd);
-
- return 0;
-}
-
-
-/*
- * server_opendir - opendir function for server protocol
- * @frame: call frame
- * @bound_xl:
- * @params: parameter dictionary
- *
- * not for external reference
- */
-int
-server_opendir (call_frame_t *frame, xlator_t *bound_xl,
- gf_hdr_common_t *hdr, size_t hdrlen,
- struct iobuf *iobuf)
-{
- call_stub_t *opendir_stub = NULL;
- gf_fop_opendir_req_t *req = NULL;
- server_state_t *state = NULL;
- int32_t ret = -1;
- size_t pathlen = 0;
-
- req = gf_param (hdr);
- state = CALL_STATE(frame);
- {
- state->path = req->path;
- pathlen = STRLEN_0(state->path);
- state->ino = ntoh64 (req->ino);
- }
-
- ret = server_loc_fill (&state->loc, state, state->ino, 0, NULL,
- state->path);
-
- opendir_stub = fop_opendir_stub (frame, server_opendir_resume,
- &(state->loc), NULL);
-
- if (((state->loc.parent == NULL) && IS_NOT_ROOT(pathlen)) ||
- (state->loc.inode == NULL)) {
- do_path_lookup (opendir_stub, &(state->loc));
- } else {
- call_resume (opendir_stub);
- }
-
- return 0;
-}
-
-
-/*
- * server_releasedir - releasedir function for server protocol
- * @frame: call frame
- * @bound_xl:
- * @params: parameter dictionary
- *
- * not for external reference
- */
-int
-server_releasedir (call_frame_t *frame, xlator_t *bound_xl,
- gf_hdr_common_t *hdr, size_t hdrlen,
- struct iobuf *iobuf)
-{
- gf_cbk_releasedir_req_t *req = NULL;
- server_state_t *state = NULL;
- server_connection_t *conn = NULL;
-
- conn = SERVER_CONNECTION(frame);
-
- req = gf_param (hdr);
- state = CALL_STATE(frame);
-
- state->fd_no = ntoh64 (req->fd);
- state->fd = gf_fd_fdptr_get (conn->fdtable, state->fd_no);
-
- if (state->fd == NULL) {
- gf_log (frame->this->name, GF_LOG_ERROR,
- "fd - %"PRId64": unresolved fd",
- state->fd_no);
-
- server_releasedir_cbk (frame, NULL, frame->this, -1, EBADF);
- goto out;
- }
-
- gf_log (bound_xl->name, GF_LOG_TRACE,
- "%"PRId64": RELEASEDIR \'fd=%"PRId64" (%"PRId64")\'",
- frame->root->unique, state->fd_no, state->fd->inode->ino);
-
- gf_fd_put (conn->fdtable, state->fd_no);
-
- server_releasedir_cbk (frame, NULL, frame->this, 0, 0);
-out:
- return 0;
-}
-
-
-/*
- * server_readdir - readdir function for server protocol
- * @frame: call frame
- * @bound_xl:
- * @params: parameter dictionary
- *
- * not for external reference
- */
-int
-server_getdents (call_frame_t *frame, xlator_t *bound_xl,
- gf_hdr_common_t *hdr, size_t hdrlen,
- struct iobuf *iobuf)
-{
- gf_fop_getdents_req_t *req = NULL;
- server_state_t *state = NULL;
- server_connection_t *conn = NULL;
-
- conn = SERVER_CONNECTION (frame);
-
- req = gf_param (hdr);
- state = CALL_STATE(frame);
- {
- state->fd_no = ntoh64 (req->fd);
- if (state->fd_no >= 0)
- state->fd = gf_fd_fdptr_get (conn->fdtable,
- state->fd_no);
-
- state->size = ntoh32 (req->size);
- state->offset = ntoh64 (req->offset);
- state->flags = ntoh32 (req->flags);
- }
-
-
- if (state->fd == NULL) {
- gf_log (frame->this->name, GF_LOG_ERROR,
- "fd - %"PRId64": unresolved fd",
- state->fd_no);
-
- server_getdents_cbk (frame, NULL, frame->this, -1, EBADF,
- NULL, 0);
- goto out;
- }
-
- gf_log (bound_xl->name, GF_LOG_TRACE,
- "%"PRId64": GETDENTS \'fd=%"PRId64" (%"PRId64"); "
- "offset=%"PRId64"; size=%"PRId64,
- frame->root->unique, state->fd_no, state->fd->inode->ino,
- state->offset, (int64_t)state->size);
-
- STACK_WIND (frame, server_getdents_cbk,
- bound_xl,
- bound_xl->fops->getdents,
- state->fd, state->size, state->offset, state->flags);
-out:
- return 0;
-}
-
-/*
- * server_readdirp_cbk - getdents callback for server protocol
- * @frame: call frame
- * @cookie:
- * @this:
- * @op_ret:
- * @op_errno:
- *
- * not for external reference
- */
-int
-server_readdirp_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, gf_dirent_t *entries)
-{
- gf_hdr_common_t *hdr = NULL;
- gf_fop_readdirp_rsp_t *rsp = NULL;
- size_t hdrlen = 0;
- size_t buf_size = 0;
- int32_t gf_errno = 0;
- server_state_t *state = NULL;
-
- if (op_ret > 0)
- buf_size = gf_dirent_serialize (entries, NULL, 0);
-
- hdrlen = gf_hdr_len (rsp, buf_size);
- hdr = gf_hdr_new (rsp, buf_size);
- rsp = gf_param (hdr);
-
- hdr->rsp.op_ret = hton32 (op_ret);
- gf_errno = gf_errno_to_error (op_errno);
- hdr->rsp.op_errno = hton32 (gf_errno);
-
- if (op_ret > 0) {
- rsp->size = hton32 (buf_size);
- gf_dirent_serialize (entries, rsp->buf, buf_size);
- } else {
- state = CALL_STATE(frame);
-
- gf_log (this->name, GF_LOG_TRACE,
- "%"PRId64": READDIRP %"PRId64" (%"PRId64") ==>"
- "%"PRId32" (%s)",
- frame->root->unique, state->fd_no,
- state->fd ? state->fd->inode->ino : 0, op_ret,
- strerror (op_errno));
- }
-
- protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_FOP_READDIRP,
- hdr, hdrlen, NULL, 0, NULL);
-
- return 0;
-}
-
-
-
-/*
- * server_readdirp - readdirp function for server protocol
- * @frame: call frame
- * @bound_xl:
- * @params: parameter dictionary
- *
- * not for external reference
- */
-int
-server_readdirp (call_frame_t *frame, xlator_t *bound_xl, gf_hdr_common_t *hdr,
- size_t hdrlen, struct iobuf *iobuf)
-{
- gf_fop_readdirp_req_t *req = NULL;
- server_state_t *state = NULL;
- server_connection_t *conn = NULL;
-
- conn = SERVER_CONNECTION(frame);
-
- req = gf_param (hdr);
- state = CALL_STATE(frame);
- {
- state->fd_no = ntoh64 (req->fd);
- if (state->fd_no >= 0)
- state->fd = gf_fd_fdptr_get (conn->fdtable,
- state->fd_no);
-
- state->size = ntoh32 (req->size);
- state->offset = ntoh64 (req->offset);
- }
-
-
- if (state->fd == NULL) {
- gf_log (frame->this->name, GF_LOG_ERROR,
- "fd - %"PRId64": unresolved fd",
- state->fd_no);
-
- server_readdirp_cbk (frame, NULL, frame->this, -1, EBADF, NULL);
- goto out;
- }
-
- gf_log (bound_xl->name, GF_LOG_TRACE,
- "%"PRId64": READDIRP \'fd=%"PRId64" (%"PRId64"); "
- "offset=%"PRId64"; size=%"PRId64,
- frame->root->unique, state->fd_no, state->fd->inode->ino,
- state->offset, (int64_t)state->size);
-
- STACK_WIND (frame, server_readdirp_cbk, bound_xl,
- bound_xl->fops->readdirp, state->fd, state->size,
- state->offset);
-out:
- return 0;
-}
-
-
-
-/*
- * server_readdir - readdir function for server protocol
- * @frame: call frame
- * @bound_xl:
- * @params: parameter dictionary
- *
- * not for external reference
- */
-int
-server_readdir (call_frame_t *frame, xlator_t *bound_xl,
- gf_hdr_common_t *hdr, size_t hdrlen,
- struct iobuf *iobuf)
-{
- gf_fop_readdir_req_t *req = NULL;
- server_state_t *state = NULL;
- server_connection_t *conn = NULL;
-
- conn = SERVER_CONNECTION(frame);
-
- req = gf_param (hdr);
- state = CALL_STATE(frame);
- {
- state->fd_no = ntoh64 (req->fd);
- if (state->fd_no >= 0)
- state->fd = gf_fd_fdptr_get (conn->fdtable,
- state->fd_no);
-
- state->size = ntoh32 (req->size);
- state->offset = ntoh64 (req->offset);
- }
-
-
- if (state->fd == NULL) {
- gf_log (frame->this->name, GF_LOG_ERROR,
- "fd - %"PRId64": unresolved fd",
- state->fd_no);
-
- server_readdir_cbk (frame, NULL, frame->this, -1, EBADF, NULL);
- goto out;
- }
-
- gf_log (bound_xl->name, GF_LOG_TRACE,
- "%"PRId64": READDIR \'fd=%"PRId64" (%"PRId64"); "
- "offset=%"PRId64"; size=%"PRId64,
- frame->root->unique, state->fd_no, state->fd->inode->ino,
- state->offset, (int64_t)state->size);
-
- STACK_WIND (frame, server_readdir_cbk,
- bound_xl,
- bound_xl->fops->readdir,
- state->fd, state->size, state->offset);
-out:
- return 0;
-}
-
-
-
-/*
- * server_fsyncdir - fsyncdir function for server protocol
- * @frame: call frame
- * @bound_xl:
- * @params: parameter dictionary
- *
- * not for external reference
- */
-int
-server_fsyncdir (call_frame_t *frame, xlator_t *bound_xl,
- gf_hdr_common_t *hdr, size_t hdrlen,
- struct iobuf *iobuf)
-{
- gf_fop_fsyncdir_req_t *req = NULL;
- server_state_t *state = NULL;
- server_connection_t *conn = NULL;
-
- conn = SERVER_CONNECTION (frame);
-
- req = gf_param (hdr);
- state = CALL_STATE(frame);
- {
- state->fd_no = ntoh64 (req->fd);
- if (state->fd_no >= 0)
- state->fd = gf_fd_fdptr_get (conn->fdtable,
- state->fd_no);
-
- state->flags = ntoh32 (req->data);
- }
-
- if (state->fd == NULL) {
- gf_log (frame->this->name, GF_LOG_ERROR,
- "fd - %"PRId64": unresolved fd",
- state->fd_no);
-
- server_fsyncdir_cbk (frame, NULL, frame->this, -1, EBADF);
- goto out;
- }
-
- gf_log (bound_xl->name, GF_LOG_TRACE,
- "%"PRId64": FSYNCDIR \'fd=%"PRId64" (%"PRId64")\'",
- frame->root->unique, state->fd_no, state->fd->inode->ino);
-
- STACK_WIND (frame, server_fsyncdir_cbk,
- bound_xl,
- bound_xl->fops->fsyncdir,
- state->fd, state->flags);
-out:
- return 0;
-}
-
-
-int
-server_mknod_resume (call_frame_t *frame, xlator_t *this, loc_t *loc,
- mode_t mode, dev_t dev)
-{
- server_state_t *state = NULL;
-
- state = CALL_STATE (frame);
-
- if (state->loc.parent == NULL)
- state->loc.parent = inode_ref (loc->parent);
-
- state->loc.inode = inode_new (state->itable);
-
- gf_log (BOUND_XL(frame)->name, GF_LOG_TRACE,
- "%"PRId64": MKNOD \'%"PRId64"/%s\'",
- frame->root->unique, state->par, state->bname);
-
- STACK_WIND (frame, server_mknod_cbk,
- BOUND_XL(frame),
- BOUND_XL(frame)->fops->mknod,
- &(state->loc), mode, dev);
-
- return 0;
-}
-
-/*
- * server_mknod - mknod function for server protocol
- * @frame: call frame
- * @bound_xl:
- * @params: parameter dictionary
- *
- * not for external reference
- */
-int
-server_mknod (call_frame_t *frame, xlator_t *bound_xl,
- gf_hdr_common_t *hdr, size_t hdrlen,
- struct iobuf *iobuf)
-{
- gf_fop_mknod_req_t *req = NULL;
- server_state_t *state = NULL;
- call_stub_t *mknod_stub = NULL;
- int32_t ret = -1;
- size_t pathlen = 0;
-
- req = gf_param (hdr);
- state = CALL_STATE (frame);
- {
- pathlen = STRLEN_0(req->path);
-
- state->par = ntoh64 (req->par);
- state->path = req->path;
- if (IS_NOT_ROOT(pathlen))
- state->bname = req->bname + pathlen;
-
- state->mode = ntoh32 (req->mode);
- state->dev = ntoh64 (req->dev);
- }
- ret = server_loc_fill (&(state->loc), state, 0, state->par,
- state->bname, state->path);
-
- mknod_stub = fop_mknod_stub (frame, server_mknod_resume,
- &(state->loc), state->mode, state->dev);
-
- if (state->loc.parent == NULL) {
- do_path_lookup (mknod_stub, &(state->loc));
- } else {
- call_resume (mknod_stub);
- }
-
- return 0;
-}
-
-
-int
-server_mkdir_resume (call_frame_t *frame, xlator_t *this, loc_t *loc,
- mode_t mode)
-
-{
- server_state_t *state = NULL;
-
- state = CALL_STATE (frame);
-
- if (state->loc.parent == NULL)
- state->loc.parent = inode_ref (loc->parent);
-
- state->loc.inode = inode_new (state->itable);
-
- gf_log (BOUND_XL(frame)->name, GF_LOG_TRACE,
- "%"PRId64": MKDIR \'%"PRId64"/%s\'",
- frame->root->unique, state->par, state->bname);
-
- STACK_WIND (frame, server_mkdir_cbk,
- BOUND_XL(frame),
- BOUND_XL(frame)->fops->mkdir,
- &(state->loc), state->mode);
-
- return 0;
-}
-
-/*
- * server_mkdir - mkdir function for server protocol
- * @frame: call frame
- * @bound_xl:
- * @params:
- *
- * not for external reference
- */
-int
-server_mkdir (call_frame_t *frame, xlator_t *bound_xl,
- gf_hdr_common_t *hdr, size_t hdrlen,
- struct iobuf *iobuf)
-{
- gf_fop_mkdir_req_t *req = NULL;
- server_state_t *state = NULL;
- call_stub_t *mkdir_stub = NULL;
- int32_t ret = -1;
- size_t pathlen = 0;
-
- req = gf_param (hdr);
- state = CALL_STATE(frame);
- {
- pathlen = STRLEN_0(req->path);
- state->mode = ntoh32 (req->mode);
-
- state->path = req->path;
- state->bname = req->bname + pathlen;
- state->par = ntoh64 (req->par);
- }
-
-
- ret = server_loc_fill (&(state->loc), state, 0, state->par,
- state->bname, state->path);
-
- mkdir_stub = fop_mkdir_stub (frame, server_mkdir_resume,
- &(state->loc), state->mode);
-
- if (state->loc.parent == NULL) {
- do_path_lookup (mkdir_stub, &(state->loc));
- } else {
- call_resume (mkdir_stub);
- }
-
- return 0;
-}
-
-
-int
-server_rmdir_resume (call_frame_t *frame, xlator_t *this, loc_t *loc)
-{
- server_state_t *state = NULL;
-
- state = CALL_STATE(frame);
-
- if (state->loc.parent == NULL)
- state->loc.parent = inode_ref (loc->parent);
-
- if (state->loc.inode == NULL)
- state->loc.inode = inode_ref (loc->inode);
-
- gf_log (BOUND_XL(frame)->name, GF_LOG_TRACE,
- "%"PRId64": RMDIR \'%"PRId64"/%s\'",
- frame->root->unique, state->par, state->bname);
-
- STACK_WIND (frame, server_rmdir_cbk,
- BOUND_XL(frame),
- BOUND_XL(frame)->fops->rmdir,
- loc);
- return 0;
-}
-
-/*
- * server_rmdir - rmdir function for server protocol
- * @frame: call frame
- * @bound_xl:
- * @params:
- *
- * not for external reference
- */
-int
-server_rmdir (call_frame_t *frame, xlator_t *bound_xl,
- gf_hdr_common_t *hdr, size_t hdrlen,
- struct iobuf *iobuf)
-{
- call_stub_t *rmdir_stub = NULL;
- gf_fop_rmdir_req_t *req = NULL;
- server_state_t *state = NULL;
- int32_t ret = -1;
- size_t pathlen = 0;
-
- req = gf_param (hdr);
- state = CALL_STATE(frame);
- {
- pathlen = STRLEN_0(req->path);
- state->path = req->path;
- state->par = ntoh64 (req->par);
- state->bname = req->bname + pathlen;
- }
-
-
- ret = server_loc_fill (&(state->loc), state, state->ino, state->par,
- state->bname, state->path);
-
- rmdir_stub = fop_rmdir_stub (frame, server_rmdir_resume,
- &(state->loc));
-
- if ((state->loc.parent == NULL) ||
- (state->loc.inode == NULL)) {
- do_path_lookup (rmdir_stub, &(state->loc));
- } else {
- call_resume (rmdir_stub);
- }
-
- return 0;
-}
-
-
-int
-server_inodelk_resume (call_frame_t *frame, xlator_t *this,
- const char *volume, loc_t *loc, int32_t cmd,
- struct flock *flock)
-{
- server_state_t *state = NULL;
-
- state = CALL_STATE(frame);
- if (state->loc.inode == NULL) {
- state->loc.inode = inode_ref (loc->inode);
- }
-
- if (state->loc.parent == NULL) {
- state->loc.parent = inode_ref (loc->parent);
- }
-
- gf_log (BOUND_XL(frame)->name, GF_LOG_TRACE,
- "%"PRId64": INODELK \'%s (%"PRId64")\'",
- frame->root->unique, state->path, state->ino);
-
- STACK_WIND (frame, server_inodelk_cbk,
- BOUND_XL(frame),
- BOUND_XL(frame)->fops->inodelk,
- volume, loc, cmd, flock);
- return 0;
-
-}
-
-
-int
-server_inodelk (call_frame_t *frame, xlator_t *bound_xl,
- gf_hdr_common_t *hdr, size_t hdrlen,
- struct iobuf *iobuf)
-{
- call_stub_t *inodelk_stub = NULL;
- gf_fop_inodelk_req_t *req = NULL;
- server_state_t *state = NULL;
- size_t pathlen = 0;
- size_t vollen = 0;
-
- req = gf_param (hdr);
- state = CALL_STATE(frame);
- {
- state->cmd = ntoh32 (req->cmd);
- switch (state->cmd) {
- case GF_LK_GETLK:
- state->cmd = F_GETLK;
- break;
- case GF_LK_SETLK:
- state->cmd = F_SETLK;
- break;
- case GF_LK_SETLKW:
- state->cmd = F_SETLKW;
- break;
- }
-
- state->type = ntoh32 (req->type);
-
- pathlen = STRLEN_0(req->path);
- vollen = STRLEN_0(req->volume + vollen);
-
- state->path = req->path;
- state->volume = strdup (req->volume + vollen);
- state->ino = ntoh64 (req->ino);
-
- gf_flock_to_flock (&req->flock, &state->flock);
-
- switch (state->type) {
- case GF_LK_F_RDLCK:
- state->flock.l_type = F_RDLCK;
- break;
- case GF_LK_F_WRLCK:
- state->flock.l_type = F_WRLCK;
- break;
- case GF_LK_F_UNLCK:
- state->flock.l_type = F_UNLCK;
- break;
- }
-
- }
-
- server_loc_fill (&(state->loc), state, state->ino, 0, NULL,
- state->path);
-
- inodelk_stub = fop_inodelk_stub (frame, server_inodelk_resume,
- state->volume, &state->loc,
- state->cmd, &state->flock);
-
- if (state->loc.inode == NULL) {
- do_path_lookup (inodelk_stub, &(state->loc));
- } else {
- call_resume (inodelk_stub);
- }
-
- return 0;
-}
-
-
-int
-server_finodelk (call_frame_t *frame, xlator_t *bound_xl,
- gf_hdr_common_t *hdr, size_t hdrlen,
- struct iobuf *iobuf)
-{
- gf_fop_finodelk_req_t *req = NULL;
- server_state_t *state = NULL;
- server_connection_t *conn = NULL;
-
- conn = SERVER_CONNECTION(frame);
-
- req = gf_param (hdr);
- state = CALL_STATE(frame);
- {
- state->volume = strdup (req->volume);
-
- state->fd_no = ntoh64 (req->fd);
- if (state->fd_no >= 0)
- state->fd = gf_fd_fdptr_get (conn->fdtable,
- state->fd_no);
-
- state->cmd = ntoh32 (req->cmd);
- switch (state->cmd) {
- case GF_LK_GETLK:
- state->cmd = F_GETLK;
- break;
- case GF_LK_SETLK:
- state->cmd = F_SETLK;
- break;
- case GF_LK_SETLKW:
- state->cmd = F_SETLKW;
- break;
- }
-
- state->type = ntoh32 (req->type);
-
- gf_flock_to_flock (&req->flock, &state->flock);
-
- switch (state->type) {
- case GF_LK_F_RDLCK:
- state->flock.l_type = F_RDLCK;
- break;
- case GF_LK_F_WRLCK:
- state->flock.l_type = F_WRLCK;
- break;
- case GF_LK_F_UNLCK:
- state->flock.l_type = F_UNLCK;
- break;
- }
-
- }
-
- if (state->fd == NULL) {
- gf_log (frame->this->name, GF_LOG_ERROR,
- "fd - %"PRId64": unresolved fd",
- state->fd_no);
-
- server_finodelk_cbk (frame, NULL, frame->this,
- -1, EBADF);
- return -1;
- }
-
- gf_log (BOUND_XL(frame)->name, GF_LOG_TRACE,
- "%"PRId64": FINODELK \'fd=%"PRId64" (%"PRId64")\'",
- frame->root->unique, state->fd_no, state->fd->inode->ino);
-
- STACK_WIND (frame, server_finodelk_cbk,
- BOUND_XL(frame),
- BOUND_XL(frame)->fops->finodelk,
- state->volume, state->fd, state->cmd, &state->flock);
- return 0;
-}
-
-
-int
-server_entrylk_resume (call_frame_t *frame, xlator_t *this,
- const char *volume, loc_t *loc, const char *name,
- entrylk_cmd cmd, entrylk_type type)
-{
- server_state_t *state = NULL;
-
- state = CALL_STATE(frame);
-
- if (state->loc.inode == NULL)
- state->loc.inode = inode_ref (loc->inode);
-
- if ((state->loc.parent == NULL) &&
- (loc->parent))
- state->loc.parent = inode_ref (loc->parent);
-
- gf_log (BOUND_XL(frame)->name, GF_LOG_TRACE,
- "%"PRId64": ENTRYLK \'%s (%"PRId64") \'",
- frame->root->unique, state->path, state->ino);
-
- STACK_WIND (frame, server_entrylk_cbk,
- BOUND_XL(frame),
- BOUND_XL(frame)->fops->entrylk,
- volume, loc, name, cmd, type);
- return 0;
-
-}
-
-/*
- * server_entrylk - entrylk function for server protocol
- * @frame: call frame
- * @bound_xl:
- * @params: parameter dictionary
- *
- * not for external reference
- */
-int
-server_entrylk (call_frame_t *frame, xlator_t *bound_xl,
- gf_hdr_common_t *hdr, size_t hdrlen,
- struct iobuf *iobuf)
-{
- gf_fop_entrylk_req_t *req = NULL;
- server_state_t *state = NULL;
- call_stub_t *entrylk_stub = NULL;
- size_t pathlen = 0;
- size_t namelen = 0;
- size_t vollen = 0;
-
- req = gf_param (hdr);
- state = CALL_STATE (frame);
- {
- pathlen = STRLEN_0(req->path);
-
- state->path = req->path;
- state->ino = ntoh64 (req->ino);
- namelen = ntoh64 (req->namelen);
- if (namelen)
- state->name = req->name + pathlen;
-
- vollen = STRLEN_0(req->volume + pathlen + namelen);
- state->volume = strdup (req->volume + pathlen + namelen);
-
- state->cmd = ntoh32 (req->cmd);
- state->type = ntoh32 (req->type);
- }
-
-
- server_loc_fill (&(state->loc), state, state->ino, 0, NULL,
- state->path);
-
- entrylk_stub = fop_entrylk_stub (frame, server_entrylk_resume,
- state->volume, &state->loc,
- state->name, state->cmd, state->type);
-
- if (state->loc.inode == NULL) {
- do_path_lookup (entrylk_stub, &(state->loc));
- } else {
- call_resume (entrylk_stub);
- }
-
- return 0;
-}
-
-
-int
-server_fentrylk (call_frame_t *frame, xlator_t *bound_xl,
- gf_hdr_common_t *hdr, size_t hdrlen,
- struct iobuf *iobuf)
-{
- gf_fop_fentrylk_req_t *req = NULL;
- server_state_t *state = NULL;
- size_t namelen = 0;
- size_t vollen = 0;
- server_connection_t *conn = NULL;
-
- conn = SERVER_CONNECTION (frame);
-
- req = gf_param (hdr);
- state = CALL_STATE(frame);
- {
- state->fd_no = ntoh64 (req->fd);
- if (state->fd_no >= 0)
- state->fd = gf_fd_fdptr_get (conn->fdtable,
- state->fd_no);
-
- state->cmd = ntoh32 (req->cmd);
- state->type = ntoh32 (req->type);
- namelen = ntoh64 (req->namelen);
-
- if (namelen)
- state->name = req->name;
-
- vollen = STRLEN_0(req->volume + namelen);
- state->volume = strdup (req->volume + namelen);
- }
-
- if (state->fd == NULL) {
- gf_log (frame->this->name, GF_LOG_ERROR,
- "fd - %"PRId64": unresolved fd",
- state->fd_no);
-
- server_fentrylk_cbk (frame, NULL, frame->this, -1, EBADF);
- return -1;
- }
-
- gf_log (BOUND_XL(frame)->name, GF_LOG_TRACE,
- "%"PRId64": FENTRYLK \'fd=%"PRId64" (%"PRId64")\'",
- frame->root->unique, state->fd_no, state->fd->inode->ino);
-
- STACK_WIND (frame, server_fentrylk_cbk,
- BOUND_XL(frame),
- BOUND_XL(frame)->fops->fentrylk,
- state->volume, state->fd, state->name,
- state->cmd, state->type);
- return 0;
-}
-
-
-int
-server_access_resume (call_frame_t *frame, xlator_t *this, loc_t *loc,
- int32_t mask)
-{
- server_state_t *state = NULL;
-
- state = CALL_STATE (frame);
-
- gf_log (BOUND_XL(frame)->name, GF_LOG_TRACE,
- "%"PRId64": ACCESS \'%s (%"PRId64")\'",
- frame->root->unique, state->path, state->ino);
-
- STACK_WIND (frame, server_access_cbk,
- BOUND_XL(frame),
- BOUND_XL(frame)->fops->access,
- loc, mask);
- return 0;
-}
-
-/*
- * server_access - access function for server protocol
- * @frame: call frame
- * @bound_xl:
- * @params: parameter dictionary
- *
- * not for external reference
- */
-int
-server_access (call_frame_t *frame, xlator_t *bound_xl,
- gf_hdr_common_t *hdr, size_t hdrlen,
- struct iobuf *iobuf)
-{
- call_stub_t *access_stub = NULL;
- gf_fop_access_req_t *req = NULL;
- server_state_t *state = NULL;
- int32_t ret = -1;
- size_t pathlen = 0;
-
- req = gf_param (hdr);
- state = CALL_STATE(frame);
-
- state->mask = ntoh32 (req->mask);
-
- state->ino = ntoh64 (req->ino);
- state->path = req->path;
- pathlen = STRLEN_0(state->path);
-
- ret = server_loc_fill (&(state->loc), state, state->ino, 0, NULL,
- state->path);
-
- access_stub = fop_access_stub (frame, server_access_resume,
- &(state->loc), state->mask);
-
- if (((state->loc.parent == NULL) && IS_NOT_ROOT(pathlen)) ||
- (state->loc.inode == NULL)) {
- do_path_lookup (access_stub, &(state->loc));
- } else {
- call_resume (access_stub);
- }
-
- return 0;
-}
-
-
-int
-server_symlink_resume (call_frame_t *frame, xlator_t *this,
- const char *linkname, loc_t *loc)
-{
- server_state_t *state = NULL;
-
- state = CALL_STATE (frame);
- if (state->loc.parent == NULL)
- state->loc.parent = inode_ref (loc->parent);
-
- state->loc.inode = inode_new (BOUND_XL(frame)->itable);
-
- gf_log (BOUND_XL(frame)->name, GF_LOG_TRACE,
- "%"PRId64": SYMLINK \'%"PRId64"/%s \'",
- frame->root->unique, state->par, state->bname);
-
- STACK_WIND (frame, server_symlink_cbk,
- BOUND_XL(frame),
- BOUND_XL(frame)->fops->symlink,
- linkname, &(state->loc));
-
- return 0;
-}
-
-/*
- * server_symlink- symlink function for server protocol
- * @frame: call frame
- * @bound_xl:
- * @params: parameter dictionary
- *
- * not for external reference
- */
-
-int
-server_symlink (call_frame_t *frame, xlator_t *bound_xl,
- gf_hdr_common_t *hdr, size_t hdrlen,
- struct iobuf *iobuf)
-{
- server_state_t *state = NULL;
- gf_fop_symlink_req_t *req = NULL;
- call_stub_t *symlink_stub = NULL;
- int32_t ret = -1;
- size_t pathlen = 0;
- size_t baselen = 0;
-
- req = gf_param (hdr);
- state = CALL_STATE(frame);
- {
- pathlen = STRLEN_0(req->path);
- baselen = STRLEN_0(req->bname + pathlen);
-
- state->par = ntoh64 (req->par);
- state->path = req->path;
- state->bname = req->bname + pathlen;
-
- state->name = (req->linkname + pathlen + baselen);
- }
-
- ret = server_loc_fill (&(state->loc), state, 0, state->par,
- state->bname, state->path);
-
- symlink_stub = fop_symlink_stub (frame, server_symlink_resume,
- state->name, &(state->loc));
-
- if (state->loc.parent == NULL) {
- do_path_lookup (symlink_stub, &(state->loc));
- } else {
- call_resume (symlink_stub);
- }
-
- return 0;
-}
-
-
-int
-server_link_resume (call_frame_t *frame, xlator_t *this, loc_t *oldloc,
- loc_t *newloc)
-{
- server_state_t *state = NULL;
-
- state = CALL_STATE (frame);
-
- if (state->loc.parent == NULL)
- state->loc.parent = inode_ref (oldloc->parent);
-
- if (state->loc.inode == NULL) {
- state->loc.inode = inode_ref (oldloc->inode);
- } else if (state->loc.inode != oldloc->inode) {
- if (state->loc.inode)
- inode_unref (state->loc.inode);
- state->loc.inode = inode_ref (oldloc->inode);
- }
-
- if (state->loc2.parent == NULL)
- state->loc2.parent = inode_ref (newloc->parent);
-
- state->loc2.inode = inode_ref (state->loc.inode);
-
- gf_log (BOUND_XL(frame)->name, GF_LOG_TRACE,
- "%"PRId64": LINK \'%"PRId64"/%s ==> %s (%"PRId64")\'",
- frame->root->unique, state->par2, state->bname2,
- state->path, state->ino);
-
- STACK_WIND (frame, server_link_cbk,
- BOUND_XL(frame),
- BOUND_XL(frame)->fops->link,
- &(state->loc), &(state->loc2));
- return 0;
-}
-
-/*
- * server_link - link function for server protocol
- * @frame: call frame
- * @bound_xl:
- * @params:
- *
- * not for external reference
- */
-int
-server_link (call_frame_t *frame, xlator_t *this,
- gf_hdr_common_t *hdr, size_t hdrlen,
- struct iobuf *iobuf)
-{
- gf_fop_link_req_t *req = NULL;
- server_state_t *state = NULL;
- call_stub_t *link_stub = NULL;
- int32_t ret = -1;
- size_t oldpathlen = 0;
- size_t newpathlen = 0;
- size_t newbaselen = 0;
-
- req = gf_param (hdr);
-
- state = CALL_STATE(frame);
- {
- oldpathlen = STRLEN_0(req->oldpath);
- newpathlen = STRLEN_0(req->newpath + oldpathlen);
- newbaselen = STRLEN_0(req->newbname + oldpathlen + newpathlen);
-
- state->path = req->oldpath;
- state->path2 = req->newpath + oldpathlen;
- state->bname2 = req->newbname + oldpathlen + newpathlen;
- state->ino = ntoh64 (req->oldino);
- state->par2 = ntoh64 (req->newpar);
- }
-
- ret = server_loc_fill (&(state->loc), state, state->ino, 0, NULL,
- state->path);
- ret = server_loc_fill (&(state->loc2), state, 0, state->par2,
- state->bname2, state->path2);
-
- link_stub = fop_link_stub (frame, server_link_resume,
- &(state->loc), &(state->loc2));
-
- if ((state->loc.parent == NULL) ||
- (state->loc.inode == NULL)) {
- do_path_lookup (link_stub, &(state->loc));
- } else if (state->loc2.parent == NULL) {
- do_path_lookup (link_stub, &(state->loc2));
- } else {
- call_resume (link_stub);
- }
-
- return 0;
-}
-
-
-int
-server_rename_resume (call_frame_t *frame, xlator_t *this, loc_t *oldloc,
- loc_t *newloc)
-{
- server_state_t *state = NULL;
-
- state = CALL_STATE (frame);
-
- if (state->loc.parent == NULL)
- state->loc.parent = inode_ref (oldloc->parent);
-
- if (state->loc.inode == NULL) {
- state->loc.inode = inode_ref (oldloc->inode);
- }
-
- if (state->loc2.parent == NULL)
- state->loc2.parent = inode_ref (newloc->parent);
-
-
- gf_log (BOUND_XL(frame)->name, GF_LOG_TRACE,
- "%"PRId64": RENAME %s (%"PRId64"/%s) ==> %s (%"PRId64"/%s)",
- frame->root->unique, state->path, state->par, state->bname,
- state->path2, state->par2, state->bname2);
-
- STACK_WIND (frame, server_rename_cbk,
- BOUND_XL(frame),
- BOUND_XL(frame)->fops->rename,
- &(state->loc), &(state->loc2));
- return 0;
-}
-
-/*
- * server_rename - rename function for server protocol
- * @frame: call frame
- * @bound_xl:
- * @params: parameter dictionary
- *
- * not for external reference
- */
-int
-server_rename (call_frame_t *frame, xlator_t *bound_xl,
- gf_hdr_common_t *hdr, size_t hdrlen,
- struct iobuf *iobuf)
-{
- gf_fop_rename_req_t *req = NULL;
- server_state_t *state = NULL;
- call_stub_t *rename_stub = NULL;
- int32_t ret = -1;
- size_t oldpathlen = 0;
- size_t oldbaselen = 0;
- size_t newpathlen = 0;
- size_t newbaselen = 0;
-
- req = gf_param (hdr);
-
- state = CALL_STATE (frame);
- {
- oldpathlen = STRLEN_0(req->oldpath);
- oldbaselen = STRLEN_0(req->oldbname + oldpathlen);
- newpathlen = STRLEN_0(req->newpath + oldpathlen + oldbaselen);
- newbaselen = STRLEN_0(req->newbname + oldpathlen +
- oldbaselen + newpathlen);
-
- state->path = req->oldpath;
- state->bname = req->oldbname + oldpathlen;
- state->path2 = req->newpath + oldpathlen + oldbaselen;
- state->bname2 = (req->newbname + oldpathlen + oldbaselen +
- newpathlen);
-
- state->par = ntoh64 (req->oldpar);
- state->par2 = ntoh64 (req->newpar);
- }
-
- ret = server_loc_fill (&(state->loc), state, 0, state->par,
- state->bname, state->path);
- ret = server_loc_fill (&(state->loc2), state, 0, state->par2,
- state->bname2, state->path2);
-
- rename_stub = fop_rename_stub (frame, server_rename_resume,
- &(state->loc), &(state->loc2));
-
- if ((state->loc.parent == NULL) ||
- (state->loc.inode == NULL)){
- do_path_lookup (rename_stub, &(state->loc));
- } else if ((state->loc2.parent == NULL)){
- do_path_lookup (rename_stub, &(state->loc2));
- } else {
- /* we have found inode for both oldpath and newpath in
- * inode cache. lets continue with fops->rename() */
- call_resume (rename_stub);
- }
-
- return 0;
-}
-
-
-/*
- * server_lk - lk function for server protocol
- * @frame: call frame
- * @bound_xl:
- * @params: parameter dictionary
- *
- * not for external reference
- */
-
-int
-server_lk (call_frame_t *frame, xlator_t *bound_xl,
- gf_hdr_common_t *hdr, size_t hdrlen,
- struct iobuf *iobuf)
-{
- struct flock lock = {0, };
- gf_fop_lk_req_t *req = NULL;
- server_state_t *state = NULL;
- server_connection_t *conn = NULL;
-
- conn = SERVER_CONNECTION (frame);
-
- req = gf_param (hdr);
- state = CALL_STATE (frame);
- {
- state->fd_no = ntoh64 (req->fd);
- if (state->fd_no >= 0)
- state->fd = gf_fd_fdptr_get (conn->fdtable,
- state->fd_no);
-
- state->cmd = ntoh32 (req->cmd);
- state->type = ntoh32 (req->type);
- }
-
-
- if (state->fd == NULL) {
- gf_log (frame->this->name, GF_LOG_ERROR,
- "fd - %"PRId64": unresolved fd",
- state->fd_no);
-
- server_lk_cbk (frame, NULL, frame->this, -1, EBADF, NULL);
- goto out;
- }
-
- switch (state->cmd) {
- case GF_LK_GETLK:
- state->cmd = F_GETLK;
- break;
- case GF_LK_SETLK:
- state->cmd = F_SETLK;
- break;
- case GF_LK_SETLKW:
- state->cmd = F_SETLKW;
- break;
- }
-
- switch (state->type) {
- case GF_LK_F_RDLCK:
- lock.l_type = F_RDLCK;
- break;
- case GF_LK_F_WRLCK:
- lock.l_type = F_WRLCK;
- break;
- case GF_LK_F_UNLCK:
- lock.l_type = F_UNLCK;
- break;
- default:
- gf_log (bound_xl->name, GF_LOG_ERROR,
- "fd - %"PRId64" (%"PRId64"): Unknown lock type: %"PRId32"!",
- state->fd_no, state->fd->inode->ino, state->type);
- break;
- }
-
- gf_flock_to_flock (&req->flock, &lock);
-
- gf_log (BOUND_XL(frame)->name, GF_LOG_TRACE,
- "%"PRId64": LK \'fd=%"PRId64" (%"PRId64")\'",
- frame->root->unique, state->fd_no, state->fd->inode->ino);
-
- STACK_WIND (frame, server_lk_cbk,
- BOUND_XL(frame),
- BOUND_XL(frame)->fops->lk,
- state->fd, state->cmd, &lock);
-out:
- return 0;
-}
-
-
-/*
- * server_writedir -
- *
- * @frame:
- * @bound_xl:
- * @params:
- *
- */
-int
-server_setdents (call_frame_t *frame, xlator_t *bound_xl,
- gf_hdr_common_t *hdr, size_t hdrlen,
- struct iobuf *iobuf)
-{
- server_connection_t *conn = NULL;
- gf_fop_setdents_req_t *req = NULL;
- server_state_t *state = NULL;
- dir_entry_t *entry = NULL;
- dir_entry_t *trav = NULL;
- dir_entry_t *prev = NULL;
- int32_t count = 0;
- int32_t i = 0;
- int32_t bread = 0;
- char *ender = NULL;
- char *buffer_ptr = NULL;
- char tmp_buf[512] = {0,};
-
- conn = SERVER_CONNECTION(frame);
-
- req = gf_param (hdr);
- state = CALL_STATE(frame);
-
- state->fd_no = ntoh64 (req->fd);
- if (state->fd_no >= 0)
- state->fd = gf_fd_fdptr_get (conn->fdtable,
- state->fd_no);
-
- state->nr_count = ntoh32 (req->count);
-
- if (state->fd == NULL) {
- gf_log (frame->this->name, GF_LOG_ERROR,
- "fd - %"PRId64": unresolved fd",
- state->fd_no);
-
- server_setdents_cbk (frame, NULL, frame->this, -1, EBADF);
-
- goto out;
- }
-
- if (iobuf == NULL) {
- gf_log (frame->this->name, GF_LOG_ERROR,
- "fd - %"PRId64" (%"PRId64"): received a null buffer, "
- "returning EINVAL",
- state->fd_no, state->fd->inode->ino);
-
- server_setdents_cbk (frame, NULL, frame->this, -1, ENOMEM);
-
- goto out;
- }
-
- entry = CALLOC (1, sizeof (dir_entry_t));
- ERR_ABORT (entry);
- prev = entry;
- buffer_ptr = iobuf->ptr;
-
- for (i = 0; i < state->nr_count ; i++) {
- bread = 0;
- trav = CALLOC (1, sizeof (dir_entry_t));
- ERR_ABORT (trav);
-
- ender = strchr (buffer_ptr, '/');
- if (!ender)
- break;
- count = ender - buffer_ptr;
- trav->name = CALLOC (1, count + 2);
- ERR_ABORT (trav->name);
-
- strncpy (trav->name, buffer_ptr, count);
- bread = count + 1;
- buffer_ptr += bread;
-
- ender = strchr (buffer_ptr, '\n');
- if (!ender)
- break;
- count = ender - buffer_ptr;
- strncpy (tmp_buf, buffer_ptr, count);
- bread = count + 1;
- buffer_ptr += bread;
-
- /* TODO: use str_to_stat instead */
- {
- uint64_t dev;
- uint64_t ino;
- uint32_t mode;
- uint32_t nlink;
- uint32_t uid;
- uint32_t gid;
- uint64_t rdev;
- uint64_t size;
- uint32_t blksize;
- uint64_t blocks;
- uint32_t atime;
- uint32_t atime_nsec;
- uint32_t mtime;
- uint32_t mtime_nsec;
- uint32_t ctime;
- uint32_t ctime_nsec;
-
- sscanf (tmp_buf, GF_STAT_PRINT_FMT_STR,
- &dev, &ino, &mode, &nlink, &uid, &gid, &rdev,
- &size, &blksize, &blocks, &atime, &atime_nsec,
- &mtime, &mtime_nsec, &ctime, &ctime_nsec);
-
- trav->buf.st_dev = dev;
- trav->buf.st_ino = ino;
- trav->buf.st_mode = mode;
- trav->buf.st_nlink = nlink;
- trav->buf.st_uid = uid;
- trav->buf.st_gid = gid;
- trav->buf.st_rdev = rdev;
- trav->buf.st_size = size;
- trav->buf.st_blksize = blksize;
- trav->buf.st_blocks = blocks;
-
- trav->buf.st_atime = atime;
- trav->buf.st_mtime = mtime;
- trav->buf.st_ctime = ctime;
-
- ST_ATIM_NSEC_SET(&trav->buf, atime_nsec);
- ST_MTIM_NSEC_SET(&trav->buf, mtime_nsec);
- ST_CTIM_NSEC_SET(&trav->buf, ctime_nsec);
-
- }
-
- ender = strchr (buffer_ptr, '\n');
- if (!ender)
- break;
- count = ender - buffer_ptr;
- *ender = '\0';
- if (S_ISLNK (trav->buf.st_mode)) {
- trav->link = strdup (buffer_ptr);
- } else
- trav->link = "";
- bread = count + 1;
- buffer_ptr += bread;
-
- prev->next = trav;
- prev = trav;
- }
-
- gf_log (bound_xl->name, GF_LOG_TRACE,
- "%"PRId64": SETDENTS \'fd=%"PRId64" (%"PRId64"); count=%"PRId64,
- frame->root->unique, state->fd_no, state->fd->inode->ino,
- (int64_t)state->nr_count);
-
- STACK_WIND (frame, server_setdents_cbk,
- BOUND_XL(frame),
- BOUND_XL(frame)->fops->setdents,
- state->fd, state->flags, entry, state->nr_count);
-
-
- /* Free the variables allocated in this fop here */
- trav = entry->next;
- prev = entry;
- while (trav) {
- prev->next = trav->next;
- FREE (trav->name);
- if (S_ISLNK (trav->buf.st_mode))
- FREE (trav->link);
- FREE (trav);
- trav = prev->next;
- }
- FREE (entry);
-
-out:
- if (iobuf)
- iobuf_unref (iobuf);
- return 0;
-}
-
-
-
-/* xxx_MOPS */
-int
-_volfile_update_checksum (xlator_t *this, char *key, uint32_t checksum)
-{
- server_conf_t *conf = NULL;
- struct _volfile_ctx *temp_volfile = NULL;
-
- conf = this->private;
- temp_volfile = conf->volfile;
-
- while (temp_volfile) {
- if ((NULL == key) && (NULL == temp_volfile->key))
- break;
- if ((NULL == key) || (NULL == temp_volfile->key)) {
- temp_volfile = temp_volfile->next;
- continue;
- }
- if (strcmp (temp_volfile->key, key) == 0)
- break;
- temp_volfile = temp_volfile->next;
- }
-
- if (!temp_volfile) {
- temp_volfile = CALLOC (1, sizeof (struct _volfile_ctx));
-
- temp_volfile->next = conf->volfile;
- temp_volfile->key = (key)? strdup (key): NULL;
- temp_volfile->checksum = checksum;
-
- conf->volfile = temp_volfile;
- goto out;
- }
-
- if (temp_volfile->checksum != checksum) {
- gf_log (this->name, GF_LOG_CRITICAL,
- "the volume file got modified between earlier access "
- "and now, this may lead to inconsistency between "
- "clients, advised to remount client");
- temp_volfile->checksum = checksum;
- }
-
- out:
- return 0;
-}
-
-
-size_t
-build_volfile_path (xlator_t *this, const char *key, char *path,
- size_t path_len)
-{
- int ret = -1;
- int free_filename = 0;
- char *filename = NULL;
- char data_key[256] = {0,};
-
- /* Inform users that this option is changed now */
- ret = dict_get_str (this->options, "client-volume-filename",
- &filename);
- if (ret == 0) {
- gf_log (this->name, GF_LOG_WARNING,
- "option 'client-volume-filename' is changed to "
- "'volume-filename.<key>' which now takes 'key' as an "
- "option to choose/fetch different files from server. "
- "Refer documentation or contact developers for more "
- "info. Currently defaulting to given file '%s'",
- filename);
- }
-
- if (key && !filename) {
- sprintf (data_key, "volume-filename.%s", key);
- ret = dict_get_str (this->options, data_key, &filename);
- if (ret < 0) {
- /* Make sure that key doesn't contain
- * "../" in path
- */
- if (!strstr (key, "../")) {
- ret = asprintf (&filename, "%s/%s.vol",
- CONFDIR, key);
- if (-1 == ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "asprintf failed to get "
- "volume file path");
- } else {
- free_filename = 1;
- }
- } else {
- gf_log (this->name, GF_LOG_DEBUG,
- "%s: invalid key", key);
- }
- }
- }
-
- if (!filename) {
- ret = dict_get_str (this->options,
- "volume-filename.default", &filename);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_DEBUG,
- "no default volume filename given, "
- "defaulting to %s", DEFAULT_VOLUME_FILE_PATH);
-
- filename = DEFAULT_VOLUME_FILE_PATH;
- }
- }
-
- ret = -1;
- if ((filename) && (path_len > strlen (filename))) {
- strcpy (path, filename);
- ret = strlen (filename);
- }
-
- if (free_filename)
- free (filename);
-
- return ret;
-}
-
-int
-_validate_volfile_checksum (xlator_t *this, char *key,
- uint32_t checksum)
-{
- char filename[ZR_PATH_MAX] = {0,};
- server_conf_t *conf = NULL;
- struct _volfile_ctx *temp_volfile = NULL;
- int ret = 0;
- uint32_t local_checksum = 0;
-
- conf = this->private;
- temp_volfile = conf->volfile;
-
- if (!checksum)
- goto out;
-
- if (!temp_volfile) {
- ret = build_volfile_path (this, key, filename,
- sizeof (filename));
- if (ret <= 0)
- goto out;
- ret = open (filename, O_RDONLY);
- if (-1 == ret) {
- ret = 0;
- gf_log (this->name, GF_LOG_DEBUG,
- "failed to open volume file (%s) : %s",
- filename, strerror (errno));
- goto out;
- }
- get_checksum_for_file (ret, &local_checksum);
- _volfile_update_checksum (this, key, local_checksum);
- close (ret);
- }
-
- temp_volfile = conf->volfile;
- while (temp_volfile) {
- if ((NULL == key) && (NULL == temp_volfile->key))
- break;
- if ((NULL == key) || (NULL == temp_volfile->key)) {
- temp_volfile = temp_volfile->next;
- continue;
- }
- if (strcmp (temp_volfile->key, key) == 0)
- break;
- temp_volfile = temp_volfile->next;
- }
-
- if (!temp_volfile)
- goto out;
-
- if ((temp_volfile->checksum) &&
- (checksum != temp_volfile->checksum))
- ret = -1;
-
-out:
- return ret;
-}
-
-/* Management Calls */
-/*
- * mop_getspec - getspec function for server protocol
- * @frame: call frame
- * @bound_xl:
- * @params:
- *
- */
-int
-mop_getspec (call_frame_t *frame, xlator_t *bound_xl,
- gf_hdr_common_t *hdr, size_t hdrlen,
- struct iobuf *iobuf)
-{
- gf_hdr_common_t *_hdr = NULL;
- gf_mop_getspec_rsp_t *rsp = NULL;
- int32_t ret = -1;
- int32_t op_errno = ENOENT;
- int32_t gf_errno = 0;
- int32_t spec_fd = -1;
- size_t file_len = 0;
- size_t _hdrlen = 0;
- char filename[ZR_PATH_MAX] = {0,};
- struct stat stbuf = {0,};
- gf_mop_getspec_req_t *req = NULL;
- uint32_t checksum = 0;
- uint32_t flags = 0;
- uint32_t keylen = 0;
- char *key = NULL;
- server_conf_t *conf = NULL;
-
- req = gf_param (hdr);
- flags = ntoh32 (req->flags);
- keylen = ntoh32 (req->keylen);
- if (keylen) {
- key = req->key;
- }
-
- conf = frame->this->private;
-
- ret = build_volfile_path (frame->this, key, filename,
- sizeof (filename));
- if (ret > 0) {
- /* to allocate the proper buffer to hold the file data */
- ret = stat (filename, &stbuf);
- if (ret < 0){
- gf_log (frame->this->name, GF_LOG_ERROR,
- "Unable to stat %s (%s)",
- filename, strerror (errno));
- goto fail;
- }
-
- spec_fd = open (filename, O_RDONLY);
- if (spec_fd < 0) {
- gf_log (frame->this->name, GF_LOG_ERROR,
- "Unable to open %s (%s)",
- filename, strerror (errno));
- goto fail;
- }
- ret = 0;
- file_len = stbuf.st_size;
- if (conf->verify_volfile_checksum) {
- get_checksum_for_file (spec_fd, &checksum);
- _volfile_update_checksum (frame->this, key, checksum);
- }
- } else {
- errno = ENOENT;
- }
-
-fail:
- op_errno = errno;
-
- _hdrlen = gf_hdr_len (rsp, file_len + 1);
- _hdr = gf_hdr_new (rsp, file_len + 1);
- rsp = gf_param (_hdr);
-
- _hdr->rsp.op_ret = hton32 (ret);
- gf_errno = gf_errno_to_error (op_errno);
- _hdr->rsp.op_errno = hton32 (gf_errno);
-
- if (file_len) {
- ret = read (spec_fd, rsp->spec, file_len);
- close (spec_fd);
- }
- protocol_server_reply (frame, GF_OP_TYPE_MOP_REPLY, GF_MOP_GETSPEC,
- _hdr, _hdrlen, NULL, 0, NULL);
-
- return 0;
-}
-
-
-int
-server_checksum_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno,
- uint8_t *fchecksum, uint8_t *dchecksum)
-{
- gf_hdr_common_t *hdr = NULL;
- gf_fop_checksum_rsp_t *rsp = NULL;
- size_t hdrlen = 0;
- int32_t gf_errno = 0;
-
- hdrlen = gf_hdr_len (rsp, NAME_MAX + 1 + NAME_MAX + 1);
- hdr = gf_hdr_new (rsp, NAME_MAX + 1 + NAME_MAX + 1);
- rsp = gf_param (hdr);
-
- hdr->rsp.op_ret = hton32 (op_ret);
- gf_errno = gf_errno_to_error (op_errno);
- hdr->rsp.op_errno = hton32 (gf_errno);
-
- if (op_ret >= 0) {
- memcpy (rsp->fchecksum, fchecksum, NAME_MAX);
- rsp->fchecksum[NAME_MAX] = '\0';
- memcpy (rsp->dchecksum + NAME_MAX,
- dchecksum, NAME_MAX);
- rsp->dchecksum[NAME_MAX + NAME_MAX] = '\0';
- }
-
- protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_FOP_CHECKSUM,
- hdr, hdrlen, NULL, 0, NULL);
-
- return 0;
-}
-
-
-int
-server_checksum (call_frame_t *frame, xlator_t *bound_xl,
- gf_hdr_common_t *hdr, size_t hdrlen,
- struct iobuf *iobuf)
-{
- loc_t loc = {0,};
- int32_t flag = 0;
- gf_fop_checksum_req_t *req = NULL;
-
- req = gf_param (hdr);
-
- loc.path = req->path;
- loc.ino = ntoh64 (req->ino);
- loc.inode = NULL;
- flag = ntoh32 (req->flag);
-
- gf_log (bound_xl->name, GF_LOG_TRACE,
- "%"PRId64": CHECKSUM \'%s (%"PRId64")\'",
- frame->root->unique, loc.path, loc.ino);
-
- STACK_WIND (frame, server_checksum_cbk,
- BOUND_XL(frame),
- BOUND_XL(frame)->fops->checksum,
- &loc, flag);
- return 0;
-}
-
-
-int
-server_rchecksum_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno,
- uint32_t weak_checksum, uint8_t *strong_checksum)
-{
- gf_hdr_common_t *hdr = NULL;
- gf_fop_rchecksum_rsp_t *rsp = NULL;
- size_t hdrlen = 0;
- int32_t gf_errno = 0;
-
- hdrlen = gf_hdr_len (rsp, MD5_DIGEST_LEN + 1);
- hdr = gf_hdr_new (rsp, MD5_DIGEST_LEN + 1);
- rsp = gf_param (hdr);
-
- hdr->rsp.op_ret = hton32 (op_ret);
- gf_errno = gf_errno_to_error (op_errno);
- hdr->rsp.op_errno = hton32 (gf_errno);
-
- if (op_ret >= 0) {
- rsp->weak_checksum = weak_checksum;
-
- memcpy (rsp->strong_checksum,
- strong_checksum, MD5_DIGEST_LEN);
-
- rsp->strong_checksum[MD5_DIGEST_LEN] = '\0';
- }
-
- protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_FOP_RCHECKSUM,
- hdr, hdrlen, NULL, 0, NULL);
-
- return 0;
-}
-
-
-int
-server_rchecksum (call_frame_t *frame, xlator_t *bound_xl,
- gf_hdr_common_t *hdr, size_t hdrlen,
- struct iobuf *iobuf)
-{
- gf_fop_rchecksum_req_t *req = NULL;
- server_state_t *state = NULL;
- server_connection_t *conn = NULL;
-
- conn = SERVER_CONNECTION(frame);
-
- req = gf_param (hdr);
-
- state = CALL_STATE(frame);
- {
- state->fd_no = ntoh64 (req->fd);
- if (state->fd_no >= 0)
- state->fd = gf_fd_fdptr_get (conn->fdtable,
- state->fd_no);
-
- state->offset = ntoh64 (req->offset);
- state->size = ntoh32 (req->len);
- }
-
- GF_VALIDATE_OR_GOTO(bound_xl->name, state->fd, fail);
-
- gf_log (bound_xl->name, GF_LOG_TRACE,
- "%"PRId64": RCHECKSUM \'fd=%"PRId64" (%"PRId64"); "
- "offset=%"PRId64"\'",
- frame->root->unique, state->fd_no, state->fd->inode->ino,
- state->offset);
-
- STACK_WIND (frame, server_rchecksum_cbk,
- bound_xl,
- bound_xl->fops->rchecksum,
- state->fd, state->offset, state->size);
- return 0;
-fail:
- server_rchecksum_cbk (frame, NULL, frame->this, -1, EINVAL, 0, NULL);
-
- return 0;
-}
-
-
-/*
- * mop_unlock - unlock management function for server protocol
- * @frame: call frame
- * @bound_xl:
- * @params: parameter dictionary
- *
- */
-int
-mop_getvolume (call_frame_t *frame, xlator_t *bound_xl,
- gf_hdr_common_t *hdr, size_t hdrlen,
- struct iobuf *iobuf)
-{
- return 0;
-}
-
-struct __get_xl_struct {
- const char *name;
- xlator_t *reply;
-};
-
-void __check_and_set (xlator_t *each, void *data)
-{
- if (!strcmp (each->name,
- ((struct __get_xl_struct *) data)->name))
- ((struct __get_xl_struct *) data)->reply = each;
-}
-
-static xlator_t *
-get_xlator_by_name (xlator_t *some_xl, const char *name)
-{
- struct __get_xl_struct get = {
- .name = name,
- .reply = NULL
- };
-
- xlator_foreach (some_xl, __check_and_set, &get);
-
- return get.reply;
-}
-
-
-/*
- * mop_setvolume - setvolume management function for server protocol
- * @frame: call frame
- * @bound_xl:
- * @params: parameter dictionary
- *
- */
-int
-mop_setvolume (call_frame_t *frame, xlator_t *bound_xl,
- gf_hdr_common_t *req_hdr, size_t req_hdrlen,
- struct iobuf *iobuf)
-{
- server_connection_t *conn = NULL;
- server_conf_t *conf = NULL;
- gf_hdr_common_t *rsp_hdr = NULL;
- gf_mop_setvolume_req_t *req = NULL;
- gf_mop_setvolume_rsp_t *rsp = NULL;
- peer_info_t *peerinfo = NULL;
- int32_t ret = -1;
- int32_t op_ret = -1;
- int32_t op_errno = EINVAL;
- int32_t gf_errno = 0;
- dict_t *reply = NULL;
- dict_t *config_params = NULL;
- dict_t *params = NULL;
- char *name = NULL;
- char *version = NULL;
- char *process_uuid = NULL;
- xlator_t *xl = NULL;
- transport_t *trans = NULL;
- size_t rsp_hdrlen = -1;
- size_t dict_len = -1;
- size_t req_dictlen = -1;
- char *msg = NULL;
- char *volfile_key = NULL;
- uint32_t checksum = 0;
- int32_t lru_limit = 1024;
-
- params = dict_new ();
- reply = dict_new ();
-
- req = gf_param (req_hdr);
- req_dictlen = ntoh32 (req->dict_len);
- ret = dict_unserialize (req->buf, req_dictlen, &params);
-
- config_params = dict_copy_with_ref (frame->this->options, NULL);
- trans = TRANSPORT_FROM_FRAME(frame);
- conf = SERVER_CONF(frame);
-
- if (ret < 0) {
- ret = dict_set_str (reply, "ERROR",
- "Internal error: failed to unserialize "
- "request dictionary");
- if (ret < 0)
- gf_log (bound_xl->name, GF_LOG_DEBUG,
- "failed to set error msg \"%s\"",
- "Internal error: failed to unserialize "
- "request dictionary");
-
- op_ret = -1;
- op_errno = EINVAL;
- goto fail;
- }
-
- ret = dict_get_str (params, "process-uuid", &process_uuid);
- if (ret < 0) {
- ret = dict_set_str (reply, "ERROR",
- "UUID not specified");
- if (ret < 0)
- gf_log (bound_xl->name, GF_LOG_DEBUG,
- "failed to set error msg");
-
- op_ret = -1;
- op_errno = EINVAL;
- goto fail;
- }
-
-
- conn = server_connection_get (frame->this, process_uuid);
- if (trans->xl_private != conn)
- trans->xl_private = conn;
-
- ret = dict_get_str (params, "protocol-version", &version);
- if (ret < 0) {
- ret = dict_set_str (reply, "ERROR",
- "No version number specified");
- if (ret < 0)
- gf_log (trans->xl->name, GF_LOG_DEBUG,
- "failed to set error msg");
-
- op_ret = -1;
- op_errno = EINVAL;
- goto fail;
- }
-
- ret = strcmp (version, GF_PROTOCOL_VERSION);
- if (ret != 0) {
- ret = asprintf (&msg, "protocol version mismatch: client(%s) "
- "- server(%s)", version, GF_PROTOCOL_VERSION);
- if (-1 == ret) {
- gf_log (trans->xl->name, GF_LOG_ERROR,
- "asprintf failed while setting up error msg");
- goto fail;
- }
- ret = dict_set_dynstr (reply, "ERROR", msg);
- if (ret < 0)
- gf_log (trans->xl->name, GF_LOG_DEBUG,
- "failed to set error msg");
-
- op_ret = -1;
- op_errno = EINVAL;
- goto fail;
- }
-
- ret = dict_get_str (params,
- "remote-subvolume", &name);
- if (ret < 0) {
- ret = dict_set_str (reply, "ERROR",
- "No remote-subvolume option specified");
- if (ret < 0)
- gf_log (trans->xl->name, GF_LOG_DEBUG,
- "failed to set error msg");
-
- op_ret = -1;
- op_errno = EINVAL;
- goto fail;
- }
-
- xl = get_xlator_by_name (frame->this, name);
- if (xl == NULL) {
- ret = asprintf (&msg, "remote-subvolume \"%s\" is not found",
- name);
- if (-1 == ret) {
- gf_log (trans->xl->name, GF_LOG_ERROR,
- "asprintf failed while setting error msg");
- goto fail;
- }
- ret = dict_set_dynstr (reply, "ERROR", msg);
- if (ret < 0)
- gf_log (trans->xl->name, GF_LOG_DEBUG,
- "failed to set error msg");
-
- op_ret = -1;
- op_errno = ENOENT;
- goto fail;
- }
-
- if (conf->verify_volfile_checksum) {
- ret = dict_get_uint32 (params, "volfile-checksum", &checksum);
- if (ret == 0) {
- ret = dict_get_str (params, "volfile-key",
- &volfile_key);
-
- ret = _validate_volfile_checksum (trans->xl,
- volfile_key,
- checksum);
- if (-1 == ret) {
- ret = dict_set_str (reply, "ERROR",
- "volume-file checksum "
- "varies from earlier "
- "access");
- if (ret < 0)
- gf_log (trans->xl->name, GF_LOG_DEBUG,
- "failed to set error msg");
-
- op_ret = -1;
- op_errno = ESTALE;
- goto fail;
- }
- }
- }
-
-
- peerinfo = &trans->peerinfo;
- ret = dict_set_static_ptr (params, "peer-info", peerinfo);
- if (ret < 0)
- gf_log (trans->xl->name, GF_LOG_DEBUG,
- "failed to set peer-info");
-
- if (conf->auth_modules == NULL) {
- gf_log (trans->xl->name, GF_LOG_ERROR,
- "Authentication module not initialized");
- }
-
- ret = gf_authenticate (params, config_params,
- conf->auth_modules);
- if (ret == AUTH_ACCEPT) {
- gf_log (trans->xl->name, GF_LOG_INFO,
- "accepted client from %s",
- peerinfo->identifier);
- op_ret = 0;
- conn->bound_xl = xl;
- ret = dict_set_str (reply, "ERROR", "Success");
- if (ret < 0)
- gf_log (trans->xl->name, GF_LOG_DEBUG,
- "failed to set error msg");
- } else {
- gf_log (trans->xl->name, GF_LOG_ERROR,
- "Cannot authenticate client from %s",
- peerinfo->identifier);
- op_ret = -1;
- op_errno = EACCES;
- ret = dict_set_str (reply, "ERROR", "Authentication failed");
- if (ret < 0)
- gf_log (bound_xl->name, GF_LOG_DEBUG,
- "failed to set error msg");
-
- goto fail;
- }
-
- if (conn->bound_xl == NULL) {
- ret = dict_set_str (reply, "ERROR",
- "Check volfile and handshake "
- "options in protocol/client");
- if (ret < 0)
- gf_log (trans->xl->name, GF_LOG_DEBUG,
- "failed to set error msg");
-
- op_ret = -1;
- op_errno = EACCES;
- goto fail;
- }
-
- if ((conn->bound_xl != NULL) &&
- (ret >= 0) &&
- (conn->bound_xl->itable == NULL)) {
- /* create inode table for this bound_xl, if one doesn't
- already exist */
- lru_limit = INODE_LRU_LIMIT (frame->this);
-
- gf_log (trans->xl->name, GF_LOG_TRACE,
- "creating inode table with lru_limit=%"PRId32", "
- "xlator=%s", lru_limit, conn->bound_xl->name);
-
- conn->bound_xl->itable =
- inode_table_new (lru_limit,
- conn->bound_xl);
- }
-
- ret = dict_set_str (reply, "process-uuid",
- xl->ctx->process_uuid);
-
- ret = dict_set_uint64 (reply, "transport-ptr",
- ((uint64_t) (long) trans));
-
-fail:
- dict_len = dict_serialized_length (reply);
- if (dict_len < 0) {
- gf_log (xl->name, GF_LOG_DEBUG,
- "failed to get serialized length of reply dict");
- op_ret = -1;
- op_errno = EINVAL;
- dict_len = 0;
- }
-
- rsp_hdr = gf_hdr_new (rsp, dict_len);
- rsp_hdrlen = gf_hdr_len (rsp, dict_len);
- rsp = gf_param (rsp_hdr);
-
- if (dict_len) {
- ret = dict_serialize (reply, rsp->buf);
- if (ret < 0) {
- gf_log (xl->name, GF_LOG_DEBUG,
- "failed to serialize reply dict");
- op_ret = -1;
- op_errno = -ret;
- }
- }
- rsp->dict_len = hton32 (dict_len);
-
- rsp_hdr->rsp.op_ret = hton32 (op_ret);
- gf_errno = gf_errno_to_error (op_errno);
- rsp_hdr->rsp.op_errno = hton32 (gf_errno);
-
- protocol_server_reply (frame, GF_OP_TYPE_MOP_REPLY, GF_MOP_SETVOLUME,
- rsp_hdr, rsp_hdrlen, NULL, 0, NULL);
-
- dict_unref (params);
- dict_unref (reply);
- dict_unref (config_params);
-
- return 0;
-}
-
-/*
- * server_mop_stats_cbk - stats callback for server management operation
- * @frame: call frame
- * @cookie:
- * @this:
- * @op_ret: return value
- * @op_errno: errno
- * @stats:err
- *
- * not for external reference
- */
-
-int
-server_mop_stats_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t ret, int32_t op_errno,
- struct xlator_stats *stats)
-{
- /* TODO: get this information from somewhere else, not extern */
- gf_hdr_common_t *hdr = NULL;
- gf_mop_stats_rsp_t *rsp = NULL;
- char buffer[256] = {0,};
- int64_t glusterfsd_stats_nr_clients = 0;
- size_t hdrlen = 0;
- size_t buf_len = 0;
- int32_t gf_errno = 0;
-
- if (ret >= 0) {
- sprintf (buffer,
- "%"PRIx64",%"PRIx64",%"PRIx64
- ",%"PRIx64",%"PRIx64",%"PRIx64
- ",%"PRIx64",%"PRIx64"\n",
- stats->nr_files, stats->disk_usage, stats->free_disk,
- stats->total_disk_size, stats->read_usage,
- stats->write_usage, stats->disk_speed,
- glusterfsd_stats_nr_clients);
-
- buf_len = strlen (buffer);
- }
-
- hdrlen = gf_hdr_len (rsp, buf_len + 1);
- hdr = gf_hdr_new (rsp, buf_len + 1);
- rsp = gf_param (hdr);
-
- hdr->rsp.op_ret = hton32 (ret);
- gf_errno = gf_errno_to_error (op_errno);
- hdr->rsp.op_errno = hton32 (gf_errno);
-
- strcpy (rsp->buf, buffer);
-
- protocol_server_reply (frame, GF_OP_TYPE_MOP_REPLY, GF_MOP_STATS,
- hdr, hdrlen, NULL, 0, NULL);
-
- return 0;
-}
-
-
-/*
- * mop_unlock - unlock management function for server protocol
- * @frame: call frame
- * @bound_xl:
- * @params: parameter dictionary
- *
- */
-int
-mop_stats (call_frame_t *frame, xlator_t *bound_xl,
- gf_hdr_common_t *hdr, size_t hdrlen,
- struct iobuf *iobuf)
-{
- int32_t flag = 0;
- gf_mop_stats_req_t *req = NULL;
-
- req = gf_param (hdr);
-
- flag = ntoh32 (req->flags);
-
- STACK_WIND (frame, server_mop_stats_cbk,
- bound_xl,
- bound_xl->mops->stats,
- flag);
-
- return 0;
-}
-
-
-int
-mop_ping (call_frame_t *frame, xlator_t *bound_xl,
- gf_hdr_common_t *hdr, size_t hdrlen,
- struct iobuf *iobuf)
-{
- gf_hdr_common_t *rsp_hdr = NULL;
- gf_mop_ping_rsp_t *rsp = NULL;
- size_t rsp_hdrlen = 0;
-
- rsp_hdrlen = gf_hdr_len (rsp, 0);
- rsp_hdr = gf_hdr_new (rsp, 0);
-
- hdr->rsp.op_ret = 0;
-
- protocol_server_reply (frame, GF_OP_TYPE_MOP_REPLY, GF_MOP_PING,
- rsp_hdr, rsp_hdrlen, NULL, 0, NULL);
-
- return 0;
-}
-
-
-int
-mop_log (call_frame_t *frame, xlator_t *bound_xl,
- gf_hdr_common_t *hdr, size_t hdrlen,
- struct iobuf *iobuf)
-{
- gf_mop_log_req_t * req = NULL;
- char * msg = NULL;
- uint32_t msglen = 0;
-
- transport_t * trans = NULL;
-
- trans = TRANSPORT_FROM_FRAME (frame);
-
- req = gf_param (hdr);
- msglen = ntoh32 (req->msglen);
-
- if (msglen)
- msg = req->msg;
-
- gf_log_from_client (msg, trans->peerinfo.identifier);
-
- return 0;
-}
-
-
-/*
- * unknown_op_cbk - This function is called when a opcode for unknown
- * type is called. Helps to keep the backward/forward
- * compatiblity
- * @frame: call frame
- * @type:
- * @opcode:
- *
- */
-
-int
-unknown_op_cbk (call_frame_t *frame, int32_t type, int32_t opcode)
-{
- gf_hdr_common_t *hdr = NULL;
- gf_fop_flush_rsp_t *rsp = NULL;
- size_t hdrlen = 0;
- int32_t gf_errno = 0;
-
- hdrlen = gf_hdr_len (rsp, 0);
- hdr = gf_hdr_new (rsp, 0);
- rsp = gf_param (hdr);
-
- hdr->rsp.op_ret = hton32 (-1);
- gf_errno = gf_errno_to_error (ENOSYS);
- hdr->rsp.op_errno = hton32 (gf_errno);
-
- protocol_server_reply (frame, type, opcode,
- hdr, hdrlen, NULL, 0, NULL);
-
- return 0;
-}
-
-/*
- * get_frame_for_transport - get call frame for specified transport object
- *
- * @trans: transport object
- *
- */
-static call_frame_t *
-get_frame_for_transport (transport_t *trans)
-{
- call_frame_t *frame = NULL;
- call_pool_t *pool = NULL;
- server_connection_t *conn = NULL;
- server_state_t *state = NULL;;
-
- GF_VALIDATE_OR_GOTO("server", trans, out);
-
- if (trans->xl && trans->xl->ctx)
- pool = trans->xl->ctx->pool;
- GF_VALIDATE_OR_GOTO("server", pool, out);
-
- frame = create_frame (trans->xl, pool);
- GF_VALIDATE_OR_GOTO("server", frame, out);
-
- state = CALLOC (1, sizeof (*state));
- GF_VALIDATE_OR_GOTO("server", state, out);
-
- conn = trans->xl_private;
- if (conn) {
- if (conn->bound_xl)
- state->itable = conn->bound_xl->itable;
- state->bound_xl = conn->bound_xl;
- }
-
- state->trans = transport_ref (trans);
-
- frame->root->trans = conn;
- frame->root->state = state; /* which socket */
- frame->root->unique = 0; /* which call */
-
-out:
- return frame;
-}
-
-/*
- * get_frame_for_call - create a frame into the capable of
- * generating and replying the reply packet by itself.
- * By making a call with this frame, the last UNWIND
- * function will have all needed state from its
- * frame_t->root to send reply.
- * @trans:
- * @blk:
- * @params:
- *
- * not for external reference
- */
-static call_frame_t *
-get_frame_for_call (transport_t *trans, gf_hdr_common_t *hdr)
-{
- call_frame_t *frame = NULL;
-
- frame = get_frame_for_transport (trans);
-
- frame->root->op = ntoh32 (hdr->op);
- frame->root->type = ntoh32 (hdr->type);
-
- frame->root->uid = ntoh32 (hdr->req.uid);
- frame->root->unique = ntoh64 (hdr->callid); /* which call */
- frame->root->gid = ntoh32 (hdr->req.gid);
- frame->root->pid = ntoh32 (hdr->req.pid);
-
- return frame;
-}
-
-/*
- * prototype of operations function for each of mop and
- * fop at server protocol level
- *
- * @frame: call frame pointer
- * @bound_xl: the xlator that this frame is bound to
- * @params: parameters dictionary
- *
- * to be used by protocol interpret, _not_ for exterenal reference
- */
-typedef int32_t (*gf_op_t) (call_frame_t *frame, xlator_t *bould_xl,
- gf_hdr_common_t *hdr, size_t hdrlen,
- struct iobuf *iobuf);
-
-
-static gf_op_t gf_fops[] = {
- [GF_FOP_STAT] = server_stat,
- [GF_FOP_READLINK] = server_readlink,
- [GF_FOP_MKNOD] = server_mknod,
- [GF_FOP_MKDIR] = server_mkdir,
- [GF_FOP_UNLINK] = server_unlink,
- [GF_FOP_RMDIR] = server_rmdir,
- [GF_FOP_SYMLINK] = server_symlink,
- [GF_FOP_RENAME] = server_rename,
- [GF_FOP_LINK] = server_link,
- [GF_FOP_TRUNCATE] = server_truncate,
- [GF_FOP_OPEN] = server_open,
- [GF_FOP_READ] = server_readv,
- [GF_FOP_WRITE] = server_writev,
- [GF_FOP_STATFS] = server_statfs,
- [GF_FOP_FLUSH] = server_flush,
- [GF_FOP_FSYNC] = server_fsync,
- [GF_FOP_SETXATTR] = server_setxattr,
- [GF_FOP_GETXATTR] = server_getxattr,
- [GF_FOP_FGETXATTR] = server_fgetxattr,
- [GF_FOP_FSETXATTR] = server_fsetxattr,
- [GF_FOP_REMOVEXATTR] = server_removexattr,
- [GF_FOP_OPENDIR] = server_opendir,
- [GF_FOP_GETDENTS] = server_getdents,
- [GF_FOP_FSYNCDIR] = server_fsyncdir,
- [GF_FOP_ACCESS] = server_access,
- [GF_FOP_CREATE] = server_create,
- [GF_FOP_FTRUNCATE] = server_ftruncate,
- [GF_FOP_FSTAT] = server_fstat,
- [GF_FOP_LK] = server_lk,
- [GF_FOP_LOOKUP] = server_lookup,
- [GF_FOP_SETDENTS] = server_setdents,
- [GF_FOP_READDIR] = server_readdir,
- [GF_FOP_READDIRP] = server_readdirp,
- [GF_FOP_INODELK] = server_inodelk,
- [GF_FOP_FINODELK] = server_finodelk,
- [GF_FOP_ENTRYLK] = server_entrylk,
- [GF_FOP_FENTRYLK] = server_fentrylk,
- [GF_FOP_CHECKSUM] = server_checksum,
- [GF_FOP_RCHECKSUM] = server_rchecksum,
- [GF_FOP_XATTROP] = server_xattrop,
- [GF_FOP_FXATTROP] = server_fxattrop,
- [GF_FOP_SETATTR] = server_setattr,
- [GF_FOP_FSETATTR] = server_fsetattr,
-};
-
-
-
-static gf_op_t gf_mops[] = {
- [GF_MOP_SETVOLUME] = mop_setvolume,
- [GF_MOP_GETVOLUME] = mop_getvolume,
- [GF_MOP_STATS] = mop_stats,
- [GF_MOP_GETSPEC] = mop_getspec,
- [GF_MOP_PING] = mop_ping,
- [GF_MOP_LOG] = mop_log,
-};
-
-static gf_op_t gf_cbks[] = {
- [GF_CBK_FORGET] = server_forget,
- [GF_CBK_RELEASE] = server_release,
- [GF_CBK_RELEASEDIR] = server_releasedir
-};
-
-int
-protocol_server_interpret (xlator_t *this, transport_t *trans,
- char *hdr_p, size_t hdrlen, struct iobuf *iobuf)
-{
- server_connection_t *conn = NULL;
- gf_hdr_common_t *hdr = NULL;
- xlator_t *bound_xl = NULL;
- call_frame_t *frame = NULL;
- peer_info_t *peerinfo = NULL;
- int32_t type = -1;
- int32_t op = -1;
- int32_t ret = -1;
-
- hdr = (gf_hdr_common_t *)hdr_p;
- type = ntoh32 (hdr->type);
- op = ntoh32 (hdr->op);
-
- conn = trans->xl_private;
- if (conn)
- bound_xl = conn->bound_xl;
-
- peerinfo = &trans->peerinfo;
- switch (type) {
- case GF_OP_TYPE_FOP_REQUEST:
- if ((op < 0) || (op >= GF_FOP_MAXVALUE)) {
- gf_log (this->name, GF_LOG_ERROR,
- "invalid fop %"PRId32" from client %s",
- op, peerinfo->identifier);
- break;
- }
- if (bound_xl == NULL) {
- gf_log (this->name, GF_LOG_ERROR,
- "Received fop %"PRId32" before "
- "authentication.", op);
- break;
- }
- frame = get_frame_for_call (trans, hdr);
- ret = gf_fops[op] (frame, bound_xl, hdr, hdrlen, iobuf);
- break;
-
- case GF_OP_TYPE_MOP_REQUEST:
- if ((op < 0) || (op >= GF_MOP_MAXVALUE)) {
- gf_log (this->name, GF_LOG_ERROR,
- "invalid mop %"PRId32" from client %s",
- op, peerinfo->identifier);
- break;
- }
- frame = get_frame_for_call (trans, hdr);
- ret = gf_mops[op] (frame, bound_xl, hdr, hdrlen, iobuf);
- break;
-
- case GF_OP_TYPE_CBK_REQUEST:
- if ((op < 0) || (op >= GF_CBK_MAXVALUE)) {
- gf_log (this->name, GF_LOG_ERROR,
- "invalid cbk %"PRId32" from client %s",
- op, peerinfo->identifier);
- break;
- }
- if (bound_xl == NULL) {
- gf_log (this->name, GF_LOG_ERROR,
- "Received cbk %d before authentication.", op);
- break;
- }
-
- frame = get_frame_for_call (trans, hdr);
- ret = gf_cbks[op] (frame, bound_xl, hdr, hdrlen, iobuf);
- break;
-
- default:
- break;
- }
-
- return ret;
-}
-
-
-/*
- * server_nop_cbk - nop callback for server protocol
- * @frame: call frame
- * @cookie:
- * @this:
- * @op_ret: return value
- * @op_errno: errno
- *
- * not for external reference
- */
-int
-server_nop_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno)
-{
- server_state_t *state = NULL;
-
- state = CALL_STATE(frame);
-
- if (state)
- free_state (state);
- STACK_DESTROY (frame->root);
- return 0;
-}
-
-/*
- * server_fd - fdtable dump function for server protocol
- * @this:
- *
- */
-int
-server_fd (xlator_t *this)
-{
- server_conf_t *conf = NULL;
- server_connection_t *trav = NULL;
- char key[GF_DUMP_MAX_BUF_LEN];
- int i = 1;
- int ret = -1;
-
- if (!this)
- return -1;
-
- conf = this->private;
- if (!conf) {
- gf_log (this->name, GF_LOG_WARNING,
- "conf null in xlator");
- return -1;
- }
-
- gf_proc_dump_add_section("xlator.protocol.server.conn");
-
- ret = pthread_mutex_trylock (&conf->mutex);
- if (ret) {
- gf_log("", GF_LOG_WARNING, "Unable to dump fdtable"
- " errno: %d", errno);
- return -1;
- }
-
- list_for_each_entry (trav, &conf->conns, list) {
- if (trav->id) {
- gf_proc_dump_build_key(key,
- "xlator.protocol.server.conn",
- "%d.id", i);
- gf_proc_dump_write(key, "%s", trav->id);
- }
-
- gf_proc_dump_build_key(key,"xlator.protocol.server.conn",
- "%d.ref",i)
- gf_proc_dump_write(key, "%d", trav->ref);
- if (trav->bound_xl) {
- gf_proc_dump_build_key(key,
- "xlator.protocol.server.conn",
- "%d.bound_xl", i);
- gf_proc_dump_write(key, "%s", trav->bound_xl->name);
- }
-
- gf_proc_dump_build_key(key,
- "xlator.protocol.server.conn",
- "%d.id", i);
- fdtable_dump(trav->fdtable,key);
- i++;
- }
- pthread_mutex_unlock (&conf->mutex);
-
-
- return 0;
- }
-
-int
-server_priv (xlator_t *this)
-{
- return 0;
-}
-
-int
-server_inode (xlator_t *this)
-{
- server_conf_t *conf = NULL;
- server_connection_t *trav = NULL;
- char key[GF_DUMP_MAX_BUF_LEN];
- int i = 1;
- int ret = -1;
-
- if (!this)
- return -1;
-
- conf = this->private;
- if (!conf) {
- gf_log (this->name, GF_LOG_WARNING,
- "conf null in xlator");
- return -1;
- }
-
- ret = pthread_mutex_trylock (&conf->mutex);
- if (ret) {
- gf_log("", GF_LOG_WARNING, "Unable to dump itable"
- " errno: %d", errno);
- return -1;
- }
-
- list_for_each_entry (trav, &conf->conns, list) {
- if (trav->bound_xl && trav->bound_xl->itable) {
- gf_proc_dump_build_key(key,
- "xlator.protocol.server.conn",
- "%d.bound_xl.%s",
- i, trav->bound_xl->name);
- inode_table_dump(trav->bound_xl->itable,key);
- i++;
- }
- }
- pthread_mutex_unlock (&conf->mutex);
-
-
- return 0;
-}
-
-
-static void
-get_auth_types (dict_t *this, char *key, data_t *value, void *data)
-{
- dict_t *auth_dict = NULL;
- char *saveptr = NULL;
- char *tmp = NULL;
- char *key_cpy = NULL;
- int32_t ret = -1;
-
- auth_dict = data;
- key_cpy = strdup (key);
- GF_VALIDATE_OR_GOTO("server", key_cpy, out);
-
- tmp = strtok_r (key_cpy, ".", &saveptr);
- ret = strcmp (tmp, "auth");
- if (ret == 0) {
- tmp = strtok_r (NULL, ".", &saveptr);
- if (strcmp (tmp, "ip") == 0) {
- /* TODO: backward compatibility, remove when
- newer versions are available */
- tmp = "addr";
- gf_log ("server", GF_LOG_WARNING,
- "assuming 'auth.ip' to be 'auth.addr'");
- }
- ret = dict_set_dynptr (auth_dict, tmp, NULL, 0);
- if (ret < 0) {
- gf_log ("server", GF_LOG_DEBUG,
- "failed to dict_set_dynptr");
- }
- }
-
- FREE (key_cpy);
-out:
- return;
-}
-
-
-int
-validate_auth_options (xlator_t *this, dict_t *dict)
-{
- int ret = -1;
- int error = 0;
- xlator_list_t *trav = NULL;
- data_pair_t *pair = NULL;
- char *saveptr = NULL;
- char *tmp = NULL;
- char *key_cpy = NULL;
-
- trav = this->children;
- while (trav) {
- error = -1;
- for (pair = dict->members_list; pair; pair = pair->next) {
- key_cpy = strdup (pair->key);
- tmp = strtok_r (key_cpy, ".", &saveptr);
- ret = strcmp (tmp, "auth");
- if (ret == 0) {
- /* for module type */
- tmp = strtok_r (NULL, ".", &saveptr);
- /* for volume name */
- tmp = strtok_r (NULL, ".", &saveptr);
- }
-
- if (strcmp (tmp, trav->xlator->name) == 0) {
- error = 0;
- free (key_cpy);
- break;
- }
- free (key_cpy);
- }
- if (-1 == error) {
- gf_log (this->name, GF_LOG_ERROR,
- "volume '%s' defined as subvolume, but no "
- "authentication defined for the same",
- trav->xlator->name);
- break;
- }
- trav = trav->next;
- }
-
- return error;
-}
-
-
-/*
- * init - called during server protocol initialization
- *
- * @this:
- *
- */
-int
-init (xlator_t *this)
-{
- int32_t ret = -1;
- transport_t *trans = NULL;
- server_conf_t *conf = NULL;
- data_t *data = NULL;
-
- if (this->children == NULL) {
- gf_log (this->name, GF_LOG_ERROR,
- "protocol/server should have subvolume");
- goto out;
- }
-
- trans = transport_load (this->options, this);
- if (trans == NULL) {
- gf_log (this->name, GF_LOG_ERROR,
- "failed to load transport");
- goto out;
- }
-
- ret = transport_listen (trans);
- if (ret == -1) {
- gf_log (this->name, GF_LOG_ERROR,
- "failed to bind/listen on socket");
- goto out;
- }
-
- conf = CALLOC (1, sizeof (server_conf_t));
- GF_VALIDATE_OR_GOTO(this->name, conf, out);
-
- INIT_LIST_HEAD (&conf->conns);
- pthread_mutex_init (&conf->mutex, NULL);
-
- conf->trans = trans;
-
- conf->auth_modules = dict_new ();
- GF_VALIDATE_OR_GOTO(this->name, conf->auth_modules, out);
-
- dict_foreach (this->options, get_auth_types,
- conf->auth_modules);
- ret = validate_auth_options (this, this->options);
- if (ret == -1) {
- /* logging already done in validate_auth_options function. */
- goto out;
- }
-
- ret = gf_auth_init (this, conf->auth_modules);
- if (ret) {
- dict_unref (conf->auth_modules);
- goto out;
- }
-
- this->private = conf;
-
- ret = dict_get_int32 (this->options, "inode-lru-limit",
- &conf->inode_lru_limit);
- if (ret < 0) {
- conf->inode_lru_limit = 1024;
- }
-
- ret = dict_get_int32 (this->options, "limits.transaction-size",
- &conf->max_block_size);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_TRACE,
- "defaulting limits.transaction-size to %d",
- DEFAULT_BLOCK_SIZE);
- conf->max_block_size = DEFAULT_BLOCK_SIZE;
- }
-
- conf->verify_volfile_checksum = 1;
- data = dict_get (this->options, "verify-volfile-checksum");
- if (data) {
- ret = gf_string2boolean(data->data,
- &conf->verify_volfile_checksum);
- if (ret != 0) {
- gf_log (this->name, GF_LOG_DEBUG,
- "wrong value for verify-volfile-checksum");
- conf->verify_volfile_checksum = 1;
- }
- }
-
-#ifndef GF_DARWIN_HOST_OS
- {
- struct rlimit lim;
-
- lim.rlim_cur = 1048576;
- lim.rlim_max = 1048576;
-
- if (setrlimit (RLIMIT_NOFILE, &lim) == -1) {
- gf_log (this->name, GF_LOG_WARNING,
- "WARNING: Failed to set 'ulimit -n 1M': %s",
- strerror(errno));
- lim.rlim_cur = 65536;
- lim.rlim_max = 65536;
-
- if (setrlimit (RLIMIT_NOFILE, &lim) == -1) {
- gf_log (this->name, GF_LOG_WARNING,
- "Failed to set max open fd to 64k: %s",
- strerror(errno));
- } else {
- gf_log (this->name, GF_LOG_TRACE,
- "max open fd set to 64k");
- }
- }
- }
-#endif
- this->ctx->top = this;
-
- ret = 0;
-out:
- return ret;
-}
-
-
-
-int
-protocol_server_pollin (xlator_t *this, transport_t *trans)
-{
- char *hdr = NULL;
- size_t hdrlen = 0;
- int ret = -1;
- struct iobuf *iobuf = NULL;
-
-
- ret = transport_receive (trans, &hdr, &hdrlen, &iobuf);
-
- if (ret == 0)
- ret = protocol_server_interpret (this, trans, hdr,
- hdrlen, iobuf);
-
- /* TODO: use mem-pool */
- FREE (hdr);
-
- return ret;
-}
-
-
-/*
- * fini - finish function for server protocol, called before
- * unloading server protocol.
- *
- * @this:
- *
- */
-void
-fini (xlator_t *this)
-{
- server_conf_t *conf = this->private;
-
- GF_VALIDATE_OR_GOTO(this->name, conf, out);
-
- if (conf->auth_modules) {
- dict_unref (conf->auth_modules);
- }
-
- FREE (conf);
- this->private = NULL;
-out:
- return;
-}
-
-/*
- * server_protocol_notify - notify function for server protocol
- * @this:
- * @trans:
- * @event:
- *
- */
-int
-notify (xlator_t *this, int32_t event, void *data, ...)
-{
- int ret = 0;
- transport_t *trans = data;
- peer_info_t *peerinfo = NULL;
- peer_info_t *myinfo = NULL;
-
- if (trans != NULL) {
- peerinfo = &(trans->peerinfo);
- myinfo = &(trans->myinfo);
- }
-
- switch (event) {
- case GF_EVENT_POLLIN:
- ret = protocol_server_pollin (this, trans);
- break;
- case GF_EVENT_POLLERR:
- {
- gf_log (trans->xl->name, GF_LOG_INFO, "%s disconnected",
- peerinfo->identifier);
-
- ret = -1;
- transport_disconnect (trans);
- if (trans->xl_private == NULL) {
- gf_log (this->name, GF_LOG_DEBUG,
- "POLLERR received on (%s) even before "
- "handshake with (%s) is successful",
- myinfo->identifier, peerinfo->identifier);
- } else {
- /*
- * FIXME: shouldn't we check for return value?
- * what should be done if cleanup fails?
- */
- server_connection_cleanup (this, trans->xl_private);
- }
- }
- break;
-
- case GF_EVENT_TRANSPORT_CLEANUP:
- {
- if (trans->xl_private) {
- server_connection_put (this, trans->xl_private);
- } else {
- gf_log (this->name, GF_LOG_DEBUG,
- "transport (%s) cleaned up even before "
- "handshake with (%s) is successful",
- myinfo->identifier, peerinfo->identifier);
- }
- }
- break;
-
- default:
- default_notify (this, event, data);
- break;
- }
-
- return ret;
-}
-
-
-struct xlator_mops mops = {
-};
-
-struct xlator_fops fops = {
-};
-
-struct xlator_cbks cbks = {
-};
-
-struct xlator_dumpops dumpops = {
- .inode = server_inode,
- .priv = server_priv,
- .fd = server_fd,
-};
-
-
-struct volume_options options[] = {
- { .key = {"transport-type"},
- .value = {"tcp", "socket", "ib-verbs", "unix", "ib-sdp",
- "tcp/server", "ib-verbs/server"},
- .type = GF_OPTION_TYPE_STR
- },
- { .key = {"volume-filename.*"},
- .type = GF_OPTION_TYPE_PATH,
- },
- { .key = {"inode-lru-limit"},
- .type = GF_OPTION_TYPE_INT,
- .min = 0,
- .max = (1 * GF_UNIT_MB)
- },
- { .key = {"client-volume-filename"},
- .type = GF_OPTION_TYPE_PATH
- },
- { .key = {"verify-volfile-checksum"},
- .type = GF_OPTION_TYPE_BOOL
- },
- { .key = {NULL} },
-};
diff --git a/xlators/protocol/server/src/server-protocol.h b/xlators/protocol/server/src/server-protocol.h
deleted file mode 100644
index 2f88b6346..000000000
--- a/xlators/protocol/server/src/server-protocol.h
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- Copyright (c) 2006-2009 Z RESEARCH, Inc. <http://www.zresearch.com>
- This file is part of GlusterFS.
-
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _SERVER_PROTOCOL_H_
-#define _SERVER_PROTOCOL_H_
-
-#ifndef _CONFIG_H
-#define _CONFIG_H
-#include "config.h"
-#endif
-
-#include <pthread.h>
-
-#include "glusterfs.h"
-#include "xlator.h"
-#include "logging.h"
-#include "call-stub.h"
-#include "authenticate.h"
-#include "fd.h"
-#include "byte-order.h"
-
-#define DEFAULT_BLOCK_SIZE 4194304 /* 4MB */
-#define DEFAULT_VOLUME_FILE_PATH CONFDIR "/glusterfs.vol"
-
-typedef struct _server_state server_state_t;
-
-struct _locker {
- struct list_head lockers;
- char *volume;
- loc_t loc;
- fd_t *fd;
- pid_t pid;
-};
-
-struct _lock_table {
- struct list_head file_lockers;
- struct list_head dir_lockers;
- gf_lock_t lock;
- size_t count;
-};
-
-
-/* private structure per connection (transport object)
- * used as transport_t->xl_private
- */
-struct _server_connection {
- struct list_head list;
- char *id;
- int ref;
- int active_transports;
- pthread_mutex_t lock;
- char disconnected;
- fdtable_t *fdtable;
- struct _lock_table *ltable;
- xlator_t *bound_xl;
-};
-
-typedef struct _server_connection server_connection_t;
-
-
-server_connection_t *
-server_connection_get (xlator_t *this, const char *id);
-
-void
-server_connection_put (xlator_t *this, server_connection_t *conn);
-
-int
-server_connection_destroy (xlator_t *this, server_connection_t *conn);
-
-int
-server_connection_cleanup (xlator_t *this, server_connection_t *conn);
-
-int
-server_nop_cbk (call_frame_t *frame, void *cookie,
- xlator_t *this, int32_t op_ret, int32_t op_errno);
-
-
-struct _volfile_ctx {
- struct _volfile_ctx *next;
- char *key;
- uint32_t checksum;
-};
-
-typedef struct {
- struct _volfile_ctx *volfile;
-
- dict_t *auth_modules;
- transport_t *trans;
- int32_t max_block_size;
- int32_t inode_lru_limit;
- pthread_mutex_t mutex;
- struct list_head conns;
- gf_boolean_t verify_volfile_checksum;
-} server_conf_t;
-
-
-struct _server_state {
- transport_t *trans;
- xlator_t *bound_xl;
- loc_t loc;
- loc_t loc2;
- int flags;
- fd_t *fd;
- size_t size;
- off_t offset;
- mode_t mode;
- dev_t dev;
- size_t nr_count;
- int cmd;
- int type;
- char *name;
- int name_len;
- inode_table_t *itable;
- int64_t fd_no;
- ino_t ino;
- ino_t par;
- ino_t ino2;
- ino_t par2;
- char *path;
- char *path2;
- char *bname;
- char *bname2;
- int mask;
- char is_revalidate;
- dict_t *xattr_req;
- struct flock flock;
- char *resolved;
- const char *volume;
-};
-
-
-int
-server_stub_resume (call_stub_t *stub, int32_t op_ret, int32_t op_errno,
- inode_t *inode, inode_t *parent);
-
-int
-do_path_lookup (call_stub_t *stub, const loc_t *loc);
-
-#endif
diff --git a/xlators/protocol/server/src/server-resolve.c b/xlators/protocol/server/src/server-resolve.c
new file mode 100644
index 000000000..cc4686a03
--- /dev/null
+++ b/xlators/protocol/server/src/server-resolve.c
@@ -0,0 +1,598 @@
+/*
+ Copyright (c) 2010-2013 Red Hat, Inc. <http://www.redhat.com>
+ This file is part of GlusterFS.
+
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
+*/
+
+#ifndef _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+#include "server.h"
+#include "server-helpers.h"
+
+
+int
+server_resolve_all (call_frame_t *frame);
+int
+resolve_entry_simple (call_frame_t *frame);
+int
+resolve_inode_simple (call_frame_t *frame);
+int
+resolve_continue (call_frame_t *frame);
+int
+resolve_anonfd_simple (call_frame_t *frame);
+
+int
+resolve_loc_touchup (call_frame_t *frame)
+{
+ server_state_t *state = NULL;
+ server_resolve_t *resolve = NULL;
+ loc_t *loc = NULL;
+ char *path = NULL;
+ int ret = 0;
+
+ state = CALL_STATE (frame);
+
+ resolve = state->resolve_now;
+ loc = state->loc_now;
+
+ if (!loc->path) {
+ if (loc->parent && resolve->bname) {
+ ret = inode_path (loc->parent, resolve->bname, &path);
+ } else if (loc->inode) {
+ ret = inode_path (loc->inode, NULL, &path);
+ }
+ if (ret)
+ gf_log (frame->this->name, GF_LOG_TRACE,
+ "return value inode_path %d", ret);
+ loc->path = path;
+ }
+
+ return 0;
+}
+
+
+int
+resolve_gfid_entry_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int op_ret, int op_errno, inode_t *inode,
+ struct iatt *buf, dict_t *xdata,
+ struct iatt *postparent)
+{
+ server_state_t *state = NULL;
+ server_resolve_t *resolve = NULL;
+ inode_t *link_inode = NULL;
+ loc_t *resolve_loc = NULL;
+
+ state = CALL_STATE (frame);
+ resolve = state->resolve_now;
+ resolve_loc = &resolve->resolve_loc;
+
+ if (op_ret == -1) {
+ gf_log (this->name, ((op_errno == ENOENT) ? GF_LOG_DEBUG :
+ GF_LOG_WARNING),
+ "%s/%s: failed to resolve (%s)",
+ uuid_utoa (resolve_loc->pargfid), resolve_loc->name,
+ strerror (op_errno));
+ goto out;
+ }
+
+ link_inode = inode_link (inode, resolve_loc->parent,
+ resolve_loc->name, buf);
+
+ if (!link_inode)
+ goto out;
+
+ inode_lookup (link_inode);
+
+ inode_unref (link_inode);
+
+out:
+ loc_wipe (resolve_loc);
+
+ resolve_continue (frame);
+ return 0;
+}
+
+
+int
+resolve_gfid_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int op_ret, int op_errno, inode_t *inode, struct iatt *buf,
+ dict_t *xdata, struct iatt *postparent)
+{
+ server_state_t *state = NULL;
+ server_resolve_t *resolve = NULL;
+ inode_t *link_inode = NULL;
+ loc_t *resolve_loc = NULL;
+
+ state = CALL_STATE (frame);
+ resolve = state->resolve_now;
+ resolve_loc = &resolve->resolve_loc;
+
+ if (op_ret == -1) {
+ gf_log (this->name, ((op_errno == ENOENT) ? GF_LOG_DEBUG :
+ GF_LOG_WARNING),
+ "%s: failed to resolve (%s)",
+ uuid_utoa (resolve_loc->gfid), strerror (op_errno));
+ loc_wipe (&resolve->resolve_loc);
+ goto out;
+ }
+
+ loc_wipe (resolve_loc);
+
+ link_inode = inode_link (inode, NULL, NULL, buf);
+
+ if (!link_inode)
+ goto out;
+
+ inode_lookup (link_inode);
+
+ if (uuid_is_null (resolve->pargfid)) {
+ inode_unref (link_inode);
+ goto out;
+ }
+
+ resolve_loc->parent = link_inode;
+ uuid_copy (resolve_loc->pargfid, resolve_loc->parent->gfid);
+
+ resolve_loc->name = resolve->bname;
+
+ resolve_loc->inode = inode_new (state->itable);
+ inode_path (resolve_loc->parent, resolve_loc->name,
+ (char **) &resolve_loc->path);
+
+ STACK_WIND (frame, resolve_gfid_entry_cbk,
+ frame->root->client->bound_xl,
+ frame->root->client->bound_xl->fops->lookup,
+ &resolve->resolve_loc, NULL);
+ return 0;
+out:
+ resolve_continue (frame);
+ return 0;
+}
+
+
+int
+resolve_gfid (call_frame_t *frame)
+{
+ server_state_t *state = NULL;
+ xlator_t *this = NULL;
+ server_resolve_t *resolve = NULL;
+ loc_t *resolve_loc = NULL;
+ int ret = 0;
+
+ state = CALL_STATE (frame);
+ this = frame->this;
+ resolve = state->resolve_now;
+ resolve_loc = &resolve->resolve_loc;
+
+ if (!uuid_is_null (resolve->pargfid))
+ uuid_copy (resolve_loc->gfid, resolve->pargfid);
+ else if (!uuid_is_null (resolve->gfid))
+ uuid_copy (resolve_loc->gfid, resolve->gfid);
+
+ resolve_loc->inode = inode_new (state->itable);
+ ret = loc_path (resolve_loc, NULL);
+
+ STACK_WIND (frame, resolve_gfid_cbk,
+ frame->root->client->bound_xl,
+ frame->root->client->bound_xl->fops->lookup,
+ &resolve->resolve_loc, NULL);
+ return 0;
+}
+
+int
+resolve_continue (call_frame_t *frame)
+{
+ server_state_t *state = NULL;
+ xlator_t *this = NULL;
+ server_resolve_t *resolve = NULL;
+ int ret = 0;
+
+ state = CALL_STATE (frame);
+ this = frame->this;
+ resolve = state->resolve_now;
+
+ resolve->op_ret = 0;
+ resolve->op_errno = 0;
+
+ if (resolve->fd_no != -1) {
+ ret = resolve_anonfd_simple (frame);
+ goto out;
+ } else if (!uuid_is_null (resolve->pargfid))
+ ret = resolve_entry_simple (frame);
+ else if (!uuid_is_null (resolve->gfid))
+ ret = resolve_inode_simple (frame);
+ if (ret)
+ gf_log (this->name, GF_LOG_DEBUG,
+ "return value of resolve_*_simple %d", ret);
+
+ resolve_loc_touchup (frame);
+out:
+ server_resolve_all (frame);
+
+ return 0;
+}
+
+
+/*
+ Check if the requirements are fulfilled by entries in the inode cache itself
+ Return value:
+ <= 0 - simple resolution was decisive and complete (either success or failure)
+ > 0 - indecisive, need to perform deep resolution
+*/
+
+int
+resolve_entry_simple (call_frame_t *frame)
+{
+ server_state_t *state = NULL;
+ xlator_t *this = NULL;
+ server_resolve_t *resolve = NULL;
+ inode_t *parent = NULL;
+ inode_t *inode = NULL;
+ int ret = 0;
+
+ state = CALL_STATE (frame);
+ this = frame->this;
+ resolve = state->resolve_now;
+
+ parent = inode_find (state->itable, resolve->pargfid);
+ if (!parent) {
+ /* simple resolution is indecisive. need to perform
+ deep resolution */
+ resolve->op_ret = -1;
+ resolve->op_errno = ENOENT;
+ ret = 1;
+ goto out;
+ }
+
+ /* expected @parent was found from the inode cache */
+ uuid_copy (state->loc_now->pargfid, resolve->pargfid);
+ state->loc_now->parent = inode_ref (parent);
+ state->loc_now->name = resolve->bname;
+
+ inode = inode_grep (state->itable, parent, resolve->bname);
+ if (!inode) {
+ switch (resolve->type) {
+ case RESOLVE_DONTCARE:
+ case RESOLVE_NOT:
+ ret = 0;
+ break;
+ case RESOLVE_MAY:
+ ret = 1;
+ break;
+ default:
+ resolve->op_ret = -1;
+ resolve->op_errno = ENOENT;
+ ret = 1;
+ break;
+ }
+
+ goto out;
+ }
+
+ if (resolve->type == RESOLVE_NOT) {
+ gf_log (this->name, GF_LOG_DEBUG, "inode (pointer: %p gfid:%s"
+ " found for path (%s) while type is RESOLVE_NOT",
+ inode, uuid_utoa (inode->gfid), resolve->path);
+ resolve->op_ret = -1;
+ resolve->op_errno = EEXIST;
+ ret = -1;
+ goto out;
+ }
+
+ ret = 0;
+
+ state->loc_now->inode = inode_ref (inode);
+
+out:
+ if (parent)
+ inode_unref (parent);
+
+ if (inode)
+ inode_unref (inode);
+
+ return ret;
+}
+
+
+int
+server_resolve_entry (call_frame_t *frame)
+{
+ server_state_t *state = NULL;
+ int ret = 0;
+ loc_t *loc = NULL;
+
+ state = CALL_STATE (frame);
+ loc = state->loc_now;
+
+ ret = resolve_entry_simple (frame);
+
+ if (ret > 0) {
+ loc_wipe (loc);
+ resolve_gfid (frame);
+ return 0;
+ }
+
+ if (ret == 0)
+ resolve_loc_touchup (frame);
+
+ server_resolve_all (frame);
+
+ return 0;
+}
+
+
+int
+resolve_inode_simple (call_frame_t *frame)
+{
+ server_state_t *state = NULL;
+ server_resolve_t *resolve = NULL;
+ inode_t *inode = NULL;
+ int ret = 0;
+
+ state = CALL_STATE (frame);
+ resolve = state->resolve_now;
+
+ inode = inode_find (state->itable, resolve->gfid);
+
+ if (!inode) {
+ resolve->op_ret = -1;
+ resolve->op_errno = ENOENT;
+ ret = 1;
+ goto out;
+ }
+
+ ret = 0;
+
+ state->loc_now->inode = inode_ref (inode);
+ uuid_copy (state->loc_now->gfid, resolve->gfid);
+
+out:
+ if (inode)
+ inode_unref (inode);
+
+ return ret;
+}
+
+
+int
+server_resolve_inode (call_frame_t *frame)
+{
+ server_state_t *state = NULL;
+ int ret = 0;
+ loc_t *loc = NULL;
+
+ state = CALL_STATE (frame);
+ loc = state->loc_now;
+
+ ret = resolve_inode_simple (frame);
+
+ if (ret > 0) {
+ loc_wipe (loc);
+ resolve_gfid (frame);
+ return 0;
+ }
+
+ if (ret == 0)
+ resolve_loc_touchup (frame);
+
+ server_resolve_all (frame);
+
+ return 0;
+}
+
+
+int
+resolve_anonfd_simple (call_frame_t *frame)
+{
+ server_state_t *state = NULL;
+ server_resolve_t *resolve = NULL;
+ inode_t *inode = NULL;
+ int ret = 0;
+
+ state = CALL_STATE (frame);
+ resolve = state->resolve_now;
+
+ inode = inode_find (state->itable, resolve->gfid);
+
+ if (!inode) {
+ resolve->op_ret = -1;
+ resolve->op_errno = ENOENT;
+ ret = 1;
+ goto out;
+ }
+
+ ret = 0;
+
+ state->fd = fd_anonymous (inode);
+out:
+ if (inode)
+ inode_unref (inode);
+
+ if (ret != 0)
+ gf_log ("server", GF_LOG_WARNING, "inode for the gfid (%s) is "
+ "not found. anonymous fd creation failed",
+ uuid_utoa (resolve->gfid));
+ return ret;
+}
+
+
+int
+server_resolve_anonfd (call_frame_t *frame)
+{
+ server_state_t *state = NULL;
+ int ret = 0;
+ loc_t *loc = NULL;
+
+ state = CALL_STATE (frame);
+ loc = state->loc_now;
+
+ ret = resolve_anonfd_simple (frame);
+
+ if (ret > 0) {
+ loc_wipe (loc);
+ resolve_gfid (frame);
+ return 0;
+ }
+
+ server_resolve_all (frame);
+
+ return 0;
+
+}
+
+
+int
+server_resolve_fd (call_frame_t *frame)
+{
+ server_ctx_t *serv_ctx = NULL;
+ server_state_t *state = NULL;
+ client_t *client = NULL;
+ server_resolve_t *resolve = NULL;
+ uint64_t fd_no = -1;
+
+ state = CALL_STATE (frame);
+ resolve = state->resolve_now;
+
+ fd_no = resolve->fd_no;
+
+ if (fd_no == GF_ANON_FD_NO) {
+ server_resolve_anonfd (frame);
+ return 0;
+ }
+
+ client = frame->root->client;
+
+ serv_ctx = server_ctx_get (client, client->this);
+
+ if (serv_ctx == NULL) {
+ gf_log ("", GF_LOG_INFO, "server_ctx_get() failed");
+ resolve->op_ret = -1;
+ resolve->op_errno = ENOMEM;
+ return 0;
+ }
+
+ state->fd = gf_fd_fdptr_get (serv_ctx->fdtable, fd_no);
+
+ if (!state->fd) {
+ gf_log ("", GF_LOG_INFO, "fd not found in context");
+ resolve->op_ret = -1;
+ resolve->op_errno = EBADF;
+ }
+
+ server_resolve_all (frame);
+
+ return 0;
+}
+
+
+int
+server_resolve (call_frame_t *frame)
+{
+ server_state_t *state = NULL;
+ server_resolve_t *resolve = NULL;
+
+ state = CALL_STATE (frame);
+ resolve = state->resolve_now;
+
+ if (resolve->fd_no != -1) {
+
+ server_resolve_fd (frame);
+
+ } else if (!uuid_is_null (resolve->pargfid)) {
+
+ server_resolve_entry (frame);
+
+ } else if (!uuid_is_null (resolve->gfid)) {
+
+ server_resolve_inode (frame);
+
+ } else {
+ if (resolve == &state->resolve)
+ gf_log (frame->this->name, GF_LOG_WARNING,
+ "no resolution type for %s (%s)",
+ resolve->path, gf_fop_list[frame->root->op]);
+
+ resolve->op_ret = -1;
+ resolve->op_errno = EINVAL;
+
+ server_resolve_all (frame);
+ }
+
+ return 0;
+}
+
+
+int
+server_resolve_done (call_frame_t *frame)
+{
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ server_print_request (frame);
+
+ state->resume_fn (frame, frame->root->client->bound_xl);
+
+ return 0;
+}
+
+
+/*
+ * This function is called multiple times, once per resolving one location/fd.
+ * state->resolve_now is used to decide which location/fd is to be resolved now
+ */
+int
+server_resolve_all (call_frame_t *frame)
+{
+ server_state_t *state = NULL;
+ xlator_t *this = NULL;
+
+ this = frame->this;
+ state = CALL_STATE (frame);
+
+ if (state->resolve_now == NULL) {
+
+ state->resolve_now = &state->resolve;
+ state->loc_now = &state->loc;
+
+ server_resolve (frame);
+
+ } else if (state->resolve_now == &state->resolve) {
+
+ state->resolve_now = &state->resolve2;
+ state->loc_now = &state->loc2;
+
+ server_resolve (frame);
+
+ } else if (state->resolve_now == &state->resolve2) {
+
+ server_resolve_done (frame);
+
+ } else {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Invalid pointer for state->resolve_now");
+ }
+
+ return 0;
+}
+
+
+int
+resolve_and_resume (call_frame_t *frame, server_resume_fn_t fn)
+{
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+ state->resume_fn = fn;
+
+ server_resolve_all (frame);
+
+ return 0;
+}
diff --git a/xlators/protocol/server/src/server-rpc-fops.c b/xlators/protocol/server/src/server-rpc-fops.c
new file mode 100644
index 000000000..138e601ce
--- /dev/null
+++ b/xlators/protocol/server/src/server-rpc-fops.c
@@ -0,0 +1,6179 @@
+/*
+ Copyright (c) 2010-2013 Red Hat, Inc. <http://www.redhat.com>
+ This file is part of GlusterFS.
+
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
+*/
+
+
+#ifndef _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+#include <openssl/md5.h>
+
+#include "server.h"
+#include "server-helpers.h"
+#include "glusterfs3-xdr.h"
+#include "glusterfs3.h"
+#include "compat-errno.h"
+
+#include "xdr-nfs3.h"
+
+#define SERVER_REQ_SET_ERROR(req, ret) \
+ do { \
+ rpcsvc_request_seterr (req, GARBAGE_ARGS); \
+ ret = RPCSVC_ACTOR_ERROR; \
+ } while (0)
+
+/* Callback function section */
+int
+server_statfs_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct statvfs *buf,
+ dict_t *xdata)
+{
+ gfs3_statfs_rsp rsp = {0,};
+ rpcsvc_request_t *req = NULL;
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
+ rsp.xdata.xdata_len, op_errno, out);
+
+ if (op_ret < 0) {
+ gf_log (this->name, GF_LOG_WARNING, "%"PRId64": STATFS (%s)",
+ frame->root->unique, strerror (op_errno));
+ goto out;
+ }
+
+ gf_statfs_from_statfs (&rsp.statfs, buf);
+
+out:
+ rsp.op_ret = op_ret;
+ rsp.op_errno = gf_errno_to_error (op_errno);
+
+ req = frame->local;
+ server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
+ (xdrproc_t)xdr_gfs3_statfs_rsp);
+
+ GF_FREE (rsp.xdata.xdata_val);
+
+ return 0;
+}
+
+int
+server_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno,
+ inode_t *inode, struct iatt *stbuf, dict_t *xdata,
+ struct iatt *postparent)
+{
+ rpcsvc_request_t *req = NULL;
+ server_state_t *state = NULL;
+ inode_t *root_inode = NULL;
+ inode_t *link_inode = NULL;
+ loc_t fresh_loc = {0,};
+ gfs3_lookup_rsp rsp = {0,};
+ uuid_t rootgfid = {0,};
+
+ state = CALL_STATE (frame);
+
+ if (state->is_revalidate == 1 && op_ret == -1) {
+ state->is_revalidate = 2;
+ loc_copy (&fresh_loc, &state->loc);
+ inode_unref (fresh_loc.inode);
+ fresh_loc.inode = inode_new (state->itable);
+
+ STACK_WIND (frame, server_lookup_cbk,
+ frame->root->client->bound_xl,
+ frame->root->client->bound_xl->fops->lookup,
+ &fresh_loc, state->xdata);
+
+ loc_wipe (&fresh_loc);
+ return 0;
+ }
+
+ gf_stat_from_iatt (&rsp.postparent, postparent);
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
+ rsp.xdata.xdata_len, op_errno, out);
+
+ if (op_ret) {
+ if (state->is_revalidate && op_errno == ENOENT) {
+ if (!__is_root_gfid (state->resolve.gfid)) {
+ inode_unlink (state->loc.inode,
+ state->loc.parent,
+ state->loc.name);
+ }
+ }
+ goto out;
+ }
+
+ root_inode = frame->root->client->bound_xl->itable->root;
+ if (inode == root_inode) {
+ /* we just looked up root ("/") */
+ stbuf->ia_ino = 1;
+ rootgfid[15] = 1;
+ uuid_copy (stbuf->ia_gfid, rootgfid);
+ if (inode->ia_type == 0)
+ inode->ia_type = stbuf->ia_type;
+ }
+
+ gf_stat_from_iatt (&rsp.stat, stbuf);
+
+ if (!__is_root_gfid (inode->gfid)) {
+ link_inode = inode_link (inode, state->loc.parent,
+ state->loc.name, stbuf);
+ if (link_inode) {
+ inode_lookup (link_inode);
+ inode_unref (link_inode);
+ }
+ }
+
+out:
+ rsp.op_ret = op_ret;
+ rsp.op_errno = gf_errno_to_error (op_errno);
+
+ if (op_ret) {
+ if (state->resolve.bname) {
+ gf_log (this->name, ((op_errno == ENOENT) ?
+ GF_LOG_TRACE : GF_LOG_INFO),
+ "%"PRId64": LOOKUP %s (%s/%s) ==> "
+ "(%s)", frame->root->unique,
+ state->loc.path,
+ uuid_utoa (state->resolve.pargfid),
+ state->resolve.bname,
+ strerror (op_errno));
+ } else {
+ gf_log (this->name, ((op_errno == ENOENT) ?
+ GF_LOG_TRACE : GF_LOG_INFO),
+ "%"PRId64": LOOKUP %s (%s) ==> (%s)",
+ frame->root->unique, state->loc.path,
+ uuid_utoa (state->resolve.gfid),
+ strerror (op_errno));
+ }
+ }
+
+ req = frame->local;
+ server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
+ (xdrproc_t)xdr_gfs3_lookup_rsp);
+
+ GF_FREE (rsp.xdata.xdata_val);
+
+ return 0;
+}
+
+
+int
+server_lk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct gf_flock *lock,
+ dict_t *xdata)
+{
+ gfs3_lk_rsp rsp = {0,};
+ rpcsvc_request_t *req = NULL;
+ server_state_t *state = NULL;
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
+ rsp.xdata.xdata_len, op_errno, out);
+
+ if (op_ret) {
+ if ((op_errno != ENOSYS) && (op_errno != EAGAIN)) {
+ state = CALL_STATE (frame);
+ gf_log (this->name, GF_LOG_INFO,
+ "%"PRId64": LK %"PRId64" (%s) ==> "
+ "(%s)", frame->root->unique,
+ state->resolve.fd_no,
+ uuid_utoa (state->resolve.gfid),
+ strerror (op_errno));
+ }
+ goto out;
+ }
+
+ switch (lock->l_type) {
+ case F_RDLCK:
+ lock->l_type = GF_LK_F_RDLCK;
+ break;
+ case F_WRLCK:
+ lock->l_type = GF_LK_F_WRLCK;
+ break;
+ case F_UNLCK:
+ lock->l_type = GF_LK_F_UNLCK;
+ break;
+ default:
+ gf_log (this->name, GF_LOG_ERROR,
+ "Unknown lock type: %"PRId32"!", lock->l_type);
+ break;
+ }
+
+ gf_proto_flock_from_flock (&rsp.flock, lock);
+
+out:
+ rsp.op_ret = op_ret;
+ rsp.op_errno = gf_errno_to_error (op_errno);
+
+ req = frame->local;
+ server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
+ (xdrproc_t)xdr_gfs3_lk_rsp);
+
+ GF_FREE (rsp.xdata.xdata_val);
+
+ return 0;
+}
+
+
+int
+server_inodelk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata)
+{
+ gf_common_rsp rsp = {0,};
+ server_state_t *state = NULL;
+ rpcsvc_request_t *req = NULL;
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
+ rsp.xdata.xdata_len, op_errno, out);
+
+ state = CALL_STATE (frame);
+
+ if (op_ret < 0) {
+ if ((op_errno != ENOSYS) && (op_errno != EAGAIN)) {
+ gf_log (this->name, (op_errno == ENOENT)?
+ GF_LOG_DEBUG:GF_LOG_ERROR,
+ "%"PRId64": INODELK %s (%s) ==> (%s)",
+ frame->root->unique, state->loc.path,
+ uuid_utoa (state->resolve.gfid),
+ strerror (op_errno));
+ }
+ goto out;
+ }
+
+out:
+ rsp.op_ret = op_ret;
+ rsp.op_errno = gf_errno_to_error (op_errno);
+
+ req = frame->local;
+ server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
+ (xdrproc_t)xdr_gf_common_rsp);
+
+ GF_FREE (rsp.xdata.xdata_val);
+
+ return 0;
+}
+
+
+int
+server_finodelk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata)
+{
+ gf_common_rsp rsp = {0,};
+ server_state_t *state = NULL;
+ rpcsvc_request_t *req = NULL;
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
+ rsp.xdata.xdata_len, op_errno, out);
+
+ state = CALL_STATE (frame);
+
+ if (op_ret < 0) {
+ if ((op_errno != ENOSYS) && (op_errno != EAGAIN)) {
+ gf_log (this->name, GF_LOG_INFO,
+ "%"PRId64": FINODELK %"PRId64" (%s) "
+ "==> (%s)", frame->root->unique,
+ state->resolve.fd_no,
+ uuid_utoa (state->resolve.gfid),
+ strerror (op_errno));
+ }
+ goto out;
+ }
+
+out:
+ rsp.op_ret = op_ret;
+ rsp.op_errno = gf_errno_to_error (op_errno);
+
+ req = frame->local;
+ server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
+ (xdrproc_t)xdr_gf_common_rsp);
+
+ GF_FREE (rsp.xdata.xdata_val);
+
+ return 0;
+}
+
+int
+server_entrylk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata)
+{
+ gf_common_rsp rsp = {0,};
+ server_state_t *state = NULL;
+ rpcsvc_request_t *req = NULL;
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
+ rsp.xdata.xdata_len, op_errno, out);
+
+ state = CALL_STATE (frame);
+
+ if (op_ret < 0) {
+ if ((op_errno != ENOSYS) && (op_errno != EAGAIN)) {
+ gf_log (this->name, GF_LOG_INFO,
+ "%"PRId64": ENTRYLK %s (%s) ==> (%s)",
+ frame->root->unique, state->loc.path,
+ uuid_utoa (state->resolve.gfid),
+ strerror (op_errno));
+ }
+ goto out;
+ }
+
+out:
+ rsp.op_ret = op_ret;
+ rsp.op_errno = gf_errno_to_error (op_errno);
+
+ req = frame->local;
+ server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
+ (xdrproc_t)xdr_gf_common_rsp);
+
+ GF_FREE (rsp.xdata.xdata_val);
+
+ return 0;
+}
+
+
+int
+server_fentrylk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata)
+{
+ gf_common_rsp rsp = {0,};
+ server_state_t *state = NULL;
+ rpcsvc_request_t *req = NULL;
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
+ rsp.xdata.xdata_len, op_errno, out);
+
+ state = CALL_STATE (frame);
+
+ if (op_ret < 0) {
+ if ((op_errno != ENOSYS) && (op_errno != EAGAIN)) {
+ gf_log (this->name, GF_LOG_INFO,
+ "%"PRId64": FENTRYLK %"PRId64" (%s) ==>(%s)",
+ frame->root->unique, state->resolve.fd_no,
+ uuid_utoa (state->resolve.gfid),
+ strerror (op_errno));
+ }
+ goto out;
+ }
+
+out:
+ rsp.op_ret = op_ret;
+ rsp.op_errno = gf_errno_to_error (op_errno);
+
+ req = frame->local;
+ server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
+ (xdrproc_t)xdr_gf_common_rsp);
+
+ GF_FREE (rsp.xdata.xdata_val);
+
+ return 0;
+}
+
+
+int
+server_access_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata)
+{
+ gf_common_rsp rsp = {0,};
+ rpcsvc_request_t *req = NULL;
+ server_state_t *state = NULL;
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
+ rsp.xdata.xdata_len, op_errno, out);
+
+ if (op_ret) {
+ state = CALL_STATE (frame);
+ gf_log (this->name, GF_LOG_INFO,
+ "%"PRId64": ACCESS %s (%s) ==> (%s)",
+ frame->root->unique, state->loc.path,
+ uuid_utoa (state->resolve.gfid),
+ strerror (op_errno));
+ goto out;
+ }
+
+out:
+ rsp.op_ret = op_ret;
+ rsp.op_errno = gf_errno_to_error (op_errno);
+
+ req = frame->local;
+ server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
+ (xdrproc_t)xdr_gf_common_rsp);
+
+ GF_FREE (rsp.xdata.xdata_val);
+
+ return 0;
+}
+
+int
+server_rmdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct iatt *preparent,
+ struct iatt *postparent, dict_t *xdata)
+{
+ gfs3_rmdir_rsp rsp = {0,};
+ server_state_t *state = NULL;
+ inode_t *parent = NULL;
+ rpcsvc_request_t *req = NULL;
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
+ rsp.xdata.xdata_len, op_errno, out);
+
+ state = CALL_STATE (frame);
+
+ if (op_ret) {
+ gf_log (this->name, GF_LOG_INFO,
+ "%"PRId64": RMDIR %s (%s/%s) ==> (%s)",
+ frame->root->unique, state->loc.path,
+ uuid_utoa (state->resolve.pargfid),
+ state->resolve.bname, strerror (op_errno));
+ goto out;
+ }
+
+ inode_unlink (state->loc.inode, state->loc.parent,
+ state->loc.name);
+ parent = inode_parent (state->loc.inode, 0, NULL);
+ if (parent)
+ /* parent should not be found for directories after
+ * inode_unlink, since directories cannot have
+ * hardlinks.
+ */
+ inode_unref (parent);
+ else
+ inode_forget (state->loc.inode, 0);
+
+ gf_stat_from_iatt (&rsp.preparent, preparent);
+ gf_stat_from_iatt (&rsp.postparent, postparent);
+
+out:
+ rsp.op_ret = op_ret;
+ rsp.op_errno = gf_errno_to_error (op_errno);
+
+ req = frame->local;
+ server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
+ (xdrproc_t)xdr_gfs3_rmdir_rsp);
+
+ GF_FREE (rsp.xdata.xdata_val);
+
+ return 0;
+}
+
+int
+server_mkdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, inode_t *inode,
+ struct iatt *stbuf, struct iatt *preparent,
+ struct iatt *postparent, dict_t *xdata)
+{
+ gfs3_mkdir_rsp rsp = {0,};
+ server_state_t *state = NULL;
+ inode_t *link_inode = NULL;
+ rpcsvc_request_t *req = NULL;
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
+ rsp.xdata.xdata_len, op_errno, out);
+
+ state = CALL_STATE (frame);
+
+ if (op_ret < 0) {
+ gf_log (this->name, GF_LOG_INFO,
+ "%"PRId64": MKDIR %s (%s/%s) ==> (%s)",
+ frame->root->unique, state->loc.path,
+ uuid_utoa (state->resolve.pargfid),
+ state->resolve.bname, strerror (op_errno));
+ goto out;
+ }
+
+ gf_stat_from_iatt (&rsp.stat, stbuf);
+ gf_stat_from_iatt (&rsp.preparent, preparent);
+ gf_stat_from_iatt (&rsp.postparent, postparent);
+
+ link_inode = inode_link (inode, state->loc.parent,
+ state->loc.name, stbuf);
+ inode_lookup (link_inode);
+ inode_unref (link_inode);
+
+out:
+ rsp.op_ret = op_ret;
+ rsp.op_errno = gf_errno_to_error (op_errno);
+
+ req = frame->local;
+ server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
+ (xdrproc_t)xdr_gfs3_mkdir_rsp);
+
+ GF_FREE (rsp.xdata.xdata_val);
+
+ return 0;
+}
+
+int
+server_mknod_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno,
+ inode_t *inode, struct iatt *stbuf, struct iatt *preparent,
+ struct iatt *postparent, dict_t *xdata)
+{
+ gfs3_mknod_rsp rsp = {0,};
+ server_state_t *state = NULL;
+ inode_t *link_inode = NULL;
+ rpcsvc_request_t *req = NULL;
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
+ rsp.xdata.xdata_len, op_errno, out);
+
+ state = CALL_STATE (frame);
+
+ if (op_ret < 0) {
+ gf_log (this->name, GF_LOG_INFO,
+ "%"PRId64": MKNOD %s (%s/%s) ==> (%s)",
+ frame->root->unique, state->loc.path,
+ uuid_utoa (state->resolve.pargfid),
+ state->resolve.bname, strerror (op_errno));
+ goto out;
+ }
+
+ gf_stat_from_iatt (&rsp.stat, stbuf);
+ gf_stat_from_iatt (&rsp.preparent, preparent);
+ gf_stat_from_iatt (&rsp.postparent, postparent);
+
+ link_inode = inode_link (inode, state->loc.parent,
+ state->loc.name, stbuf);
+ inode_lookup (link_inode);
+ inode_unref (link_inode);
+
+out:
+ rsp.op_ret = op_ret;
+ rsp.op_errno = gf_errno_to_error (op_errno);
+
+ req = frame->local;
+ server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
+ (xdrproc_t)xdr_gfs3_mknod_rsp);
+
+ GF_FREE (rsp.xdata.xdata_val);
+
+ return 0;
+}
+
+int
+server_fsyncdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata)
+{
+ gf_common_rsp rsp = {0,};
+ server_state_t *state = NULL;
+ rpcsvc_request_t *req = NULL;
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
+ rsp.xdata.xdata_len, op_errno, out);
+
+ if (op_ret < 0) {
+ state = CALL_STATE (frame);
+ gf_log (this->name, GF_LOG_INFO,
+ "%"PRId64": FSYNCDIR %"PRId64" (%s) ==> (%s)",
+ frame->root->unique, state->resolve.fd_no,
+ uuid_utoa (state->resolve.gfid),
+ strerror (op_errno));
+ goto out;
+ }
+
+out:
+ rsp.op_ret = op_ret;
+ rsp.op_errno = gf_errno_to_error (op_errno);
+
+ req = frame->local;
+ server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
+ (xdrproc_t)xdr_gf_common_rsp);
+
+ GF_FREE (rsp.xdata.xdata_val);
+
+ return 0;
+}
+
+int
+server_readdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, gf_dirent_t *entries,
+ dict_t *xdata)
+{
+ gfs3_readdir_rsp rsp = {0,};
+ server_state_t *state = NULL;
+ rpcsvc_request_t *req = NULL;
+ int ret = 0;
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
+ rsp.xdata.xdata_len, op_errno, out);
+
+ if (op_ret < 0) {
+ state = CALL_STATE (frame);
+ gf_log (this->name, GF_LOG_INFO,
+ "%"PRId64": READDIR %"PRId64" (%s) ==> (%s)",
+ frame->root->unique, state->resolve.fd_no,
+ uuid_utoa (state->resolve.gfid),
+ strerror (op_errno));
+ goto out;
+ }
+
+ /* (op_ret == 0) is valid, and means EOF */
+ if (op_ret) {
+ ret = serialize_rsp_dirent (entries, &rsp);
+ if (ret == -1) {
+ op_ret = -1;
+ op_errno = ENOMEM;
+ goto out;
+ }
+ }
+
+out:
+ rsp.op_ret = op_ret;
+ rsp.op_errno = gf_errno_to_error (op_errno);
+
+ req = frame->local;
+ server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
+ (xdrproc_t)xdr_gfs3_readdir_rsp);
+
+ GF_FREE (rsp.xdata.xdata_val);
+
+ readdir_rsp_cleanup (&rsp);
+
+ return 0;
+}
+
+int
+server_opendir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, fd_t *fd, dict_t *xdata)
+{
+ server_state_t *state = NULL;
+ server_ctx_t *serv_ctx = NULL;
+ rpcsvc_request_t *req = NULL;
+ gfs3_opendir_rsp rsp = {0,};
+ uint64_t fd_no = 0;
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
+ rsp.xdata.xdata_len, op_errno, out);
+
+ if (op_ret < 0) {
+ state = CALL_STATE (frame);
+ gf_log (this->name, (op_errno == ENOENT)?
+ GF_LOG_DEBUG:GF_LOG_ERROR,
+ "%"PRId64": OPENDIR %s (%s) ==> (%s)",
+ frame->root->unique, state->loc.path,
+ uuid_utoa (state->resolve.gfid), strerror (op_errno));
+ goto out;
+ }
+
+ serv_ctx = server_ctx_get (frame->root->client, this);
+ if (serv_ctx == NULL) {
+ gf_log (this->name, GF_LOG_INFO, "server_ctx_get() failed");
+ goto out;
+ }
+
+ fd_bind (fd);
+ fd_no = gf_fd_unused_get (serv_ctx->fdtable, fd);
+ fd_ref (fd); // on behalf of the client
+
+out:
+ rsp.fd = fd_no;
+ rsp.op_ret = op_ret;
+ rsp.op_errno = gf_errno_to_error (op_errno);
+
+ req = frame->local;
+ server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
+ (xdrproc_t)xdr_gfs3_opendir_rsp);
+
+ GF_FREE (rsp.xdata.xdata_val);
+
+ return 0;
+}
+
+int
+server_removexattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata)
+{
+ gf_common_rsp rsp = {0,};
+ rpcsvc_request_t *req = NULL;
+ server_state_t *state = NULL;
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
+ rsp.xdata.xdata_len, op_errno, out);
+
+ if (op_ret == -1) {
+ state = CALL_STATE (frame);
+ gf_log (this->name, GF_LOG_INFO,
+ "%"PRId64": REMOVEXATTR %s (%s) of key %s ==> (%s)",
+ frame->root->unique, state->loc.path,
+ uuid_utoa (state->resolve.gfid),
+ state->name, strerror (op_errno));
+ goto out;
+ }
+
+out:
+ rsp.op_ret = op_ret;
+ rsp.op_errno = gf_errno_to_error (op_errno);
+
+ req = frame->local;
+ server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
+ (xdrproc_t)xdr_gf_common_rsp);
+
+ GF_FREE (rsp.xdata.xdata_val);
+
+ return 0;
+}
+
+int
+server_fremovexattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata)
+{
+ gf_common_rsp rsp = {0,};
+ rpcsvc_request_t *req = NULL;
+ server_state_t *state = NULL;
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
+ rsp.xdata.xdata_len, op_errno, out);
+
+ if (op_ret == -1) {
+ state = CALL_STATE (frame);
+ gf_log (this->name, GF_LOG_INFO,
+ "%"PRId64": FREMOVEXATTR %"PRId64" (%s) (%s) ==> (%s)",
+ frame->root->unique, state->resolve.fd_no,
+ uuid_utoa (state->resolve.gfid), state->name,
+ strerror (op_errno));
+ goto out;
+ }
+
+out:
+ rsp.op_ret = op_ret;
+ rsp.op_errno = gf_errno_to_error (op_errno);
+
+ req = frame->local;
+ server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
+ (xdrproc_t)xdr_gf_common_rsp);
+
+ GF_FREE (rsp.xdata.xdata_val);
+
+ return 0;
+}
+
+int
+server_getxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *dict,
+ dict_t *xdata)
+{
+ gfs3_getxattr_rsp rsp = {0,};
+ rpcsvc_request_t *req = NULL;
+ server_state_t *state = NULL;
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
+ rsp.xdata.xdata_len, op_errno, out);
+
+ if (op_ret == -1) {
+ state = CALL_STATE (frame);
+ gf_log (this->name, (((op_errno == ENOTSUP) ||
+ (op_errno == ENODATA) ||
+ (op_errno == ENOENT)) ?
+ GF_LOG_DEBUG : GF_LOG_INFO),
+ "%"PRId64": GETXATTR %s (%s) (%s) ==> (%s)",
+ frame->root->unique, state->loc.path,
+ uuid_utoa (state->resolve.gfid),
+ state->name, strerror (op_errno));
+ goto out;
+ }
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, dict, &rsp.dict.dict_val,
+ rsp.dict.dict_len, op_errno, out);
+
+out:
+ rsp.op_ret = op_ret;
+ rsp.op_errno = gf_errno_to_error (op_errno);
+
+ req = frame->local;
+ server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
+ (xdrproc_t)xdr_gfs3_getxattr_rsp);
+
+ GF_FREE (rsp.dict.dict_val);
+
+ GF_FREE (rsp.xdata.xdata_val);
+
+ return 0;
+}
+
+
+int
+server_fgetxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *dict,
+ dict_t *xdata)
+{
+ gfs3_fgetxattr_rsp rsp = {0,};
+ server_state_t *state = NULL;
+ rpcsvc_request_t *req = NULL;
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
+ rsp.xdata.xdata_len, op_errno, out);
+
+ if (op_ret == -1) {
+ state = CALL_STATE (frame);
+ gf_log (this->name, ((op_errno == ENOTSUP) ?
+ GF_LOG_DEBUG : GF_LOG_INFO),
+ "%"PRId64": FGETXATTR %"PRId64" (%s) (%s) ==> (%s)",
+ frame->root->unique, state->resolve.fd_no,
+ uuid_utoa (state->resolve.gfid),
+ state->name, strerror (op_errno));
+ goto out;
+ }
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, dict, &rsp.dict.dict_val,
+ rsp.dict.dict_len, op_errno, out);
+
+out:
+
+ rsp.op_ret = op_ret;
+ rsp.op_errno = gf_errno_to_error (op_errno);
+
+ req = frame->local;
+ server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
+ (xdrproc_t)xdr_gfs3_fgetxattr_rsp);
+
+ GF_FREE (rsp.dict.dict_val);
+
+ GF_FREE (rsp.xdata.xdata_val);
+
+ return 0;
+}
+
+/* print every key */
+static int
+_gf_server_log_setxattr_failure (dict_t *d, char *k, data_t *v,
+ void *tmp)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+
+ frame = tmp;
+ state = CALL_STATE (frame);
+
+ gf_log (THIS->name, GF_LOG_INFO,
+ "%"PRId64": SETXATTR %s (%s) ==> %s",
+ frame->root->unique, state->loc.path,
+ uuid_utoa (state->resolve.gfid), k);
+ return 0;
+}
+
+int
+server_setxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata)
+{
+ gf_common_rsp rsp = {0,};
+ rpcsvc_request_t *req = NULL;
+ server_state_t *state = NULL;
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
+ rsp.xdata.xdata_len, op_errno, out);
+
+ if (op_ret == -1) {
+ state = CALL_STATE (frame);
+ if (op_errno != ENOTSUP)
+ dict_foreach (state->dict,
+ _gf_server_log_setxattr_failure,
+ frame);
+
+ gf_log (THIS->name, ((op_errno == ENOTSUP) ?
+ GF_LOG_DEBUG : GF_LOG_INFO),
+ "%s", strerror (op_errno));
+ goto out;
+ }
+
+out:
+ rsp.op_ret = op_ret;
+ rsp.op_errno = gf_errno_to_error (op_errno);
+
+ req = frame->local;
+ server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
+ (xdrproc_t)xdr_gf_common_rsp);
+
+ GF_FREE (rsp.xdata.xdata_val);
+
+ return 0;
+}
+
+/* print every key here */
+static int
+_gf_server_log_fsetxattr_failure (dict_t *d, char *k, data_t *v,
+ void *tmp)
+{
+ call_frame_t *frame = NULL;
+ server_state_t *state = NULL;
+
+ frame = tmp;
+ state = CALL_STATE (frame);
+
+ gf_log (THIS->name, GF_LOG_INFO,
+ "%"PRId64": FSETXATTR %"PRId64" (%s) ==> %s",
+ frame->root->unique, state->resolve.fd_no,
+ uuid_utoa (state->resolve.gfid), k);
+
+ return 0;
+}
+
+int
+server_fsetxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata)
+{
+ gf_common_rsp rsp = {0,};
+ rpcsvc_request_t *req = NULL;
+ server_state_t *state = NULL;
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
+ rsp.xdata.xdata_len, op_errno, out);
+
+ if (op_ret == -1) {
+ state = CALL_STATE (frame);
+ if (op_errno != ENOTSUP) {
+ dict_foreach (state->dict,
+ _gf_server_log_fsetxattr_failure,
+ frame);
+ }
+ gf_log (THIS->name, ((op_errno == ENOTSUP) ?
+ GF_LOG_DEBUG : GF_LOG_INFO),
+ "%s", strerror (op_errno));
+ goto out;
+ }
+
+out:
+ rsp.op_ret = op_ret;
+ rsp.op_errno = gf_errno_to_error (op_errno);
+
+ req = frame->local;
+ server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
+ (xdrproc_t)xdr_gf_common_rsp);
+
+ GF_FREE (rsp.xdata.xdata_val);
+
+ return 0;
+}
+
+int
+server_rename_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct iatt *stbuf,
+ struct iatt *preoldparent, struct iatt *postoldparent,
+ struct iatt *prenewparent, struct iatt *postnewparent,
+ dict_t *xdata)
+{
+ gfs3_rename_rsp rsp = {0,};
+ server_state_t *state = NULL;
+ rpcsvc_request_t *req = NULL;
+ inode_t *tmp_inode = NULL;
+ inode_t *tmp_parent = NULL;
+ char oldpar_str[50] = {0,};
+ char newpar_str[50] = {0,};
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
+ rsp.xdata.xdata_len, op_errno, out);
+
+ state = CALL_STATE (frame);
+
+ if (op_ret == -1) {
+ uuid_utoa_r (state->resolve.gfid, oldpar_str);
+ uuid_utoa_r (state->resolve2.gfid, newpar_str);
+ gf_log (this->name, GF_LOG_INFO,
+ "%"PRId64": RENAME %s (%s/%s) -> %s (%s/%s) ==> (%s)",
+ frame->root->unique, state->loc.path,
+ oldpar_str, state->resolve.bname, state->loc2.path,
+ newpar_str, state->resolve2.bname, strerror (op_errno));
+ goto out;
+ }
+
+ stbuf->ia_type = state->loc.inode->ia_type;
+
+ /* TODO: log gfid of the inodes */
+ gf_log (frame->root->client->bound_xl->name, GF_LOG_TRACE,
+ "%"PRId64": RENAME_CBK %s ==> %s",
+ frame->root->unique, state->loc.name, state->loc2.name);
+
+ /* Before renaming the inode, we have to get the inode for the
+ * destination entry (i.e. inode with state->loc2.parent as
+ * parent and state->loc2.name as name). If it exists, then
+ * unlink that inode, and send forget on that inode if the
+ * unlinked entry is the last entry. In case of fuse client
+ * the fuse kernel module itself sends the forget on the
+ * unlinked inode.
+ */
+ tmp_inode = inode_grep (state->loc.inode->table,
+ state->loc2.parent, state->loc2.name);
+ if (tmp_inode) {
+ inode_unlink (tmp_inode, state->loc2.parent,
+ state->loc2.name);
+ tmp_parent = inode_parent (tmp_inode, 0, NULL);
+ if (tmp_parent)
+ inode_unref (tmp_parent);
+ else
+ inode_forget (tmp_inode, 0);
+
+ inode_unref (tmp_inode);
+ }
+
+ inode_rename (state->itable,
+ state->loc.parent, state->loc.name,
+ state->loc2.parent, state->loc2.name,
+ state->loc.inode, stbuf);
+ gf_stat_from_iatt (&rsp.stat, stbuf);
+
+ gf_stat_from_iatt (&rsp.preoldparent, preoldparent);
+ gf_stat_from_iatt (&rsp.postoldparent, postoldparent);
+
+ gf_stat_from_iatt (&rsp.prenewparent, prenewparent);
+ gf_stat_from_iatt (&rsp.postnewparent, postnewparent);
+
+out:
+ rsp.op_ret = op_ret;
+ rsp.op_errno = gf_errno_to_error (op_errno);
+
+ req = frame->local;
+ server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
+ (xdrproc_t)xdr_gfs3_rename_rsp);
+
+ GF_FREE (rsp.xdata.xdata_val);
+
+ return 0;
+}
+
+int
+server_unlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct iatt *preparent,
+ struct iatt *postparent, dict_t *xdata)
+{
+ gfs3_unlink_rsp rsp = {0,};
+ server_state_t *state = NULL;
+ inode_t *parent = NULL;
+ rpcsvc_request_t *req = NULL;
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
+ rsp.xdata.xdata_len, op_errno, out);
+
+ state = CALL_STATE (frame);
+
+ if (op_ret) {
+ gf_log (this->name, (op_errno == ENOENT)?
+ GF_LOG_DEBUG:GF_LOG_ERROR,
+ "%"PRId64": UNLINK %s (%s/%s) ==> (%s)",
+ frame->root->unique, state->loc.path,
+ uuid_utoa (state->resolve.pargfid),
+ state->resolve.bname, strerror (op_errno));
+ goto out;
+ }
+
+ /* TODO: log gfid of the inodes */
+ gf_log (frame->root->client->bound_xl->name, GF_LOG_TRACE,
+ "%"PRId64": UNLINK_CBK %s",
+ frame->root->unique, state->loc.name);
+
+ inode_unlink (state->loc.inode, state->loc.parent,
+ state->loc.name);
+
+ parent = inode_parent (state->loc.inode, 0, NULL);
+ if (parent)
+ inode_unref (parent);
+ else
+ inode_forget (state->loc.inode, 0);
+
+ gf_stat_from_iatt (&rsp.preparent, preparent);
+ gf_stat_from_iatt (&rsp.postparent, postparent);
+
+out:
+ rsp.op_ret = op_ret;
+ rsp.op_errno = gf_errno_to_error (op_errno);
+
+ req = frame->local;
+ server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
+ (xdrproc_t)xdr_gfs3_unlink_rsp);
+
+ GF_FREE (rsp.xdata.xdata_val);
+
+ return 0;
+}
+
+int
+server_symlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, inode_t *inode,
+ struct iatt *stbuf, struct iatt *preparent,
+ struct iatt *postparent, dict_t *xdata)
+{
+ gfs3_symlink_rsp rsp = {0,};
+ server_state_t *state = NULL;
+ inode_t *link_inode = NULL;
+ rpcsvc_request_t *req = NULL;
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
+ rsp.xdata.xdata_len, op_errno, out);
+
+ state = CALL_STATE (frame);
+
+ if (op_ret < 0) {
+ gf_log (this->name, GF_LOG_INFO,
+ "%"PRId64": SYMLINK %s (%s/%s) ==> (%s)",
+ frame->root->unique, state->loc.path,
+ uuid_utoa (state->resolve.pargfid),
+ state->resolve.bname, strerror (op_errno));
+ goto out;
+ }
+
+ gf_stat_from_iatt (&rsp.stat, stbuf);
+ gf_stat_from_iatt (&rsp.preparent, preparent);
+ gf_stat_from_iatt (&rsp.postparent, postparent);
+
+ link_inode = inode_link (inode, state->loc.parent,
+ state->loc.name, stbuf);
+ inode_lookup (link_inode);
+ inode_unref (link_inode);
+
+out:
+ rsp.op_ret = op_ret;
+ rsp.op_errno = gf_errno_to_error (op_errno);
+
+ req = frame->local;
+ server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
+ (xdrproc_t)xdr_gfs3_symlink_rsp);
+
+ GF_FREE (rsp.xdata.xdata_val);
+
+ return 0;
+}
+
+
+int
+server_link_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, inode_t *inode,
+ struct iatt *stbuf, struct iatt *preparent,
+ struct iatt *postparent, dict_t *xdata)
+{
+ gfs3_link_rsp rsp = {0,};
+ server_state_t *state = NULL;
+ inode_t *link_inode = NULL;
+ rpcsvc_request_t *req = NULL;
+ char gfid_str[50] = {0,};
+ char newpar_str[50] = {0,};
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
+ rsp.xdata.xdata_len, op_errno, out);
+
+ state = CALL_STATE (frame);
+
+ if (op_ret) {
+ uuid_utoa_r (state->resolve.gfid, gfid_str);
+ uuid_utoa_r (state->resolve2.pargfid, newpar_str);
+
+ gf_log (this->name, GF_LOG_INFO,
+ "%"PRId64": LINK %s (%s) -> %s/%s ==> (%s)",
+ frame->root->unique, state->loc.path,
+ gfid_str, newpar_str, state->resolve2.bname,
+ strerror (op_errno));
+ goto out;
+ }
+
+ gf_stat_from_iatt (&rsp.stat, stbuf);
+ gf_stat_from_iatt (&rsp.preparent, preparent);
+ gf_stat_from_iatt (&rsp.postparent, postparent);
+
+ link_inode = inode_link (inode, state->loc2.parent,
+ state->loc2.name, stbuf);
+ inode_unref (link_inode);
+
+out:
+ rsp.op_ret = op_ret;
+ rsp.op_errno = gf_errno_to_error (op_errno);
+
+ req = frame->local;
+ server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
+ (xdrproc_t)xdr_gfs3_link_rsp);
+
+ GF_FREE (rsp.xdata.xdata_val);
+
+ return 0;
+}
+
+int
+server_truncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
+ struct iatt *postbuf, dict_t *xdata)
+{
+ gfs3_truncate_rsp rsp = {0,};
+ server_state_t *state = NULL;
+ rpcsvc_request_t *req = NULL;
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
+ rsp.xdata.xdata_len, op_errno, out);
+
+ if (op_ret) {
+ state = CALL_STATE (frame);
+ gf_log (this->name, GF_LOG_INFO,
+ "%"PRId64": TRUNCATE %s (%s) ==> (%s)",
+ frame->root->unique, state->loc.path,
+ uuid_utoa (state->resolve.gfid), strerror (op_errno));
+ goto out;
+ }
+
+ gf_stat_from_iatt (&rsp.prestat, prebuf);
+ gf_stat_from_iatt (&rsp.poststat, postbuf);
+
+out:
+ rsp.op_ret = op_ret;
+ rsp.op_errno = gf_errno_to_error (op_errno);
+
+ req = frame->local;
+ server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
+ (xdrproc_t)xdr_gfs3_truncate_rsp);
+
+ GF_FREE (rsp.xdata.xdata_val);
+
+ return 0;
+}
+
+int
+server_fstat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct iatt *stbuf,
+ dict_t *xdata)
+{
+ gfs3_fstat_rsp rsp = {0,};
+ server_state_t *state = NULL;
+ rpcsvc_request_t *req = NULL;
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
+ rsp.xdata.xdata_len, op_errno, out);
+
+ if (op_ret) {
+ state = CALL_STATE (frame);
+ gf_log (this->name, GF_LOG_INFO,
+ "%"PRId64": FSTAT %"PRId64" (%s) ==> (%s)",
+ frame->root->unique, state->resolve.fd_no,
+ uuid_utoa (state->resolve.gfid), strerror (op_errno));
+ goto out;
+ }
+
+ gf_stat_from_iatt (&rsp.stat, stbuf);
+
+out:
+ rsp.op_ret = op_ret;
+ rsp.op_errno = gf_errno_to_error (op_errno);
+
+ req = frame->local;
+ server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
+ (xdrproc_t)xdr_gfs3_fstat_rsp);
+
+ GF_FREE (rsp.xdata.xdata_val);
+
+ return 0;
+}
+
+int
+server_ftruncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
+ struct iatt *postbuf, dict_t *xdata)
+{
+ gfs3_ftruncate_rsp rsp = {0};
+ server_state_t *state = NULL;
+ rpcsvc_request_t *req = NULL;
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
+ rsp.xdata.xdata_len, op_errno, out);
+
+ if (op_ret) {
+ state = CALL_STATE (frame);
+ gf_log (this->name, GF_LOG_INFO,
+ "%"PRId64": FTRUNCATE %"PRId64" (%s)==> (%s)",
+ frame->root->unique, state->resolve.fd_no,
+ uuid_utoa (state->resolve.gfid), strerror (op_errno));
+ goto out;
+ }
+
+ gf_stat_from_iatt (&rsp.prestat, prebuf);
+ gf_stat_from_iatt (&rsp.poststat, postbuf);
+
+out:
+ rsp.op_ret = op_ret;
+ rsp.op_errno = gf_errno_to_error (op_errno);
+
+ req = frame->local;
+ server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
+ (xdrproc_t)xdr_gfs3_ftruncate_rsp);
+
+ GF_FREE (rsp.xdata.xdata_val);
+
+ return 0;
+}
+
+int
+server_flush_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata)
+{
+ gf_common_rsp rsp = {0,};
+ server_state_t *state = NULL;
+ rpcsvc_request_t *req = NULL;
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
+ rsp.xdata.xdata_len, op_errno, out);
+
+ if (op_ret < 0) {
+ state = CALL_STATE (frame);
+ gf_log (this->name, (op_errno == ENOENT)?
+ GF_LOG_DEBUG:GF_LOG_ERROR,
+ "%"PRId64": FLUSH %"PRId64" (%s) ==> (%s)",
+ frame->root->unique, state->resolve.fd_no,
+ uuid_utoa (state->resolve.gfid), strerror (op_errno));
+ goto out;
+ }
+
+out:
+ rsp.op_ret = op_ret;
+ rsp.op_errno = gf_errno_to_error (op_errno);
+
+ req = frame->local;
+ server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
+ (xdrproc_t)xdr_gf_common_rsp);
+
+ GF_FREE (rsp.xdata.xdata_val);
+
+ return 0;
+}
+
+int
+server_fsync_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
+ struct iatt *postbuf, dict_t *xdata)
+{
+ gfs3_fsync_rsp rsp = {0,};
+ server_state_t *state = NULL;
+ rpcsvc_request_t *req = NULL;
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
+ rsp.xdata.xdata_len, op_errno, out);
+
+ if (op_ret < 0) {
+ state = CALL_STATE (frame);
+ gf_log (this->name, GF_LOG_INFO,
+ "%"PRId64": FSYNC %"PRId64" (%s) ==> (%s)",
+ frame->root->unique, state->resolve.fd_no,
+ uuid_utoa (state->resolve.gfid), strerror (op_errno));
+ goto out;
+ }
+
+ gf_stat_from_iatt (&(rsp.prestat), prebuf);
+ gf_stat_from_iatt (&(rsp.poststat), postbuf);
+
+out:
+ rsp.op_ret = op_ret;
+ rsp.op_errno = gf_errno_to_error (op_errno);
+
+ req = frame->local;
+ server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
+ (xdrproc_t)xdr_gfs3_fsync_rsp);
+
+ GF_FREE (rsp.xdata.xdata_val);
+
+ return 0;
+}
+
+int
+server_writev_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
+ struct iatt *postbuf, dict_t *xdata)
+{
+ gfs3_write_rsp rsp = {0,};
+ server_state_t *state = NULL;
+ rpcsvc_request_t *req = NULL;
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
+ rsp.xdata.xdata_len, op_errno, out);
+
+ if (op_ret < 0) {
+ state = CALL_STATE (frame);
+ gf_log (this->name, GF_LOG_INFO,
+ "%"PRId64": WRITEV %"PRId64" (%s) ==> (%s)",
+ frame->root->unique, state->resolve.fd_no,
+ uuid_utoa (state->resolve.gfid), strerror (op_errno));
+ goto out;
+ }
+
+ gf_stat_from_iatt (&rsp.prestat, prebuf);
+ gf_stat_from_iatt (&rsp.poststat, postbuf);
+
+out:
+ rsp.op_ret = op_ret;
+ rsp.op_errno = gf_errno_to_error (op_errno);
+
+ req = frame->local;
+ server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
+ (xdrproc_t)xdr_gfs3_write_rsp);
+
+ GF_FREE (rsp.xdata.xdata_val);
+
+ return 0;
+}
+
+
+int
+server_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 iatt *stbuf, struct iobref *iobref, dict_t *xdata)
+{
+ gfs3_read_rsp rsp = {0,};
+ server_state_t *state = NULL;
+ rpcsvc_request_t *req = NULL;
+
+#ifdef GF_TESTING_IO_XDATA
+ {
+ int ret = 0;
+ if (!xdata)
+ xdata = dict_new ();
+
+ ret = dict_set_str (xdata, "testing-the-xdata-key",
+ "testing-xdata-value");
+ }
+#endif
+ GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
+ rsp.xdata.xdata_len, op_errno, out);
+
+ if (op_ret < 0) {
+ state = CALL_STATE (frame);
+ gf_log (this->name, GF_LOG_INFO,
+ "%"PRId64": READV %"PRId64" (%s) ==> (%s)",
+ frame->root->unique, state->resolve.fd_no,
+ uuid_utoa (state->resolve.gfid), strerror (op_errno));
+ goto out;
+ }
+
+ gf_stat_from_iatt (&rsp.stat, stbuf);
+ rsp.size = op_ret;
+
+out:
+ rsp.op_ret = op_ret;
+ rsp.op_errno = gf_errno_to_error (op_errno);
+
+ req = frame->local;
+ server_submit_reply (frame, req, &rsp, vector, count, iobref,
+ (xdrproc_t)xdr_gfs3_read_rsp);
+
+ GF_FREE (rsp.xdata.xdata_val);
+
+ return 0;
+}
+
+int
+server_rchecksum_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno,
+ uint32_t weak_checksum, uint8_t *strong_checksum,
+ dict_t *xdata)
+{
+ gfs3_rchecksum_rsp rsp = {0,};
+ rpcsvc_request_t *req = NULL;
+ server_state_t *state = NULL;
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
+ rsp.xdata.xdata_len, op_errno, out);
+
+ if (op_ret < 0) {
+ state = CALL_STATE (frame);
+ gf_log (this->name, GF_LOG_INFO,
+ "%"PRId64": RCHECKSUM %"PRId64" (%s)==> (%s)",
+ frame->root->unique, state->resolve.fd_no,
+ uuid_utoa (state->resolve.gfid), strerror (op_errno));
+ goto out;
+ }
+
+ rsp.weak_checksum = weak_checksum;
+
+ rsp.strong_checksum.strong_checksum_val = (char *)strong_checksum;
+ rsp.strong_checksum.strong_checksum_len = MD5_DIGEST_LENGTH;
+
+out:
+ rsp.op_ret = op_ret;
+ rsp.op_errno = gf_errno_to_error (op_errno);
+
+ req = frame->local;
+ server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
+ (xdrproc_t)xdr_gfs3_rchecksum_rsp);
+
+ GF_FREE (rsp.xdata.xdata_val);
+
+ return 0;
+}
+
+
+int
+server_open_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, fd_t *fd, dict_t *xdata)
+{
+ server_state_t *state = NULL;
+ server_ctx_t *serv_ctx = NULL;
+ rpcsvc_request_t *req = NULL;
+ uint64_t fd_no = 0;
+ gfs3_open_rsp rsp = {0,};
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
+ rsp.xdata.xdata_len, op_errno, out);
+
+ if (op_ret < 0) {
+ state = CALL_STATE (frame);
+ gf_log (this->name, (op_errno == ENOENT)?
+ GF_LOG_DEBUG:GF_LOG_ERROR,
+ "%"PRId64": OPEN %s (%s) ==> (%s)",
+ frame->root->unique, state->loc.path,
+ uuid_utoa (state->resolve.gfid),
+ strerror (op_errno));
+ goto out;
+ }
+
+ serv_ctx = server_ctx_get (frame->root->client, this);
+ if (serv_ctx == NULL) {
+ gf_log (this->name, GF_LOG_INFO, "server_ctx_get() failed");
+ goto out;
+ }
+
+ fd_bind (fd);
+ fd_no = gf_fd_unused_get (serv_ctx->fdtable, fd);
+ fd_ref (fd);
+ rsp.fd = fd_no;
+
+out:
+ rsp.op_ret = op_ret;
+ rsp.op_errno = gf_errno_to_error (op_errno);
+
+ req = frame->local;
+ server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
+ (xdrproc_t)xdr_gfs3_open_rsp);
+ GF_FREE (rsp.xdata.xdata_val);
+
+ return 0;
+}
+
+
+int
+server_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 iatt *stbuf, struct iatt *preparent,
+ struct iatt *postparent, dict_t *xdata)
+{
+ server_state_t *state = NULL;
+ server_ctx_t *serv_ctx = NULL;
+ inode_t *link_inode = NULL;
+ rpcsvc_request_t *req = NULL;
+ uint64_t fd_no = 0;
+ gfs3_create_rsp rsp = {0,};
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
+ rsp.xdata.xdata_len, op_errno, out);
+
+ state = CALL_STATE (frame);
+
+ if (op_ret < 0) {
+ gf_log (this->name, GF_LOG_INFO,
+ "%"PRId64": CREATE %s (%s/%s) ==> (%s)",
+ frame->root->unique, state->loc.path,
+ uuid_utoa (state->resolve.pargfid),
+ state->resolve.bname, strerror (op_errno));
+ goto out;
+ }
+
+ /* TODO: log gfid too */
+ gf_log (frame->root->client->bound_xl->name, GF_LOG_TRACE,
+ "%"PRId64": CREATE %s (%s)",
+ frame->root->unique, state->loc.name,
+ uuid_utoa (stbuf->ia_gfid));
+
+ link_inode = inode_link (inode, state->loc.parent,
+ state->loc.name, stbuf);
+
+ if (!link_inode) {
+ op_ret = -1;
+ op_errno = ENOENT;
+ goto out;
+ }
+
+ if (link_inode != inode) {
+ /*
+ VERY racy code (if used anywhere else)
+ -- don't do this without understanding
+ */
+
+ inode_unref (fd->inode);
+ fd->inode = inode_ref (link_inode);
+ }
+
+ inode_lookup (link_inode);
+ inode_unref (link_inode);
+
+ serv_ctx = server_ctx_get (frame->root->client, this);
+ if (serv_ctx == NULL) {
+ gf_log (this->name, GF_LOG_INFO, "server_ctx_get() failed");
+ goto out;
+ }
+
+ fd_bind (fd);
+ fd_no = gf_fd_unused_get (serv_ctx->fdtable, fd);
+ fd_ref (fd);
+
+ if ((fd_no < 0) || (fd == 0)) {
+ op_ret = fd_no;
+ op_errno = errno;
+ }
+
+ gf_stat_from_iatt (&rsp.stat, stbuf);
+ gf_stat_from_iatt (&rsp.preparent, preparent);
+ gf_stat_from_iatt (&rsp.postparent, postparent);
+
+out:
+ rsp.fd = fd_no;
+ rsp.op_ret = op_ret;
+ rsp.op_errno = gf_errno_to_error (op_errno);
+
+ req = frame->local;
+ server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
+ (xdrproc_t)xdr_gfs3_create_rsp);
+
+ GF_FREE (rsp.xdata.xdata_val);
+
+ return 0;
+}
+
+int
+server_readlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, const char *buf,
+ struct iatt *stbuf, dict_t *xdata)
+{
+ gfs3_readlink_rsp rsp = {0,};
+ server_state_t *state = NULL;
+ rpcsvc_request_t *req = NULL;
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
+ rsp.xdata.xdata_len, op_errno, out);
+
+ if (op_ret < 0) {
+ state = CALL_STATE (frame);
+ gf_log (this->name, GF_LOG_INFO,
+ "%"PRId64": READLINK %s (%s) ==> (%s)",
+ frame->root->unique, state->loc.path,
+ uuid_utoa (state->resolve.gfid),
+ strerror (op_errno));
+ goto out;
+ }
+
+ gf_stat_from_iatt (&rsp.buf, stbuf);
+ rsp.path = (char *)buf;
+
+out:
+ rsp.op_ret = op_ret;
+ rsp.op_errno = gf_errno_to_error (op_errno);
+
+ if (!rsp.path)
+ rsp.path = "";
+
+ req = frame->local;
+ server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
+ (xdrproc_t)xdr_gfs3_readlink_rsp);
+
+ GF_FREE (rsp.xdata.xdata_val);
+
+ return 0;
+}
+
+int
+server_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct iatt *stbuf,
+ dict_t *xdata)
+{
+ gfs3_stat_rsp rsp = {0,};
+ server_state_t *state = NULL;
+ rpcsvc_request_t *req = NULL;
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
+ rsp.xdata.xdata_len, op_errno, out);
+
+ if (op_ret) {
+ state = CALL_STATE (frame);
+ gf_log (this->name, (op_errno == ENOENT)?
+ GF_LOG_DEBUG:GF_LOG_ERROR,
+ "%"PRId64": STAT %s (%s) ==> (%s)",
+ frame->root->unique, state->loc.path,
+ uuid_utoa (state->resolve.gfid),
+ strerror (op_errno));
+ goto out;
+ }
+
+ gf_stat_from_iatt (&rsp.stat, stbuf);
+
+out:
+ rsp.op_ret = op_ret;
+ rsp.op_errno = gf_errno_to_error (op_errno);
+
+ req = frame->local;
+ server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
+ (xdrproc_t)xdr_gfs3_stat_rsp);
+
+ GF_FREE (rsp.xdata.xdata_val);
+
+ return 0;
+}
+
+
+int
+server_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno,
+ struct iatt *statpre, struct iatt *statpost, dict_t *xdata)
+{
+ gfs3_setattr_rsp rsp = {0,};
+ server_state_t *state = NULL;
+ rpcsvc_request_t *req = NULL;
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
+ rsp.xdata.xdata_len, op_errno, out);
+
+ if (op_ret) {
+ state = CALL_STATE (frame);
+ gf_log (this->name, GF_LOG_INFO,
+ "%"PRId64": SETATTR %s (%s) ==> (%s)",
+ frame->root->unique, state->loc.path,
+ uuid_utoa (state->resolve.gfid),
+ strerror (op_errno));
+ goto out;
+ }
+
+ gf_stat_from_iatt (&rsp.statpre, statpre);
+ gf_stat_from_iatt (&rsp.statpost, statpost);
+
+out:
+ rsp.op_ret = op_ret;
+ rsp.op_errno = gf_errno_to_error (op_errno);
+
+ req = frame->local;
+ server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
+ (xdrproc_t)xdr_gfs3_setattr_rsp);
+
+ GF_FREE (rsp.xdata.xdata_val);
+
+ return 0;
+}
+
+int
+server_fsetattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno,
+ struct iatt *statpre, struct iatt *statpost, dict_t *xdata)
+{
+ gfs3_fsetattr_rsp rsp = {0,};
+ server_state_t *state = NULL;
+ rpcsvc_request_t *req = NULL;
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
+ rsp.xdata.xdata_len, op_errno, out);
+
+ if (op_ret) {
+ state = CALL_STATE (frame);
+ gf_log (this->name, GF_LOG_INFO,
+ "%"PRId64": FSETATTR %"PRId64" (%s) ==> (%s)",
+ frame->root->unique, state->resolve.fd_no,
+ uuid_utoa (state->resolve.gfid),
+ strerror (op_errno));
+ goto out;
+ }
+
+ gf_stat_from_iatt (&rsp.statpre, statpre);
+ gf_stat_from_iatt (&rsp.statpost, statpost);
+
+out:
+ rsp.op_ret = op_ret;
+ rsp.op_errno = gf_errno_to_error (op_errno);
+
+ req = frame->local;
+ server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
+ (xdrproc_t)xdr_gfs3_fsetattr_rsp);
+
+ GF_FREE (rsp.xdata.xdata_val);
+
+ return 0;
+}
+
+
+int
+server_xattrop_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *dict,
+ dict_t *xdata)
+{
+ gfs3_xattrop_rsp rsp = {0,};
+ server_state_t *state = NULL;
+ rpcsvc_request_t *req = NULL;
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
+ rsp.xdata.xdata_len, op_errno, out);
+
+ if (op_ret < 0) {
+ state = CALL_STATE (frame);
+ gf_log (this->name, GF_LOG_INFO,
+ "%"PRId64": XATTROP %s (%s) ==> (%s)",
+ frame->root->unique, state->loc.path,
+ uuid_utoa (state->resolve.gfid),
+ strerror (op_errno));
+ goto out;
+ }
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, dict, &rsp.dict.dict_val,
+ rsp.dict.dict_len, op_errno, out);
+
+out:
+ rsp.op_ret = op_ret;
+ rsp.op_errno = gf_errno_to_error (op_errno);
+
+ req = frame->local;
+ server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
+ (xdrproc_t)xdr_gfs3_xattrop_rsp);
+
+ GF_FREE (rsp.dict.dict_val);
+
+ GF_FREE (rsp.xdata.xdata_val);
+
+ return 0;
+}
+
+
+int
+server_fxattrop_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *dict,
+ dict_t *xdata)
+{
+ gfs3_xattrop_rsp rsp = {0,};
+ server_state_t *state = NULL;
+ rpcsvc_request_t *req = NULL;
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
+ rsp.xdata.xdata_len, op_errno, out);
+
+ if (op_ret < 0) {
+ state = CALL_STATE (frame);
+ gf_log (this->name, GF_LOG_INFO,
+ "%"PRId64": FXATTROP %"PRId64" (%s) ==> (%s)",
+ frame->root->unique, state->resolve.fd_no,
+ uuid_utoa (state->resolve.gfid),
+ strerror (op_errno));
+ goto out;
+ }
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, dict, &rsp.dict.dict_val,
+ rsp.dict.dict_len, op_errno, out);
+
+out:
+ rsp.op_ret = op_ret;
+ rsp.op_errno = gf_errno_to_error (op_errno);
+
+ req = frame->local;
+ server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
+ (xdrproc_t)xdr_gfs3_fxattrop_rsp);
+
+ GF_FREE (rsp.dict.dict_val);
+
+ GF_FREE (rsp.xdata.xdata_val);
+
+ return 0;
+}
+
+
+int
+server_readdirp_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, gf_dirent_t *entries,
+ dict_t *xdata)
+{
+ gfs3_readdirp_rsp rsp = {0,};
+ server_state_t *state = NULL;
+ rpcsvc_request_t *req = NULL;
+ int ret = 0;
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
+ rsp.xdata.xdata_len, op_errno, out);
+
+ if (op_ret < 0) {
+ state = CALL_STATE (frame);
+ gf_log (this->name, GF_LOG_INFO,
+ "%"PRId64": READDIRP %"PRId64" (%s) ==> (%s)",
+ frame->root->unique, state->resolve.fd_no,
+ uuid_utoa (state->resolve.gfid),
+ strerror (op_errno));
+ goto out;
+ }
+
+ /* (op_ret == 0) is valid, and means EOF */
+ if (op_ret) {
+ ret = serialize_rsp_direntp (entries, &rsp);
+ if (ret == -1) {
+ op_ret = -1;
+ op_errno = ENOMEM;
+ goto out;
+ }
+ }
+
+ /* TODO: need more clear thoughts before calling this function. */
+ /* gf_link_inodes_from_dirent (this, state->fd->inode, entries); */
+
+out:
+ rsp.op_ret = op_ret;
+ rsp.op_errno = gf_errno_to_error (op_errno);
+
+ req = frame->local;
+ server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
+ (xdrproc_t)xdr_gfs3_readdirp_rsp);
+
+ GF_FREE (rsp.xdata.xdata_val);
+
+ readdirp_rsp_cleanup (&rsp);
+
+ return 0;
+}
+
+int
+server_fallocate_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno,
+ struct iatt *statpre, struct iatt *statpost, dict_t *xdata)
+{
+ gfs3_fallocate_rsp rsp = {0,};
+ server_state_t *state = NULL;
+ rpcsvc_request_t *req = NULL;
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
+ rsp.xdata.xdata_len, op_errno, out);
+
+ if (op_ret) {
+ state = CALL_STATE (frame);
+ gf_log (this->name, GF_LOG_INFO,
+ "%"PRId64": FALLOCATE %"PRId64" (%s) ==> (%s)",
+ frame->root->unique, state->resolve.fd_no,
+ uuid_utoa (state->resolve.gfid),
+ strerror (op_errno));
+ goto out;
+ }
+
+ gf_stat_from_iatt (&rsp.statpre, statpre);
+ gf_stat_from_iatt (&rsp.statpost, statpost);
+
+out:
+ rsp.op_ret = op_ret;
+ rsp.op_errno = gf_errno_to_error (op_errno);
+
+ req = frame->local;
+ server_submit_reply(frame, req, &rsp, NULL, 0, NULL,
+ (xdrproc_t) xdr_gfs3_fallocate_rsp);
+
+ GF_FREE (rsp.xdata.xdata_val);
+
+ return 0;
+}
+
+int
+server_discard_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno,
+ struct iatt *statpre, struct iatt *statpost, dict_t *xdata)
+{
+ gfs3_discard_rsp rsp = {0,};
+ server_state_t *state = NULL;
+ rpcsvc_request_t *req = NULL;
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
+ rsp.xdata.xdata_len, op_errno, out);
+
+ if (op_ret) {
+ state = CALL_STATE (frame);
+ gf_log (this->name, GF_LOG_INFO,
+ "%"PRId64": DISCARD %"PRId64" (%s) ==> (%s)",
+ frame->root->unique, state->resolve.fd_no,
+ uuid_utoa (state->resolve.gfid),
+ strerror (op_errno));
+ goto out;
+ }
+
+ gf_stat_from_iatt (&rsp.statpre, statpre);
+ gf_stat_from_iatt (&rsp.statpost, statpost);
+
+out:
+ rsp.op_ret = op_ret;
+ rsp.op_errno = gf_errno_to_error (op_errno);
+
+ req = frame->local;
+ server_submit_reply(frame, req, &rsp, NULL, 0, NULL,
+ (xdrproc_t) xdr_gfs3_discard_rsp);
+
+ GF_FREE (rsp.xdata.xdata_val);
+
+ return 0;
+}
+
+int
+server_zerofill_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno,
+ struct iatt *statpre, struct iatt *statpost, dict_t *xdata)
+{
+ gfs3_zerofill_rsp rsp = {0,};
+ server_state_t *state = NULL;
+ rpcsvc_request_t *req = NULL;
+
+ req = frame->local;
+ state = CALL_STATE (frame);
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, xdata, (&rsp.xdata.xdata_val),
+ rsp.xdata.xdata_len, op_errno, out);
+
+ if (op_ret) {
+ gf_log (this->name, GF_LOG_INFO,
+ "%"PRId64": ZEROFILL%"PRId64" (%s) ==> (%s)",
+ frame->root->unique, state->resolve.fd_no,
+ uuid_utoa (state->resolve.gfid),
+ strerror (op_errno));
+ goto out;
+ }
+
+ gf_stat_from_iatt (&rsp.statpre, statpre);
+ gf_stat_from_iatt (&rsp.statpost, statpost);
+
+out:
+ rsp.op_ret = op_ret;
+ rsp.op_errno = gf_errno_to_error (op_errno);
+
+ server_submit_reply(frame, req, &rsp, NULL, 0, NULL,
+ (xdrproc_t) xdr_gfs3_zerofill_rsp);
+
+ GF_FREE (rsp.xdata.xdata_val);
+
+ return 0;
+}
+
+
+/* Resume function section */
+
+int
+server_rchecksum_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+ int op_ret = 0;
+ int op_errno = EINVAL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0) {
+ op_ret = state->resolve.op_ret;
+ op_errno = state->resolve.op_errno;
+ goto err;
+ }
+
+ STACK_WIND (frame, server_rchecksum_cbk, bound_xl,
+ bound_xl->fops->rchecksum, state->fd,
+ state->offset, state->size, state->xdata);
+
+ return 0;
+err:
+ server_rchecksum_cbk (frame, NULL, frame->this, op_ret, op_errno, 0,
+ NULL, NULL);
+
+ return 0;
+
+}
+
+int
+server_lk_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ STACK_WIND (frame, server_lk_cbk, bound_xl, bound_xl->fops->lk,
+ state->fd, state->cmd, &state->flock, state->xdata);
+
+ return 0;
+
+err:
+ server_lk_cbk (frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, NULL);
+ return 0;
+}
+
+int
+server_rename_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+ int op_ret = 0;
+ int op_errno = 0;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0) {
+ op_ret = state->resolve.op_ret;
+ op_errno = state->resolve.op_errno;
+ goto err;
+ }
+
+ if (state->resolve2.op_ret != 0) {
+ op_ret = state->resolve2.op_ret;
+ op_errno = state->resolve2.op_errno;
+ goto err;
+ }
+
+ STACK_WIND (frame, server_rename_cbk,
+ bound_xl, bound_xl->fops->rename,
+ &state->loc, &state->loc2, state->xdata);
+ return 0;
+err:
+ server_rename_cbk (frame, NULL, frame->this, op_ret, op_errno,
+ NULL, NULL, NULL, NULL, NULL, NULL);
+ return 0;
+}
+
+
+int
+server_link_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+ int op_ret = 0;
+ int op_errno = 0;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0) {
+ op_ret = state->resolve.op_ret;
+ op_errno = state->resolve.op_errno;
+ goto err;
+ }
+
+ if (state->resolve2.op_ret != 0) {
+ op_ret = state->resolve2.op_ret;
+ op_errno = state->resolve2.op_errno;
+ goto err;
+ }
+
+ state->loc2.inode = inode_ref (state->loc.inode);
+
+ STACK_WIND (frame, server_link_cbk, bound_xl, bound_xl->fops->link,
+ &state->loc, &state->loc2, state->xdata);
+
+ return 0;
+err:
+ server_link_cbk (frame, NULL, frame->this, op_ret, op_errno,
+ NULL, NULL, NULL, NULL, NULL);
+ return 0;
+}
+
+int
+server_symlink_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ state->loc.inode = inode_new (state->itable);
+
+ STACK_WIND (frame, server_symlink_cbk,
+ bound_xl, bound_xl->fops->symlink,
+ state->name, &state->loc, state->umask, state->xdata);
+
+ return 0;
+err:
+ server_symlink_cbk (frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, NULL, NULL, NULL, NULL);
+ return 0;
+}
+
+
+int
+server_access_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ STACK_WIND (frame, server_access_cbk,
+ bound_xl, bound_xl->fops->access,
+ &state->loc, state->mask, state->xdata);
+ return 0;
+err:
+ server_access_cbk (frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL);
+ return 0;
+}
+
+int
+server_fentrylk_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ GF_UNUSED int ret = -1;
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ if (!state->xdata)
+ state->xdata = dict_new ();
+
+ if (state->xdata)
+ ret = dict_set_str (state->xdata, "connection-id",
+ frame->root->client->client_uid);
+
+ STACK_WIND (frame, server_fentrylk_cbk, bound_xl,
+ bound_xl->fops->fentrylk,
+ state->volume, state->fd, state->name,
+ state->cmd, state->type, state->xdata);
+
+ return 0;
+err:
+ server_fentrylk_cbk (frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL);
+ return 0;
+}
+
+
+int
+server_entrylk_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ GF_UNUSED int ret = -1;
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ if (!state->xdata)
+ state->xdata = dict_new ();
+
+ if (state->xdata)
+ ret = dict_set_str (state->xdata, "connection-id",
+ frame->root->client->client_uid);
+
+ STACK_WIND (frame, server_entrylk_cbk,
+ bound_xl, bound_xl->fops->entrylk,
+ state->volume, &state->loc, state->name,
+ state->cmd, state->type, state->xdata);
+ return 0;
+err:
+ server_entrylk_cbk (frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL);
+ return 0;
+}
+
+
+int
+server_finodelk_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ GF_UNUSED int ret = -1;
+ server_state_t *state = NULL;
+
+ gf_log (bound_xl->name, GF_LOG_WARNING, "frame %p, xlator %p",
+ frame, bound_xl);
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ if (!state->xdata)
+ state->xdata = dict_new ();
+
+ if (state->xdata)
+ ret = dict_set_str (state->xdata, "connection-id",
+ frame->root->client->client_uid);
+
+ STACK_WIND (frame, server_finodelk_cbk, bound_xl,
+ bound_xl->fops->finodelk, state->volume, state->fd,
+ state->cmd, &state->flock, state->xdata);
+
+ return 0;
+err:
+ server_finodelk_cbk (frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL);
+
+ return 0;
+}
+
+int
+server_inodelk_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ GF_UNUSED int ret = -1;
+ server_state_t *state = NULL;
+
+ gf_log (bound_xl->name, GF_LOG_WARNING, "frame %p, xlator %p",
+ frame, bound_xl);
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ if (!state->xdata)
+ state->xdata = dict_new ();
+
+ if (state->xdata)
+ ret = dict_set_str (state->xdata, "connection-id",
+ frame->root->client->client_uid);
+
+ STACK_WIND (frame, server_inodelk_cbk, bound_xl,
+ bound_xl->fops->inodelk, state->volume, &state->loc,
+ state->cmd, &state->flock, state->xdata);
+ return 0;
+err:
+ server_inodelk_cbk (frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL);
+ return 0;
+}
+
+int
+server_rmdir_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ STACK_WIND (frame, server_rmdir_cbk, bound_xl, bound_xl->fops->rmdir,
+ &state->loc, state->flags, state->xdata);
+ return 0;
+err:
+ server_rmdir_cbk (frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, NULL, NULL);
+ return 0;
+}
+
+int
+server_mkdir_resume (call_frame_t *frame, xlator_t *bound_xl)
+
+{
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ state->loc.inode = inode_new (state->itable);
+
+ STACK_WIND (frame, server_mkdir_cbk,
+ bound_xl, bound_xl->fops->mkdir,
+ &(state->loc), state->mode, state->umask, state->xdata);
+
+ return 0;
+err:
+ server_mkdir_cbk (frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, NULL, NULL, NULL, NULL);
+ return 0;
+}
+
+
+int
+server_mknod_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ state->loc.inode = inode_new (state->itable);
+
+ STACK_WIND (frame, server_mknod_cbk,
+ bound_xl, bound_xl->fops->mknod,
+ &(state->loc), state->mode, state->dev,
+ state->umask, state->xdata);
+
+ return 0;
+err:
+ server_mknod_cbk (frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, NULL, NULL, NULL, NULL);
+ return 0;
+}
+
+
+int
+server_fsyncdir_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ STACK_WIND (frame, server_fsyncdir_cbk,
+ bound_xl,
+ bound_xl->fops->fsyncdir,
+ state->fd, state->flags, state->xdata);
+ return 0;
+
+err:
+ server_fsyncdir_cbk (frame, NULL, frame->this,
+ state->resolve.op_ret,
+ state->resolve.op_errno, NULL);
+ return 0;
+}
+
+
+int
+server_readdir_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ GF_ASSERT (state->fd);
+
+ STACK_WIND (frame, server_readdir_cbk,
+ bound_xl,
+ bound_xl->fops->readdir,
+ state->fd, state->size, state->offset, state->xdata);
+
+ return 0;
+err:
+ server_readdir_cbk (frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, NULL);
+ return 0;
+}
+
+int
+server_readdirp_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ STACK_WIND (frame, server_readdirp_cbk, bound_xl,
+ bound_xl->fops->readdirp, state->fd, state->size,
+ state->offset, state->dict);
+
+ return 0;
+err:
+ server_readdirp_cbk (frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, NULL);
+ return 0;
+}
+
+
+int
+server_opendir_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ state->fd = fd_create (state->loc.inode, frame->root->pid);
+ if (!state->fd) {
+ gf_log ("server", GF_LOG_ERROR, "could not create the fd");
+ goto err;
+ }
+
+ STACK_WIND (frame, server_opendir_cbk,
+ bound_xl, bound_xl->fops->opendir,
+ &state->loc, state->fd, state->xdata);
+ return 0;
+err:
+ server_opendir_cbk (frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, NULL);
+ return 0;
+}
+
+
+int
+server_statfs_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret !=0)
+ goto err;
+
+ STACK_WIND (frame, server_statfs_cbk,
+ bound_xl, bound_xl->fops->statfs,
+ &state->loc, state->xdata);
+ return 0;
+
+err:
+ server_statfs_cbk (frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, NULL);
+ return 0;
+}
+
+
+int
+server_removexattr_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ STACK_WIND (frame, server_removexattr_cbk,
+ bound_xl, bound_xl->fops->removexattr,
+ &state->loc, state->name, state->xdata);
+ return 0;
+err:
+ server_removexattr_cbk (frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL);
+ return 0;
+}
+
+int
+server_fremovexattr_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ STACK_WIND (frame, server_fremovexattr_cbk,
+ bound_xl, bound_xl->fops->fremovexattr,
+ state->fd, state->name, state->xdata);
+ return 0;
+err:
+ server_fremovexattr_cbk (frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL);
+ return 0;
+}
+
+int
+server_fgetxattr_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ STACK_WIND (frame, server_fgetxattr_cbk,
+ bound_xl, bound_xl->fops->fgetxattr,
+ state->fd, state->name, state->xdata);
+ return 0;
+err:
+ server_fgetxattr_cbk (frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, NULL);
+ return 0;
+}
+
+
+int
+server_xattrop_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ STACK_WIND (frame, server_xattrop_cbk,
+ bound_xl, bound_xl->fops->xattrop,
+ &state->loc, state->flags, state->dict, state->xdata);
+ return 0;
+err:
+ server_xattrop_cbk (frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, NULL);
+ return 0;
+}
+
+int
+server_fxattrop_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ STACK_WIND (frame, server_fxattrop_cbk,
+ bound_xl, bound_xl->fops->fxattrop,
+ state->fd, state->flags, state->dict, state->xdata);
+ return 0;
+err:
+ server_fxattrop_cbk (frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, NULL);
+ return 0;
+}
+
+int
+server_fsetxattr_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ STACK_WIND (frame, server_setxattr_cbk,
+ bound_xl, bound_xl->fops->fsetxattr,
+ state->fd, state->dict, state->flags, state->xdata);
+ return 0;
+err:
+ server_fsetxattr_cbk (frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL);
+
+ return 0;
+}
+
+int
+server_unlink_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ STACK_WIND (frame, server_unlink_cbk,
+ bound_xl, bound_xl->fops->unlink,
+ &state->loc, state->flags, state->xdata);
+ return 0;
+err:
+ server_unlink_cbk (frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, NULL, NULL);
+ return 0;
+}
+
+int
+server_truncate_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ STACK_WIND (frame, server_truncate_cbk,
+ bound_xl, bound_xl->fops->truncate,
+ &state->loc, state->offset, state->xdata);
+ return 0;
+err:
+ server_truncate_cbk (frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, NULL, NULL);
+ return 0;
+}
+
+
+
+int
+server_fstat_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ STACK_WIND (frame, server_fstat_cbk,
+ bound_xl, bound_xl->fops->fstat,
+ state->fd, state->xdata);
+ return 0;
+err:
+ server_fstat_cbk (frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, NULL);
+ return 0;
+}
+
+
+int
+server_setxattr_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ STACK_WIND (frame, server_setxattr_cbk,
+ bound_xl, bound_xl->fops->setxattr,
+ &state->loc, state->dict, state->flags, state->xdata);
+ return 0;
+err:
+ server_setxattr_cbk (frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL);
+
+ return 0;
+}
+
+
+int
+server_getxattr_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ STACK_WIND (frame, server_getxattr_cbk,
+ bound_xl, bound_xl->fops->getxattr,
+ &state->loc, state->name, state->xdata);
+ return 0;
+err:
+ server_getxattr_cbk (frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, NULL);
+ return 0;
+}
+
+
+int
+server_ftruncate_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ STACK_WIND (frame, server_ftruncate_cbk,
+ bound_xl, bound_xl->fops->ftruncate,
+ state->fd, state->offset, state->xdata);
+ return 0;
+err:
+ server_ftruncate_cbk (frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, NULL, NULL);
+
+ return 0;
+}
+
+
+int
+server_flush_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ STACK_WIND (frame, server_flush_cbk,
+ bound_xl, bound_xl->fops->flush, state->fd, state->xdata);
+ return 0;
+err:
+ server_flush_cbk (frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL);
+
+ return 0;
+}
+
+
+int
+server_fsync_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ STACK_WIND (frame, server_fsync_cbk,
+ bound_xl, bound_xl->fops->fsync,
+ state->fd, state->flags, state->xdata);
+ return 0;
+err:
+ server_fsync_cbk (frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, NULL, NULL);
+
+ return 0;
+}
+
+int
+server_writev_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ STACK_WIND (frame, server_writev_cbk,
+ bound_xl, bound_xl->fops->writev,
+ state->fd, state->payload_vector, state->payload_count,
+ state->offset, state->flags, state->iobref, state->xdata);
+
+ return 0;
+err:
+ server_writev_cbk (frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, NULL, NULL);
+ return 0;
+}
+
+
+int
+server_readv_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ STACK_WIND (frame, server_readv_cbk,
+ bound_xl, bound_xl->fops->readv,
+ state->fd, state->size, state->offset, state->flags, state->xdata);
+
+ return 0;
+err:
+ server_readv_cbk (frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, 0, NULL, NULL, NULL);
+ return 0;
+}
+
+
+int
+server_create_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ state->loc.inode = inode_new (state->itable);
+
+ state->fd = fd_create (state->loc.inode, frame->root->pid);
+ if (!state->fd) {
+ gf_log ("server", GF_LOG_ERROR, "fd creation for the inode %s "
+ "failed", state->loc.inode?
+ uuid_utoa (state->loc.inode->gfid):NULL);
+ state->resolve.op_ret = -1;
+ state->resolve.op_errno = ENOMEM;
+ goto err;
+ }
+ state->fd->flags = state->flags;
+
+ STACK_WIND (frame, server_create_cbk,
+ bound_xl, bound_xl->fops->create,
+ &(state->loc), state->flags, state->mode,
+ state->umask, state->fd, state->xdata);
+
+ return 0;
+err:
+ server_create_cbk (frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, NULL, NULL,
+ NULL, NULL, NULL);
+ return 0;
+}
+
+
+int
+server_open_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ state->fd = fd_create (state->loc.inode, frame->root->pid);
+ state->fd->flags = state->flags;
+
+ STACK_WIND (frame, server_open_cbk,
+ bound_xl, bound_xl->fops->open,
+ &state->loc, state->flags, state->fd, state->xdata);
+
+ return 0;
+err:
+ server_open_cbk (frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, NULL);
+ return 0;
+}
+
+
+int
+server_readlink_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ STACK_WIND (frame, server_readlink_cbk,
+ bound_xl, bound_xl->fops->readlink,
+ &state->loc, state->size, state->xdata);
+ return 0;
+err:
+ server_readlink_cbk (frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, NULL, NULL);
+ return 0;
+}
+
+
+int
+server_fsetattr_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ STACK_WIND (frame, server_fsetattr_cbk,
+ bound_xl, bound_xl->fops->fsetattr,
+ state->fd, &state->stbuf, state->valid, state->xdata);
+ return 0;
+err:
+ server_fsetattr_cbk (frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, NULL, NULL);
+
+ return 0;
+}
+
+
+int
+server_setattr_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ STACK_WIND (frame, server_setattr_cbk,
+ bound_xl, bound_xl->fops->setattr,
+ &state->loc, &state->stbuf, state->valid, state->xdata);
+ return 0;
+err:
+ server_setattr_cbk (frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, NULL, NULL);
+
+ return 0;
+}
+
+
+int
+server_stat_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ STACK_WIND (frame, server_stat_cbk,
+ bound_xl, bound_xl->fops->stat, &state->loc, state->xdata);
+ return 0;
+err:
+ server_stat_cbk (frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, NULL);
+ return 0;
+}
+
+int
+server_lookup_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ if (!state->loc.inode)
+ state->loc.inode = inode_new (state->itable);
+ else
+ state->is_revalidate = 1;
+
+ STACK_WIND (frame, server_lookup_cbk,
+ bound_xl, bound_xl->fops->lookup,
+ &state->loc, state->xdata);
+
+ return 0;
+err:
+ server_lookup_cbk (frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, NULL, NULL, NULL);
+
+ return 0;
+}
+
+int
+server_fallocate_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ STACK_WIND (frame, server_fallocate_cbk,
+ bound_xl, bound_xl->fops->fallocate,
+ state->fd, state->flags, state->offset, state->size,
+ state->xdata);
+ return 0;
+err:
+ server_fallocate_cbk(frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, NULL, NULL);
+
+ return 0;
+}
+
+int
+server_discard_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ STACK_WIND (frame, server_discard_cbk,
+ bound_xl, bound_xl->fops->discard,
+ state->fd, state->offset, state->size, state->xdata);
+ return 0;
+err:
+ server_discard_cbk(frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, NULL, NULL);
+
+ return 0;
+}
+
+int
+server_zerofill_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ STACK_WIND (frame, server_zerofill_cbk,
+ bound_xl, bound_xl->fops->zerofill,
+ state->fd, state->offset, state->size, state->xdata);
+ return 0;
+err:
+ server_zerofill_cbk(frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, NULL, NULL);
+
+ return 0;
+}
+
+
+
+/* Fop section */
+
+int
+server3_3_stat (rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfs3_stat_req args = {{0,},};
+ int ret = -1;
+ int op_errno = 0;
+
+ if (!req)
+ return 0;
+
+ /* Initialize args first, then decode */
+
+ ret = xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_stat_req);
+ if (ret < 0) {
+ //failed to decode msg;
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ frame = get_frame_from_request (req);
+ if (!frame) {
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+ frame->root->op = GF_FOP_STAT;
+
+ state = CALL_STATE (frame);
+ if (!frame->root->client->bound_xl) {
+ /* auth failure, request on subvolume without setvolume */
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ memcpy (state->resolve.gfid, args.gfid, 16);
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl,
+ state->xdata,
+ args.xdata.xdata_val,
+ args.xdata.xdata_len, ret,
+ op_errno, out);
+
+
+ ret = 0;
+ resolve_and_resume (frame, server_stat_resume);
+
+out:
+ free (args.xdata.xdata_val);
+
+ if (op_errno)
+ SERVER_REQ_SET_ERROR (req, ret);
+
+ return ret;
+}
+
+
+int
+server3_3_setattr (rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfs3_setattr_req args = {{0,},};
+ int ret = -1;
+ int op_errno = 0;
+
+ if (!req)
+ return 0;
+
+ ret = xdr_to_generic (req->msg[0], &args,
+ (xdrproc_t)xdr_gfs3_setattr_req);
+ if (ret < 0) {
+ //failed to decode msg;
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ frame = get_frame_from_request (req);
+ if (!frame) {
+ // something wrong, mostly insufficient memory
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+ frame->root->op = GF_FOP_SETATTR;
+
+ state = CALL_STATE (frame);
+ if (!frame->root->client->bound_xl) {
+ /* auth failure, request on subvolume without setvolume */
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ memcpy (state->resolve.gfid, args.gfid, 16);
+
+ gf_stat_to_iatt (&args.stbuf, &state->stbuf);
+ state->valid = args.valid;
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl,
+ state->xdata,
+ args.xdata.xdata_val,
+ args.xdata.xdata_len, ret,
+ op_errno, out);
+
+ ret = 0;
+ resolve_and_resume (frame, server_setattr_resume);
+
+out:
+ if (op_errno)
+ SERVER_REQ_SET_ERROR (req, ret);
+
+ free (args.xdata.xdata_val);
+
+ return ret;
+}
+
+
+int
+server3_3_fsetattr (rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfs3_fsetattr_req args = {0,};
+ int ret = -1;
+ int op_errno = 0;
+
+ if (!req)
+ return ret;
+
+ ret = xdr_to_generic (req->msg[0], &args,
+ (xdrproc_t)xdr_gfs3_fsetattr_req);
+ if (ret < 0) {
+ //failed to decode msg;
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ frame = get_frame_from_request (req);
+ if (!frame) {
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+ frame->root->op = GF_FOP_FSETATTR;
+
+ state = CALL_STATE (frame);
+ if (!frame->root->client->bound_xl) {
+ /* auth failure, request on subvolume without setvolume */
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ state->resolve.fd_no = args.fd;
+
+ gf_stat_to_iatt (&args.stbuf, &state->stbuf);
+ state->valid = args.valid;
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl,
+ state->xdata,
+ args.xdata.xdata_val,
+ args.xdata.xdata_len, ret,
+ op_errno, out);
+
+ ret = 0;
+ resolve_and_resume (frame, server_fsetattr_resume);
+
+out:
+ free (args.xdata.xdata_val);
+
+ if (op_errno)
+ SERVER_REQ_SET_ERROR (req, ret);
+
+ return ret;
+}
+
+int
+server3_3_fallocate(rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfs3_fallocate_req args = {{0},};
+ int ret = -1;
+ int op_errno = 0;
+
+ if (!req)
+ return ret;
+
+ ret = xdr_to_generic (req->msg[0], &args,
+ (xdrproc_t)xdr_gfs3_fallocate_req);
+ if (ret < 0) {
+ //failed to decode msg;
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ frame = get_frame_from_request (req);
+ if (!frame) {
+ // something wrong, mostly insufficient memory
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+ frame->root->op = GF_FOP_FALLOCATE;
+
+ state = CALL_STATE (frame);
+ if (!frame->root->client->bound_xl) {
+ /* auth failure, request on subvolume without setvolume */
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ state->resolve.fd_no = args.fd;
+
+ state->flags = args.flags;
+ state->offset = args.offset;
+ state->size = args.size;
+ memcpy(state->resolve.gfid, args.gfid, 16);
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl,
+ state->xdata,
+ args.xdata.xdata_val,
+ args.xdata.xdata_len, ret,
+ op_errno, out);
+
+ ret = 0;
+ resolve_and_resume (frame, server_fallocate_resume);
+
+out:
+ free (args.xdata.xdata_val);
+
+ if (op_errno)
+ SERVER_REQ_SET_ERROR (req, ret);
+
+ return ret;
+}
+
+
+int
+server3_3_discard(rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfs3_discard_req args = {{0},};
+ int ret = -1;
+ int op_errno = 0;
+
+ if (!req)
+ return ret;
+
+ ret = xdr_to_generic (req->msg[0], &args,
+ (xdrproc_t)xdr_gfs3_discard_req);
+ if (ret < 0) {
+ //failed to decode msg;
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ frame = get_frame_from_request (req);
+ if (!frame) {
+ // something wrong, mostly insufficient memory
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+ frame->root->op = GF_FOP_DISCARD;
+
+ state = CALL_STATE (frame);
+ if (!frame->root->client->bound_xl) {
+ /* auth failure, request on subvolume without setvolume */
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ state->resolve.fd_no = args.fd;
+
+ state->offset = args.offset;
+ state->size = args.size;
+ memcpy(state->resolve.gfid, args.gfid, 16);
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl,
+ state->xdata,
+ args.xdata.xdata_val,
+ args.xdata.xdata_len, ret,
+ op_errno, out);
+
+ ret = 0;
+ resolve_and_resume (frame, server_discard_resume);
+
+out:
+ free (args.xdata.xdata_val);
+
+ if (op_errno)
+ SERVER_REQ_SET_ERROR (req, ret);
+
+ return ret;
+}
+
+
+int
+server3_3_zerofill(rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfs3_zerofill_req args = {{0},};
+ int ret = -1;
+ int op_errno = 0;
+
+ if (!req)
+ return ret;
+
+ ret = xdr_to_generic (req->msg[0], &args,
+ (xdrproc_t)xdr_gfs3_zerofill_req);
+ if (ret < 0) {
+ /*failed to decode msg*/;
+ req->rpc_err = GARBAGE_ARGS;
+ goto out;
+ }
+
+ frame = get_frame_from_request (req);
+ if (!frame) {
+ /* something wrong, mostly insufficient memory*/
+ req->rpc_err = GARBAGE_ARGS; /* TODO */
+ goto out;
+ }
+ frame->root->op = GF_FOP_ZEROFILL;
+
+ state = CALL_STATE (frame);
+ if (!frame->root->client->bound_xl) {
+ /* auth failure, request on subvolume without setvolume */
+ req->rpc_err = GARBAGE_ARGS;
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ state->resolve.fd_no = args.fd;
+
+ state->offset = args.offset;
+ state->size = args.size;
+ memcpy(state->resolve.gfid, args.gfid, 16);
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl, state->xdata,
+ (args.xdata.xdata_val),
+ (args.xdata.xdata_len), ret,
+ op_errno, out);
+
+ ret = 0;
+ resolve_and_resume (frame, server_zerofill_resume);
+
+out:
+ free (args.xdata.xdata_val);
+
+ if (op_errno)
+ req->rpc_err = GARBAGE_ARGS;
+
+ return ret;
+}
+
+int
+server3_3_readlink (rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfs3_readlink_req args = {{0,},};
+ int ret = -1;
+ int op_errno = 0;
+
+ if (!req)
+ return ret;
+
+ ret = xdr_to_generic (req->msg[0], &args,
+ (xdrproc_t)xdr_gfs3_readlink_req);
+ if (ret < 0) {
+ //failed to decode msg;
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ frame = get_frame_from_request (req);
+ if (!frame) {
+ // something wrong, mostly insufficient memory
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+ frame->root->op = GF_FOP_READLINK;
+
+ state = CALL_STATE (frame);
+ if (!frame->root->client->bound_xl) {
+ /* auth failure, request on subvolume without setvolume */
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ memcpy (state->resolve.gfid, args.gfid, 16);
+
+ state->size = args.size;
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl,
+ state->xdata,
+ args.xdata.xdata_val,
+ args.xdata.xdata_len, ret,
+ op_errno, out);
+
+ ret = 0;
+ resolve_and_resume (frame, server_readlink_resume);
+
+out:
+ free (args.xdata.xdata_val);
+
+ if (op_errno)
+ SERVER_REQ_SET_ERROR (req, ret);
+
+ return ret;
+}
+
+
+int
+server3_3_create (rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfs3_create_req args = {{0,},};
+ int ret = -1;
+ int op_errno = 0;
+
+ if (!req)
+ return ret;
+
+ args.bname = alloca (req->msg[0].iov_len);
+
+ ret = xdr_to_generic (req->msg[0], &args,
+ (xdrproc_t)xdr_gfs3_create_req);
+ if (ret < 0) {
+ //failed to decode msg;
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ frame = get_frame_from_request (req);
+ if (!frame) {
+ // something wrong, mostly insufficient memory
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+ frame->root->op = GF_FOP_CREATE;
+
+ state = CALL_STATE (frame);
+ if (!frame->root->client->bound_xl) {
+ /* auth failure, request on subvolume without setvolume */
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+
+ state->resolve.bname = gf_strdup (args.bname);
+ state->mode = args.mode;
+ state->umask = args.umask;
+ state->flags = gf_flags_to_flags (args.flags);
+ memcpy (state->resolve.pargfid, args.pargfid, 16);
+
+ if (state->flags & O_EXCL) {
+ state->resolve.type = RESOLVE_NOT;
+ } else {
+ state->resolve.type = RESOLVE_DONTCARE;
+ }
+
+ /* TODO: can do alloca for xdata field instead of stdalloc */
+ GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl,
+ state->xdata,
+ args.xdata.xdata_val,
+ args.xdata.xdata_len, ret,
+ op_errno, out);
+
+ ret = 0;
+ resolve_and_resume (frame, server_create_resume);
+
+out:
+ /* memory allocated by libc, don't use GF_FREE */
+ free (args.xdata.xdata_val);
+
+ if (op_errno)
+ SERVER_REQ_SET_ERROR (req, ret);
+
+ return ret;
+}
+
+
+int
+server3_3_open (rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfs3_open_req args = {{0,},};
+ int ret = -1;
+ int op_errno = 0;
+
+ if (!req)
+ return ret;
+
+ ret = xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_open_req);
+ if (ret < 0) {
+ //failed to decode msg;
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ frame = get_frame_from_request (req);
+ if (!frame) {
+ // something wrong, mostly insufficient memory
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+ frame->root->op = GF_FOP_OPEN;
+
+ state = CALL_STATE (frame);
+ if (!frame->root->client->bound_xl) {
+ /* auth failure, request on subvolume without setvolume */
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ memcpy (state->resolve.gfid, args.gfid, 16);
+
+ state->flags = gf_flags_to_flags (args.flags);
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl,
+ state->xdata,
+ args.xdata.xdata_val,
+ args.xdata.xdata_len, ret,
+ op_errno, out);
+
+ ret = 0;
+ resolve_and_resume (frame, server_open_resume);
+out:
+ if (op_errno)
+ SERVER_REQ_SET_ERROR (req, ret);
+
+ free (args.xdata.xdata_val);
+
+ return ret;
+}
+
+
+int
+server3_3_readv (rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfs3_read_req args = {{0,},};
+ int ret = -1;
+ int op_errno = 0;
+
+ if (!req)
+ goto out;
+
+ ret = xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_read_req);
+ if (ret < 0) {
+ //failed to decode msg;
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ frame = get_frame_from_request (req);
+ if (!frame) {
+ // something wrong, mostly insufficient memory
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+ frame->root->op = GF_FOP_READ;
+
+ state = CALL_STATE (frame);
+ if (!frame->root->client->bound_xl) {
+ /* auth failure, request on subvolume without setvolume */
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ state->resolve.fd_no = args.fd;
+ state->size = args.size;
+ state->offset = args.offset;
+ state->flags = args.flag;
+
+ memcpy (state->resolve.gfid, args.gfid, 16);
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl,
+ state->xdata,
+ args.xdata.xdata_val,
+ args.xdata.xdata_len, ret,
+ op_errno, out);
+
+ ret = 0;
+ resolve_and_resume (frame, server_readv_resume);
+out:
+ /* memory allocated by libc, don't use GF_FREE */
+ free (args.xdata.xdata_val);
+
+ if (op_errno)
+ SERVER_REQ_SET_ERROR (req, ret);
+
+ return ret;
+}
+
+
+int
+server3_3_writev (rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfs3_write_req args = {{0,},};
+ ssize_t len = 0;
+ int i = 0;
+ int ret = -1;
+ int op_errno = 0;
+
+ if (!req)
+ return ret;
+
+ len = xdr_to_generic (req->msg[0], &args,
+ (xdrproc_t)xdr_gfs3_write_req);
+ if (len < 0) {
+ //failed to decode msg;
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ frame = get_frame_from_request (req);
+ if (!frame) {
+ // something wrong, mostly insufficient memory
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+ frame->root->op = GF_FOP_WRITE;
+
+ state = CALL_STATE (frame);
+ if (!frame->root->client->bound_xl) {
+ /* auth failure, request on subvolume without setvolume */
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ state->resolve.fd_no = args.fd;
+ state->offset = args.offset;
+ state->flags = args.flag;
+ state->iobref = iobref_ref (req->iobref);
+ memcpy (state->resolve.gfid, args.gfid, 16);
+
+ if (len < req->msg[0].iov_len) {
+ state->payload_vector[0].iov_base
+ = (req->msg[0].iov_base + len);
+ state->payload_vector[0].iov_len
+ = req->msg[0].iov_len - len;
+ state->payload_count = 1;
+ }
+
+ for (i = 1; i < req->count; i++) {
+ state->payload_vector[state->payload_count++]
+ = req->msg[i];
+ }
+
+ for (i = 0; i < state->payload_count; i++) {
+ state->size += state->payload_vector[i].iov_len;
+ }
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl,
+ state->xdata,
+ args.xdata.xdata_val,
+ args.xdata.xdata_len, ret,
+ op_errno, out);
+
+#ifdef GF_TESTING_IO_XDATA
+ dict_dump (state->xdata);
+#endif
+
+ ret = 0;
+ resolve_and_resume (frame, server_writev_resume);
+out:
+ free (args.xdata.xdata_val);
+
+ if (op_errno)
+ SERVER_REQ_SET_ERROR (req, ret);
+
+ return ret;
+}
+
+
+#define SERVER3_3_VECWRITE_START 0
+#define SERVER3_3_VECWRITE_READING_HDR 1
+#define SERVER3_3_VECWRITE_READING_OPAQUE 2
+
+int
+server3_3_writev_vecsizer (int state, ssize_t *readsize, char *base_addr,
+ char *curr_addr)
+{
+ ssize_t size = 0;
+ int nextstate = 0;
+ gfs3_write_req write_req = {{0,},};
+ XDR xdr;
+
+ switch (state) {
+ case SERVER3_3_VECWRITE_START:
+ size = xdr_sizeof ((xdrproc_t) xdr_gfs3_write_req,
+ &write_req);
+ *readsize = size;
+ nextstate = SERVER3_3_VECWRITE_READING_HDR;
+ break;
+ case SERVER3_3_VECWRITE_READING_HDR:
+ size = xdr_sizeof ((xdrproc_t) xdr_gfs3_write_req,
+ &write_req);
+
+ xdrmem_create (&xdr, base_addr, size, XDR_DECODE);
+
+ /* This will fail if there is xdata sent from client, if not,
+ well and good */
+ xdr_gfs3_write_req (&xdr, &write_req);
+
+ /* need to round off to proper roof (%4), as XDR packing pads
+ the end of opaque object with '0' */
+ size = roof (write_req.xdata.xdata_len, 4);
+
+ *readsize = size;
+
+ if (!size)
+ nextstate = SERVER3_3_VECWRITE_START;
+ else
+ nextstate = SERVER3_3_VECWRITE_READING_OPAQUE;
+
+ free (write_req.xdata.xdata_val);
+
+ break;
+
+ case SERVER3_3_VECWRITE_READING_OPAQUE:
+ *readsize = 0;
+ nextstate = SERVER3_3_VECWRITE_START;
+ break;
+ default:
+ gf_log ("server", GF_LOG_ERROR, "wrong state: %d", state);
+ }
+
+ return nextstate;
+}
+
+
+int
+server3_3_release (rpcsvc_request_t *req)
+{
+ client_t *client = NULL;
+ server_ctx_t *serv_ctx = NULL;
+ gfs3_release_req args = {{0,},};
+ gf_common_rsp rsp = {0,};
+ int ret = -1;
+
+ ret = xdr_to_generic (req->msg[0], &args,
+ (xdrproc_t)xdr_gfs3_release_req);
+ if (ret < 0) {
+ //failed to decode msg;
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ client = req->trans->xl_private;
+ if (!client) {
+ /* Handshake is not complete yet. */
+ req->rpc_err = SYSTEM_ERR;
+ goto out;
+ }
+
+ serv_ctx = server_ctx_get (client, client->this);
+ if (serv_ctx == NULL) {
+ gf_log (req->trans->name, GF_LOG_INFO,
+ "server_ctx_get() failed");
+ req->rpc_err = SYSTEM_ERR;
+ goto out;
+ }
+
+ gf_fd_put (serv_ctx->fdtable, args.fd);
+
+ server_submit_reply (NULL, req, &rsp, NULL, 0, NULL,
+ (xdrproc_t)xdr_gf_common_rsp);
+
+ ret = 0;
+out:
+ return ret;
+}
+
+int
+server3_3_releasedir (rpcsvc_request_t *req)
+{
+ client_t *client = NULL;
+ server_ctx_t *serv_ctx = NULL;
+ gfs3_releasedir_req args = {{0,},};
+ gf_common_rsp rsp = {0,};
+ int ret = -1;
+
+ ret = xdr_to_generic (req->msg[0], &args,
+ (xdrproc_t)xdr_gfs3_release_req);
+ if (ret < 0) {
+ //failed to decode msg;
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ client = req->trans->xl_private;
+ if (!client) {
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ serv_ctx = server_ctx_get (client, client->this);
+ if (serv_ctx == NULL) {
+ gf_log (req->trans->name, GF_LOG_INFO,
+ "server_ctx_get() failed");
+ req->rpc_err = SYSTEM_ERR;
+ goto out;
+ }
+
+ gf_fd_put (serv_ctx->fdtable, args.fd);
+
+ server_submit_reply (NULL, req, &rsp, NULL, 0, NULL,
+ (xdrproc_t)xdr_gf_common_rsp);
+
+ ret = 0;
+out:
+ return ret;
+}
+
+
+int
+server3_3_fsync (rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfs3_fsync_req args = {{0,},};
+ int ret = -1;
+ int op_errno = 0;
+
+ if (!req)
+ return ret;
+
+ ret = xdr_to_generic (req->msg[0], &args,
+ (xdrproc_t)xdr_gfs3_fsync_req);
+ if (ret < 0) {
+ //failed to decode msg;
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ frame = get_frame_from_request (req);
+ if (!frame) {
+ // something wrong, mostly insufficient memory
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+ frame->root->op = GF_FOP_FSYNC;
+
+ state = CALL_STATE (frame);
+ if (!frame->root->client->bound_xl) {
+ /* auth failure, request on subvolume without setvolume */
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ state->resolve.fd_no = args.fd;
+ state->flags = args.data;
+ memcpy (state->resolve.gfid, args.gfid, 16);
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl,
+ state->xdata,
+ args.xdata.xdata_val,
+ args.xdata.xdata_len, ret,
+ op_errno, out);
+
+ ret = 0;
+ resolve_and_resume (frame, server_fsync_resume);
+out:
+ free (args.xdata.xdata_val);
+
+ if (op_errno)
+ SERVER_REQ_SET_ERROR (req, ret);
+
+ return ret;
+}
+
+
+
+int
+server3_3_flush (rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfs3_flush_req args = {{0,},};
+ int ret = -1;
+ int op_errno = 0;
+
+ if (!req)
+ return ret;
+
+ ret = xdr_to_generic (req->msg[0], &args,
+ (xdrproc_t)xdr_gfs3_flush_req);
+ if (ret < 0) {
+ //failed to decode msg;
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ frame = get_frame_from_request (req);
+ if (!frame) {
+ // something wrong, mostly insufficient memory
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+ frame->root->op = GF_FOP_FLUSH;
+
+ state = CALL_STATE (frame);
+ if (!frame->root->client->bound_xl) {
+ /* auth failure, request on subvolume without setvolume */
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ state->resolve.fd_no = args.fd;
+ memcpy (state->resolve.gfid, args.gfid, 16);
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl,
+ state->xdata,
+ args.xdata.xdata_val,
+ args.xdata.xdata_len, ret,
+ op_errno, out);
+
+ ret = 0;
+ resolve_and_resume (frame, server_flush_resume);
+out:
+ free (args.xdata.xdata_val);
+
+ if (op_errno)
+ SERVER_REQ_SET_ERROR (req, ret);
+
+ return ret;
+}
+
+
+
+int
+server3_3_ftruncate (rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfs3_ftruncate_req args = {{0,},};
+ int ret = -1;
+ int op_errno = 0;
+
+ if (!req)
+ return ret;
+
+ ret = xdr_to_generic (req->msg[0], &args,
+ (xdrproc_t)xdr_gfs3_ftruncate_req);
+ if (ret < 0) {
+ //failed to decode msg;
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ frame = get_frame_from_request (req);
+ if (!frame) {
+ // something wrong, mostly insufficient memory
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+ frame->root->op = GF_FOP_FTRUNCATE;
+
+ state = CALL_STATE (frame);
+ if (!frame->root->client->bound_xl) {
+ /* auth failure, request on subvolume without setvolume */
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ state->resolve.fd_no = args.fd;
+ state->offset = args.offset;
+ memcpy (state->resolve.gfid, args.gfid, 16);
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl,
+ state->xdata,
+ args.xdata.xdata_val,
+ args.xdata.xdata_len, ret,
+ op_errno, out);
+
+ ret = 0;
+ resolve_and_resume (frame, server_ftruncate_resume);
+out:
+ free (args.xdata.xdata_val);
+
+ if (op_errno)
+ SERVER_REQ_SET_ERROR (req, ret);
+
+ return ret;
+}
+
+
+int
+server3_3_fstat (rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfs3_fstat_req args = {{0,},};
+ int ret = -1;
+ int op_errno = 0;
+
+ if (!req)
+ return ret;
+
+ ret = xdr_to_generic (req->msg[0], &args,
+ (xdrproc_t)xdr_gfs3_fstat_req);
+ if (ret < 0) {
+ //failed to decode msg;
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ frame = get_frame_from_request (req);
+ if (!frame) {
+ // something wrong, mostly insufficient memory
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+ frame->root->op = GF_FOP_FSTAT;
+
+ state = CALL_STATE (frame);
+ if (!frame->root->client->bound_xl) {
+ /* auth failure, request on subvolume without setvolume */
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ state->resolve.fd_no = args.fd;
+ memcpy (state->resolve.gfid, args.gfid, 16);
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl,
+ state->xdata,
+ args.xdata.xdata_val,
+ args.xdata.xdata_len, ret,
+ op_errno, out);
+
+ ret = 0;
+ resolve_and_resume (frame, server_fstat_resume);
+out:
+ free (args.xdata.xdata_val);
+
+ if (op_errno)
+ SERVER_REQ_SET_ERROR (req, ret);
+
+ return ret;
+}
+
+
+int
+server3_3_truncate (rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfs3_truncate_req args = {{0,},};
+ int ret = -1;
+ int op_errno = 0;
+
+ if (!req)
+ return ret;
+
+ ret = xdr_to_generic (req->msg[0], &args,
+ (xdrproc_t)xdr_gfs3_truncate_req);
+ if (ret < 0) {
+ //failed to decode msg;
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ frame = get_frame_from_request (req);
+ if (!frame) {
+ // something wrong, mostly insufficient memory
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+ frame->root->op = GF_FOP_TRUNCATE;
+
+ state = CALL_STATE (frame);
+ if (!frame->root->client->bound_xl) {
+ /* auth failure, request on subvolume without setvolume */
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ memcpy (state->resolve.gfid, args.gfid, 16);
+ state->offset = args.offset;
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl,
+ state->xdata,
+ args.xdata.xdata_val,
+ args.xdata.xdata_len, ret,
+ op_errno, out);
+
+ ret = 0;
+ resolve_and_resume (frame, server_truncate_resume);
+out:
+ free (args.xdata.xdata_val);
+
+ if (op_errno)
+ SERVER_REQ_SET_ERROR (req, ret);
+
+ return ret;
+}
+
+
+
+int
+server3_3_unlink (rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfs3_unlink_req args = {{0,},};
+ int ret = -1;
+ int op_errno = 0;
+
+ if (!req)
+ return ret;
+
+ args.bname = alloca (req->msg[0].iov_len);
+
+ ret = xdr_to_generic (req->msg[0], &args,
+ (xdrproc_t)xdr_gfs3_unlink_req);
+ if (ret < 0) {
+ //failed to decode msg;
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ frame = get_frame_from_request (req);
+ if (!frame) {
+ // something wrong, mostly insufficient memory
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+ frame->root->op = GF_FOP_UNLINK;
+
+ state = CALL_STATE (frame);
+ if (!frame->root->client->bound_xl) {
+ /* auth failure, request on subvolume without setvolume */
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ state->resolve.bname = gf_strdup (args.bname);
+ memcpy (state->resolve.pargfid, args.pargfid, 16);
+
+ state->flags = args.xflags;
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl,
+ state->xdata,
+ args.xdata.xdata_val,
+ args.xdata.xdata_len, ret,
+ op_errno, out);
+
+ ret = 0;
+ resolve_and_resume (frame, server_unlink_resume);
+out:
+ free (args.xdata.xdata_val);
+
+ if (op_errno)
+ SERVER_REQ_SET_ERROR (req, ret);
+
+ return ret;
+}
+
+
+int
+server3_3_setxattr (rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ dict_t *dict = NULL;
+ call_frame_t *frame = NULL;
+ gfs3_setxattr_req args = {{0,},};
+ int32_t ret = -1;
+ int32_t op_errno = 0;
+
+ if (!req)
+ return ret;
+
+ args.dict.dict_val = alloca (req->msg[0].iov_len);
+
+ ret = xdr_to_generic (req->msg[0], &args,
+ (xdrproc_t)xdr_gfs3_setxattr_req);
+ if (ret < 0) {
+ //failed to decode msg;
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ frame = get_frame_from_request (req);
+ if (!frame) {
+ // something wrong, mostly insufficient memory
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+ frame->root->op = GF_FOP_SETXATTR;
+
+ state = CALL_STATE (frame);
+ if (!frame->root->client->bound_xl) {
+ /* auth failure, request on subvolume without setvolume */
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ state->flags = args.flags;
+ memcpy (state->resolve.gfid, args.gfid, 16);
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl,
+ dict,
+ (args.dict.dict_val),
+ (args.dict.dict_len), ret,
+ op_errno, out);
+
+ state->dict = dict;
+
+ /* There can be some commands hidden in key, check and proceed */
+ gf_server_check_setxattr_cmd (frame, dict);
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl,
+ state->xdata,
+ args.xdata.xdata_val,
+ args.xdata.xdata_len, ret,
+ op_errno, out);
+
+ ret = 0;
+ resolve_and_resume (frame, server_setxattr_resume);
+
+ return ret;
+out:
+ free (args.xdata.xdata_val);
+
+ if (op_errno)
+ SERVER_REQ_SET_ERROR (req, ret);
+
+ if (dict)
+ dict_unref (dict);
+
+ return ret;
+}
+
+
+
+int
+server3_3_fsetxattr (rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ dict_t *dict = NULL;
+ call_frame_t *frame = NULL;
+ gfs3_fsetxattr_req args = {{0,},};
+ int32_t ret = -1;
+ int32_t op_errno = 0;
+
+ if (!req)
+ return ret;
+
+ args.dict.dict_val = alloca (req->msg[0].iov_len);
+ ret = xdr_to_generic (req->msg[0], &args,
+ (xdrproc_t)xdr_gfs3_fsetxattr_req);
+ if (ret < 0) {
+ //failed to decode msg;
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ frame = get_frame_from_request (req);
+ if (!frame) {
+ // something wrong, mostly insufficient memory
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+ frame->root->op = GF_FOP_FSETXATTR;
+
+ state = CALL_STATE (frame);
+ if (!frame->root->client->bound_xl) {
+ /* auth failure, request on subvolume without setvolume */
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ state->resolve.fd_no = args.fd;
+ state->flags = args.flags;
+ memcpy (state->resolve.gfid, args.gfid, 16);
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl,
+ dict,
+ (args.dict.dict_val),
+ (args.dict.dict_len), ret,
+ op_errno, out);
+
+ state->dict = dict;
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl,
+ state->xdata,
+ args.xdata.xdata_val,
+ args.xdata.xdata_len, ret,
+ op_errno, out);
+
+ ret = 0;
+ resolve_and_resume (frame, server_fsetxattr_resume);
+
+ return ret;
+out:
+ free (args.xdata.xdata_val);
+
+ if (op_errno)
+ SERVER_REQ_SET_ERROR (req, ret);
+
+ if (dict)
+ dict_unref (dict);
+
+ return ret;
+}
+
+
+
+int
+server3_3_fxattrop (rpcsvc_request_t *req)
+{
+ dict_t *dict = NULL;
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfs3_fxattrop_req args = {{0,},};
+ int32_t ret = -1;
+ int32_t op_errno = 0;
+
+ if (!req)
+ return ret;
+
+ args.dict.dict_val = alloca (req->msg[0].iov_len);
+ ret = xdr_to_generic (req->msg[0], &args,
+ (xdrproc_t)xdr_gfs3_fxattrop_req);
+ if (ret < 0) {
+ //failed to decode msg;
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ frame = get_frame_from_request (req);
+ if (!frame) {
+ // something wrong, mostly insufficient memory
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+ frame->root->op = GF_FOP_FXATTROP;
+
+ state = CALL_STATE (frame);
+ if (!frame->root->client->bound_xl) {
+ /* auth failure, request on subvolume without setvolume */
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ state->resolve.fd_no = args.fd;
+ state->flags = args.flags;
+ memcpy (state->resolve.gfid, args.gfid, 16);
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl,
+ dict,
+ (args.dict.dict_val),
+ (args.dict.dict_len), ret,
+ op_errno, out);
+
+ state->dict = dict;
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl,
+ state->xdata,
+ args.xdata.xdata_val,
+ args.xdata.xdata_len, ret,
+ op_errno, out);
+
+ ret = 0;
+ resolve_and_resume (frame, server_fxattrop_resume);
+
+ return ret;
+
+out:
+ free (args.xdata.xdata_val);
+
+ if (op_errno)
+ SERVER_REQ_SET_ERROR (req, ret);
+
+ if (dict)
+ dict_unref (dict);
+
+ return ret;
+}
+
+
+
+int
+server3_3_xattrop (rpcsvc_request_t *req)
+{
+ dict_t *dict = NULL;
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfs3_xattrop_req args = {{0,},};
+ int32_t ret = -1;
+ int32_t op_errno = 0;
+
+ if (!req)
+ return ret;
+
+ args.dict.dict_val = alloca (req->msg[0].iov_len);
+
+ ret = xdr_to_generic (req->msg[0], &args,
+ (xdrproc_t)xdr_gfs3_xattrop_req);
+ if (ret < 0) {
+ //failed to decode msg;
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ frame = get_frame_from_request (req);
+ if (!frame) {
+ // something wrong, mostly insufficient memory
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+ frame->root->op = GF_FOP_XATTROP;
+
+ state = CALL_STATE (frame);
+ if (!frame->root->client->bound_xl) {
+ /* auth failure, request on subvolume without setvolume */
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ state->flags = args.flags;
+ memcpy (state->resolve.gfid, args.gfid, 16);
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl,
+ dict,
+ (args.dict.dict_val),
+ (args.dict.dict_len), ret,
+ op_errno, out);
+
+ state->dict = dict;
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl,
+ state->xdata,
+ args.xdata.xdata_val,
+ args.xdata.xdata_len, ret,
+ op_errno, out);
+
+ ret = 0;
+ resolve_and_resume (frame, server_xattrop_resume);
+
+ return ret;
+out:
+ free (args.xdata.xdata_val);
+
+ if (op_errno)
+ SERVER_REQ_SET_ERROR (req, ret);
+
+ if (dict)
+ dict_unref (dict);
+
+ return ret;
+}
+
+
+int
+server3_3_getxattr (rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfs3_getxattr_req args = {{0,},};
+ int ret = -1;
+ int op_errno = 0;
+
+ if (!req)
+ return ret;
+
+ args.name = alloca (256);
+
+ ret = xdr_to_generic (req->msg[0], &args,
+ (xdrproc_t)xdr_gfs3_getxattr_req);
+ if (ret < 0) {
+ //failed to decode msg;
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ frame = get_frame_from_request (req);
+ if (!frame) {
+ // something wrong, mostly insufficient memory
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+ frame->root->op = GF_FOP_GETXATTR;
+
+ state = CALL_STATE (frame);
+ if (!frame->root->client->bound_xl) {
+ /* auth failure, request on subvolume without setvolume */
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ memcpy (state->resolve.gfid, args.gfid, 16);
+
+ if (args.namelen) {
+ state->name = gf_strdup (args.name);
+ /* There can be some commands hidden in key, check and proceed */
+ gf_server_check_getxattr_cmd (frame, state->name);
+ }
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl,
+ state->xdata,
+ args.xdata.xdata_val,
+ args.xdata.xdata_len, ret,
+ op_errno, out);
+
+ ret = 0;
+ resolve_and_resume (frame, server_getxattr_resume);
+out:
+ free (args.xdata.xdata_val);
+
+ if (op_errno)
+ SERVER_REQ_SET_ERROR (req, ret);
+
+ return ret;
+}
+
+
+int
+server3_3_fgetxattr (rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfs3_fgetxattr_req args = {{0,},};
+ int ret = -1;
+ int op_errno = 0;
+
+ if (!req)
+ return ret;
+
+ args.name = alloca (256);
+ ret = xdr_to_generic (req->msg[0], &args,
+ (xdrproc_t)xdr_gfs3_fgetxattr_req);
+ if (ret < 0) {
+ //failed to decode msg;
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ frame = get_frame_from_request (req);
+ if (!frame) {
+ // something wrong, mostly insufficient memory
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+ frame->root->op = GF_FOP_FGETXATTR;
+
+ state = CALL_STATE (frame);
+ if (!frame->root->client->bound_xl) {
+ /* auth failure, request on subvolume without setvolume */
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ state->resolve.fd_no = args.fd;
+ memcpy (state->resolve.gfid, args.gfid, 16);
+
+ if (args.namelen)
+ state->name = gf_strdup (args.name);
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl,
+ state->xdata,
+ args.xdata.xdata_val,
+ args.xdata.xdata_len, ret,
+ op_errno, out);
+
+ ret = 0;
+ resolve_and_resume (frame, server_fgetxattr_resume);
+out:
+ free (args.xdata.xdata_val);
+
+ if (op_errno)
+ SERVER_REQ_SET_ERROR (req, ret);
+
+ return ret;
+}
+
+
+
+int
+server3_3_removexattr (rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfs3_removexattr_req args = {{0,},};
+ int ret = -1;
+ int op_errno = 0;
+
+ if (!req)
+ return ret;
+
+ args.name = alloca (256);
+
+ ret = xdr_to_generic (req->msg[0], &args,
+ (xdrproc_t)xdr_gfs3_removexattr_req);
+ if (ret < 0) {
+ //failed to decode msg;
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ frame = get_frame_from_request (req);
+ if (!frame) {
+ // something wrong, mostly insufficient memory
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+ frame->root->op = GF_FOP_REMOVEXATTR;
+
+ state = CALL_STATE (frame);
+ if (!frame->root->client->bound_xl) {
+ /* auth failure, request on subvolume without setvolume */
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ memcpy (state->resolve.gfid, args.gfid, 16);
+ state->name = gf_strdup (args.name);
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl,
+ state->xdata,
+ args.xdata.xdata_val,
+ args.xdata.xdata_len, ret,
+ op_errno, out);
+
+ ret = 0;
+ resolve_and_resume (frame, server_removexattr_resume);
+out:
+ free (args.xdata.xdata_val);
+
+ if (op_errno)
+ SERVER_REQ_SET_ERROR (req, ret);
+
+ return ret;
+}
+
+int
+server3_3_fremovexattr (rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfs3_fremovexattr_req args = {{0,},};
+ int ret = -1;
+ int op_errno = 0;
+
+ if (!req)
+ return ret;
+
+ args.name = alloca (4096);
+
+ ret = xdr_to_generic (req->msg[0], &args,
+ (xdrproc_t)xdr_gfs3_fremovexattr_req);
+ if (ret < 0) {
+ //failed to decode msg;
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ frame = get_frame_from_request (req);
+ if (!frame) {
+ // something wrong, mostly insufficient memory
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+ frame->root->op = GF_FOP_FREMOVEXATTR;
+
+ state = CALL_STATE (frame);
+ if (!frame->root->client->bound_xl) {
+ /* auth failure, request on subvolume without setvolume */
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ state->resolve.fd_no = args.fd;
+ memcpy (state->resolve.gfid, args.gfid, 16);
+ state->name = gf_strdup (args.name);
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl,
+ state->xdata,
+ args.xdata.xdata_val,
+ args.xdata.xdata_len, ret,
+ op_errno, out);
+
+ ret = 0;
+ resolve_and_resume (frame, server_fremovexattr_resume);
+out:
+ free (args.xdata.xdata_val);
+
+ if (op_errno)
+ SERVER_REQ_SET_ERROR (req, ret);
+
+ return ret;
+}
+
+
+
+
+int
+server3_3_opendir (rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfs3_opendir_req args = {{0,},};
+ int ret = -1;
+ int op_errno = 0;
+
+ if (!req)
+ return ret;
+
+ ret = xdr_to_generic (req->msg[0], &args,
+ (xdrproc_t)xdr_gfs3_opendir_req);
+ if (ret < 0) {
+ //failed to decode msg;
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ frame = get_frame_from_request (req);
+ if (!frame) {
+ // something wrong, mostly insufficient memory
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+ frame->root->op = GF_FOP_OPENDIR;
+
+ state = CALL_STATE (frame);
+ if (!frame->root->client->bound_xl) {
+ /* auth failure, request on subvolume without setvolume */
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ memcpy (state->resolve.gfid, args.gfid, 16);
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl,
+ state->xdata,
+ args.xdata.xdata_val,
+ args.xdata.xdata_len, ret,
+ op_errno, out);
+
+ ret = 0;
+ resolve_and_resume (frame, server_opendir_resume);
+out:
+ free (args.xdata.xdata_val);
+
+ if (op_errno)
+ SERVER_REQ_SET_ERROR (req, ret);
+
+ return ret;
+}
+
+
+int
+server3_3_readdirp (rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfs3_readdirp_req args = {{0,},};
+ size_t headers_size = 0;
+ int ret = -1;
+ int op_errno = 0;
+
+ if (!req)
+ return ret;
+
+ ret = xdr_to_generic (req->msg[0], &args,
+ (xdrproc_t)xdr_gfs3_readdirp_req);
+ if (ret < 0) {
+ //failed to decode msg;
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ frame = get_frame_from_request (req);
+ if (!frame) {
+ // something wrong, mostly insufficient memory
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+ frame->root->op = GF_FOP_READDIRP;
+
+ state = CALL_STATE (frame);
+ if (!frame->root->client->bound_xl) {
+ /* auth failure, request on subvolume without setvolume */
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ /* FIXME: this should go away when variable sized iobufs are introduced
+ * and transport layer can send msgs bigger than current page-size.
+ */
+ headers_size = sizeof (struct rpc_msg) + sizeof (gfs3_readdir_rsp);
+ if ((frame->this->ctx->page_size < args.size)
+ || ((frame->this->ctx->page_size - args.size) < headers_size)) {
+ state->size = frame->this->ctx->page_size - headers_size;
+ } else {
+ state->size = args.size;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ state->resolve.fd_no = args.fd;
+ state->offset = args.offset;
+ memcpy (state->resolve.gfid, args.gfid, 16);
+
+ /* here, dict itself works as xdata */
+ GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl,
+ state->dict,
+ (args.dict.dict_val),
+ (args.dict.dict_len), ret,
+ op_errno, out);
+
+
+ ret = 0;
+ resolve_and_resume (frame, server_readdirp_resume);
+out:
+ if (op_errno)
+ SERVER_REQ_SET_ERROR (req, ret);
+
+ free (args.dict.dict_val);
+
+ return ret;
+}
+
+int
+server3_3_readdir (rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfs3_readdir_req args = {{0,},};
+ size_t headers_size = 0;
+ int ret = -1;
+ int op_errno = 0;
+
+ if (!req)
+ return ret;
+
+ ret = xdr_to_generic (req->msg[0], &args,
+ (xdrproc_t)xdr_gfs3_readdir_req);
+ if (ret < 0) {
+ //failed to decode msg;
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ frame = get_frame_from_request (req);
+ if (!frame) {
+ // something wrong, mostly insufficient memory
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+ frame->root->op = GF_FOP_READDIR;
+
+ state = CALL_STATE (frame);
+ if (!frame->root->client->bound_xl) {
+ /* auth failure, request on subvolume without setvolume */
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ /* FIXME: this should go away when variable sized iobufs are introduced
+ * and transport layer can send msgs bigger than current page-size.
+ */
+ headers_size = sizeof (struct rpc_msg) + sizeof (gfs3_readdir_rsp);
+ if ((frame->this->ctx->page_size < args.size)
+ || ((frame->this->ctx->page_size - args.size) < headers_size)) {
+ state->size = frame->this->ctx->page_size - headers_size;
+ } else {
+ state->size = args.size;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ state->resolve.fd_no = args.fd;
+ state->offset = args.offset;
+ memcpy (state->resolve.gfid, args.gfid, 16);
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl,
+ state->xdata,
+ args.xdata.xdata_val,
+ args.xdata.xdata_len, ret,
+ op_errno, out);
+
+ ret = 0;
+ resolve_and_resume (frame, server_readdir_resume);
+out:
+ free (args.xdata.xdata_val);
+
+ if (op_errno)
+ SERVER_REQ_SET_ERROR (req, ret);
+
+ return ret;
+}
+
+int
+server3_3_fsyncdir (rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfs3_fsyncdir_req args = {{0,},};
+ int ret = -1;
+ int op_errno = 0;
+
+ if (!req)
+ return ret;
+
+ ret = xdr_to_generic (req->msg[0], &args,
+ (xdrproc_t)xdr_gfs3_fsyncdir_req);
+ if (ret < 0) {
+ //failed to decode msg;
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ frame = get_frame_from_request (req);
+ if (!frame) {
+ // something wrong, mostly insufficient memory
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+ frame->root->op = GF_FOP_FSYNCDIR;
+
+ state = CALL_STATE (frame);
+ if (!frame->root->client->bound_xl) {
+ /* auth failure, request on subvolume without setvolume */
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ state->resolve.fd_no = args.fd;
+ state->flags = args.data;
+ memcpy (state->resolve.gfid, args.gfid, 16);
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl,
+ state->xdata,
+ args.xdata.xdata_val,
+ args.xdata.xdata_len, ret,
+ op_errno, out);
+
+ ret = 0;
+ resolve_and_resume (frame, server_fsyncdir_resume);
+out:
+ free (args.xdata.xdata_val);
+
+ if (op_errno)
+ SERVER_REQ_SET_ERROR (req, ret);
+
+ return ret;
+}
+
+
+
+int
+server3_3_mknod (rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfs3_mknod_req args = {{0,},};
+ int ret = -1;
+ int op_errno = 0;
+
+ if (!req)
+ return ret;
+
+ args.bname = alloca (req->msg[0].iov_len);
+
+ ret = xdr_to_generic (req->msg[0], &args,
+ (xdrproc_t)xdr_gfs3_mknod_req);
+ if (ret < 0) {
+ //failed to decode msg;
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ frame = get_frame_from_request (req);
+ if (!frame) {
+ // something wrong, mostly insufficient memory
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+ frame->root->op = GF_FOP_MKNOD;
+
+ state = CALL_STATE (frame);
+ if (!frame->root->client->bound_xl) {
+ /* auth failure, request on subvolume without setvolume */
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_NOT;
+ memcpy (state->resolve.pargfid, args.pargfid, 16);
+ state->resolve.bname = gf_strdup (args.bname);
+
+ state->mode = args.mode;
+ state->dev = args.dev;
+ state->umask = args.umask;
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl,
+ state->xdata,
+ args.xdata.xdata_val,
+ args.xdata.xdata_len, ret,
+ op_errno, out);
+
+ ret = 0;
+ resolve_and_resume (frame, server_mknod_resume);
+
+out:
+ if (op_errno)
+ SERVER_REQ_SET_ERROR (req, ret);
+
+ /* memory allocated by libc, don't use GF_FREE */
+ free (args.xdata.xdata_val);
+
+ return ret;
+
+}
+
+
+int
+server3_3_mkdir (rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfs3_mkdir_req args = {{0,},};
+ int ret = -1;
+ int op_errno = 0;
+
+ if (!req)
+ return ret;
+
+ args.bname = alloca (req->msg[0].iov_len);
+
+ ret = xdr_to_generic (req->msg[0], &args,
+ (xdrproc_t)xdr_gfs3_mkdir_req);
+ if (ret < 0) {
+ //failed to decode msg;
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ frame = get_frame_from_request (req);
+ if (!frame) {
+ // something wrong, mostly insufficient memory
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+ frame->root->op = GF_FOP_MKDIR;
+
+ state = CALL_STATE (frame);
+ if (!frame->root->client->bound_xl) {
+ /* auth failure, request on subvolume without setvolume */
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_NOT;
+ memcpy (state->resolve.pargfid, args.pargfid, 16);
+ state->resolve.bname = gf_strdup (args.bname);
+
+ state->mode = args.mode;
+ state->umask = args.umask;
+
+ /* TODO: can do alloca for xdata field instead of stdalloc */
+ GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl,
+ state->xdata,
+ args.xdata.xdata_val,
+ args.xdata.xdata_len, ret,
+ op_errno, out);
+
+ ret = 0;
+ resolve_and_resume (frame, server_mkdir_resume);
+
+out:
+ if (op_errno)
+ SERVER_REQ_SET_ERROR (req, ret);
+
+ free (args.xdata.xdata_val);
+
+ return ret;
+}
+
+
+int
+server3_3_rmdir (rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfs3_rmdir_req args = {{0,},};
+ int ret = -1;
+ int op_errno = 0;
+
+ if (!req)
+ return ret;
+
+ args.bname = alloca (req->msg[0].iov_len);
+
+ ret = xdr_to_generic (req->msg[0], &args,
+ (xdrproc_t)xdr_gfs3_rmdir_req);
+ if (ret < 0) {
+ //failed to decode msg;
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ frame = get_frame_from_request (req);
+ if (!frame) {
+ // something wrong, mostly insufficient memory
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+ frame->root->op = GF_FOP_RMDIR;
+
+ state = CALL_STATE (frame);
+ if (!frame->root->client->bound_xl) {
+ /* auth failure, request on subvolume without setvolume */
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ memcpy (state->resolve.pargfid, args.pargfid, 16);
+ state->resolve.bname = gf_strdup (args.bname);
+
+ state->flags = args.xflags;
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl,
+ state->xdata,
+ args.xdata.xdata_val,
+ args.xdata.xdata_len, ret,
+ op_errno, out);
+
+ ret = 0;
+ resolve_and_resume (frame, server_rmdir_resume);
+out:
+ free (args.xdata.xdata_val);
+
+ if (op_errno)
+ SERVER_REQ_SET_ERROR (req, ret);
+
+ return ret;
+}
+
+
+
+int
+server3_3_inodelk (rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfs3_inodelk_req args = {{0,},};
+ int cmd = 0;
+ int ret = -1;
+ int op_errno = 0;
+
+ if (!req)
+ return ret;
+
+ args.volume = alloca (256);
+
+ ret = xdr_to_generic (req->msg[0], &args,
+ (xdrproc_t)xdr_gfs3_inodelk_req);
+ if (ret < 0) {
+ //failed to decode msg;
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ frame = get_frame_from_request (req);
+ if (!frame) {
+ // something wrong, mostly insufficient memory
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+ frame->root->op = GF_FOP_INODELK;
+
+ state = CALL_STATE (frame);
+ if (!frame->root->client->bound_xl) {
+ /* auth failure, request on subvolume without setvolume */
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_EXACT;
+ memcpy (state->resolve.gfid, args.gfid, 16);
+
+ cmd = args.cmd;
+ switch (cmd) {
+ case GF_LK_GETLK:
+ state->cmd = F_GETLK;
+ break;
+ case GF_LK_SETLK:
+ state->cmd = F_SETLK;
+ break;
+ case GF_LK_SETLKW:
+ state->cmd = F_SETLKW;
+ break;
+ }
+
+ state->type = args.type;
+ state->volume = gf_strdup (args.volume);
+
+ gf_proto_flock_to_flock (&args.flock, &state->flock);
+
+ switch (state->type) {
+ case GF_LK_F_RDLCK:
+ state->flock.l_type = F_RDLCK;
+ break;
+ case GF_LK_F_WRLCK:
+ state->flock.l_type = F_WRLCK;
+ break;
+ case GF_LK_F_UNLCK:
+ state->flock.l_type = F_UNLCK;
+ break;
+ }
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl,
+ state->xdata,
+ args.xdata.xdata_val,
+ args.xdata.xdata_len, ret,
+ op_errno, out);
+
+ ret = 0;
+ resolve_and_resume (frame, server_inodelk_resume);
+out:
+ free (args.xdata.xdata_val);
+
+ free (args.flock.lk_owner.lk_owner_val);
+
+ if (op_errno)
+ SERVER_REQ_SET_ERROR (req, ret);
+
+ return ret;
+}
+
+int
+server3_3_finodelk (rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfs3_finodelk_req args = {{0,},};
+ int ret = -1;
+ int op_errno = 0;
+
+ if (!req)
+ return ret;
+
+ args.volume = alloca (256);
+ ret = xdr_to_generic (req->msg[0], &args,
+ (xdrproc_t)xdr_gfs3_finodelk_req);
+ if (ret < 0) {
+ //failed to decode msg;
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ frame = get_frame_from_request (req);
+ if (!frame) {
+ // something wrong, mostly insufficient memory
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+ frame->root->op = GF_FOP_FINODELK;
+
+ state = CALL_STATE (frame);
+ if (!frame->root->client->bound_xl) {
+ /* auth failure, request on subvolume without setvolume */
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_EXACT;
+ state->volume = gf_strdup (args.volume);
+ state->resolve.fd_no = args.fd;
+ state->cmd = args.cmd;
+ memcpy (state->resolve.gfid, args.gfid, 16);
+
+ switch (state->cmd) {
+ case GF_LK_GETLK:
+ state->cmd = F_GETLK;
+ break;
+ case GF_LK_SETLK:
+ state->cmd = F_SETLK;
+ break;
+ case GF_LK_SETLKW:
+ state->cmd = F_SETLKW;
+ break;
+ }
+
+ state->type = args.type;
+
+ gf_proto_flock_to_flock (&args.flock, &state->flock);
+
+ switch (state->type) {
+ case GF_LK_F_RDLCK:
+ state->flock.l_type = F_RDLCK;
+ break;
+ case GF_LK_F_WRLCK:
+ state->flock.l_type = F_WRLCK;
+ break;
+ case GF_LK_F_UNLCK:
+ state->flock.l_type = F_UNLCK;
+ break;
+ }
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl,
+ state->xdata,
+ args.xdata.xdata_val,
+ args.xdata.xdata_len, ret,
+ op_errno, out);
+
+ ret = 0;
+ resolve_and_resume (frame, server_finodelk_resume);
+out:
+ free (args.xdata.xdata_val);
+
+ free (args.flock.lk_owner.lk_owner_val);
+
+ if (op_errno)
+ SERVER_REQ_SET_ERROR (req, ret);
+
+ return ret;
+}
+
+
+int
+server3_3_entrylk (rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfs3_entrylk_req args = {{0,},};
+ int ret = -1;
+ int op_errno = 0;
+
+ if (!req)
+ return ret;
+
+ args.volume = alloca (256);
+ args.name = alloca (256);
+
+ ret = xdr_to_generic (req->msg[0], &args,
+ (xdrproc_t)xdr_gfs3_entrylk_req);
+ if (ret < 0) {
+ //failed to decode msg;
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ frame = get_frame_from_request (req);
+ if (!frame) {
+ // something wrong, mostly insufficient memory
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+ frame->root->op = GF_FOP_ENTRYLK;
+
+ state = CALL_STATE (frame);
+ if (!frame->root->client->bound_xl) {
+ /* auth failure, request on subvolume without setvolume */
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_EXACT;
+ memcpy (state->resolve.gfid, args.gfid, 16);
+
+ if (args.namelen)
+ state->name = gf_strdup (args.name);
+ state->volume = gf_strdup (args.volume);
+
+ state->cmd = args.cmd;
+ state->type = args.type;
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl,
+ state->xdata,
+ args.xdata.xdata_val,
+ args.xdata.xdata_len, ret,
+ op_errno, out);
+
+ ret = 0;
+ resolve_and_resume (frame, server_entrylk_resume);
+out:
+ free (args.xdata.xdata_val);
+
+ if (op_errno)
+ SERVER_REQ_SET_ERROR (req, ret);
+
+ return ret;
+}
+
+int
+server3_3_fentrylk (rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfs3_fentrylk_req args = {{0,},};
+ int ret = -1;
+ int op_errno = 0;
+
+ if (!req)
+ return ret;
+
+ args.name = alloca (256);
+ args.volume = alloca (256);
+
+ ret = xdr_to_generic (req->msg[0], &args,
+ (xdrproc_t)xdr_gfs3_fentrylk_req);
+ if (ret < 0) {
+ //failed to decode msg;
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ frame = get_frame_from_request (req);
+ if (!frame) {
+ // something wrong, mostly insufficient memory
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+ frame->root->op = GF_FOP_FENTRYLK;
+
+ state = CALL_STATE (frame);
+ if (!frame->root->client->bound_xl) {
+ /* auth failure, request on subvolume without setvolume */
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_EXACT;
+ state->resolve.fd_no = args.fd;
+ state->cmd = args.cmd;
+ state->type = args.type;
+ memcpy (state->resolve.gfid, args.gfid, 16);
+
+ if (args.namelen)
+ state->name = gf_strdup (args.name);
+ state->volume = gf_strdup (args.volume);
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl,
+ state->xdata,
+ args.xdata.xdata_val,
+ args.xdata.xdata_len, ret,
+ op_errno, out);
+
+ ret = 0;
+ resolve_and_resume (frame, server_fentrylk_resume);
+out:
+ free (args.xdata.xdata_val);
+
+ if (op_errno)
+ SERVER_REQ_SET_ERROR (req, ret);
+
+ return ret;
+}
+
+int
+server3_3_access (rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfs3_access_req args = {{0,},};
+ int ret = -1;
+ int op_errno = 0;
+
+ if (!req)
+ return ret;
+
+ ret = xdr_to_generic (req->msg[0], &args,
+ (xdrproc_t)xdr_gfs3_access_req);
+ if (ret < 0) {
+ //failed to decode msg;
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ frame = get_frame_from_request (req);
+ if (!frame) {
+ // something wrong, mostly insufficient memory
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+ frame->root->op = GF_FOP_ACCESS;
+
+ state = CALL_STATE (frame);
+ if (!frame->root->client->bound_xl) {
+ /* auth failure, request on subvolume without setvolume */
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ memcpy (state->resolve.gfid, args.gfid, 16);
+ state->mask = args.mask;
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl,
+ state->xdata,
+ args.xdata.xdata_val,
+ args.xdata.xdata_len, ret,
+ op_errno, out);
+
+ ret = 0;
+ resolve_and_resume (frame, server_access_resume);
+out:
+ free (args.xdata.xdata_val);
+
+ if (op_errno)
+ SERVER_REQ_SET_ERROR (req, ret);
+
+ return ret;
+}
+
+
+
+int
+server3_3_symlink (rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfs3_symlink_req args = {{0,},};
+ int ret = -1;
+ int op_errno = 0;
+
+ if (!req)
+ return ret;
+
+ args.bname = alloca (req->msg[0].iov_len);
+ args.linkname = alloca (4096);
+
+ ret = xdr_to_generic (req->msg[0], &args,
+ (xdrproc_t)xdr_gfs3_symlink_req);
+ if (ret < 0) {
+ //failed to decode msg;
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ frame = get_frame_from_request (req);
+ if (!frame) {
+ // something wrong, mostly insufficient memory
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+ frame->root->op = GF_FOP_SYMLINK;
+
+ state = CALL_STATE (frame);
+ if (!frame->root->client->bound_xl) {
+ /* auth failure, request on subvolume without setvolume */
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_NOT;
+ memcpy (state->resolve.pargfid, args.pargfid, 16);
+ state->resolve.bname = gf_strdup (args.bname);
+ state->name = gf_strdup (args.linkname);
+ state->umask = args.umask;
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl,
+ state->xdata,
+ args.xdata.xdata_val,
+ args.xdata.xdata_len, ret,
+ op_errno, out);
+
+ ret = 0;
+ resolve_and_resume (frame, server_symlink_resume);
+
+out:
+ if (op_errno)
+ SERVER_REQ_SET_ERROR (req, ret);
+
+ /* memory allocated by libc, don't use GF_FREE */
+ free (args.xdata.xdata_val);
+
+ return ret;
+}
+
+
+
+int
+server3_3_link (rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfs3_link_req args = {{0,},};
+ int ret = -1;
+ int op_errno = 0;
+
+ if (!req)
+ return ret;
+
+ args.newbname = alloca (req->msg[0].iov_len);
+
+ ret = xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_link_req);
+ if (ret < 0) {
+ //failed to decode msg;
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ frame = get_frame_from_request (req);
+ if (!frame) {
+ // something wrong, mostly insufficient memory
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+ frame->root->op = GF_FOP_LINK;
+
+ state = CALL_STATE (frame);
+ if (!frame->root->client->bound_xl) {
+ /* auth failure, request on subvolume without setvolume */
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ memcpy (state->resolve.gfid, args.oldgfid, 16);
+
+ state->resolve2.type = RESOLVE_NOT;
+ state->resolve2.bname = gf_strdup (args.newbname);
+ memcpy (state->resolve2.pargfid, args.newgfid, 16);
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl,
+ state->xdata,
+ args.xdata.xdata_val,
+ args.xdata.xdata_len, ret,
+ op_errno, out);
+
+ ret = 0;
+ resolve_and_resume (frame, server_link_resume);
+out:
+ free (args.xdata.xdata_val);
+
+ if (op_errno)
+ SERVER_REQ_SET_ERROR (req, ret);
+
+ return ret;
+}
+
+
+int
+server3_3_rename (rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfs3_rename_req args = {{0,},};
+ int ret = -1;
+ int op_errno = 0;
+
+ if (!req)
+ return ret;
+
+ args.oldbname = alloca (req->msg[0].iov_len);
+ args.newbname = alloca (req->msg[0].iov_len);
+
+ ret = xdr_to_generic (req->msg[0], &args,
+ (xdrproc_t)xdr_gfs3_rename_req);
+ if (ret < 0) {
+ //failed to decode msg;
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ frame = get_frame_from_request (req);
+ if (!frame) {
+ // something wrong, mostly insufficient memory
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+ frame->root->op = GF_FOP_RENAME;
+
+ state = CALL_STATE (frame);
+ if (!frame->root->client->bound_xl) {
+ /* auth failure, request on subvolume without setvolume */
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ state->resolve.bname = gf_strdup (args.oldbname);
+ memcpy (state->resolve.pargfid, args.oldgfid, 16);
+
+ state->resolve2.type = RESOLVE_MAY;
+ state->resolve2.bname = gf_strdup (args.newbname);
+ memcpy (state->resolve2.pargfid, args.newgfid, 16);
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl,
+ state->xdata,
+ args.xdata.xdata_val,
+ args.xdata.xdata_len, ret,
+ op_errno, out);
+
+ ret = 0;
+ resolve_and_resume (frame, server_rename_resume);
+out:
+ free (args.xdata.xdata_val);
+
+ if (op_errno)
+ SERVER_REQ_SET_ERROR (req, ret);
+
+ return ret;
+}
+
+int
+server3_3_lk (rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfs3_lk_req args = {{0,},};
+ int ret = -1;
+ int op_errno = 0;
+
+ if (!req)
+ return ret;
+
+ ret = xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_lk_req);
+ if (ret < 0) {
+ //failed to decode msg;
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ frame = get_frame_from_request (req);
+ if (!frame) {
+ // something wrong, mostly insufficient memory
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+ frame->root->op = GF_FOP_LK;
+
+ state = CALL_STATE (frame);
+ if (!frame->root->client->bound_xl) {
+ /* auth failure, request on subvolume without setvolume */
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ state->resolve.fd_no = args.fd;
+ state->cmd = args.cmd;
+ state->type = args.type;
+ memcpy (state->resolve.gfid, args.gfid, 16);
+
+ switch (state->cmd) {
+ case GF_LK_GETLK:
+ state->cmd = F_GETLK;
+ break;
+ case GF_LK_SETLK:
+ state->cmd = F_SETLK;
+ break;
+ case GF_LK_SETLKW:
+ state->cmd = F_SETLKW;
+ break;
+ case GF_LK_RESLK_LCK:
+ state->cmd = F_RESLK_LCK;
+ break;
+ case GF_LK_RESLK_LCKW:
+ state->cmd = F_RESLK_LCKW;
+ break;
+ case GF_LK_RESLK_UNLCK:
+ state->cmd = F_RESLK_UNLCK;
+ break;
+ case GF_LK_GETLK_FD:
+ state->cmd = F_GETLK_FD;
+ break;
+
+ }
+
+
+ gf_proto_flock_to_flock (&args.flock, &state->flock);
+
+ switch (state->type) {
+ case GF_LK_F_RDLCK:
+ state->flock.l_type = F_RDLCK;
+ break;
+ case GF_LK_F_WRLCK:
+ state->flock.l_type = F_WRLCK;
+ break;
+ case GF_LK_F_UNLCK:
+ state->flock.l_type = F_UNLCK;
+ break;
+ default:
+ gf_log (frame->root->client->bound_xl->name, GF_LOG_ERROR,
+ "fd - %"PRId64" (%s): Unknown lock type: %"PRId32"!",
+ state->resolve.fd_no,
+ uuid_utoa (state->fd->inode->gfid), state->type);
+ break;
+ }
+
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl,
+ state->xdata,
+ args.xdata.xdata_val,
+ args.xdata.xdata_len, ret,
+ op_errno, out);
+
+ ret = 0;
+ resolve_and_resume (frame, server_lk_resume);
+out:
+ free (args.xdata.xdata_val);
+
+ free (args.flock.lk_owner.lk_owner_val);
+
+ if (op_errno)
+ SERVER_REQ_SET_ERROR (req, ret);
+
+ return ret;
+}
+
+
+int
+server3_3_rchecksum (rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfs3_rchecksum_req args = {0,};
+ int ret = -1;
+ int op_errno = 0;
+
+ if (!req)
+ return ret;
+
+ ret = xdr_to_generic (req->msg[0], &args,
+ (xdrproc_t)xdr_gfs3_rchecksum_req);
+ if (ret < 0) {
+ //failed to decode msg;
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ frame = get_frame_from_request (req);
+ if (!frame) {
+ // something wrong, mostly insufficient memory
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+ frame->root->op = GF_FOP_RCHECKSUM;
+
+ state = CALL_STATE (frame);
+ if (!frame->root->client->bound_xl) {
+ /* auth failure, request on subvolume without setvolume */
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MAY;
+ state->resolve.fd_no = args.fd;
+ state->offset = args.offset;
+ state->size = args.len;
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl,
+ state->xdata,
+ args.xdata.xdata_val,
+ args.xdata.xdata_len, ret,
+ op_errno, out);
+
+ ret = 0;
+ resolve_and_resume (frame, server_rchecksum_resume);
+out:
+ free (args.xdata.xdata_val);
+
+ if (op_errno)
+ SERVER_REQ_SET_ERROR (req, ret);
+
+ return ret;
+}
+
+int
+server_null (rpcsvc_request_t *req)
+{
+ gf_common_rsp rsp = {0,};
+
+ /* Accepted */
+ rsp.op_ret = 0;
+
+ server_submit_reply (NULL, req, &rsp, NULL, 0, NULL,
+ (xdrproc_t)xdr_gf_common_rsp);
+
+ return 0;
+}
+
+int
+server3_3_lookup (rpcsvc_request_t *req)
+{
+ call_frame_t *frame = NULL;
+ server_state_t *state = NULL;
+ gfs3_lookup_req args = {{0,},};
+ int ret = -1;
+ int op_errno = 0;
+
+ GF_VALIDATE_OR_GOTO ("server", req, err);
+
+ args.bname = alloca (req->msg[0].iov_len);
+ args.xdata.xdata_val = alloca (req->msg[0].iov_len);
+
+ ret = xdr_to_generic (req->msg[0], &args,
+ (xdrproc_t)xdr_gfs3_lookup_req);
+ if (ret < 0) {
+ //failed to decode msg;
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto err;
+ }
+
+ frame = get_frame_from_request (req);
+ if (!frame) {
+ // something wrong, mostly insufficient memory
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto err;
+ }
+ frame->root->op = GF_FOP_LOOKUP;
+
+ /* NOTE: lookup() uses req->ino only to identify if a lookup()
+ * is requested for 'root' or not
+ */
+
+ state = CALL_STATE (frame);
+ if (!frame->root->client->bound_xl) {
+ /* auth failure, request on subvolume without setvolume */
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_DONTCARE;
+
+ if (args.bname && strcmp (args.bname, "")) {
+ memcpy (state->resolve.pargfid, args.pargfid, 16);
+ state->resolve.bname = gf_strdup (args.bname);
+ } else {
+ memcpy (state->resolve.gfid, args.gfid, 16);
+ }
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl,
+ state->xdata,
+ args.xdata.xdata_val,
+ args.xdata.xdata_len, ret,
+ op_errno, out);
+
+ ret = 0;
+ resolve_and_resume (frame, server_lookup_resume);
+
+ return ret;
+out:
+
+ server_lookup_cbk (frame, NULL, frame->this, -1, EINVAL, NULL, NULL,
+ NULL, NULL);
+ ret = 0;
+err:
+ return ret;
+}
+
+int
+server3_3_statfs (rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfs3_statfs_req args = {{0,},};
+ int ret = -1;
+ int op_errno = 0;
+
+ if (!req)
+ return ret;
+
+ ret = xdr_to_generic (req->msg[0], &args,
+ (xdrproc_t)xdr_gfs3_statfs_req);
+ if (ret < 0) {
+ //failed to decode msg;
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ frame = get_frame_from_request (req);
+ if (!frame) {
+ // something wrong, mostly insufficient memory
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+ frame->root->op = GF_FOP_STATFS;
+
+ state = CALL_STATE (frame);
+ if (!frame->root->client->bound_xl) {
+ /* auth failure, request on subvolume without setvolume */
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ memcpy (state->resolve.gfid, args.gfid, 16);
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl,
+ state->xdata,
+ args.xdata.xdata_val,
+ args.xdata.xdata_len, ret,
+ op_errno, out);
+
+ ret = 0;
+ resolve_and_resume (frame, server_statfs_resume);
+out:
+ if (op_errno)
+ SERVER_REQ_SET_ERROR (req, ret);
+
+ return ret;
+}
+
+
+rpcsvc_actor_t glusterfs3_3_fop_actors[] = {
+ [GFS3_OP_NULL] = {"NULL", GFS3_OP_NULL, server_null, NULL, 0, DRC_NA},
+ [GFS3_OP_STAT] = {"STAT", GFS3_OP_STAT, server3_3_stat, NULL, 0, DRC_NA},
+ [GFS3_OP_READLINK] = {"READLINK", GFS3_OP_READLINK, server3_3_readlink, NULL, 0, DRC_NA},
+ [GFS3_OP_MKNOD] = {"MKNOD", GFS3_OP_MKNOD, server3_3_mknod, NULL, 0, DRC_NA},
+ [GFS3_OP_MKDIR] = {"MKDIR", GFS3_OP_MKDIR, server3_3_mkdir, NULL, 0, DRC_NA},
+ [GFS3_OP_UNLINK] = {"UNLINK", GFS3_OP_UNLINK, server3_3_unlink, NULL, 0, DRC_NA},
+ [GFS3_OP_RMDIR] = {"RMDIR", GFS3_OP_RMDIR, server3_3_rmdir, NULL, 0, DRC_NA},
+ [GFS3_OP_SYMLINK] = {"SYMLINK", GFS3_OP_SYMLINK, server3_3_symlink, NULL, 0, DRC_NA},
+ [GFS3_OP_RENAME] = {"RENAME", GFS3_OP_RENAME, server3_3_rename, NULL, 0, DRC_NA},
+ [GFS3_OP_LINK] = {"LINK", GFS3_OP_LINK, server3_3_link, NULL, 0, DRC_NA},
+ [GFS3_OP_TRUNCATE] = {"TRUNCATE", GFS3_OP_TRUNCATE, server3_3_truncate, NULL, 0, DRC_NA},
+ [GFS3_OP_OPEN] = {"OPEN", GFS3_OP_OPEN, server3_3_open, NULL, 0, DRC_NA},
+ [GFS3_OP_READ] = {"READ", GFS3_OP_READ, server3_3_readv, NULL, 0, DRC_NA},
+ [GFS3_OP_WRITE] = {"WRITE", GFS3_OP_WRITE, server3_3_writev, server3_3_writev_vecsizer, 0, DRC_NA},
+ [GFS3_OP_STATFS] = {"STATFS", GFS3_OP_STATFS, server3_3_statfs, NULL, 0, DRC_NA},
+ [GFS3_OP_FLUSH] = {"FLUSH", GFS3_OP_FLUSH, server3_3_flush, NULL, 0, DRC_NA},
+ [GFS3_OP_FSYNC] = {"FSYNC", GFS3_OP_FSYNC, server3_3_fsync, NULL, 0, DRC_NA},
+ [GFS3_OP_SETXATTR] = {"SETXATTR", GFS3_OP_SETXATTR, server3_3_setxattr, NULL, 0, DRC_NA},
+ [GFS3_OP_GETXATTR] = {"GETXATTR", GFS3_OP_GETXATTR, server3_3_getxattr, NULL, 0, DRC_NA},
+ [GFS3_OP_REMOVEXATTR] = {"REMOVEXATTR", GFS3_OP_REMOVEXATTR, server3_3_removexattr, NULL, 0, DRC_NA},
+ [GFS3_OP_OPENDIR] = {"OPENDIR", GFS3_OP_OPENDIR, server3_3_opendir, NULL, 0, DRC_NA},
+ [GFS3_OP_FSYNCDIR] = {"FSYNCDIR", GFS3_OP_FSYNCDIR, server3_3_fsyncdir, NULL, 0, DRC_NA},
+ [GFS3_OP_ACCESS] = {"ACCESS", GFS3_OP_ACCESS, server3_3_access, NULL, 0, DRC_NA},
+ [GFS3_OP_CREATE] = {"CREATE", GFS3_OP_CREATE, server3_3_create, NULL, 0, DRC_NA},
+ [GFS3_OP_FTRUNCATE] = {"FTRUNCATE", GFS3_OP_FTRUNCATE, server3_3_ftruncate, NULL, 0, DRC_NA},
+ [GFS3_OP_FSTAT] = {"FSTAT", GFS3_OP_FSTAT, server3_3_fstat, NULL, 0, DRC_NA},
+ [GFS3_OP_LK] = {"LK", GFS3_OP_LK, server3_3_lk, NULL, 0, DRC_NA},
+ [GFS3_OP_LOOKUP] = {"LOOKUP", GFS3_OP_LOOKUP, server3_3_lookup, NULL, 0, DRC_NA},
+ [GFS3_OP_READDIR] = {"READDIR", GFS3_OP_READDIR, server3_3_readdir, NULL, 0, DRC_NA},
+ [GFS3_OP_INODELK] = {"INODELK", GFS3_OP_INODELK, server3_3_inodelk, NULL, 0, DRC_NA},
+ [GFS3_OP_FINODELK] = {"FINODELK", GFS3_OP_FINODELK, server3_3_finodelk, NULL, 0, DRC_NA},
+ [GFS3_OP_ENTRYLK] = {"ENTRYLK", GFS3_OP_ENTRYLK, server3_3_entrylk, NULL, 0, DRC_NA},
+ [GFS3_OP_FENTRYLK] = {"FENTRYLK", GFS3_OP_FENTRYLK, server3_3_fentrylk, NULL, 0, DRC_NA},
+ [GFS3_OP_XATTROP] = {"XATTROP", GFS3_OP_XATTROP, server3_3_xattrop, NULL, 0, DRC_NA},
+ [GFS3_OP_FXATTROP] = {"FXATTROP", GFS3_OP_FXATTROP, server3_3_fxattrop, NULL, 0, DRC_NA},
+ [GFS3_OP_FGETXATTR] = {"FGETXATTR", GFS3_OP_FGETXATTR, server3_3_fgetxattr, NULL, 0, DRC_NA},
+ [GFS3_OP_FSETXATTR] = {"FSETXATTR", GFS3_OP_FSETXATTR, server3_3_fsetxattr, NULL, 0, DRC_NA},
+ [GFS3_OP_RCHECKSUM] = {"RCHECKSUM", GFS3_OP_RCHECKSUM, server3_3_rchecksum, NULL, 0, DRC_NA},
+ [GFS3_OP_SETATTR] = {"SETATTR", GFS3_OP_SETATTR, server3_3_setattr, NULL, 0, DRC_NA},
+ [GFS3_OP_FSETATTR] = {"FSETATTR", GFS3_OP_FSETATTR, server3_3_fsetattr, NULL, 0, DRC_NA},
+ [GFS3_OP_READDIRP] = {"READDIRP", GFS3_OP_READDIRP, server3_3_readdirp, NULL, 0, DRC_NA},
+ [GFS3_OP_RELEASE] = {"RELEASE", GFS3_OP_RELEASE, server3_3_release, NULL, 0, DRC_NA},
+ [GFS3_OP_RELEASEDIR] = {"RELEASEDIR", GFS3_OP_RELEASEDIR, server3_3_releasedir, NULL, 0, DRC_NA},
+ [GFS3_OP_FREMOVEXATTR] = {"FREMOVEXATTR", GFS3_OP_FREMOVEXATTR, server3_3_fremovexattr, NULL, 0, DRC_NA},
+ [GFS3_OP_FALLOCATE] = {"FALLOCATE", GFS3_OP_FALLOCATE, server3_3_fallocate, NULL, 0, DRC_NA},
+ [GFS3_OP_DISCARD] = {"DISCARD", GFS3_OP_DISCARD, server3_3_discard, NULL, 0, DRC_NA},
+ [GFS3_OP_ZEROFILL] = {"ZEROFILL", GFS3_OP_ZEROFILL, server3_3_zerofill, NULL, 0, DRC_NA},
+};
+
+
+struct rpcsvc_program glusterfs3_3_fop_prog = {
+ .progname = "GlusterFS 3.3",
+ .prognum = GLUSTER_FOP_PROGRAM,
+ .progver = GLUSTER_FOP_VERSION,
+ .numactors = GLUSTER_FOP_PROCCNT,
+ .actors = glusterfs3_3_fop_actors,
+};
diff --git a/xlators/protocol/server/src/server.c b/xlators/protocol/server/src/server.c
new file mode 100644
index 000000000..589bd7b36
--- /dev/null
+++ b/xlators/protocol/server/src/server.c
@@ -0,0 +1,1214 @@
+/*
+ Copyright (c) 2010-2013 Red Hat, Inc. <http://www.redhat.com>
+ This file is part of GlusterFS.
+
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
+*/
+
+
+#ifndef _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+#include <sys/time.h>
+#include <sys/resource.h>
+
+
+#include "server.h"
+#include "server-helpers.h"
+#include "glusterfs3-xdr.h"
+#include "call-stub.h"
+#include "statedump.h"
+#include "defaults.h"
+#include "authenticate.h"
+
+void
+grace_time_handler (void *data)
+{
+ client_t *client = NULL;
+ xlator_t *this = NULL;
+ gf_timer_t *timer = NULL;
+ server_ctx_t *serv_ctx = NULL;
+ gf_boolean_t cancelled = _gf_false;
+ gf_boolean_t detached = _gf_false;
+
+ client = data;
+ this = client->this;
+
+ GF_VALIDATE_OR_GOTO (THIS->name, this, out);
+
+ gf_log (this->name, GF_LOG_INFO, "grace timer expired for %s",
+ client->client_uid);
+
+ serv_ctx = server_ctx_get (client, this);
+
+ if (serv_ctx == NULL) {
+ gf_log (this->name, GF_LOG_INFO, "server_ctx_get() failed");
+ goto out;
+ }
+
+ LOCK (&serv_ctx->fdtable_lock);
+ {
+ if (serv_ctx->grace_timer) {
+ timer = serv_ctx->grace_timer;
+ serv_ctx->grace_timer = NULL;
+ }
+ }
+ UNLOCK (&serv_ctx->fdtable_lock);
+ if (timer) {
+ gf_timer_call_cancel (this->ctx, timer);
+ cancelled = _gf_true;
+ }
+ if (cancelled) {
+
+ /*
+ * client must not be destroyed in gf_client_put(),
+ * so take a ref.
+ */
+ gf_client_ref (client);
+ gf_client_put (client, &detached);
+ if (detached)//reconnection did not happen :-(
+ server_connection_cleanup (this, client,
+ INTERNAL_LOCKS | POSIX_LOCKS);
+ gf_client_unref (client);
+ }
+out:
+ return;
+}
+
+struct iobuf *
+gfs_serialize_reply (rpcsvc_request_t *req, void *arg, struct iovec *outmsg,
+ xdrproc_t xdrproc)
+{
+ struct iobuf *iob = NULL;
+ ssize_t retlen = 0;
+ ssize_t xdr_size = 0;
+
+ GF_VALIDATE_OR_GOTO ("server", req, ret);
+
+ /* First, get the io buffer into which the reply in arg will
+ * be serialized.
+ */
+ if (arg && xdrproc) {
+ xdr_size = xdr_sizeof (xdrproc, arg);
+ iob = iobuf_get2 (req->svc->ctx->iobuf_pool, xdr_size);
+ if (!iob) {
+ gf_log_callingfn (THIS->name, GF_LOG_ERROR,
+ "Failed to get iobuf");
+ goto ret;
+ };
+
+ iobuf_to_iovec (iob, outmsg);
+ /* Use the given serializer to translate the give C structure in arg
+ * to XDR format which will be written into the buffer in outmsg.
+ */
+ /* retlen is used to received the error since size_t is unsigned and we
+ * need -1 for error notification during encoding.
+ */
+
+ retlen = xdr_serialize_generic (*outmsg, arg, xdrproc);
+ if (retlen == -1) {
+ /* Failed to Encode 'GlusterFS' msg in RPC is not exactly
+ failure of RPC return values.. client should get
+ notified about this, so there are no missing frames */
+ gf_log_callingfn ("", GF_LOG_ERROR, "Failed to encode message");
+ req->rpc_err = GARBAGE_ARGS;
+ retlen = 0;
+ }
+ }
+ outmsg->iov_len = retlen;
+ret:
+ if (retlen == -1) {
+ iobuf_unref (iob);
+ iob = NULL;
+ }
+
+ return iob;
+}
+
+int
+server_submit_reply (call_frame_t *frame, rpcsvc_request_t *req, void *arg,
+ struct iovec *payload, int payloadcount,
+ struct iobref *iobref, xdrproc_t xdrproc)
+{
+ struct iobuf *iob = NULL;
+ int ret = -1;
+ struct iovec rsp = {0,};
+ server_state_t *state = NULL;
+ char new_iobref = 0;
+ client_t *client = NULL;
+ gf_boolean_t lk_heal = _gf_false;
+ server_conf_t *conf = NULL;
+ gf_barrier_t *barrier = NULL;
+ gf_barrier_payload_t *stub = NULL;
+ gf_boolean_t barriered = _gf_false;
+
+ GF_VALIDATE_OR_GOTO ("server", req, ret);
+
+ if (frame) {
+ state = CALL_STATE (frame);
+ frame->local = NULL;
+ client = frame->root->client;
+ conf = (server_conf_t *) client->this->private;
+ }
+
+ if (client)
+ lk_heal = ((server_conf_t *) client->this->private)->lk_heal;
+
+ if (!iobref) {
+ iobref = iobref_new ();
+ if (!iobref) {
+ goto ret;
+ }
+
+ new_iobref = 1;
+ }
+
+ iob = gfs_serialize_reply (req, arg, &rsp, xdrproc);
+ if (!iob) {
+ gf_log ("", GF_LOG_ERROR, "Failed to serialize reply");
+ goto ret;
+ }
+
+ iobref_add (iobref, iob);
+
+ if (conf)
+ barrier = conf->barrier;
+ if (barrier) {
+ /* todo: write's with fd flags set to O_SYNC and O_DIRECT */
+ LOCK (&barrier->lock);
+ {
+ if (is_fop_barriered (barrier->fops, req->procnum) &&
+ (barrier_add_to_queue (barrier))) {
+ stub = gf_barrier_payload (req, &rsp, frame,
+ payload,
+ payloadcount, iobref,
+ iob, new_iobref);
+ if (stub) {
+ gf_barrier_enqueue (barrier, stub);
+ barriered = _gf_true;
+ } else {
+ gf_log ("", GF_LOG_ERROR, "Failed to "
+ " barrier fop %"PRIu64,
+ ((uint64_t)1 << req->procnum));
+ }
+ }
+ }
+ UNLOCK (&barrier->lock);
+ if (barriered == _gf_true)
+ goto out;
+ }
+ /* Then, submit the message for transmission. */
+ ret = rpcsvc_submit_generic (req, &rsp, 1, payload, payloadcount,
+ iobref);
+
+ /* TODO: this is demo purpose only */
+ /* ret = rpcsvc_callback_submit (req->svc, req->trans, req->prog,
+ GF_CBK_NULL, &rsp, 1);
+ */
+ /* Now that we've done our job of handing the message to the RPC layer
+ * we can safely unref the iob in the hope that RPC layer must have
+ * ref'ed the iob on receiving into the txlist.
+ */
+ iobuf_unref (iob);
+ if (ret == -1) {
+ gf_log_callingfn ("", GF_LOG_ERROR, "Reply submission failed");
+ if (frame && client && !lk_heal) {
+ server_connection_cleanup (frame->this, client,
+ INTERNAL_LOCKS | POSIX_LOCKS);
+ } else {
+ gf_log_callingfn ("", GF_LOG_ERROR,
+ "Reply submission failed");
+ /* TODO: Failure of open(dir), create, inodelk, entrylk
+ or lk fops send failure must be handled specially. */
+ }
+ goto ret;
+ }
+
+ ret = 0;
+ret:
+ if (state) {
+ free_state (state);
+ }
+
+ if (frame) {
+ gf_client_unref (client);
+ STACK_DESTROY (frame->root);
+ }
+
+ if (new_iobref) {
+ iobref_unref (iobref);
+ }
+out:
+ return ret;
+}
+
+
+int
+server_priv_to_dict (xlator_t *this, dict_t *dict)
+{
+ server_conf_t *conf = NULL;
+ rpc_transport_t *xprt = NULL;
+ peer_info_t *peerinfo = NULL;
+ char key[32] = {0,};
+ int count = 0;
+ int ret = -1;
+
+ GF_VALIDATE_OR_GOTO (THIS->name, this, out);
+ GF_VALIDATE_OR_GOTO (THIS->name, dict, out);
+
+ conf = this->private;
+ if (!conf)
+ return 0;
+ //TODO: Dump only specific info to dict
+
+ pthread_mutex_lock (&conf->mutex);
+ {
+ list_for_each_entry (xprt, &conf->xprt_list, list) {
+ peerinfo = &xprt->peerinfo;
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "client%d.hostname",
+ count);
+ ret = dict_set_str (dict, key, peerinfo->identifier);
+ if (ret)
+ goto unlock;
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "client%d.bytesread",
+ count);
+ ret = dict_set_uint64 (dict, key,
+ xprt->total_bytes_read);
+ if (ret)
+ goto unlock;
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "client%d.byteswrite",
+ count);
+ ret = dict_set_uint64 (dict, key,
+ xprt->total_bytes_write);
+ if (ret)
+ goto unlock;
+
+ count++;
+ }
+ }
+unlock:
+ pthread_mutex_unlock (&conf->mutex);
+ if (ret)
+ goto out;
+
+ ret = dict_set_int32 (dict, "clientcount", count);
+
+out:
+ return ret;
+}
+
+int
+server_priv (xlator_t *this)
+{
+ server_conf_t *conf = NULL;
+ rpc_transport_t *xprt = NULL;
+ char key[GF_DUMP_MAX_BUF_LEN] = {0,};
+ uint64_t total_read = 0;
+ uint64_t total_write = 0;
+ int32_t ret = -1;
+
+ GF_VALIDATE_OR_GOTO ("server", this, out);
+
+ conf = this->private;
+ if (!conf)
+ return 0;
+
+ gf_proc_dump_build_key (key, "xlator.protocol.server", "priv");
+ gf_proc_dump_add_section (key);
+
+ ret = pthread_mutex_trylock (&conf->mutex);
+ if (ret != 0)
+ goto out;
+ {
+ list_for_each_entry (xprt, &conf->xprt_list, list) {
+ total_read += xprt->total_bytes_read;
+ total_write += xprt->total_bytes_write;
+ }
+ }
+ pthread_mutex_unlock (&conf->mutex);
+
+ gf_proc_dump_build_key(key, "server", "total-bytes-read");
+ gf_proc_dump_write(key, "%"PRIu64, total_read);
+
+ gf_proc_dump_build_key(key, "server", "total-bytes-write");
+ gf_proc_dump_write(key, "%"PRIu64, total_write);
+
+ ret = 0;
+out:
+ if (ret)
+ gf_proc_dump_write ("Unable to print priv",
+ "(Lock acquisition failed) %s",
+ this?this->name:"server");
+
+ return ret;
+}
+
+
+static int
+get_auth_types (dict_t *this, char *key, data_t *value, void *data)
+{
+ dict_t *auth_dict = NULL;
+ char *saveptr = NULL;
+ char *tmp = NULL;
+ char *key_cpy = NULL;
+ int32_t ret = -1;
+
+ GF_VALIDATE_OR_GOTO ("server", this, out);
+ GF_VALIDATE_OR_GOTO ("server", key, out);
+ GF_VALIDATE_OR_GOTO ("server", data, out);
+
+ auth_dict = data;
+ key_cpy = gf_strdup (key);
+ GF_VALIDATE_OR_GOTO("server", key_cpy, out);
+
+ tmp = strtok_r (key_cpy, ".", &saveptr);
+ ret = strcmp (tmp, "auth");
+ if (ret == 0) {
+ tmp = strtok_r (NULL, ".", &saveptr);
+ if (strcmp (tmp, "ip") == 0) {
+ /* TODO: backward compatibility, remove when
+ newer versions are available */
+ tmp = "addr";
+ gf_log ("server", GF_LOG_WARNING,
+ "assuming 'auth.ip' to be 'auth.addr'");
+ }
+ ret = dict_set_dynptr (auth_dict, tmp, NULL, 0);
+ if (ret < 0) {
+ gf_log ("server", GF_LOG_DEBUG,
+ "failed to dict_set_dynptr");
+ }
+ }
+
+ GF_FREE (key_cpy);
+out:
+ return 0;
+}
+
+int
+_check_for_auth_option (dict_t *d, char *k, data_t *v,
+ void *tmp)
+{
+ int ret = 0;
+ xlator_t *xl = NULL;
+ char *tail = NULL;
+ char *tmp_addr_list = NULL;
+ char *addr = NULL;
+ char *tmp_str = NULL;
+
+ xl = tmp;
+
+ tail = strtail (k, "auth.");
+ if (!tail)
+ goto out;
+
+ /* fast fwd thru module type */
+ tail = strchr (tail, '.');
+ if (!tail)
+ goto out;
+ tail++;
+
+ tail = strtail (tail, xl->name);
+ if (!tail)
+ goto out;
+
+ if (*tail == '.') {
+ /* when we are here, the key is checked for
+ * valid auth.allow.<xlator>
+ * Now we verify the ip address
+ */
+ if (!strcmp (v->data, "*")) {
+ ret = 0;
+ goto out;
+ }
+
+ tmp_addr_list = gf_strdup (v->data);
+ addr = strtok_r (tmp_addr_list, ",", &tmp_str);
+ if (!addr)
+ addr = v->data;
+
+ while (addr) {
+ if (valid_internet_address (addr, _gf_true)) {
+ ret = 0;
+ } else {
+ ret = -1;
+ gf_log (xl->name, GF_LOG_ERROR,
+ "internet address '%s'"
+ " does not conform to"
+ " standards.", addr);
+ goto out;
+ }
+ if (tmp_str)
+ addr = strtok_r (NULL, ",", &tmp_str);
+ else
+ addr = NULL;
+ }
+
+ GF_FREE (tmp_addr_list);
+ tmp_addr_list = NULL;
+ }
+out:
+ return ret;
+}
+
+int
+validate_auth_options (xlator_t *this, dict_t *dict)
+{
+ int error = -1;
+ xlator_list_t *trav = NULL;
+
+ GF_VALIDATE_OR_GOTO ("server", this, out);
+ GF_VALIDATE_OR_GOTO ("server", dict, out);
+
+ trav = this->children;
+ while (trav) {
+ error = dict_foreach (dict, _check_for_auth_option,
+ trav->xlator);
+
+ if (-1 == error) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "volume '%s' defined as subvolume, but no "
+ "authentication defined for the same",
+ trav->xlator->name);
+ break;
+ }
+ trav = trav->next;
+ }
+
+out:
+ return error;
+}
+
+
+int
+server_rpc_notify (rpcsvc_t *rpc, void *xl, rpcsvc_event_t event,
+ void *data)
+{
+ gf_boolean_t detached = _gf_false;
+ xlator_t *this = NULL;
+ rpc_transport_t *trans = NULL;
+ server_conf_t *conf = NULL;
+ client_t *client = NULL;
+ server_ctx_t *serv_ctx = NULL;
+
+ if (!xl || !data) {
+ gf_log_callingfn ("server", GF_LOG_WARNING,
+ "Calling rpc_notify without initializing");
+ goto out;
+ }
+
+ this = xl;
+ trans = data;
+ conf = this->private;
+
+ switch (event) {
+ case RPCSVC_EVENT_ACCEPT:
+ {
+ /* Have a structure per new connection */
+ /* TODO: Should we create anything here at all ? * /
+ client->conn = create_server_conn_state (this, trans);
+ if (!client->conn)
+ goto out;
+
+ trans->protocol_private = client->conn;
+ */
+ INIT_LIST_HEAD (&trans->list);
+
+ pthread_mutex_lock (&conf->mutex);
+ {
+ list_add_tail (&trans->list, &conf->xprt_list);
+ }
+ pthread_mutex_unlock (&conf->mutex);
+
+ break;
+ }
+ case RPCSVC_EVENT_DISCONNECT:
+ /* transport has to be removed from the list upon disconnect
+ * irrespective of whether lock self heal is off or on, since
+ * new transport will be created upon reconnect.
+ */
+ pthread_mutex_lock (&conf->mutex);
+ {
+ list_del_init (&trans->list);
+ }
+ pthread_mutex_unlock (&conf->mutex);
+
+ client = trans->xl_private;
+ if (!client)
+ break;
+
+ gf_log (this->name, GF_LOG_INFO, "disconnecting connection"
+ "from %s", client->client_uid);
+
+ /* If lock self heal is off, then destroy the
+ conn object, else register a grace timer event */
+ if (!conf->lk_heal) {
+ gf_client_ref (client);
+ gf_client_put (client, &detached);
+ if (detached)
+ server_connection_cleanup (this, client,
+ INTERNAL_LOCKS | POSIX_LOCKS);
+ gf_client_unref (client);
+ break;
+ }
+ trans->xl_private = NULL;
+ server_connection_cleanup (this, client, INTERNAL_LOCKS);
+
+ serv_ctx = server_ctx_get (client, this);
+
+ if (serv_ctx == NULL) {
+ gf_log (this->name, GF_LOG_INFO,
+ "server_ctx_get() failed");
+ goto out;
+ }
+
+ LOCK (&serv_ctx->fdtable_lock);
+ {
+ if (!serv_ctx->grace_timer) {
+
+ gf_log (this->name, GF_LOG_INFO,
+ "starting a grace timer for %s",
+ client->client_uid);
+
+ serv_ctx->grace_timer =
+ gf_timer_call_after (this->ctx,
+ conf->grace_ts,
+ grace_time_handler,
+ client);
+ }
+ }
+ UNLOCK (&serv_ctx->fdtable_lock);
+ break;
+ case RPCSVC_EVENT_TRANSPORT_DESTROY:
+ /*- conn obj has been disassociated from trans on first
+ * disconnect.
+ * conn cleanup and destruction is handed over to
+ * grace_time_handler or the subsequent handler that 'owns'
+ * the conn. Nothing left to be done here. */
+ break;
+ default:
+ break;
+ }
+
+out:
+ return 0;
+}
+
+int32_t
+mem_acct_init (xlator_t *this)
+{
+ int ret = -1;
+
+ GF_VALIDATE_OR_GOTO ("server", this, out);
+
+ ret = xlator_mem_acct_init (this, gf_server_mt_end + 1);
+
+ if (ret != 0) {
+ gf_log (this->name, GF_LOG_ERROR, "Memory accounting init"
+ "failed");
+ return ret;
+ }
+out:
+ return ret;
+}
+
+
+static int
+_delete_auth_opt (dict_t *this, char *key, data_t *value, void *data)
+{
+ char *auth_option_pattern[] = { "auth.addr.*.allow",
+ "auth.addr.*.reject",
+ NULL};
+ int i = 0;
+
+ for (i = 0; auth_option_pattern[i]; i++) {
+ if (fnmatch (auth_option_pattern[i], key, 0) == 0) {
+ dict_del (this, key);
+ break;
+ }
+ }
+
+ return 0;
+}
+
+
+static int
+_copy_auth_opt (dict_t *unused, char *key, data_t *value, void *xl_dict)
+{
+ char *auth_option_pattern[] = { "auth.addr.*.allow",
+ "auth.addr.*.reject",
+ NULL};
+ int i = 0;
+
+ for (i = 0; auth_option_pattern [i]; i++) {
+ if (fnmatch (auth_option_pattern[i], key, 0) == 0) {
+ dict_set ((dict_t *)xl_dict, key, value);
+ break;
+ }
+ }
+
+ return 0;
+}
+
+
+int
+server_init_grace_timer (xlator_t *this, dict_t *options,
+ server_conf_t *conf)
+{
+ int32_t ret = -1;
+ int32_t grace_timeout = -1;
+ char *lk_heal = NULL;
+
+ GF_VALIDATE_OR_GOTO ("server", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, options, out);
+ GF_VALIDATE_OR_GOTO (this->name, conf, out);
+
+ conf->lk_heal = _gf_false;
+
+ ret = dict_get_str (options, "lk-heal", &lk_heal);
+ if (!ret)
+ gf_string2boolean (lk_heal, &conf->lk_heal);
+
+ gf_log (this->name, GF_LOG_DEBUG, "lk-heal = %s",
+ (conf->lk_heal) ? "on" : "off");
+
+ ret = dict_get_int32 (options, "grace-timeout", &grace_timeout);
+ if (!ret)
+ conf->grace_ts.tv_sec = grace_timeout;
+ else
+ conf->grace_ts.tv_sec = 10;
+
+ gf_log (this->name, GF_LOG_DEBUG, "Server grace timeout "
+ "value = %"PRIu64, conf->grace_ts.tv_sec);
+
+ conf->grace_ts.tv_nsec = 0;
+
+ ret = 0;
+out:
+ return ret;
+}
+
+int
+reconfigure (xlator_t *this, dict_t *options)
+{
+
+ server_conf_t *conf =NULL;
+ rpcsvc_t *rpc_conf;
+ rpcsvc_listener_t *listeners;
+ int inode_lru_limit;
+ gf_boolean_t trace;
+ data_t *data;
+ int ret = 0;
+ char *statedump_path = NULL;
+ conf = this->private;
+
+ if (!conf) {
+ gf_log_callingfn (this->name, GF_LOG_DEBUG, "conf == null!!!");
+ goto out;
+ }
+ if (dict_get_int32 ( options, "inode-lru-limit", &inode_lru_limit) == 0){
+ conf->inode_lru_limit = inode_lru_limit;
+ gf_log (this->name, GF_LOG_TRACE, "Reconfigured inode-lru-limit"
+ " to %d", conf->inode_lru_limit);
+ }
+
+ data = dict_get (options, "trace");
+ if (data) {
+ ret = gf_string2boolean (data->data, &trace);
+ if (ret != 0) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "'trace' takes on only boolean values. "
+ "Neglecting option");
+ ret = -1;
+ goto out;
+ }
+ conf->trace = trace;
+ gf_log (this->name, GF_LOG_TRACE, "Reconfigured trace"
+ " to %d", conf->trace);
+
+ }
+
+ GF_OPTION_RECONF ("statedump-path", statedump_path,
+ options, path, out);
+ if (!statedump_path) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Error while reconfiguring statedump path");
+ ret = -1;
+ goto out;
+ }
+ gf_path_strip_trailing_slashes (statedump_path);
+ GF_FREE (this->ctx->statedump_path);
+ this->ctx->statedump_path = gf_strdup (statedump_path);
+
+ if (!conf->auth_modules)
+ conf->auth_modules = dict_new ();
+
+ dict_foreach (options, get_auth_types, conf->auth_modules);
+ ret = validate_auth_options (this, options);
+ if (ret == -1) {
+ /* logging already done in validate_auth_options function. */
+ goto out;
+ }
+ dict_foreach (this->options, _delete_auth_opt, this->options);
+ dict_foreach (options, _copy_auth_opt, this->options);
+
+ ret = gf_auth_init (this, conf->auth_modules);
+ if (ret) {
+ dict_unref (conf->auth_modules);
+ goto out;
+ }
+
+ rpc_conf = conf->rpc;
+ if (!rpc_conf) {
+ gf_log (this->name, GF_LOG_ERROR, "No rpc_conf !!!!");
+ goto out;
+ }
+
+ (void) rpcsvc_set_allow_insecure (rpc_conf, options);
+ (void) rpcsvc_set_root_squash (rpc_conf, options);
+ (void) rpcsvc_set_outstanding_rpc_limit (rpc_conf, options);
+ list_for_each_entry (listeners, &(rpc_conf->listeners), list) {
+ if (listeners->trans != NULL) {
+ if (listeners->trans->reconfigure )
+ listeners->trans->reconfigure (listeners->trans, options);
+ else
+ gf_log (this->name, GF_LOG_ERROR,
+ "Reconfigure not found for transport" );
+ }
+ }
+ ret = server_init_grace_timer (this, options, conf);
+
+out:
+ gf_log ("", GF_LOG_DEBUG, "returning %d", ret);
+ return ret;
+}
+
+static int32_t
+client_destroy_cbk (xlator_t *this, client_t *client)
+{
+ void *tmp = NULL;
+ server_ctx_t *ctx = NULL;
+
+ client_ctx_del (client, this, &tmp);
+
+ ctx = tmp;
+
+ if (ctx == NULL)
+ return 0;
+
+ gf_fd_fdtable_destroy (ctx->fdtable);
+ LOCK_DESTROY (&ctx->fdtable_lock);
+ GF_FREE (ctx);
+
+ return 0;
+}
+
+int
+init (xlator_t *this)
+{
+ int32_t ret = -1;
+ server_conf_t *conf = NULL;
+ rpcsvc_listener_t *listener = NULL;
+ char *statedump_path = NULL;
+ gf_barrier_t *barrier = NULL;
+ char *str = NULL;
+ GF_VALIDATE_OR_GOTO ("init", this, out);
+
+ if (this->children == NULL) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "protocol/server should have subvolume");
+ goto out;
+ }
+
+ if (this->parents != NULL) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "protocol/server should not have parent volumes");
+ goto out;
+ }
+
+ conf = GF_CALLOC (1, sizeof (server_conf_t),
+ gf_server_mt_server_conf_t);
+
+ GF_VALIDATE_OR_GOTO(this->name, conf, out);
+
+ INIT_LIST_HEAD (&conf->xprt_list);
+ pthread_mutex_init (&conf->mutex, NULL);
+
+ ret = server_init_grace_timer (this, this->options, conf);
+ if (ret)
+ goto out;
+
+ ret = server_build_config (this, conf);
+ if (ret)
+ goto out;
+
+ ret = dict_get_str (this->options, "config-directory", &conf->conf_dir);
+ if (ret)
+ conf->conf_dir = CONFDIR;
+
+ /*ret = dict_get_str (this->options, "statedump-path", &statedump_path);
+ if (!ret) {
+ gf_path_strip_trailing_slashes (statedump_path);
+ this->ctx->statedump_path = statedump_path;
+ }*/
+ GF_OPTION_INIT ("statedump-path", statedump_path, path, out);
+ if (statedump_path) {
+ gf_path_strip_trailing_slashes (statedump_path);
+ this->ctx->statedump_path = gf_strdup (statedump_path);
+ } else {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Error setting statedump path");
+ ret = -1;
+ goto out;
+ }
+
+ /* Authentication modules */
+ conf->auth_modules = dict_new ();
+ GF_VALIDATE_OR_GOTO(this->name, conf->auth_modules, out);
+
+ dict_foreach (this->options, get_auth_types, conf->auth_modules);
+ ret = validate_auth_options (this, this->options);
+ if (ret == -1) {
+ /* logging already done in validate_auth_options function. */
+ goto out;
+ }
+
+ ret = gf_auth_init (this, conf->auth_modules);
+ if (ret) {
+ dict_unref (conf->auth_modules);
+ goto out;
+ }
+
+ /* RPC related */
+ conf->rpc = rpcsvc_init (this, this->ctx, this->options, 0);
+ if (conf->rpc == NULL) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "creation of rpcsvc failed");
+ ret = -1;
+ goto out;
+ }
+
+ ret = rpcsvc_create_listeners (conf->rpc, this->options,
+ this->name);
+ if (ret < 1) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "creation of listener failed");
+ ret = -1;
+ goto out;
+ }
+
+ ret = rpcsvc_register_notify (conf->rpc, server_rpc_notify, this);
+ if (ret) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "registration of notify with rpcsvc failed");
+ goto out;
+ }
+
+ glusterfs3_3_fop_prog.options = this->options;
+ ret = rpcsvc_program_register (conf->rpc, &glusterfs3_3_fop_prog);
+ if (ret) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "registration of program (name:%s, prognum:%d, "
+ "progver:%d) failed", glusterfs3_3_fop_prog.progname,
+ glusterfs3_3_fop_prog.prognum,
+ glusterfs3_3_fop_prog.progver);
+ goto out;
+ }
+
+ gluster_handshake_prog.options = this->options;
+ ret = rpcsvc_program_register (conf->rpc, &gluster_handshake_prog);
+ if (ret) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "registration of program (name:%s, prognum:%d, "
+ "progver:%d) failed", gluster_handshake_prog.progname,
+ gluster_handshake_prog.prognum,
+ gluster_handshake_prog.progver);
+ rpcsvc_program_unregister (conf->rpc, &glusterfs3_3_fop_prog);
+ goto out;
+ }
+
+#ifndef GF_DARWIN_HOST_OS
+ {
+ struct rlimit lim;
+
+ lim.rlim_cur = 1048576;
+ lim.rlim_max = 1048576;
+
+ if (setrlimit (RLIMIT_NOFILE, &lim) == -1) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "WARNING: Failed to set 'ulimit -n 1M': %s",
+ strerror(errno));
+ lim.rlim_cur = 65536;
+ lim.rlim_max = 65536;
+
+ if (setrlimit (RLIMIT_NOFILE, &lim) == -1) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "Failed to set max open fd to 64k: %s",
+ strerror(errno));
+ } else {
+ gf_log (this->name, GF_LOG_TRACE,
+ "max open fd set to 64k");
+ }
+ }
+ }
+#endif
+ /* barrier related */
+ barrier = GF_CALLOC (1, sizeof (*barrier),1);
+ if (!barrier) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "WARNING: Failed to allocate barrier");
+ ret = -1;
+ goto out;
+ }
+
+ LOCK_INIT (&barrier->lock);
+ INIT_LIST_HEAD (&barrier->queue);
+ barrier->on = _gf_false;
+
+ GF_OPTION_INIT ("barrier-queue-length", barrier->max_size,
+ int64, out);
+ GF_OPTION_INIT ("barrier-timeout", barrier->time_out,
+ uint64, out);
+
+ ret = dict_get_str (this->options, "barrier-fops", &str);
+ if (ret) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "setting barrier fops to default value");
+ }
+ ret = gf_barrier_fops_configure (this, barrier, str);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "invalid barrier fops specified");
+ goto out;
+ }
+
+ conf->barrier = barrier;
+ this->private = conf;
+
+ ret = 0;
+out:
+ if (ret) {
+ if (this != NULL) {
+ this->fini (this);
+ }
+
+ if (listener != NULL) {
+ rpcsvc_listener_destroy (listener);
+ }
+ }
+
+ return ret;
+}
+
+
+void
+fini (xlator_t *this)
+{
+#if 0
+ server_conf_t *conf = NULL;
+
+ conf = this->private;
+
+ if (conf) {
+ if (conf->rpc) {
+ /* TODO: memory leak here, have to free RPC */
+ /*
+ if (conf->rpc->conn) {
+ rpcsvc_conn_destroy (conf->rpc->conn);
+ }
+ rpcsvc_fini (conf->rpc);
+ */
+ ;
+ }
+
+ if (conf->auth_modules)
+ dict_unref (conf->auth_modules);
+
+ GF_FREE (conf);
+ }
+
+ this->private = NULL;
+#endif
+ return;
+}
+
+int
+notify (xlator_t *this, int32_t event, void *data, ...)
+{
+ int ret = 0;
+ int32_t val = 0;
+ dict_t *dict = NULL;
+ dict_t *output = NULL;
+ va_list ap;
+
+ dict = data;
+ va_start (ap, data);
+ output = va_arg (ap, dict_t*);
+ va_end (ap);
+
+ switch (event) {
+ case GF_EVENT_VOLUME_BARRIER_OP:
+ ret = dict_get_int32 (dict, "barrier", &val);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Wrong BARRIER event");
+ goto out;
+ }
+ /* !val un-barrier, if val, barrier */
+ if (val) {
+ ret = gf_barrier_start (this);
+ if (ret)
+ gf_log (this->name, GF_LOG_ERROR,
+ "Barrier start failed");
+ } else {
+ ret = gf_barrier_stop (this);
+ if (ret)
+ gf_log (this->name, GF_LOG_ERROR,
+ "Barrier stop failed");
+ }
+ ret = dict_set_int32 (output, "barrier-status", ret);
+ if (ret)
+ gf_log (this->name, GF_LOG_ERROR,
+ "Failed to set barrier-status in dict");
+ break;
+
+ /* todo: call default_notify to make other xlators handle it.*/
+ default:
+ default_notify (this, event, data);
+ break;
+ }
+out:
+ return ret;
+}
+
+
+struct xlator_fops fops;
+
+struct xlator_cbks cbks = {
+ .client_destroy = client_destroy_cbk,
+};
+
+struct xlator_dumpops dumpops = {
+ .priv = server_priv,
+ .fd = gf_client_dump_fdtables,
+ .inode = gf_client_dump_inodes,
+ .priv_to_dict = server_priv_to_dict,
+ .fd_to_dict = gf_client_dump_fdtables_to_dict,
+ .inode_to_dict = gf_client_dump_inodes_to_dict,
+};
+
+
+struct volume_options options[] = {
+ { .key = {"transport-type"},
+ .value = {"rpc", "rpc-over-rdma", "tcp", "socket", "ib-verbs",
+ "unix", "ib-sdp", "tcp/server", "ib-verbs/server", "rdma",
+ "rdma*([ \t]),*([ \t])socket",
+ "rdma*([ \t]),*([ \t])tcp",
+ "tcp*([ \t]),*([ \t])rdma",
+ "socket*([ \t]),*([ \t])rdma"},
+ .type = GF_OPTION_TYPE_STR
+ },
+ { .key = {"volume-filename.*"},
+ .type = GF_OPTION_TYPE_PATH,
+ },
+ { .key = {"transport.*"},
+ .type = GF_OPTION_TYPE_ANY,
+ },
+ { .key = {"rpc*"},
+ .type = GF_OPTION_TYPE_ANY,
+ },
+ { .key = {"inode-lru-limit"},
+ .type = GF_OPTION_TYPE_INT,
+ .min = 0,
+ .max = (1 * GF_UNIT_MB),
+ .default_value = "16384",
+ .description = "Specifies the maximum megabytes of memory to be "
+ "used in the inode cache."
+ },
+ { .key = {"verify-volfile-checksum"},
+ .type = GF_OPTION_TYPE_BOOL
+ },
+ { .key = {"trace"},
+ .type = GF_OPTION_TYPE_BOOL
+ },
+ { .key = {"config-directory",
+ "conf-dir"},
+ .type = GF_OPTION_TYPE_PATH,
+ },
+ { .key = {"rpc-auth-allow-insecure"},
+ .type = GF_OPTION_TYPE_BOOL,
+ },
+ { .key = {"root-squash"},
+ .type = GF_OPTION_TYPE_BOOL,
+ .default_value = "off",
+ .description = "Map requests from uid/gid 0 to the anonymous "
+ "uid/gid. Note that this does not apply to any other"
+ "uids or gids that might be equally sensitive, such as"
+ "user bin or group staff."
+ },
+ { .key = {"statedump-path"},
+ .type = GF_OPTION_TYPE_PATH,
+ .default_value = DEFAULT_VAR_RUN_DIRECTORY,
+ .description = "Specifies directory in which gluster should save its"
+ " statedumps. By default it is the /tmp directory"
+ },
+ { .key = {"lk-heal"},
+ .type = GF_OPTION_TYPE_BOOL,
+ .default_value = "off",
+ },
+ {.key = {"grace-timeout"},
+ .type = GF_OPTION_TYPE_INT,
+ .min = 10,
+ .max = 1800,
+ },
+ {.key = {"tcp-window-size"},
+ .type = GF_OPTION_TYPE_SIZET,
+ .min = GF_MIN_SOCKET_WINDOW_SIZE,
+ .max = GF_MAX_SOCKET_WINDOW_SIZE,
+ .description = "Specifies the window size for tcp socket."
+ },
+
+ /* The following two options are defined in addr.c, redifined here *
+ * for the sake of validation during volume set from cli */
+
+ { .key = {"auth.addr.*.allow"},
+ .type = GF_OPTION_TYPE_INTERNET_ADDRESS_LIST,
+ .description = "Allow a comma separated list of addresses and/or "
+ "hostnames to connect to the server. By default, all"
+ " connections are allowed."
+ },
+ { .key = {"auth.addr.*.reject"},
+ .type = GF_OPTION_TYPE_INTERNET_ADDRESS_LIST,
+ .description = "Reject a comma separated list of addresses and/or "
+ "hostnames to connect to the server. By default, all"
+ " connections are allowed."
+ },
+ {.key = {"barrier-timeout"},
+ .type = GF_OPTION_TYPE_INT,
+ .default_value = "60",
+ .min = 0,
+ .max = 360,
+ .description = "Barrier timeout in seconds",
+ },
+ {.key = {"barrier-queue-length"},
+ .type = GF_OPTION_TYPE_INT,
+ .default_value = "4096",
+ .min = 0,
+ .max = 16384,
+ .description = "Barrier queue length",
+ },
+ {.key = {"barrier-fops"},
+ .type = GF_OPTION_TYPE_STR,
+ .description = "Allow a comma seperated fop lists",
+ },
+ { .key = {NULL} },
+};
diff --git a/xlators/protocol/server/src/server.h b/xlators/protocol/server/src/server.h
new file mode 100644
index 000000000..782327d77
--- /dev/null
+++ b/xlators/protocol/server/src/server.h
@@ -0,0 +1,196 @@
+/*
+ Copyright (c) 2010-2013 Red Hat, Inc. <http://www.redhat.com>
+ This file is part of GlusterFS.
+
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
+*/
+
+#ifndef _SERVER_H
+#define _SERVER_H
+
+#include <pthread.h>
+
+#include "fd.h"
+#include "rpcsvc.h"
+
+#include "fd.h"
+#include "protocol-common.h"
+#include "server-mem-types.h"
+#include "glusterfs3.h"
+#include "timer.h"
+#include "client_t.h"
+
+#define DEFAULT_BLOCK_SIZE 4194304 /* 4MB */
+#define DEFAULT_VOLUME_FILE_PATH CONFDIR "/glusterfs.vol"
+#define GF_MAX_SOCKET_WINDOW_SIZE (1 * GF_UNIT_MB)
+#define GF_MIN_SOCKET_WINDOW_SIZE (0)
+
+struct _gf_barrier_payload {
+ rpcsvc_request_t *req;
+ struct iovec rsp;
+ call_frame_t *frame;
+ struct iovec *payload;
+ struct iobref *iobref;
+ struct iobuf *iob;
+ int payload_count;
+ gf_boolean_t free_iobref;
+ struct list_head list;
+};
+
+typedef struct _gf_barrier_payload gf_barrier_payload_t;
+
+struct _gf_barrier {
+ gf_lock_t lock;
+ gf_boolean_t on;
+ gf_boolean_t force;
+ size_t cur_size;
+ int64_t max_size;
+ uint64_t fops;
+ gf_timer_t *timer;
+ uint64_t time_out;
+ struct list_head queue;
+};
+
+typedef struct _gf_barrier gf_barrier_t;
+
+typedef enum {
+ INTERNAL_LOCKS = 1,
+ POSIX_LOCKS = 2,
+} server_lock_flags_t;
+
+typedef struct _server_state server_state_t;
+
+int server_null (rpcsvc_request_t *req);
+
+struct _volfile_ctx {
+ struct _volfile_ctx *next;
+ char *key;
+ uint32_t checksum;
+};
+
+struct server_conf {
+ rpcsvc_t *rpc;
+ struct rpcsvc_config rpc_conf;
+ int inode_lru_limit;
+ gf_boolean_t verify_volfile;
+ gf_boolean_t trace;
+ gf_boolean_t lk_heal; /* If true means lock self
+ heal is on else off. */
+ char *conf_dir;
+ struct _volfile_ctx *volfile;
+ struct timespec grace_ts;
+ dict_t *auth_modules;
+ pthread_mutex_t mutex;
+ gf_barrier_t *barrier;
+ struct list_head xprt_list;
+ pthread_t barrier_th;
+};
+typedef struct server_conf server_conf_t;
+
+
+typedef enum {
+ RESOLVE_MUST = 1,
+ RESOLVE_NOT,
+ RESOLVE_MAY,
+ RESOLVE_DONTCARE,
+ RESOLVE_EXACT
+} server_resolve_type_t;
+
+
+struct resolve_comp {
+ char *basename;
+ inode_t *inode;
+};
+
+typedef struct {
+ server_resolve_type_t type;
+ int64_t fd_no;
+ u_char gfid[16];
+ u_char pargfid[16];
+ char *path;
+ char *bname;
+ int op_ret;
+ int op_errno;
+ loc_t resolve_loc;
+} server_resolve_t;
+
+
+typedef int (*server_resume_fn_t) (call_frame_t *frame, xlator_t *bound_xl);
+
+int
+resolve_and_resume (call_frame_t *frame, server_resume_fn_t fn);
+
+struct _server_state {
+ rpc_transport_t *xprt;
+ inode_table_t *itable;
+
+ server_resume_fn_t resume_fn;
+
+ loc_t loc;
+ loc_t loc2;
+ server_resolve_t resolve;
+ server_resolve_t resolve2;
+
+ /* used within resolve_and_resume */
+ loc_t *loc_now;
+ server_resolve_t *resolve_now;
+
+ struct iatt stbuf;
+ int valid;
+
+ fd_t *fd;
+ dict_t *params;
+ int32_t flags;
+ int wbflags;
+ struct iovec payload_vector[MAX_IOVEC];
+ int payload_count;
+ struct iobuf *iobuf;
+ struct iobref *iobref;
+
+ size_t size;
+ off_t offset;
+ mode_t mode;
+ dev_t dev;
+ size_t nr_count;
+ int cmd;
+ int type;
+ char *name;
+ int name_len;
+
+ int mask;
+ char is_revalidate;
+ dict_t *dict;
+ struct gf_flock flock;
+ const char *volume;
+ dir_entry_t *entry;
+
+ dict_t *xdata;
+ mode_t umask;
+};
+
+
+extern struct rpcsvc_program gluster_handshake_prog;
+extern struct rpcsvc_program glusterfs3_3_fop_prog;
+extern struct rpcsvc_program gluster_ping_prog;
+
+
+typedef struct _server_ctx {
+ gf_lock_t fdtable_lock;
+ fdtable_t *fdtable;
+ struct _gf_timer *grace_timer;
+ uint32_t lk_version;
+} server_ctx_t;
+
+
+int
+server_submit_reply (call_frame_t *frame, rpcsvc_request_t *req, void *arg,
+ struct iovec *payload, int payloadcount,
+ struct iobref *iobref, xdrproc_t xdrproc);
+
+int gf_server_check_setxattr_cmd (call_frame_t *frame, dict_t *dict);
+int gf_server_check_getxattr_cmd (call_frame_t *frame, const char *name);
+
+#endif /* !_SERVER_H */