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.am35
-rw-r--r--xlators/protocol/server/src/authenticate.c232
-rw-r--r--xlators/protocol/server/src/authenticate.h42
-rw-r--r--xlators/protocol/server/src/server-common.c842
-rw-r--r--xlators/protocol/server/src/server-common.h199
-rw-r--r--xlators/protocol/server/src/server-dentry.c413
-rw-r--r--xlators/protocol/server/src/server-handshake.c796
-rw-r--r--xlators/protocol/server/src/server-helpers.c1966
-rw-r--r--xlators/protocol/server/src/server-helpers.h148
-rw-r--r--xlators/protocol/server/src/server-mem-types.h27
-rw-r--r--xlators/protocol/server/src/server-messages.h168
-rw-r--r--xlators/protocol/server/src/server-protocol.c8318
-rw-r--r--xlators/protocol/server/src/server-protocol.h153
-rw-r--r--xlators/protocol/server/src/server-resolve.c683
-rw-r--r--xlators/protocol/server/src/server-rpc-fops.c6084
-rw-r--r--xlators/protocol/server/src/server-rpc-fops_v2.c6031
-rw-r--r--xlators/protocol/server/src/server.c1887
-rw-r--r--xlators/protocol/server/src/server.h222
18 files changed, 18763 insertions, 9483 deletions
diff --git a/xlators/protocol/server/src/Makefile.am b/xlators/protocol/server/src/Makefile.am
index dcd92aeedd9..5e875c8df0b 100644
--- a/xlators/protocol/server/src/Makefile.am
+++ b/xlators/protocol/server/src/Makefile.am
@@ -1,18 +1,33 @@
-
+if WITH_SERVER
xlator_LTLIBRARIES = server.la
+endif
+
xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/protocol
-server_la_LDFLAGS = -module -avoidversion
+server_la_LDFLAGS = -module $(GF_XLATOR_DEFAULT_LDFLAGS)
+
+server_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la \
+ $(top_builddir)/rpc/rpc-lib/src/libgfrpc.la \
+ $(top_builddir)/rpc/xdr/src/libgfxdr.la $(LIB_DL)
+
+server_la_SOURCES = server.c server-resolve.c server-helpers.c \
+ server-rpc-fops.c server-handshake.c authenticate.c \
+ server-common.c server-rpc-fops_v2.c
-server_la_SOURCES = server-protocol.c server-dentry.c server-helpers.c
-server_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la
+server_la_HEADERS = server.h server-helpers.h server-mem-types.h \
+ authenticate.h server-messages.h server-common.h
-noinst_HEADERS = server-protocol.h server-helpers.h
+server_ladir = $(includedir)/glusterfs/server
-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 -I$(top_builddir)/rpc/xdr/src \
+ -I$(top_srcdir)/glusterfsd/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 00000000000..c1229f9ebf3
--- /dev/null
+++ b/xlators/protocol/server/src/authenticate.c
@@ -0,0 +1,232 @@
+/*
+ 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 _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+
+#include <stdio.h>
+#include <dlfcn.h>
+#include <errno.h>
+#include "authenticate.h"
+#include "server-messages.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", SLEN("ip"))) {
+ gf_msg("authenticate", GF_LOG_ERROR, 0, PS_MSG_AUTHENTICATE_ERROR,
+ "AUTHENTICATION MODULE "
+ "\"IP\" HAS BEEN REPLACED BY \"ADDR\"");
+ dict_set(this, key, data_from_dynptr(NULL, 0));
+ /* TODO: 1.3.x backward 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_msg("authenticate", GF_LOG_ERROR, 0, PS_MSG_AUTHENTICATE_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_msg("authenticate", GF_LOG_ERROR, 0, PS_MSG_AUTHENTICATE_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_msg_debug("authenticate", 0,
+ "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_msg("authenticate", GF_LOG_ERROR, 0, PS_MSG_VOL_VALIDATE_FAILED,
+ "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_msg(xl->name, GF_LOG_ERROR, 0, PS_MSG_AUTH_INIT_FAILED,
+ "authentication init failed");
+ dict_foreach(auth_modules, fini, &ret);
+ ret = -1;
+ }
+ return ret;
+}
+
+typedef struct {
+ dict_t *iparams;
+ dict_t *cparams;
+ int64_t result;
+} gf_auth_args_t;
+
+static int
+gf_auth_one_method(dict_t *this, char *key, data_t *value, void *data)
+{
+ gf_auth_args_t *args = data;
+ auth_handle_t *handle = NULL;
+
+ if (!value) {
+ return 0;
+ }
+
+ handle = data_to_ptr(value);
+ if (!handle || !handle->authenticate) {
+ return 0;
+ }
+
+ switch (handle->authenticate(args->iparams, args->cparams)) {
+ case AUTH_ACCEPT:
+ if (args->result != AUTH_REJECT) {
+ args->result = AUTH_ACCEPT;
+ }
+ /* FALLTHROUGH */
+ default:
+ return 0;
+ case AUTH_REJECT:
+ args->result = AUTH_REJECT;
+ return -1;
+ }
+}
+
+auth_result_t
+gf_authenticate(dict_t *input_params, dict_t *config_params,
+ dict_t *auth_modules)
+{
+ char *name = NULL;
+ data_t *peerinfo_data = NULL;
+ gf_auth_args_t args;
+
+ args.iparams = input_params;
+ args.cparams = config_params;
+ args.result = AUTH_DONT_CARE;
+
+ dict_foreach(auth_modules, gf_auth_one_method, &args);
+
+ if (AUTH_DONT_CARE == args.result) {
+ peerinfo_data = dict_get(input_params, "peer-info-name");
+
+ if (peerinfo_data) {
+ name = peerinfo_data->data;
+ }
+
+ gf_msg("auth", GF_LOG_ERROR, 0, PS_MSG_REMOTE_CLIENT_REFUSED,
+ "no authentication module is interested in "
+ "accepting remote-client %s",
+ name);
+ args.result = AUTH_REJECT;
+ }
+
+ return args.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 00000000000..6888cf696e6
--- /dev/null
+++ b/xlators/protocol/server/src/authenticate.h
@@ -0,0 +1,42 @@
+/*
+ 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 _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+
+#include <stdio.h>
+#include <fnmatch.h>
+#include <glusterfs/dict.h>
+#include <glusterfs/compat.h>
+#include <glusterfs/list.h>
+#include <glusterfs/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;
+
+int32_t
+gf_auth_init(xlator_t *xl, dict_t *auth_modules);
+void
+gf_auth_fini(dict_t *auth_modules);
+auth_result_t
+gf_authenticate(dict_t *, dict_t *, dict_t *);
+
+#endif /* _AUTHENTICATE_H */
diff --git a/xlators/protocol/server/src/server-common.c b/xlators/protocol/server/src/server-common.c
new file mode 100644
index 00000000000..cd79cf4d930
--- /dev/null
+++ b/xlators/protocol/server/src/server-common.c
@@ -0,0 +1,842 @@
+#include "server.h"
+#include <glusterfs/defaults.h>
+#include "rpc-common-xdr.h"
+#include "glusterfs3-xdr.h"
+#include "glusterfs3.h"
+#include <glusterfs/compat-errno.h>
+#include "server-messages.h"
+#include "server-helpers.h"
+#include <glusterfs/defaults.h>
+#include <glusterfs/fd.h>
+#include "xdr-nfs3.h"
+
+void
+server_post_stat(server_state_t *state, gfs3_stat_rsp *rsp, struct iatt *stbuf)
+{
+ if (state->client->subdir_mount &&
+ !gf_uuid_compare(stbuf->ia_gfid, state->client->subdir_gfid)) {
+ /* This is very important as when we send iatt of
+ root-inode, fuse/client expect the gfid to be 1,
+ along with inode number. As for subdirectory mount,
+ we use inode table which is shared by everyone, but
+ make sure we send fops only from subdir and below,
+ we have to alter inode gfid and send it to client */
+ static uuid_t gfid = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1};
+
+ stbuf->ia_ino = 1;
+ gf_uuid_copy(stbuf->ia_gfid, gfid);
+ }
+
+ gf_stat_from_iatt(&rsp->stat, stbuf);
+}
+
+void
+server_post_readlink(gfs3_readlink_rsp *rsp, struct iatt *stbuf,
+ const char *buf)
+{
+ gf_stat_from_iatt(&rsp->buf, stbuf);
+ rsp->path = (char *)buf;
+}
+
+void
+server_post_mknod(server_state_t *state, gfs3_mknod_rsp *rsp,
+ struct iatt *stbuf, struct iatt *preparent,
+ struct iatt *postparent, inode_t *inode)
+{
+ inode_t *link_inode = NULL;
+
+ 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);
+}
+
+void
+server_post_mkdir(server_state_t *state, gfs3_mkdir_rsp *rsp, inode_t *inode,
+ struct iatt *stbuf, struct iatt *preparent,
+ struct iatt *postparent, dict_t *xdata)
+{
+ inode_t *link_inode = NULL;
+
+ 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);
+}
+
+void
+server_post_unlink(server_state_t *state, gfs3_unlink_rsp *rsp,
+ struct iatt *preparent, struct iatt *postparent)
+{
+ inode_unlink(state->loc.inode, state->loc.parent, state->loc.name);
+
+ forget_inode_if_no_dentry(state->loc.inode);
+
+ gf_stat_from_iatt(&rsp->preparent, preparent);
+ gf_stat_from_iatt(&rsp->postparent, postparent);
+}
+
+void
+server_post_rmdir(server_state_t *state, gfs3_rmdir_rsp *rsp,
+ struct iatt *preparent, struct iatt *postparent)
+{
+ inode_unlink(state->loc.inode, state->loc.parent, state->loc.name);
+ /* parent should not be found for directories after
+ * inode_unlink, since directories cannot have
+ * hardlinks.
+ */
+ forget_inode_if_no_dentry(state->loc.inode);
+
+ gf_stat_from_iatt(&rsp->preparent, preparent);
+ gf_stat_from_iatt(&rsp->postparent, postparent);
+}
+
+void
+server_post_symlink(server_state_t *state, gfs3_symlink_rsp *rsp,
+ inode_t *inode, struct iatt *stbuf, struct iatt *preparent,
+ struct iatt *postparent, dict_t *xdata)
+{
+ inode_t *link_inode = NULL;
+
+ 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);
+}
+
+void
+server_post_link(server_state_t *state, gfs3_link_rsp *rsp, inode_t *inode,
+ struct iatt *stbuf, struct iatt *preparent,
+ struct iatt *postparent, dict_t *xdata)
+{
+ inode_t *link_inode = NULL;
+
+ 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_lookup(link_inode);
+ inode_unref(link_inode);
+}
+
+void
+server_post_truncate(gfs3_truncate_rsp *rsp, struct iatt *prebuf,
+ struct iatt *postbuf)
+{
+ gf_stat_from_iatt(&rsp->prestat, prebuf);
+ gf_stat_from_iatt(&rsp->poststat, postbuf);
+}
+
+void
+server_post_writev(gfs3_write_rsp *rsp, struct iatt *prebuf,
+ struct iatt *postbuf)
+{
+ gf_stat_from_iatt(&rsp->prestat, prebuf);
+ gf_stat_from_iatt(&rsp->poststat, postbuf);
+}
+
+void
+server_post_statfs(gfs3_statfs_rsp *rsp, struct statvfs *stbuf)
+{
+ gf_statfs_from_statfs(&rsp->statfs, stbuf);
+}
+
+void
+server_post_fsync(gfs3_fsync_rsp *rsp, struct iatt *prebuf,
+ struct iatt *postbuf)
+{
+ gf_stat_from_iatt(&rsp->prestat, prebuf);
+ gf_stat_from_iatt(&rsp->poststat, postbuf);
+}
+
+void
+server_post_ftruncate(gfs3_ftruncate_rsp *rsp, struct iatt *prebuf,
+ struct iatt *postbuf)
+{
+ gf_stat_from_iatt(&rsp->prestat, prebuf);
+ gf_stat_from_iatt(&rsp->poststat, postbuf);
+}
+
+void
+server_post_fstat(server_state_t *state, gfs3_fstat_rsp *rsp,
+ struct iatt *stbuf)
+{
+ if (state->client->subdir_mount &&
+ !gf_uuid_compare(stbuf->ia_gfid, state->client->subdir_gfid)) {
+ /* This is very important as when we send iatt of
+ root-inode, fuse/client expect the gfid to be 1,
+ along with inode number. As for subdirectory mount,
+ we use inode table which is shared by everyone, but
+ make sure we send fops only from subdir and below,
+ we have to alter inode gfid and send it to client */
+ static uuid_t gfid = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1};
+
+ stbuf->ia_ino = 1;
+ gf_uuid_copy(stbuf->ia_gfid, gfid);
+ }
+
+ gf_stat_from_iatt(&rsp->stat, stbuf);
+}
+
+void
+server_post_lk(xlator_t *this, gfs3_lk_rsp *rsp, struct gf_flock *lock)
+{
+ 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_msg(this->name, GF_LOG_ERROR, 0, PS_MSG_LOCK_ERROR,
+ "Unknown lock type: %" PRId32 "!", lock->l_type);
+ break;
+ }
+
+ gf_proto_flock_from_flock(&rsp->flock, lock);
+}
+
+int
+server_post_readdir(gfs3_readdir_rsp *rsp, gf_dirent_t *entries)
+{
+ int ret = 0;
+
+ ret = serialize_rsp_dirent(entries, rsp);
+
+ return ret;
+}
+void
+server_post_zerofill(gfs3_zerofill_rsp *rsp, struct iatt *statpre,
+ struct iatt *statpost)
+{
+ gf_stat_from_iatt(&rsp->statpre, statpre);
+ gf_stat_from_iatt(&rsp->statpost, statpost);
+}
+
+void
+server_post_discard(gfs3_discard_rsp *rsp, struct iatt *statpre,
+ struct iatt *statpost)
+{
+ gf_stat_from_iatt(&rsp->statpre, statpre);
+ gf_stat_from_iatt(&rsp->statpost, statpost);
+}
+
+void
+server_post_fallocate(gfs3_fallocate_rsp *rsp, struct iatt *statpre,
+ struct iatt *statpost)
+{
+ gf_stat_from_iatt(&rsp->statpre, statpre);
+ gf_stat_from_iatt(&rsp->statpost, statpost);
+}
+
+void
+server_post_seek(gfs3_seek_rsp *rsp, off_t offset)
+{
+ rsp->offset = offset;
+}
+
+int
+server_post_readdirp(gfs3_readdirp_rsp *rsp, gf_dirent_t *entries)
+{
+ int ret = 0;
+
+ ret = serialize_rsp_direntp(entries, rsp);
+
+ return ret;
+}
+
+void
+server_post_fsetattr(gfs3_fsetattr_rsp *rsp, struct iatt *statpre,
+ struct iatt *statpost)
+{
+ gf_stat_from_iatt(&rsp->statpre, statpre);
+ gf_stat_from_iatt(&rsp->statpost, statpost);
+}
+
+void
+server_post_setattr(gfs3_setattr_rsp *rsp, struct iatt *statpre,
+ struct iatt *statpost)
+{
+ gf_stat_from_iatt(&rsp->statpre, statpre);
+ gf_stat_from_iatt(&rsp->statpost, statpost);
+}
+
+void
+server_post_rchecksum(gfs3_rchecksum_rsp *rsp, uint32_t weak_checksum,
+ uint8_t *strong_checksum)
+{
+ rsp->weak_checksum = weak_checksum;
+
+ rsp->strong_checksum.strong_checksum_val = (char *)strong_checksum;
+ rsp->strong_checksum.strong_checksum_len = MD5_DIGEST_LENGTH;
+}
+
+void
+server_post_rename(call_frame_t *frame, server_state_t *state,
+ gfs3_rename_rsp *rsp, struct iatt *stbuf,
+ struct iatt *preoldparent, struct iatt *postoldparent,
+ struct iatt *prenewparent, struct iatt *postnewparent)
+{
+ inode_t *tmp_inode = NULL;
+
+ stbuf->ia_type = state->loc.inode->ia_type;
+
+ /* TODO: log gfid of the inodes */
+ gf_msg_trace(frame->root->client->bound_xl->name, 0,
+ "%" 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);
+ forget_inode_if_no_dentry(tmp_inode);
+ 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);
+}
+
+int
+server_post_open(call_frame_t *frame, xlator_t *this, gfs3_open_rsp *rsp,
+ fd_t *fd)
+{
+ server_ctx_t *serv_ctx = NULL;
+ uint64_t fd_no = 0;
+
+ serv_ctx = server_ctx_get(frame->root->client, this);
+ if (serv_ctx == NULL) {
+ gf_msg(this->name, GF_LOG_INFO, 0, PS_MSG_SERVER_CTX_GET_FAILED,
+ "server_ctx_get() "
+ "failed");
+ return -1;
+ }
+
+ fd_bind(fd);
+ fd_ref(fd);
+ fd_no = gf_fd_unused_get(serv_ctx->fdtable, fd);
+ rsp->fd = fd_no;
+
+ return 0;
+}
+
+void
+server_post_readv(gfs3_read_rsp *rsp, struct iatt *stbuf, int op_ret)
+{
+ gf_stat_from_iatt(&rsp->stat, stbuf);
+ rsp->size = op_ret;
+}
+
+int
+server_post_opendir(call_frame_t *frame, xlator_t *this, gfs3_opendir_rsp *rsp,
+ fd_t *fd)
+{
+ server_ctx_t *serv_ctx = NULL;
+ uint64_t fd_no = 0;
+
+ serv_ctx = server_ctx_get(frame->root->client, this);
+ if (serv_ctx == NULL) {
+ gf_msg(this->name, GF_LOG_INFO, 0, PS_MSG_SERVER_CTX_GET_FAILED,
+ "server_ctx_get() "
+ "failed");
+ return -1;
+ }
+
+ fd_bind(fd);
+ fd_ref(fd);
+ fd_no = gf_fd_unused_get(serv_ctx->fdtable, fd);
+ rsp->fd = fd_no;
+
+ return 0;
+}
+
+int
+server_post_create(call_frame_t *frame, gfs3_create_rsp *rsp,
+ server_state_t *state, xlator_t *this, fd_t *fd,
+ inode_t *inode, struct iatt *stbuf, struct iatt *preparent,
+ struct iatt *postparent)
+{
+ server_ctx_t *serv_ctx = NULL;
+ inode_t *link_inode = NULL;
+ uint64_t fd_no = 0;
+ int op_errno = 0;
+
+ link_inode = inode_link(inode, state->loc.parent, state->loc.name, stbuf);
+
+ if (!link_inode) {
+ op_errno = ENOENT;
+ goto out;
+ }
+
+ if (link_inode != inode) {
+ /*
+ VERY racy code (if used anywhere else)
+ -- don't do this without understanding
+ */
+
+ inode_ctx_merge(fd, fd->inode, link_inode);
+ 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_msg(this->name, GF_LOG_INFO, 0, PS_MSG_SERVER_CTX_GET_FAILED,
+ "server_ctx_get() "
+ "failed");
+ goto out;
+ }
+
+ fd_bind(fd);
+ fd_ref(fd);
+ fd_no = gf_fd_unused_get(serv_ctx->fdtable, fd);
+
+ if ((fd_no > UINT64_MAX) || (fd == 0)) {
+ op_errno = errno;
+ }
+
+ rsp->fd = fd_no;
+ gf_stat_from_iatt(&rsp->stat, stbuf);
+ gf_stat_from_iatt(&rsp->preparent, preparent);
+ gf_stat_from_iatt(&rsp->postparent, postparent);
+
+ return 0;
+out:
+ return -op_errno;
+}
+
+/*TODO: Handle revalidate path */
+void
+server_post_lookup(gfs3_lookup_rsp *rsp, call_frame_t *frame,
+ server_state_t *state, inode_t *inode, struct iatt *stbuf,
+ struct iatt *postparent)
+{
+ inode_t *root_inode = NULL;
+ inode_t *link_inode = NULL;
+ static uuid_t rootgfid = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1};
+
+ root_inode = frame->root->client->bound_xl->itable->root;
+
+ 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);
+ }
+ }
+
+ if ((inode == root_inode) || (state->client->subdir_mount &&
+ (inode == state->client->subdir_inode))) {
+ /* we just looked up root ("/") OR
+ subdir mount directory, which is root ('/') in client */
+ /* This is very important as when we send iatt of
+ root-inode, fuse/client expect the gfid to be 1,
+ along with inode number. As for subdirectory mount,
+ we use inode table which is shared by everyone, but
+ make sure we send fops only from subdir and below,
+ we have to alter inode gfid and send it to client */
+ stbuf->ia_ino = 1;
+ gf_uuid_copy(stbuf->ia_gfid, rootgfid);
+ if (inode->ia_type == 0)
+ inode->ia_type = stbuf->ia_type;
+ }
+
+ gf_stat_from_iatt(&rsp->stat, stbuf);
+}
+
+void
+server_post_lease(gfs3_lease_rsp *rsp, struct gf_lease *lease)
+{
+ gf_proto_lease_from_lease(&rsp->lease, lease);
+}
+
+/* Version 4 helpers */
+
+void
+server4_post_readlink(gfx_readlink_rsp *rsp, struct iatt *stbuf,
+ const char *buf)
+{
+ gfx_stat_from_iattx(&rsp->buf, stbuf);
+ rsp->path = (char *)buf;
+}
+
+void
+server4_post_common_3iatt(server_state_t *state, gfx_common_3iatt_rsp *rsp,
+ inode_t *inode, struct iatt *stbuf,
+ struct iatt *preparent, struct iatt *postparent)
+{
+ inode_t *link_inode = NULL;
+
+ gfx_stat_from_iattx(&rsp->stat, stbuf);
+ if (state->client->subdir_mount &&
+ !gf_uuid_compare(preparent->ia_gfid, state->client->subdir_gfid)) {
+ /* This is very important as when we send iatt of
+ root-inode, fuse/client expect the gfid to be 1,
+ along with inode number. As for subdirectory mount,
+ we use inode table which is shared by everyone, but
+ make sure we send fops only from subdir and below,
+ we have to alter inode gfid and send it to client */
+ static uuid_t gfid = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1};
+
+ preparent->ia_ino = 1;
+ postparent->ia_ino = 1;
+ gf_uuid_copy(preparent->ia_gfid, gfid);
+ gf_uuid_copy(postparent->ia_gfid, gfid);
+ }
+
+ gfx_stat_from_iattx(&rsp->preparent, preparent);
+ gfx_stat_from_iattx(&rsp->postparent, postparent);
+
+ link_inode = inode_link(inode, state->loc.parent, state->loc.name, stbuf);
+ inode_lookup(link_inode);
+ inode_unref(link_inode);
+}
+
+void
+server4_post_common_3iatt_noinode(gfx_common_3iatt_rsp *rsp, struct iatt *stbuf,
+ struct iatt *prebuf_dst,
+ struct iatt *postbuf_dst)
+{
+ gfx_stat_from_iattx(&rsp->stat, stbuf);
+ gfx_stat_from_iattx(&rsp->preparent, prebuf_dst);
+ gfx_stat_from_iattx(&rsp->postparent, postbuf_dst);
+}
+
+void
+server4_post_common_2iatt(gfx_common_2iatt_rsp *rsp, struct iatt *prebuf,
+ struct iatt *postbuf)
+{
+ gfx_stat_from_iattx(&rsp->prestat, prebuf);
+ gfx_stat_from_iattx(&rsp->poststat, postbuf);
+}
+
+void
+server4_post_entry_remove(server_state_t *state, gfx_common_2iatt_rsp *rsp,
+ struct iatt *prebuf, struct iatt *postbuf)
+{
+ inode_unlink(state->loc.inode, state->loc.parent, state->loc.name);
+ /* parent should not be found for directories after
+ * inode_unlink, since directories cannot have
+ * hardlinks.
+ */
+ forget_inode_if_no_dentry(state->loc.inode);
+
+ gfx_stat_from_iattx(&rsp->prestat, prebuf);
+ gfx_stat_from_iattx(&rsp->poststat, postbuf);
+}
+
+void
+server4_post_statfs(gfx_statfs_rsp *rsp, struct statvfs *stbuf)
+{
+ gf_statfs_from_statfs(&rsp->statfs, stbuf);
+}
+
+void
+server4_post_common_iatt(server_state_t *state, gfx_common_iatt_rsp *rsp,
+ struct iatt *stbuf)
+{
+ if (state->client->subdir_mount &&
+ !gf_uuid_compare(stbuf->ia_gfid, state->client->subdir_gfid)) {
+ /* This is very important as when we send iatt of
+ root-inode, fuse/client expect the gfid to be 1,
+ along with inode number. As for subdirectory mount,
+ we use inode table which is shared by everyone, but
+ make sure we send fops only from subdir and below,
+ we have to alter inode gfid and send it to client */
+ static uuid_t gfid = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1};
+
+ stbuf->ia_ino = 1;
+ gf_uuid_copy(stbuf->ia_gfid, gfid);
+ }
+
+ gfx_stat_from_iattx(&rsp->stat, stbuf);
+}
+
+void
+server4_post_lk(xlator_t *this, gfx_lk_rsp *rsp, struct gf_flock *lock)
+{
+ 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_msg(this->name, GF_LOG_ERROR, 0, PS_MSG_LOCK_ERROR,
+ "Unknown lock type: %" PRId32 "!", lock->l_type);
+ break;
+ }
+
+ gf_proto_flock_from_flock(&rsp->flock, lock);
+}
+
+int
+server4_post_readdir(gfx_readdir_rsp *rsp, gf_dirent_t *entries)
+{
+ int ret = 0;
+
+ ret = serialize_rsp_dirent_v2(entries, rsp);
+
+ return ret;
+}
+
+void
+server4_post_seek(gfx_seek_rsp *rsp, off_t offset)
+{
+ rsp->offset = offset;
+}
+
+int
+server4_post_readdirp(gfx_readdirp_rsp *rsp, gf_dirent_t *entries)
+{
+ int ret = 0;
+
+ ret = serialize_rsp_direntp_v2(entries, rsp);
+
+ return ret;
+}
+
+void
+server4_post_rchecksum(gfx_rchecksum_rsp *rsp, uint32_t weak_checksum,
+ uint8_t *strong_checksum)
+{
+ rsp->weak_checksum = weak_checksum;
+ /* When the length encoding changes, update the change
+ in posix code also. */
+ rsp->strong_checksum.strong_checksum_val = (char *)strong_checksum;
+ rsp->strong_checksum.strong_checksum_len = SHA256_DIGEST_LENGTH;
+ rsp->flags = 1; /* Indicates SHA256 TYPE */
+}
+
+void
+server4_post_rename(call_frame_t *frame, server_state_t *state,
+ gfx_rename_rsp *rsp, struct iatt *stbuf,
+ struct iatt *preoldparent, struct iatt *postoldparent,
+ struct iatt *prenewparent, struct iatt *postnewparent)
+{
+ inode_t *tmp_inode = NULL;
+
+ stbuf->ia_type = state->loc.inode->ia_type;
+
+ /* TODO: log gfid of the inodes */
+ gf_msg_trace(frame->root->client->bound_xl->name, 0,
+ "%" 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);
+ forget_inode_if_no_dentry(tmp_inode);
+ inode_unref(tmp_inode);
+ }
+
+ inode_rename(state->itable, state->loc.parent, state->loc.name,
+ state->loc2.parent, state->loc2.name, state->loc.inode, stbuf);
+ gfx_stat_from_iattx(&rsp->stat, stbuf);
+
+ gfx_stat_from_iattx(&rsp->preoldparent, preoldparent);
+ gfx_stat_from_iattx(&rsp->postoldparent, postoldparent);
+
+ gfx_stat_from_iattx(&rsp->prenewparent, prenewparent);
+ gfx_stat_from_iattx(&rsp->postnewparent, postnewparent);
+}
+
+int
+server4_post_open(call_frame_t *frame, xlator_t *this, gfx_open_rsp *rsp,
+ fd_t *fd)
+{
+ server_ctx_t *serv_ctx = NULL;
+ uint64_t fd_no = 0;
+
+ serv_ctx = server_ctx_get(frame->root->client, this);
+ if (serv_ctx == NULL) {
+ gf_msg(this->name, GF_LOG_INFO, 0, PS_MSG_SERVER_CTX_GET_FAILED,
+ "server_ctx_get() "
+ "failed");
+ return -1;
+ }
+
+ fd_bind(fd);
+ fd_ref(fd);
+ fd_no = gf_fd_unused_get(serv_ctx->fdtable, fd);
+ rsp->fd = fd_no;
+
+ return 0;
+}
+
+void
+server4_post_readv(gfx_read_rsp *rsp, struct iatt *stbuf, int op_ret)
+{
+ gfx_stat_from_iattx(&rsp->stat, stbuf);
+ rsp->size = op_ret;
+}
+
+int
+server4_post_create(call_frame_t *frame, gfx_create_rsp *rsp,
+ server_state_t *state, xlator_t *this, fd_t *fd,
+ inode_t *inode, struct iatt *stbuf, struct iatt *preparent,
+ struct iatt *postparent)
+{
+ server_ctx_t *serv_ctx = NULL;
+ inode_t *link_inode = NULL;
+ uint64_t fd_no = 0;
+ int op_errno = 0;
+
+ link_inode = inode_link(inode, state->loc.parent, state->loc.name, stbuf);
+
+ if (!link_inode) {
+ op_errno = ENOENT;
+ goto out;
+ }
+
+ if (link_inode != inode) {
+ /*
+ VERY racy code (if used anywhere else)
+ -- don't do this without understanding
+ */
+
+ inode_ctx_merge(fd, fd->inode, link_inode);
+ 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_msg(this->name, GF_LOG_INFO, 0, PS_MSG_SERVER_CTX_GET_FAILED,
+ "server_ctx_get() "
+ "failed");
+ goto out;
+ }
+
+ fd_bind(fd);
+ fd_ref(fd);
+ fd_no = gf_fd_unused_get(serv_ctx->fdtable, fd);
+
+ if ((fd_no > UINT64_MAX) || (fd == 0)) {
+ op_errno = errno;
+ }
+
+ rsp->fd = fd_no;
+ gfx_stat_from_iattx(&rsp->stat, stbuf);
+ gfx_stat_from_iattx(&rsp->preparent, preparent);
+ gfx_stat_from_iattx(&rsp->postparent, postparent);
+
+ return 0;
+out:
+ return -op_errno;
+}
+
+/*TODO: Handle revalidate path */
+void
+server4_post_lookup(gfx_common_2iatt_rsp *rsp, call_frame_t *frame,
+ server_state_t *state, inode_t *inode, struct iatt *stbuf)
+{
+ inode_t *root_inode = NULL;
+ inode_t *link_inode = NULL;
+ static uuid_t rootgfid = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1};
+
+ root_inode = frame->root->client->bound_xl->itable->root;
+
+ 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);
+ }
+ }
+
+ if ((inode == root_inode) || (state->client->subdir_mount &&
+ (inode == state->client->subdir_inode))) {
+ /* we just looked up root ("/") OR
+ subdir mount directory, which is root ('/') in client */
+ /* This is very important as when we send iatt of
+ root-inode, fuse/client expect the gfid to be 1,
+ along with inode number. As for subdirectory mount,
+ we use inode table which is shared by everyone, but
+ make sure we send fops only from subdir and below,
+ we have to alter inode gfid and send it to client */
+ stbuf->ia_ino = 1;
+ gf_uuid_copy(stbuf->ia_gfid, rootgfid);
+ if (inode->ia_type == 0)
+ inode->ia_type = stbuf->ia_type;
+ }
+
+ gfx_stat_from_iattx(&rsp->prestat, stbuf);
+}
+
+void
+server4_post_lease(gfx_lease_rsp *rsp, struct gf_lease *lease)
+{
+ gf_proto_lease_from_lease(&rsp->lease, lease);
+}
+
+void
+server4_post_link(server_state_t *state, gfx_common_3iatt_rsp *rsp,
+ inode_t *inode, struct iatt *stbuf, struct iatt *preparent,
+ struct iatt *postparent)
+{
+ inode_t *link_inode = NULL;
+
+ gfx_stat_from_iattx(&rsp->stat, stbuf);
+ gfx_stat_from_iattx(&rsp->preparent, preparent);
+ gfx_stat_from_iattx(&rsp->postparent, postparent);
+
+ link_inode = inode_link(inode, state->loc2.parent, state->loc2.name, stbuf);
+ inode_lookup(link_inode);
+ inode_unref(link_inode);
+}
diff --git a/xlators/protocol/server/src/server-common.h b/xlators/protocol/server/src/server-common.h
new file mode 100644
index 00000000000..6200415e304
--- /dev/null
+++ b/xlators/protocol/server/src/server-common.h
@@ -0,0 +1,199 @@
+#include "server.h"
+#include <glusterfs/defaults.h>
+#include "rpc-common-xdr.h"
+#include "glusterfs3-xdr.h"
+#include "glusterfs3.h"
+#include <glusterfs/compat-errno.h>
+#include "server-messages.h"
+#include <glusterfs/defaults.h>
+
+#include "xdr-nfs3.h"
+void
+server_post_stat(server_state_t *state, gfs3_stat_rsp *rsp, struct iatt *stbuf);
+
+void
+server_post_readlink(gfs3_readlink_rsp *rsp, struct iatt *stbuf,
+ const char *buf);
+
+void
+server_post_mknod(server_state_t *state, gfs3_mknod_rsp *rsp,
+ struct iatt *stbuf, struct iatt *preparent,
+ struct iatt *postparent, inode_t *inode);
+void
+server_post_mkdir(server_state_t *state, gfs3_mkdir_rsp *rsp, inode_t *inode,
+ struct iatt *stbuf, struct iatt *preparent,
+ struct iatt *postparent, dict_t *xdata);
+
+void
+server_post_unlink(server_state_t *state, gfs3_unlink_rsp *rsp,
+ struct iatt *preparent, struct iatt *postparent);
+void
+server_post_rmdir(server_state_t *state, gfs3_rmdir_rsp *rsp,
+ struct iatt *preparent, struct iatt *postparent);
+
+void
+server_post_symlink(server_state_t *state, gfs3_symlink_rsp *rsp,
+ inode_t *inode, struct iatt *stbuf, struct iatt *preparent,
+ struct iatt *postparent, dict_t *xdata);
+void
+server_post_link(server_state_t *state, gfs3_link_rsp *rsp, inode_t *inode,
+ struct iatt *stbuf, struct iatt *preparent,
+ struct iatt *postparent, dict_t *xdata);
+void
+server_post_truncate(gfs3_truncate_rsp *rsp, struct iatt *prebuf,
+ struct iatt *postbuf);
+
+void
+server_post_writev(gfs3_write_rsp *rsp, struct iatt *prebuf,
+ struct iatt *postbuf);
+void
+server_post_statfs(gfs3_statfs_rsp *rsp, struct statvfs *stbuf);
+
+void
+server_post_fsync(gfs3_fsync_rsp *rsp, struct iatt *prebuf,
+ struct iatt *postbuf);
+
+void
+server_post_ftruncate(gfs3_ftruncate_rsp *rsp, struct iatt *prebuf,
+ struct iatt *postbuf);
+
+void
+server_post_fstat(server_state_t *state, gfs3_fstat_rsp *rsp,
+ struct iatt *stbuf);
+
+void
+server_post_lk(xlator_t *this, gfs3_lk_rsp *rsp, struct gf_flock *lock);
+
+int
+server_post_readdir(gfs3_readdir_rsp *rsp, gf_dirent_t *entries);
+
+void
+server_post_zerofill(gfs3_zerofill_rsp *rsp, struct iatt *statpre,
+ struct iatt *statpost);
+
+void
+server_post_discard(gfs3_discard_rsp *rsp, struct iatt *statpre,
+ struct iatt *statpost);
+
+void
+server_post_fallocate(gfs3_fallocate_rsp *rsp, struct iatt *statpre,
+ struct iatt *statpost);
+
+void
+server_post_seek(gfs3_seek_rsp *rsp, off_t offset);
+
+int
+server_post_readdirp(gfs3_readdirp_rsp *rsp, gf_dirent_t *entries);
+
+void
+server_post_fsetattr(gfs3_fsetattr_rsp *rsp, struct iatt *statpre,
+ struct iatt *statpost);
+
+void
+server_post_setattr(gfs3_setattr_rsp *rsp, struct iatt *statpre,
+ struct iatt *statpost);
+
+void
+server_post_rchecksum(gfs3_rchecksum_rsp *rsp, uint32_t weak_checksum,
+ uint8_t *strong_checksum);
+
+void
+server_post_rename(call_frame_t *frame, server_state_t *state,
+ gfs3_rename_rsp *rsp, struct iatt *stbuf,
+ struct iatt *preoldparent, struct iatt *postoldparent,
+ struct iatt *prenewparent, struct iatt *postnewparent);
+
+int
+server_post_open(call_frame_t *frame, xlator_t *this, gfs3_open_rsp *rsp,
+ fd_t *fd);
+void
+server_post_readv(gfs3_read_rsp *rsp, struct iatt *stbuf, int op_ret);
+
+int
+server_post_opendir(call_frame_t *frame, xlator_t *this, gfs3_opendir_rsp *rsp,
+ fd_t *fd);
+
+int
+server_post_create(call_frame_t *frame, gfs3_create_rsp *rsp,
+ server_state_t *state, xlator_t *this, fd_t *fd,
+ inode_t *inode, struct iatt *stbuf, struct iatt *preparent,
+ struct iatt *postparent);
+
+void
+server_post_lookup(gfs3_lookup_rsp *rsp, call_frame_t *frame,
+ server_state_t *state, inode_t *inode, struct iatt *stbuf,
+ struct iatt *postparent);
+
+void
+server_post_lease(gfs3_lease_rsp *rsp, struct gf_lease *lease);
+
+void
+server4_post_readlink(gfx_readlink_rsp *rsp, struct iatt *stbuf,
+ const char *buf);
+
+void
+server4_post_statfs(gfx_statfs_rsp *rsp, struct statvfs *stbuf);
+
+void
+server4_post_lk(xlator_t *this, gfx_lk_rsp *rsp, struct gf_flock *lock);
+
+int
+server4_post_readdir(gfx_readdir_rsp *rsp, gf_dirent_t *entries);
+
+void
+server4_post_seek(gfx_seek_rsp *rsp, off_t offset);
+
+int
+server4_post_readdirp(gfx_readdirp_rsp *rsp, gf_dirent_t *entries);
+
+void
+server4_post_rchecksum(gfx_rchecksum_rsp *rsp, uint32_t weak_checksum,
+ uint8_t *strong_checksum);
+
+void
+server4_post_rename(call_frame_t *frame, server_state_t *state,
+ gfx_rename_rsp *rsp, struct iatt *stbuf,
+ struct iatt *preoldparent, struct iatt *postoldparent,
+ struct iatt *prenewparent, struct iatt *postnewparent);
+
+int
+server4_post_open(call_frame_t *frame, xlator_t *this, gfx_open_rsp *rsp,
+ fd_t *fd);
+void
+server4_post_readv(gfx_read_rsp *rsp, struct iatt *stbuf, int op_ret);
+
+int
+server4_post_create(call_frame_t *frame, gfx_create_rsp *rsp,
+ server_state_t *state, xlator_t *this, fd_t *fd,
+ inode_t *inode, struct iatt *stbuf, struct iatt *preparent,
+ struct iatt *postparent);
+
+void
+server4_post_common_2iatt(gfx_common_2iatt_rsp *rsp, struct iatt *stbuf1,
+ struct iatt *stbuf2);
+
+void
+server4_post_entry_remove(server_state_t *state, gfx_common_2iatt_rsp *rsp,
+ struct iatt *stbuf1, struct iatt *stbuf2);
+
+void
+server4_post_common_3iatt(server_state_t *state, gfx_common_3iatt_rsp *rsp,
+ inode_t *inode, struct iatt *stbuf, struct iatt *pre,
+ struct iatt *post);
+void
+server4_post_common_iatt(server_state_t *state, gfx_common_iatt_rsp *rsp,
+ struct iatt *stbuf);
+void
+server4_post_lease(gfx_lease_rsp *rsp, struct gf_lease *lease);
+void
+server4_post_lookup(gfx_common_2iatt_rsp *rsp, call_frame_t *frame,
+ server_state_t *state, inode_t *inode, struct iatt *stbuf);
+void
+server4_post_link(server_state_t *state, gfx_common_3iatt_rsp *rsp,
+ inode_t *inode, struct iatt *stbuf, struct iatt *pre,
+ struct iatt *post);
+
+void
+server4_post_common_3iatt_noinode(gfx_common_3iatt_rsp *rsp, struct iatt *stbuf,
+ struct iatt *prebuf_dst,
+ struct iatt *postbuf_dst);
diff --git a/xlators/protocol/server/src/server-dentry.c b/xlators/protocol/server/src/server-dentry.c
deleted file mode 100644
index d3a69a393fc..00000000000
--- a/xlators/protocol/server/src/server-dentry.c
+++ /dev/null
@@ -1,413 +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)
-{
- 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 00000000000..85c87c1ab8b
--- /dev/null
+++ b/xlators/protocol/server/src/server-handshake.c
@@ -0,0 +1,796 @@
+/*
+ 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.
+*/
+
+#include "server.h"
+#include "server-helpers.h"
+#include "rpc-common-xdr.h"
+#include "glusterfs3-xdr.h"
+#include <glusterfs/compat-errno.h>
+#include "glusterfs3.h"
+#include "authenticate.h"
+#include "server-messages.h"
+#include <glusterfs/syscall.h>
+#include <glusterfs/events.h>
+#include <glusterfs/syncop.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;
+}
+
+int
+server_getspec(rpcsvc_request_t *req)
+{
+ int32_t ret = 0;
+ int32_t op_errno = ENOENT;
+ gf_getspec_req args = {
+ 0,
+ };
+ gf_getspec_rsp rsp = {
+ 0,
+ };
+
+ 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;
+ }
+
+ op_errno = ENOSYS;
+fail:
+ rsp.spec = "<this method is not in use, use glusterd for getspec>";
+ rsp.op_errno = gf_errno_to_error(op_errno);
+ rsp.op_ret = -1;
+
+ server_submit_reply(NULL, req, &rsp, NULL, 0, NULL,
+ (xdrproc_t)xdr_gf_getspec_rsp);
+
+ return 0;
+}
+
+static void
+server_first_lookup_done(rpcsvc_request_t *req, gf_setvolume_rsp *rsp)
+{
+ server_submit_reply(NULL, req, rsp, NULL, 0, NULL,
+ (xdrproc_t)xdr_gf_setvolume_rsp);
+
+ GF_FREE(rsp->dict.dict_val);
+ GF_FREE(rsp);
+}
+
+static inode_t *
+do_path_lookup(xlator_t *xl, dict_t *dict, inode_t *parinode, char *basename)
+{
+ int ret = 0;
+ loc_t loc = {
+ 0,
+ };
+ uuid_t gfid = {
+ 0,
+ };
+ struct iatt iatt = {
+ 0,
+ };
+ inode_t *inode = NULL;
+
+ loc.parent = parinode;
+ loc_touchup(&loc, basename);
+ loc.inode = inode_new(xl->itable);
+
+ gf_uuid_generate(gfid);
+ ret = dict_set_gfuuid(dict, "gfid-req", gfid, true);
+ if (ret) {
+ gf_log(xl->name, GF_LOG_ERROR, "failed to set 'gfid-req' for subdir");
+ goto out;
+ }
+
+ ret = syncop_lookup(xl, &loc, &iatt, NULL, dict, NULL);
+ if (ret < 0) {
+ gf_log(xl->name, GF_LOG_ERROR, "first lookup on subdir (%s) failed: %s",
+ basename, strerror(errno));
+ }
+
+ /* Inode linking is required so that the
+ resolution happens all fine for future fops */
+ inode = inode_link(loc.inode, loc.parent, loc.name, &iatt);
+
+ /* Extra ref so the pointer is valid till client is valid */
+ /* FIXME: not a priority, but this can lead to some inode
+ leaks if subdir is more than 1 level depth. Leak is only
+ per subdir entry, and not dependent on number of
+ connections, so it should be fine for now */
+ inode_ref(inode);
+
+out:
+ return inode;
+}
+
+int
+server_first_lookup(xlator_t *this, client_t *client, dict_t *reply)
+{
+ loc_t loc = {
+ 0,
+ };
+ struct iatt iatt = {
+ 0,
+ };
+ dict_t *dict = NULL;
+ int ret = 0;
+ xlator_t *xl = client->bound_xl;
+ char *msg = NULL;
+ inode_t *inode = NULL;
+ char *bname = NULL;
+ char *str = NULL;
+ char *tmp = NULL;
+ char *saveptr = NULL;
+
+ loc.path = "/";
+ loc.name = "";
+ loc.inode = xl->itable->root;
+ loc.parent = NULL;
+ gf_uuid_copy(loc.gfid, loc.inode->gfid);
+
+ ret = syncop_lookup(xl, &loc, &iatt, NULL, NULL, NULL);
+ if (ret < 0)
+ gf_log(xl->name, GF_LOG_ERROR, "lookup on root failed: %s",
+ strerror(errno));
+ /* Ignore error from lookup, don't set
+ * failure in rsp->op_ret. lookup on a snapview-server
+ * can fail with ESTALE
+ */
+ /* TODO-SUBDIR-MOUNT: validate above comment with respect to subdir lookup
+ */
+
+ if (client->subdir_mount) {
+ str = tmp = gf_strdup(client->subdir_mount);
+ dict = dict_new();
+ inode = xl->itable->root;
+ bname = strtok_r(str, "/", &saveptr);
+ while (bname != NULL) {
+ inode = do_path_lookup(xl, dict, inode, bname);
+ if (inode == NULL) {
+ gf_log(this->name, GF_LOG_ERROR,
+ "first lookup on subdir (%s) failed: %s",
+ client->subdir_mount, strerror(errno));
+ ret = -1;
+ goto fail;
+ }
+ bname = strtok_r(NULL, "/", &saveptr);
+ }
+
+ /* Can be used in server_resolve() */
+ gf_uuid_copy(client->subdir_gfid, inode->gfid);
+ client->subdir_inode = inode;
+ }
+
+ ret = 0;
+ goto out;
+
+fail:
+ /* we should say to client, it is not possible
+ to connect */
+ ret = gf_asprintf(&msg, "subdirectory for mount \"%s\" is not found",
+ client->subdir_mount);
+ if (-1 == ret) {
+ gf_msg(this->name, GF_LOG_ERROR, 0, PS_MSG_ASPRINTF_FAILED,
+ "asprintf failed while setting error msg");
+ }
+ ret = dict_set_dynstr(reply, "ERROR", msg);
+ if (ret < 0)
+ gf_msg_debug(this->name, 0,
+ "failed to set error "
+ "msg");
+
+ ret = -1;
+out:
+ if (dict)
+ dict_unref(dict);
+
+ inode_unref(loc.inode);
+
+ if (tmp)
+ GF_FREE(tmp);
+
+ return ret;
+}
+
+int
+server_setvolume(rpcsvc_request_t *req)
+{
+ gf_setvolume_req args = {
+ {
+ 0,
+ },
+ };
+ gf_setvolume_rsp *rsp = NULL;
+ 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 *volume_id = NULL;
+ char *client_uid = NULL;
+ char *clnt_version = NULL;
+ xlator_t *xl = NULL;
+ char *msg = NULL;
+ xlator_t *this = NULL;
+ int32_t ret = -1;
+ int32_t op_ret = -1;
+ int32_t op_errno = EINVAL;
+ uint32_t opversion = 0;
+ rpc_transport_t *xprt = NULL;
+ int32_t fop_version = 0;
+ int32_t mgmt_version = 0;
+ glusterfs_ctx_t *ctx = NULL;
+ struct _child_status *tmp = NULL;
+ char *subdir_mount = NULL;
+ char *client_name = NULL;
+ gf_boolean_t cleanup_starting = _gf_false;
+ gf_boolean_t xlator_in_graph = _gf_true;
+
+ 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;
+ }
+ ctx = THIS->ctx;
+
+ this = req->svc->xl;
+ /* this is to ensure config_params is populated with the first brick
+ * details at first place if brick multiplexing is enabled
+ */
+ config_params = dict_copy_with_ref(this->options, NULL);
+
+ ret = dict_unserialize(args.dict.dict_val, args.dict.dict_len, &params);
+ if (ret < 0) {
+ ret = dict_set_sizen_str_sizen(reply, "ERROR",
+ "Internal error: failed to unserialize "
+ "request dictionary");
+ if (ret < 0)
+ gf_msg_debug(this->name, 0,
+ "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, "remote-subvolume", &name);
+ if (ret < 0) {
+ ret = dict_set_str(reply, "ERROR",
+ "No remote-subvolume option specified");
+ if (ret < 0)
+ gf_msg_debug(this->name, 0,
+ "failed to set error "
+ "msg");
+
+ op_ret = -1;
+ op_errno = EINVAL;
+ goto fail;
+ }
+
+ LOCK(&ctx->volfile_lock);
+ {
+ xl = get_xlator_by_name(this, name);
+ if (!xl) {
+ xlator_in_graph = _gf_false;
+ xl = this;
+ }
+ }
+ UNLOCK(&ctx->volfile_lock);
+ if (xl == NULL) {
+ ret = gf_asprintf(&msg, "remote-subvolume \"%s\" is not found", name);
+ if (-1 == ret) {
+ gf_msg(this->name, GF_LOG_ERROR, 0, PS_MSG_ASPRINTF_FAILED,
+ "asprintf failed while setting error msg");
+ goto fail;
+ }
+ ret = dict_set_dynstr(reply, "ERROR", msg);
+ if (ret < 0)
+ gf_msg_debug(this->name, 0,
+ "failed to set error "
+ "msg");
+
+ op_ret = -1;
+ op_errno = ENOENT;
+ goto fail;
+ }
+
+ config_params = dict_copy_with_ref(xl->options, config_params);
+ conf = this->private;
+
+ if (conf->parent_up == _gf_false) {
+ /* PARENT_UP indicates that all xlators in graph are inited
+ * successfully
+ */
+ op_ret = -1;
+ op_errno = EAGAIN;
+
+ ret = dict_set_str(reply, "ERROR",
+ "xlator graph in server is not initialised "
+ "yet. Try again later");
+ if (ret < 0)
+ gf_msg_debug(this->name, 0,
+ "failed to set error: "
+ "xlator graph in server is not "
+ "initialised yet. Try again later");
+ goto fail;
+ }
+
+ pthread_mutex_lock(&conf->mutex);
+ list_for_each_entry(tmp, &conf->child_status->status_list, status_list)
+ {
+ if (strcmp(tmp->name, name) == 0)
+ break;
+ }
+
+ if (!tmp->name) {
+ gf_msg(this->name, GF_LOG_INFO, 0, PS_MSG_CHILD_STATUS_FAILED,
+ "No xlator %s is found in child status list", name);
+ } else {
+ ret = dict_set_int32(reply, "child_up", tmp->child_up);
+ if (ret < 0)
+ gf_msg(this->name, GF_LOG_ERROR, 0, PS_MSG_DICT_GET_FAILED,
+ "Failed to set 'child_up' for xlator %s "
+ "in the reply dict",
+ tmp->name);
+ if (!tmp->child_up) {
+ ret = dict_set_str(reply, "ERROR",
+ "Not received child_up for this xlator");
+ if (ret < 0)
+ gf_msg_debug(this->name, 0, "failed to set error msg");
+
+ gf_msg(this->name, GF_LOG_ERROR, 0, PS_MSG_CHILD_STATUS_FAILED,
+ "Not received child_up for this xlator %s", name);
+ op_ret = -1;
+ op_errno = EAGAIN;
+ pthread_mutex_unlock(&conf->mutex);
+ goto fail;
+ }
+ }
+ pthread_mutex_unlock(&conf->mutex);
+
+ 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_msg_debug(this->name, 0,
+ "failed to set error "
+ "msg");
+
+ op_ret = -1;
+ op_errno = EINVAL;
+ goto fail;
+ }
+
+ ret = dict_get_str(params, "subdir-mount", &subdir_mount);
+ if (ret < 0) {
+ /* Not a problem at all as the key is optional */
+ }
+ ret = dict_get_str(params, "process-name", &client_name);
+ if (ret < 0) {
+ client_name = "unknown";
+ }
+
+ /* If any value is set, the first element will be non-0.
+ It would be '0', but not '\0' :-) */
+ if (xl->graph->volume_id[0]) {
+ ret = dict_get_str_sizen(params, "volume-id", &volume_id);
+ if (!ret && strcmp(xl->graph->volume_id, volume_id)) {
+ ret = dict_set_str(reply, "ERROR",
+ "Volume-ID different, possible case "
+ "of same brick re-used in another volume");
+ if (ret < 0)
+ gf_msg_debug(this->name, 0, "failed to set error msg");
+
+ op_ret = -1;
+ op_errno = EINVAL;
+ goto fail;
+ }
+ ret = dict_set_str(reply, "volume-id", tmp->volume_id);
+ if (ret)
+ gf_msg_debug(this->name, 0, "failed to set 'volume-id'");
+ }
+ client = gf_client_get(this, &req->cred, client_uid, subdir_mount);
+ if (client == NULL) {
+ op_ret = -1;
+ op_errno = ENOMEM;
+ goto fail;
+ }
+
+ client->client_name = gf_strdup(client_name);
+
+ gf_msg_debug(this->name, 0, "Connected to %s", client->client_uid);
+
+ serv_ctx = server_ctx_get(client, client->this);
+ if (serv_ctx == NULL) {
+ gf_msg(this->name, GF_LOG_INFO, 0, PS_MSG_SERVER_CTX_GET_FAILED,
+ "server_ctx_get() "
+ "failed");
+ goto fail;
+ }
+
+ pthread_mutex_lock(&conf->mutex);
+ if (xl->cleanup_starting) {
+ cleanup_starting = _gf_true;
+ } else if (req->trans->xl_private != client) {
+ req->trans->xl_private = client;
+ }
+ pthread_mutex_unlock(&conf->mutex);
+
+ if (cleanup_starting) {
+ op_ret = -1;
+ op_errno = EAGAIN;
+
+ ret = dict_set_str(reply, "ERROR",
+ "cleanup flag is set for xlator. "
+ " Try again later");
+ if (ret < 0)
+ gf_msg_debug(this->name, 0,
+ "failed to set error: "
+ "cleanup flag is set for xlator. "
+ "Try again later");
+ goto fail;
+ }
+
+ auth_set_username_passwd(params, config_params, client);
+ if (req->trans->ssl_name) {
+ if (dict_set_str(params, "ssl-name", req->trans->ssl_name) != 0) {
+ gf_msg(this->name, GF_LOG_WARNING, 0, PS_MSG_SSL_NAME_SET_FAILED,
+ "failed to set "
+ "ssl_name %s",
+ req->trans->ssl_name);
+ /* Not fatal, auth will just fail. */
+ }
+ }
+
+ 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_msg_debug(this->name, 0,
+ "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_msg_debug(this->name, 0,
+ "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_msg(this->name, GF_LOG_ERROR, 0, PS_MSG_ASPRINTF_FAILED,
+ "asprintf failed while"
+ "setting up error msg");
+ goto fail;
+ }
+ ret = dict_set_dynstr(reply, "ERROR", msg);
+ if (ret < 0)
+ gf_msg_debug(this->name, 0,
+ "failed to set error "
+ "msg");
+
+ op_ret = -1;
+ op_errno = EINVAL;
+ goto fail;
+ }
+
+ peerinfo = &req->trans->peerinfo;
+ if (peerinfo) {
+ ret = dict_set_static_ptr(params, "peer-info", peerinfo);
+ if (ret < 0)
+ gf_msg_debug(this->name, 0,
+ "failed to set "
+ "peer-info");
+ }
+
+ ret = dict_get_uint32(params, "opversion", &opversion);
+ if (ret) {
+ gf_msg(this->name, GF_LOG_INFO, 0, PS_MSG_CLIENT_OPVERSION_GET_FAILED,
+ "Failed to get client opversion");
+ }
+ client->opversion = opversion;
+ /* Assign op-version value to the client */
+ pthread_mutex_lock(&conf->mutex);
+ list_for_each_entry(xprt, &conf->xprt_list, list)
+ {
+ if (strcmp(peerinfo->identifier, xprt->peerinfo.identifier))
+ continue;
+ xprt->peerinfo.max_op_version = opversion;
+ }
+ pthread_mutex_unlock(&conf->mutex);
+
+ if (conf->auth_modules == NULL) {
+ gf_msg(this->name, GF_LOG_ERROR, 0, PS_MSG_AUTH_INIT_FAILED,
+ "Authentication module not initialized");
+ }
+
+ ret = dict_get_str(params, "client-version", &clnt_version);
+ if (ret)
+ gf_msg(this->name, GF_LOG_INFO, 0, PS_MSG_CLIENT_VERSION_NOT_SET,
+ "client-version not set, may be of older version");
+
+ ret = gf_authenticate(params, config_params, conf->auth_modules);
+
+ if (ret == AUTH_ACCEPT) {
+ /* Store options received from client side */
+ req->trans->clnt_options = dict_ref(params);
+
+ gf_msg(this->name, GF_LOG_INFO, 0, PS_MSG_CLIENT_ACCEPTED,
+ "accepted client from %s (version: %s) with subvol %s",
+ client->client_uid, (clnt_version) ? clnt_version : "old", name);
+
+ gf_event(EVENT_CLIENT_CONNECT,
+ "client_uid=%s;"
+ "client_identifier=%s;server_identifier=%s;"
+ "brick_path=%s;subdir_mount=%s",
+ client->client_uid, req->trans->peerinfo.identifier,
+ req->trans->myinfo.identifier, name, subdir_mount);
+
+ op_ret = 0;
+ client->bound_xl = xl;
+
+ /* Don't be confused by the below line (like how ERROR can
+ be Success), key checked on client is 'ERROR' and hence
+ we send 'Success' in this key */
+ ret = dict_set_str(reply, "ERROR", "Success");
+ if (ret < 0)
+ gf_msg_debug(this->name, 0,
+ "failed to set error "
+ "msg");
+ } else {
+ op_ret = -1;
+ if (!xlator_in_graph) {
+ gf_msg(this->name, GF_LOG_ERROR, ENOENT, PS_MSG_AUTHENTICATE_ERROR,
+ "Cannot authenticate client"
+ " from %s %s because brick is not attached in graph",
+ client->client_uid, (clnt_version) ? clnt_version : "old");
+
+ op_errno = ENOENT;
+ ret = dict_set_str(reply, "ERROR", "Brick not found");
+ } else {
+ gf_event(EVENT_CLIENT_AUTH_REJECT,
+ "client_uid=%s;"
+ "client_identifier=%s;server_identifier=%s;"
+ "brick_path=%s",
+ client->client_uid, req->trans->peerinfo.identifier,
+ req->trans->myinfo.identifier, name);
+ gf_msg(this->name, GF_LOG_ERROR, EACCES, PS_MSG_AUTHENTICATE_ERROR,
+ "Cannot authenticate client"
+ " from %s %s",
+ client->client_uid, (clnt_version) ? clnt_version : "old");
+
+ op_errno = EACCES;
+ ret = dict_set_str(reply, "ERROR", "Authentication failed");
+ }
+ if (ret < 0)
+ gf_msg_debug(this->name, 0,
+ "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_msg_debug(this->name, 0,
+ "failed to set error "
+ "msg");
+
+ op_ret = -1;
+ op_errno = EACCES;
+ goto fail;
+ }
+
+ LOCK(&conf->itable_lock);
+ {
+ if (client->bound_xl->itable == NULL) {
+ /* create inode table for this bound_xl, if one doesn't
+ already exist */
+
+ gf_msg_trace(this->name, 0,
+ "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);
+ }
+ }
+ UNLOCK(&conf->itable_lock);
+
+ ret = dict_set_str(reply, "process-uuid", this->ctx->process_uuid);
+ if (ret)
+ gf_msg_debug(this->name, 0, "failed to set 'process-uuid'");
+
+ /* Insert a dummy key value pair to avoid failure at client side for
+ * clnt-lk-version with older clients.
+ */
+ ret = dict_set_uint32(reply, "clnt-lk-version", 0);
+ if (ret) {
+ gf_msg(this->name, GF_LOG_WARNING, 0, PS_MSG_CLIENT_LK_VERSION_ERROR,
+ "failed to set "
+ "'clnt-lk-version'");
+ }
+
+ ret = dict_set_uint64(reply, "transport-ptr", ((uint64_t)(long)req->trans));
+ if (ret)
+ gf_msg_debug(this->name, 0, "failed to set 'transport-ptr'");
+
+fail:
+ /* It is important to validate the lookup on '/' as part of handshake,
+ because if lookup itself can't succeed, we should communicate this
+ to client. Very important in case of subdirectory mounts, where if
+ client is trying to mount a non-existing directory */
+ if (op_ret >= 0 && client->bound_xl->itable) {
+ if (client->bound_xl->cleanup_starting) {
+ op_ret = -1;
+ op_errno = EAGAIN;
+ ret = dict_set_str(reply, "ERROR",
+ "cleanup flag is set for xlator "
+ "before call first_lookup Try again later");
+ /* quisce coverity about UNUSED_VALUE ret */
+ (void)(ret);
+ } else {
+ op_ret = server_first_lookup(this, client, reply);
+ if (op_ret == -1)
+ op_errno = ENOENT;
+ }
+ }
+
+ rsp = GF_CALLOC(1, sizeof(gf_setvolume_rsp), gf_server_mt_setvolume_rsp_t);
+ GF_ASSERT(rsp);
+
+ rsp->op_ret = 0;
+
+ ret = dict_allocate_and_serialize(reply, (char **)&rsp->dict.dict_val,
+ &rsp->dict.dict_len);
+ if (ret != 0) {
+ ret = -1;
+ gf_msg_debug("server-handshake", 0, "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 && (client != NULL)) {
+ /* 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;
+ }
+
+ /* Send the response properly */
+ server_first_lookup_done(req, rsp);
+
+ free(args.dict.dict_val);
+
+ dict_unref(params);
+ dict_unref(reply);
+ if (config_params) {
+ /*
+ * This might be null if we couldn't even find the translator
+ * (brick) to copy it from.
+ */
+ dict_unref(config_params);
+ }
+
+ 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 ret = -1;
+ gf_set_lk_ver_req args = {
+ 0,
+ };
+ gf_set_lk_ver_rsp rsp = {
+ 0,
+ };
+
+ ret = xdr_to_generic(req->msg[0], &args, (xdrproc_t)xdr_gf_set_lk_ver_req);
+ if (ret < 0) {
+ /* failed to decode msg */
+ req->rpc_err = GARBAGE_ARGS;
+ goto fail;
+ }
+
+ rsp.lk_ver = args.lk_ver;
+fail:
+ server_submit_reply(NULL, req, &rsp, NULL, 0, NULL,
+ (xdrproc_t)xdr_gf_set_lk_ver_rsp);
+
+ free(args.uid);
+
+ return 0;
+}
+
+static rpcsvc_actor_t gluster_handshake_actors[GF_HNDSK_MAXVALUE] = {
+ [GF_HNDSK_NULL] = {"NULL", server_null, NULL, GF_HNDSK_NULL, DRC_NA, 0},
+ [GF_HNDSK_SETVOLUME] = {"SETVOLUME", server_setvolume, NULL,
+ GF_HNDSK_SETVOLUME, DRC_NA, 0},
+ [GF_HNDSK_GETSPEC] = {"GETSPEC", server_getspec, NULL, GF_HNDSK_GETSPEC,
+ DRC_NA, 0},
+ [GF_HNDSK_PING] = {"PING", server_ping, NULL, GF_HNDSK_PING, DRC_NA, 0},
+ [GF_HNDSK_SET_LK_VER] = {"SET_LK_VER", server_set_lk_version, NULL,
+ GF_HNDSK_SET_LK_VER, DRC_NA, 0},
+};
+
+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 1fa400d5fab..6e644912a46 100644
--- a/xlators/protocol/server/src/server-helpers.c
+++ b/xlators/protocol/server/src/server-helpers.c
@@ -1,601 +1,1507 @@
/*
- 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
-#define _CONFIG_H
-#include "config.h"
-#endif
-
-#include "server-protocol.h"
+#include "server.h"
#include "server-helpers.h"
+#include <glusterfs/gidcache.h>
+#include "server-messages.h"
+#include <glusterfs/syscall.h>
+#include <glusterfs/defaults.h>
+#include <glusterfs/default-args.h>
+#include "server-common.h"
+#include <fnmatch.h>
+#include <pwd.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.
- */
+/* based on nfs_fix_aux_groups() */
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));
-
- inode_unref (loc->inode);
- loc->inode = NULL;
- }
- }
-
- 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++;
- }
+gid_resolve(server_conf_t *conf, call_stack_t *root)
+{
+ int ret = 0;
+ struct passwd mypw;
+ char mystrs[1024];
+ struct passwd *result;
+ gid_t *mygroups = NULL;
+ gid_list_t gl;
+ int ngroups;
+ const gid_list_t *agl;
+
+ agl = gid_cache_lookup(&conf->gid_cache, root->uid, 0, 0);
+ if (agl) {
+ root->ngrps = agl->gl_count;
+
+ if (root->ngrps > 0) {
+ ret = call_stack_alloc_groups(root, agl->gl_count);
+ if (ret == 0) {
+ memcpy(root->groups, agl->gl_list,
+ sizeof(gid_t) * agl->gl_count);
+ }
+ }
+
+ gid_cache_release(&conf->gid_cache, agl);
+
+ return ret;
+ }
+
+ ret = getpwuid_r(root->uid, &mypw, mystrs, sizeof(mystrs), &result);
+ if (ret != 0) {
+ gf_smsg("gid-cache", GF_LOG_ERROR, errno, PS_MSG_GET_UID_FAILED,
+ "uid=%u", root->uid, NULL);
+ return -1;
+ }
+
+ if (!result) {
+ gf_smsg("gid-cache", GF_LOG_ERROR, 0, PS_MSG_UID_NOT_FOUND, "uid=%u",
+ root->uid, NULL);
+ return -1;
+ }
+
+ gf_msg_trace("gid-cache", 0, "mapped %u => %s", root->uid, result->pw_name);
+
+ ngroups = gf_getgrouplist(result->pw_name, root->gid, &mygroups);
+ if (ngroups == -1) {
+ gf_smsg("gid-cache", GF_LOG_ERROR, 0, PS_MSG_MAPPING_ERROR,
+ "pw_name=%s", result->pw_name, "root->ngtps=%d", root->ngrps,
+ NULL);
+ return -1;
+ }
+ root->ngrps = (uint16_t)ngroups;
+
+ /* setup a full gid_list_t to add it to the gid_cache */
+ gl.gl_id = root->uid;
+ gl.gl_uid = root->uid;
+ gl.gl_gid = root->gid;
+ gl.gl_count = root->ngrps;
+
+ gl.gl_list = GF_MALLOC(root->ngrps * sizeof(gid_t), gf_common_mt_groups_t);
+ if (gl.gl_list)
+ memcpy(gl.gl_list, mygroups, sizeof(gid_t) * root->ngrps);
+ else {
+ GF_FREE(mygroups);
+ return -1;
+ }
+
+ if (root->ngrps > 0) {
+ call_stack_set_groups(root, root->ngrps, &mygroups);
+ }
+
+ if (gid_cache_add(&conf->gid_cache, &gl) != 1)
+ GF_FREE(gl.gl_list);
+
+ return ret;
+}
+int
+server_resolve_groups(call_frame_t *frame, rpcsvc_request_t *req)
+{
+ xlator_t *this = NULL;
+ server_conf_t *conf = NULL;
+
+ GF_VALIDATE_OR_GOTO("server", frame, out);
+ GF_VALIDATE_OR_GOTO("server", req, out);
+
+ this = req->trans->xl;
+ conf = this->private;
+
+ return gid_resolve(conf, frame->root);
out:
- return ret;
+ return -1;
}
-/*
- * 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)
-{
- 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);
-
-
- 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);
-
- return tmp_buf;
+int
+server_decode_groups(call_frame_t *frame, rpcsvc_request_t *req)
+{
+ int i = 0;
+
+ GF_VALIDATE_OR_GOTO("server", frame, out);
+ GF_VALIDATE_OR_GOTO("server", req, out);
+
+ if (call_stack_alloc_groups(frame->root, req->auxgidcount) != 0)
+ return -1;
+
+ frame->root->ngrps = req->auxgidcount;
+ if (frame->root->ngrps == 0)
+ return 0;
+
+ /* ngrps cannot be bigger than USHRT_MAX(65535) */
+ 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);
+ loc->parent = NULL;
+ }
+
+ if (loc->inode) {
+ inode_unref(loc->inode);
+ loc->inode = NULL;
+ }
+
+ GF_FREE((void *)loc->path);
+}
void
-server_loc_wipe (loc_t *loc)
+server_resolve_wipe(server_resolve_t *resolve)
{
- if (loc->parent)
- inode_unref (loc->parent);
- if (loc->inode)
- inode_unref (loc->inode);
- if (loc->path)
- free ((char *)loc->path);
+ GF_FREE((void *)resolve->path);
+
+ GF_FREE((void *)resolve->bname);
+
+ loc_wipe(&resolve->resolve_loc);
}
void
-free_state (server_state_t *state)
+free_state(server_state_t *state)
{
- transport_t *trans = NULL;
+ if (state->fd) {
+ fd_unref(state->fd);
+ state->fd = NULL;
+ }
+
+ if (state->params) {
+ dict_unref(state->params);
+ state->params = NULL;
+ }
+
+ if (state->iobref) {
+ iobref_unref(state->iobref);
+ state->iobref = NULL;
+ }
+
+ if (state->iobuf) {
+ iobuf_unref(state->iobuf);
+ state->iobuf = NULL;
+ }
+
+ if (state->dict) {
+ dict_unref(state->dict);
+ state->dict = NULL;
+ }
+
+ if (state->xdata) {
+ dict_unref(state->xdata);
+ state->xdata = NULL;
+ }
+
+ GF_FREE((void *)state->volume);
+
+ GF_FREE((void *)state->name);
+
+ server_loc_wipe(&state->loc);
+ server_loc_wipe(&state->loc2);
+
+ server_resolve_wipe(&state->resolve);
+ server_resolve_wipe(&state->resolve2);
+
+ /* Call rpc_trnasport_unref to avoid crashes at last after free
+ all resources because of server_rpc_notify (for transport destroy)
+ call's xlator_mem_cleanup if all xprt are destroyed that internally
+ call's inode_table_destroy.
+ */
+ if (state->xprt) {
+ rpc_transport_unref(state->xprt);
+ state->xprt = NULL;
+ }
+
+ GF_FREE(state);
+}
- trans = state->trans;
+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)
+{
+ int32_t ret = -1;
+ fd_t *fd = NULL;
+ client_t *client = NULL;
+ uint64_t fd_cnt = 0;
+ xlator_t *victim = NULL;
+ server_conf_t *conf = NULL;
+ xlator_t *serv_xl = NULL;
+ rpc_transport_t *xprt = NULL;
+ rpc_transport_t *xp_next = NULL;
+ int32_t detach = (long)cookie;
+ gf_boolean_t xprt_found = _gf_false;
+
+ GF_VALIDATE_OR_GOTO("server", this, out);
+ GF_VALIDATE_OR_GOTO("server", frame, out);
+
+ fd = frame->local;
+ client = frame->root->client;
+ serv_xl = frame->this;
+ conf = serv_xl->private;
+
+ fd_unref(fd);
+ frame->local = NULL;
+
+ if (client)
+ victim = client->bound_xl;
+
+ if (victim) {
+ fd_cnt = GF_ATOMIC_DEC(client->fd_cnt);
+ if (!fd_cnt && conf && detach) {
+ pthread_mutex_lock(&conf->mutex);
+ {
+ list_for_each_entry_safe(xprt, xp_next, &conf->xprt_list, list)
+ {
+ if (!xprt->xl_private)
+ continue;
+ if (xprt->xl_private == client) {
+ xprt_found = _gf_true;
+ break;
+ }
+ }
+ }
+ pthread_mutex_unlock(&conf->mutex);
+ if (xprt_found) {
+ rpc_transport_unref(xprt);
+ }
+ }
+ }
+
+ gf_client_unref(client);
+ STACK_DESTROY(frame->root);
+
+ ret = 0;
+out:
+ return ret;
+}
- if (state->fd)
- fd_unref (state->fd);
+static int
+do_fd_cleanup(xlator_t *this, client_t *client, fdentry_t *fdentries,
+ int fd_count, int32_t detach)
+{
+ fd_t *fd = NULL;
+ int i = 0, ret = -1;
+ call_frame_t *tmp_frame = NULL;
+ xlator_t *bound_xl = NULL;
+ 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 = create_frame(this, this->ctx->pool);
+ if (tmp_frame == NULL) {
+ goto out;
+ }
+
+ tmp_frame->root->type = GF_OP_TYPE_FOP;
+ GF_ASSERT(fd->inode);
+
+ ret = inode_path(fd->inode, NULL, &path);
+
+ if (ret > 0) {
+ gf_smsg(this->name, GF_LOG_INFO, 0, PS_MSG_FD_CLEANUP,
+ "path=%s", path, NULL);
+ GF_FREE(path);
+ } else {
+ gf_smsg(this->name, GF_LOG_INFO, 0, PS_MSG_FD_CLEANUP,
+ "inode-gfid=%s", uuid_utoa(fd->inode->gfid), NULL);
+ }
+
+ tmp_frame->local = fd;
+ tmp_frame->root->pid = 0;
+ gf_client_ref(client);
+ tmp_frame->root->client = client;
+ memset(&tmp_frame->root->lk_owner, 0, sizeof(gf_lkowner_t));
+
+ STACK_WIND_COOKIE(tmp_frame, server_connection_cleanup_flush_cbk,
+ (void *)(long)detach, bound_xl,
+ bound_xl->fops->flush, fd, NULL);
+ }
+ }
+
+ GF_FREE(fdentries);
+ ret = 0;
- transport_unref (trans);
-
- if (state->xattr_req)
- dict_unref (state->xattr_req);
+out:
+ return ret;
+}
+
+int
+server_connection_cleanup(xlator_t *this, client_t *client, int32_t flags,
+ gf_boolean_t *fd_exist)
+{
+ server_ctx_t *serv_ctx = NULL;
+ fdentry_t *fdentries = NULL;
+ uint32_t fd_count = 0;
+ int cd_ret = 0;
+ int ret = 0;
+ xlator_t *bound_xl = NULL;
+ int i = 0;
+ fd_t *fd = NULL;
+ uint64_t fd_cnt = 0;
+ int32_t detach = 0;
+
+ GF_VALIDATE_OR_GOTO("server", 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);
+
+ if (serv_ctx == NULL) {
+ gf_smsg(this->name, GF_LOG_INFO, 0, PS_MSG_SERVER_CTX_GET_FAILED, NULL);
+ goto out;
+ }
+
+ 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);
+
+ if (client->bound_xl == NULL)
+ goto out;
+
+ if (flags & INTERNAL_LOCKS) {
+ cd_ret = gf_client_disconnect(client);
+ }
+
+ if (fdentries != NULL) {
+ /* Loop to configure fd_count on victim brick */
+ bound_xl = client->bound_xl;
+ if (bound_xl) {
+ for (i = 0; i < fd_count; i++) {
+ fd = fdentries[i].fd;
+ if (!fd)
+ continue;
+ fd_cnt++;
+ }
+ if (fd_cnt) {
+ if (fd_exist)
+ (*fd_exist) = _gf_true;
+ GF_ATOMIC_ADD(client->fd_cnt, fd_cnt);
+ }
+ }
+
+ /* If fd_exist is not NULL it means function is invoke
+ by server_rpc_notify at the time of getting DISCONNECT
+ notification
+ */
+ if (fd_exist)
+ detach = 1;
+
+ gf_msg_debug(this->name, 0,
+ "Performing cleanup on %d "
+ "fdentries",
+ fd_count);
+ ret = do_fd_cleanup(this, client, fdentries, fd_count, detach);
+ } else
+ gf_smsg(this->name, GF_LOG_INFO, 0, PS_MSG_FDENTRY_NULL, NULL);
+
+ if (cd_ret || ret)
+ ret = -1;
- FREE (state);
+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;
+
+ frame->root->type = GF_OP_TYPE_FOP;
+ 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->this = client->this;
+out:
+ return frame;
+}
call_frame_t *
-server_copy_frame (call_frame_t *frame)
+get_frame_from_request(rpcsvc_request_t *req)
+{
+ call_frame_t *frame = NULL;
+ client_t *client = NULL;
+ client_t *tmp_client = NULL;
+ xlator_t *this = NULL;
+ server_conf_t *priv = NULL;
+ clienttable_t *clienttable = NULL;
+ unsigned int i = 0;
+ rpc_transport_t *trans = NULL;
+ server_state_t *state = NULL;
+
+ GF_VALIDATE_OR_GOTO("server", req, out);
+
+ frame = server_alloc_frame(req);
+ if (!frame)
+ goto out;
+
+ frame->root->op = req->procnum;
+
+ client = req->trans->xl_private;
+ this = req->trans->xl;
+ priv = this->private;
+ clienttable = this->ctx->clienttable;
+
+ for (i = 0; i < clienttable->max_clients; i++) {
+ tmp_client = clienttable->cliententries[i].client;
+ if (client == tmp_client) {
+ /* for non trusted clients username and password
+ would not have been set. So for non trusted clients
+ (i.e clients not from the same machine as the brick,
+ and clients from outside the storage pool)
+ do the root-squashing and all-squashing.
+ TODO: If any client within the storage pool (i.e
+ mounting within a machine from the pool but using
+ other machine's ip/hostname from the same pool)
+ is present treat it as a trusted client
+ */
+ if (!client->auth.username && req->pid != NFS_PID) {
+ RPC_AUTH_ROOT_SQUASH(req);
+ RPC_AUTH_ALL_SQUASH(req);
+ }
+
+ /* Problem: If we just check whether the client is
+ trusted client and do not do root squashing and
+ all squashing for them, then for smb clients and
+ UFO clients root squashing and all squashing will
+ never happen as they use the fuse mounts done within
+ the trusted pool (i.e they are trusted clients).
+ Solution: To fix it, do root squashing and all squashing
+ for trusted clients also. If one wants to have a client
+ within the storage pool for which root-squashing does
+ not happen, then the client has to be mounted with
+ --no-root-squash option. But for defrag client and
+ gsyncd client do not do root-squashing and all-squashing.
+ */
+ if (client->auth.username &&
+ req->pid != GF_CLIENT_PID_NO_ROOT_SQUASH &&
+ req->pid != GF_CLIENT_PID_GSYNCD &&
+ req->pid != GF_CLIENT_PID_DEFRAG &&
+ req->pid != GF_CLIENT_PID_SELF_HEALD &&
+ req->pid != GF_CLIENT_PID_QUOTA_MOUNT) {
+ RPC_AUTH_ROOT_SQUASH(req);
+ RPC_AUTH_ALL_SQUASH(req);
+ }
+
+ /* For nfs clients the server processes will be running
+ within the trusted storage pool machines. So if we
+ do not do root-squashing and all-squashing for nfs
+ servers, thinking that its a trusted client, then
+ root-squashing and all-squashing won't work for nfs
+ clients.
+ */
+ if (req->pid == NFS_PID) {
+ RPC_AUTH_ROOT_SQUASH(req);
+ RPC_AUTH_ALL_SQUASH(req);
+ }
+ }
+ }
+
+ /* Add a ref for this fop */
+ if (client)
+ gf_client_ref(client);
+
+ frame->root->uid = req->uid;
+ frame->root->gid = req->gid;
+ frame->root->pid = req->pid;
+ frame->root->client = client;
+ frame->root->lk_owner = req->lk_owner;
+
+ if (priv->server_manage_gids)
+ server_resolve_groups(frame, req);
+ else
+ server_decode_groups(frame, req);
+ trans = req->trans;
+ if (trans) {
+ memcpy(&frame->root->identifier, trans->peerinfo.identifier,
+ sizeof(trans->peerinfo.identifier));
+ }
+
+ /* more fields, for the clients which are 3.x series this will be 0 */
+ frame->root->flags = req->flags;
+ frame->root->ctime = req->ctime;
+
+ frame->local = req;
+
+ state = CALL_STATE(frame);
+ state->client = client;
+out:
+ return frame;
+}
+
+int
+server_build_config(xlator_t *this, server_conf_t *conf)
{
- call_frame_t *new_frame = NULL;
- server_state_t *state = NULL, *new_state = NULL;
+ 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_smsg(this->name, GF_LOG_WARNING, EINVAL, PS_MSG_WRONG_VALUE,
+ NULL);
+ }
+ }
+
+ data = dict_get(this->options, "trace");
+ if (data) {
+ ret = gf_string2boolean(data->data, &conf->trace);
+ if (ret != 0) {
+ gf_smsg(this->name, GF_LOG_WARNING, EINVAL, PS_MSG_INVALID_ENTRY,
+ NULL);
+ }
+ }
+
+ /* TODO: build_rpc_config (); */
+ ret = dict_get_int32(this->options, "limits.transaction-size",
+ &conf->rpc_conf.max_block_size);
+ if (ret < 0) {
+ gf_msg_trace(this->name, 0,
+ "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 = sys_stat(data->data, &buf);
+ if ((ret != 0) || !S_ISDIR(buf.st_mode)) {
+ gf_smsg(this->name, GF_LOG_ERROR, 0, PS_MSG_DIR_NOT_FOUND,
+ "data=%s", data->data, NULL);
+ ret = -1;
+ goto out;
+ }
+ /* Make sure that conf-dir doesn't contain ".." in path */
+ if ((gf_strstr(data->data, "/", "..")) == -1) {
+ ret = -1;
+ gf_smsg(this->name, GF_LOG_ERROR, 0, PS_MSG_CONF_DIR_INVALID,
+ "data=%s", data->data, NULL);
+ goto out;
+ }
+
+ conf->conf_dir = gf_strdup(data->data);
+ }
+ ret = 0;
+out:
+ return ret;
+}
- state = frame->root->state;
+void
+print_caller(char *str, int size, call_frame_t *frame)
+{
+ server_state_t *state = NULL;
- new_frame = copy_frame (frame);
+ GF_VALIDATE_OR_GOTO("server", str, out);
+ GF_VALIDATE_OR_GOTO("server", frame, out);
- new_state = CALLOC (1, sizeof (server_state_t));
+ state = CALL_STATE(frame);
- 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;
+ snprintf(str, size, " Callid=%" PRId64 ", Client=%s", frame->root->unique,
+ state->xprt->peerinfo.identifier);
- new_state->bound_xl = state->bound_xl;
- new_state->trans = transport_ref (state->trans);
- new_state->itable = state->itable;
+out:
+ return;
+}
- return new_frame;
+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;
}
-int32_t
-gf_add_locker (struct _lock_table *table,
- const char *volume,
- loc_t *loc,
- fd_t *fd,
- pid_t pid)
+void
+server_print_loc(char *str, int size, loc_t *loc)
{
- int32_t ret = -1;
- struct _locker *new = NULL;
- uint8_t dir = 0;
+ int filled = 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);
+ GF_VALIDATE_OR_GOTO("server", str, out);
- new->volume = strdup (volume);
+ if (!loc) {
+ snprintf(str, size, "<nul>");
+ return;
+ }
- 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);
- }
+ filled += snprintf(str + filled, size - filled, " Loc={");
- new->pid = pid;
+ 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);
- 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);
+ snprintf(str + filled, size - filled, "}");
out:
- return ret;
-}
-
-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 **bufferp)
-{
- dir_entry_t *trav = NULL;
- uint32_t len = 0;
- uint32_t this_len = 0;
- char *buffer = NULL;
- 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;
- }
-
- buffer = CALLOC (1, len);
- if (buffer == NULL) {
- gf_log ("server", GF_LOG_ERROR,
- "failed to allocate memory for buffer");
- goto out;
- }
-
- 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;
- }
- if (bufferp)
- *bufferp = buffer;
- buflen = strlen (buffer);
-
+ 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 buflen;
+ return;
}
+int
+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;
-static struct _lock_table *
-gf_lock_table_new (void)
+ return 1;
+}
+
+void
+server_print_reply(call_frame_t *frame, int op_ret, int op_errno)
{
- struct _lock_table *new = NULL;
+ server_conf_t *conf = NULL;
+ server_state_t *state = NULL;
+ xlator_t *this = NULL;
+ char caller[512];
+ char fdstr[32];
+ char *op = "UNKNOWN";
- 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);
+ 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_smsg(this->name, GF_LOG_INFO, op_errno, PS_MSG_SERVER_MSG, "op=%s", op,
+ "caller=%s", caller, "op_ret=%d", op_ret, "op_errno=%d", op_errno,
+ "fdstr=%s", fdstr, NULL);
out:
- return new;
+ return;
}
+void
+server_print_request(call_frame_t *frame)
+{
+ 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;
+
+ 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);
+ }
+
+ 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_smsg(this->name, GF_LOG_INFO, 0, PS_MSG_SERVER_MSG, "op=%s", op,
+ "caller=%s", caller, "resolve_vars=%s", resolve_vars, "loc_vars=%s",
+ loc_vars, "resolve2_vars=%s", resolve2_vars, "loc2_vars=%s",
+ loc2_vars, "other_vars=%s", other_vars, NULL);
+out:
+ return;
+}
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,};
-
-
- 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) {
- gf_fd_fdtable_destroy (conn->fdtable);
- conn->fdtable = NULL;
- }
- }
- pthread_mutex_unlock (&conn->lock);
-
- }
-
- gf_log (this->name, GF_LOG_INFO, "destroyed connection of %s",
- conn->id);
-
- FREE (conn->id);
- FREE (conn);
-
- return ret;
-}
-
-
-server_connection_t *
-server_connection_get (xlator_t *this, const char *id)
-{
- server_connection_t *conn = NULL;
- server_connection_t *trav = NULL;
- server_conf_t *conf = NULL;
-
- conf = this->private;
-
- pthread_mutex_lock (&conf->mutex);
- {
- list_for_each_entry (trav, &conf->conns, list) {
- if (!strcmp (id, trav->id)) {
- conn = trav;
- break;
- }
- }
-
- if (!conn) {
- conn = (void *) CALLOC (1, sizeof (*conn));
-
- conn->id = strdup (id);
- conn->fdtable = gf_fd_fdtable_alloc ();
- conn->ltable = gf_lock_table_new ();
+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) {
+ ret = dict_allocate_and_serialize(entry->dict,
+ (char **)&trav->dict.dict_val,
+ &trav->dict.dict_len);
+ if (ret != 0) {
+ gf_smsg(THIS->name, GF_LOG_ERROR, 0, PS_MSG_DICT_SERIALIZE_FAIL,
+ NULL);
+ errno = -ret;
+ trav->dict.dict_len = 0;
+ goto out;
+ }
+ }
+
+ if (prev)
+ prev->nextentry = trav;
+ else
+ rsp->reply = trav;
+
+ prev = trav;
+ trav = NULL;
+ }
+
+ ret = 0;
+out:
+ GF_FREE(trav);
- pthread_mutex_init (&conn->lock, NULL);
+ return ret;
+}
- list_add (&conn->list, &conf->conns);
- }
+int
+serialize_rsp_direntp_v2(gf_dirent_t *entries, gfx_readdirp_rsp *rsp)
+{
+ gf_dirent_t *entry = NULL;
+ gfx_dirplist *trav = NULL;
+ gfx_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;
+
+ gfx_stat_from_iattx(&trav->stat, &entry->d_stat);
+ dict_to_xdr(entry->dict, &trav->dict);
+
+ if (prev)
+ prev->nextentry = trav;
+ else
+ rsp->reply = trav;
+
+ prev = trav;
+ trav = NULL;
+ }
+
+ ret = 0;
+out:
+ GF_FREE(trav);
- conn->ref++;
- }
- pthread_mutex_unlock (&conf->mutex);
+ return ret;
+}
- return conn;
+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", rsp, out);
+ GF_VALIDATE_OR_GOTO("server", entries, 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
+serialize_rsp_dirent_v2(gf_dirent_t *entries, gfx_readdir_rsp *rsp)
+{
+ gf_dirent_t *entry = NULL;
+ gfx_dirlist *trav = NULL;
+ gfx_dirlist *prev = NULL;
+ int ret = -1;
+
+ GF_VALIDATE_OR_GOTO("server", rsp, out);
+ GF_VALIDATE_OR_GOTO("server", entries, 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;
+}
-void
-server_connection_put (xlator_t *this, server_connection_t *conn)
+int
+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;
+ }
+
+ 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
+readdir_rsp_cleanup_v2(gfx_readdir_rsp *rsp)
+{
+ gfx_dirlist *prev = NULL;
+ gfx_dirlist *trav = NULL;
+
+ trav = rsp->reply;
+ prev = trav;
+ while (trav) {
+ trav = trav->nextentry;
+ GF_FREE(prev);
+ prev = trav;
+ }
+
+ return 0;
+}
+
+int
+readdirp_rsp_cleanup_v2(gfx_readdirp_rsp *rsp)
+{
+ gfx_dirplist *prev = NULL;
+ gfx_dirplist *trav = NULL;
+
+ trav = rsp->reply;
+ prev = trav;
+ while (trav) {
+ trav = trav->nextentry;
+ GF_FREE(prev->dict.pairs.pairs_val);
+ GF_FREE(prev);
+ prev = trav;
+ }
+
+ return 0;
+}
+
+static int
+common_rsp_locklist(lock_migration_info_t *locklist, gfs3_locklist **reply)
+{
+ lock_migration_info_t *tmp = NULL;
+ gfs3_locklist *trav = NULL;
+ gfs3_locklist *prev = NULL;
+ int ret = -1;
+
+ GF_VALIDATE_OR_GOTO("server", locklist, out);
+
+ list_for_each_entry(tmp, &locklist->list, list)
+ {
+ trav = GF_CALLOC(1, sizeof(*trav), gf_server_mt_lock_mig_t);
+ if (!trav)
+ goto out;
+
+ switch (tmp->flock.l_type) {
+ case F_RDLCK:
+ tmp->flock.l_type = GF_LK_F_RDLCK;
+ break;
+ case F_WRLCK:
+ tmp->flock.l_type = GF_LK_F_WRLCK;
+ break;
+ case F_UNLCK:
+ tmp->flock.l_type = GF_LK_F_UNLCK;
+ break;
+
+ default:
+ gf_smsg(THIS->name, GF_LOG_ERROR, 0, PS_MSG_LOCK_ERROR,
+ "lock_type=%" PRId32, tmp->flock.l_type, NULL);
+ break;
+ }
+
+ gf_proto_flock_from_flock(&trav->flock, &tmp->flock);
+
+ trav->lk_flags = tmp->lk_flags;
+
+ trav->client_uid = tmp->client_uid;
+
+ if (prev)
+ prev->nextentry = trav;
+ else
+ *reply = trav;
+
+ prev = trav;
+ trav = NULL;
+ }
+
+ ret = 0;
+out:
+ GF_FREE(trav);
+ return ret;
+}
+
+int
+serialize_rsp_locklist(lock_migration_info_t *locklist,
+ gfs3_getactivelk_rsp *rsp)
+{
+ int ret = 0;
+
+ GF_VALIDATE_OR_GOTO("server", rsp, out);
+ ret = common_rsp_locklist(locklist, &rsp->reply);
+out:
+ return ret;
+}
+int
+serialize_rsp_locklist_v2(lock_migration_info_t *locklist,
+ gfx_getactivelk_rsp *rsp)
{
- server_conf_t *conf = NULL;
- server_connection_t *todel = NULL;
+ int ret = 0;
- conf = this->private;
+ GF_VALIDATE_OR_GOTO("server", rsp, out);
+ ret = common_rsp_locklist(locklist, &rsp->reply);
+out:
+ return ret;
+}
+
+int
+getactivelkinfo_rsp_cleanup(gfs3_getactivelk_rsp *rsp)
+{
+ gfs3_locklist *prev = NULL;
+ gfs3_locklist *trav = NULL;
+
+ trav = rsp->reply;
+ prev = trav;
+
+ while (trav) {
+ trav = trav->nextentry;
+ GF_FREE(prev);
+ prev = trav;
+ }
+
+ return 0;
+}
+int
+getactivelkinfo_rsp_cleanup_v2(gfx_getactivelk_rsp *rsp)
+{
+ gfs3_locklist *prev = NULL;
+ gfs3_locklist *trav = NULL;
- pthread_mutex_lock (&conf->mutex);
- {
- conn->ref--;
+ trav = rsp->reply;
+ prev = trav;
- if (!conn->ref) {
- list_del_init (&conn->list);
- todel = conn;
- }
- }
- pthread_mutex_unlock (&conf->mutex);
+ while (trav) {
+ trav = trav->nextentry;
+ 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_smsg("mount-point-list", GF_LOG_INFO, 0,
+ PS_MSG_MOUNT_PT_FAIL, "identifier=%s",
+ xprt->peerinfo.identifier, NULL);
+ }
+ }
+ pthread_mutex_unlock(&conf->mutex);
+ }
+
+ /* Add more options/keys here */
+
+ return 0;
+}
+
+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_smsg("stats", GF_LOG_INFO, 0, PS_MSG_RW_STAT, "total-read=%" PRIu64,
+ total_read, "total-write=%" PRIu64, total_write, NULL);
+ }
+
+ return 0;
+}
+
+server_ctx_t *
+server_ctx_get(client_t *client, xlator_t *xlator)
+{
+ void *tmp = NULL;
+ server_ctx_t *ctx = NULL;
+ server_ctx_t *setted_ctx = NULL;
- if (todel) {
- server_connection_destroy (this, todel);
- }
+ client_ctx_get(client, xlator, &tmp);
- return;
+ ctx = tmp;
+
+ if (ctx != NULL)
+ goto out;
+
+ ctx = GF_CALLOC(1, sizeof(server_ctx_t), gf_server_mt_server_conf_t);
+
+ if (ctx == NULL)
+ goto out;
+
+ ctx->fdtable = gf_fd_fdtable_alloc();
+
+ if (ctx->fdtable == NULL) {
+ GF_FREE(ctx);
+ ctx = NULL;
+ goto out;
+ }
+
+ LOCK_INIT(&ctx->fdtable_lock);
+
+ setted_ctx = client_ctx_set(client, xlator, ctx);
+ if (ctx != setted_ctx) {
+ LOCK_DESTROY(&ctx->fdtable_lock);
+ GF_FREE(ctx->fdtable);
+ GF_FREE(ctx);
+ ctx = setted_ctx;
+ }
+
+out:
+ return ctx;
+}
+
+int
+auth_set_username_passwd(dict_t *input_params, dict_t *config_params,
+ client_t *client)
+{
+ int ret = 0;
+ data_t *allow_user = NULL;
+ data_t *passwd_data = NULL;
+ char *username = NULL;
+ char *password = NULL;
+ char *brick_name = NULL;
+ char *searchstr = NULL;
+ char *username_str = NULL;
+ char *tmp = NULL;
+ char *username_cpy = NULL;
+
+ ret = dict_get_str(input_params, "username", &username);
+ if (ret) {
+ gf_msg_debug("auth/login", 0,
+ "username not found, returning "
+ "DONT-CARE");
+ /* For non trusted clients username and password
+ will not be there. So don't reject the client.
+ */
+ ret = 0;
+ goto out;
+ }
+
+ ret = dict_get_str(input_params, "password", &password);
+ if (ret) {
+ gf_smsg("auth/login", GF_LOG_WARNING, 0, PS_MSG_PASSWORD_NOT_FOUND,
+ NULL);
+ goto out;
+ }
+
+ ret = dict_get_str(input_params, "remote-subvolume", &brick_name);
+ if (ret) {
+ gf_smsg("auth/login", GF_LOG_ERROR, 0,
+ PS_MSG_REMOTE_SUBVOL_NOT_SPECIFIED, NULL);
+ ret = -1;
+ goto out;
+ }
+
+ ret = gf_asprintf(&searchstr, "auth.login.%s.allow", brick_name);
+ if (-1 == ret) {
+ ret = 0;
+ goto out;
+ }
+
+ allow_user = dict_get(config_params, searchstr);
+ GF_FREE(searchstr);
+
+ if (allow_user) {
+ username_cpy = gf_strdup(allow_user->data);
+ if (!username_cpy)
+ goto out;
+
+ username_str = strtok_r(username_cpy, " ,", &tmp);
+
+ while (username_str) {
+ if (!fnmatch(username_str, username, 0)) {
+ ret = gf_asprintf(&searchstr, "auth.login.%s.password",
+ username);
+ if (-1 == ret)
+ goto out;
+
+ passwd_data = dict_get(config_params, searchstr);
+ GF_FREE(searchstr);
+
+ if (!passwd_data) {
+ gf_smsg("auth/login", GF_LOG_ERROR, 0, PS_MSG_LOGIN_ERROR,
+ NULL);
+ ret = -1;
+ goto out;
+ }
+
+ ret = strcmp(data_to_str(passwd_data), password);
+ if (!ret) {
+ client->auth.username = gf_strdup(username);
+ client->auth.passwd = gf_strdup(password);
+ } else {
+ gf_smsg("auth/login", GF_LOG_ERROR, 0, PS_MSG_LOGIN_ERROR,
+ "username=%s", username, NULL);
+ }
+ break;
+ }
+ username_str = strtok_r(NULL, " ,", &tmp);
+ }
+ }
+
+out:
+ GF_FREE(username_cpy);
+
+ return ret;
+}
+
+inode_t *
+server_inode_new(inode_table_t *itable, uuid_t gfid)
+{
+ if (__is_root_gfid(gfid))
+ return itable->root;
+ else
+ return inode_new(itable);
+}
+
+int
+unserialize_req_locklist(gfs3_setactivelk_req *req, lock_migration_info_t *lmi)
+{
+ struct gfs3_locklist *trav = NULL;
+ lock_migration_info_t *temp = NULL;
+ int ret = -1;
+
+ trav = req->request;
+
+ INIT_LIST_HEAD(&lmi->list);
+
+ while (trav) {
+ temp = GF_CALLOC(1, sizeof(*lmi), gf_common_mt_lock_mig);
+ if (temp == NULL) {
+ gf_smsg(THIS->name, GF_LOG_ERROR, 0, PS_MSG_NO_MEM, NULL);
+ goto out;
+ }
+
+ INIT_LIST_HEAD(&temp->list);
+
+ gf_proto_flock_to_flock(&trav->flock, &temp->flock);
+
+ temp->lk_flags = trav->lk_flags;
+
+ temp->client_uid = gf_strdup(trav->client_uid);
+
+ list_add_tail(&temp->list, &lmi->list);
+
+ trav = trav->nextentry;
+ }
+
+ ret = 0;
+out:
+ return ret;
+}
+
+int
+unserialize_req_locklist_v2(gfx_setactivelk_req *req,
+ lock_migration_info_t *lmi)
+{
+ struct gfs3_locklist *trav = NULL;
+ lock_migration_info_t *temp = NULL;
+ int ret = -1;
+
+ trav = req->request;
+
+ INIT_LIST_HEAD(&lmi->list);
+
+ while (trav) {
+ temp = GF_CALLOC(1, sizeof(*lmi), gf_common_mt_lock_mig);
+ if (temp == NULL) {
+ gf_smsg(THIS->name, GF_LOG_ERROR, 0, PS_MSG_NO_MEM, NULL);
+ goto out;
+ }
+
+ INIT_LIST_HEAD(&temp->list);
+
+ gf_proto_flock_to_flock(&trav->flock, &temp->flock);
+
+ temp->lk_flags = trav->lk_flags;
+
+ temp->client_uid = gf_strdup(trav->client_uid);
+
+ list_add_tail(&temp->list, &lmi->list);
+
+ trav = trav->nextentry;
+ }
+
+ ret = 0;
+out:
+ return ret;
}
diff --git a/xlators/protocol/server/src/server-helpers.h b/xlators/protocol/server/src/server-helpers.h
index eb26de84f86..837fdc84f17 100644
--- a/xlators/protocol/server/src/server-helpers.h
+++ b/xlators/protocol/server/src/server-helpers.h
@@ -1,77 +1,107 @@
/*
- 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"
+#include <glusterfs/defaults.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)
+#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);
+void
+free_state(server_state_t *state);
-char *
-stat_to_str (struct stat *stbuf);
-
-call_frame_t *
-server_copy_frame (call_frame_t *frame);
+void
+server_loc_wipe(loc_t *loc);
-void free_state (server_state_t *state);
+void
+server_print_request(call_frame_t *frame);
-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);
-
-int32_t
-gf_del_locker (struct _lock_table *table, const char *volume,
- loc_t *loc,
- fd_t *fd,
- pid_t pid);
-
-int32_t
-gf_direntry_to_bin (dir_entry_t *head,
- char **bufferp);
-#endif /* __SERVER_HELPERS_H__ */
+call_frame_t *
+get_frame_from_request(rpcsvc_request_t *req);
+
+int
+server_connection_cleanup(xlator_t *this, struct _client *client, int32_t flags,
+ gf_boolean_t *fd_exist);
+
+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);
+int
+readdirp_rsp_cleanup_v2(gfx_readdirp_rsp *rsp);
+int
+readdir_rsp_cleanup_v2(gfx_readdir_rsp *rsp);
+int
+auth_set_username_passwd(dict_t *input_params, dict_t *config_params,
+ struct _client *client);
+
+server_ctx_t *
+server_ctx_get(client_t *client, xlator_t *xlator);
+int
+server_process_event_upcall(xlator_t *this, void *data);
+
+inode_t *
+server_inode_new(inode_table_t *itable, uuid_t gfid);
+
+int
+serialize_rsp_locklist(lock_migration_info_t *locklist,
+ gfs3_getactivelk_rsp *rsp);
+int
+serialize_rsp_locklist_v2(lock_migration_info_t *locklist,
+ gfx_getactivelk_rsp *rsp);
+
+int
+getactivelkinfo_rsp_cleanup(gfs3_getactivelk_rsp *rsp);
+int
+getactivelkinfo_rsp_cleanup_v2(gfx_getactivelk_rsp *rsp);
+
+int
+unserialize_req_locklist(gfs3_setactivelk_req *req, lock_migration_info_t *lmi);
+
+int
+unserialize_req_locklist_v2(gfx_setactivelk_req *req,
+ lock_migration_info_t *lmi);
+
+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
+serialize_rsp_dirent_v2(gf_dirent_t *entries, gfx_readdir_rsp *rsp);
+
+int
+serialize_rsp_direntp_v2(gf_dirent_t *entries, gfx_readdirp_rsp *rsp);
+
+#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 00000000000..081e9f40e84
--- /dev/null
+++ b/xlators/protocol/server/src/server-mem-types.h
@@ -0,0 +1,27 @@
+/*
+ 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 <glusterfs/mem-types.h>
+
+enum gf_server_mem_types_ {
+ gf_server_mt_server_conf_t = gf_common_mt_end + 1,
+ gf_server_mt_state_t,
+ gf_server_mt_dirent_rsp_t,
+ gf_server_mt_rsp_buf_t,
+ gf_server_mt_setvolume_rsp_t,
+ gf_server_mt_lock_mig_t,
+ gf_server_mt_compound_rsp_t,
+ gf_server_mt_child_status,
+ gf_server_mt_end,
+};
+#endif /* __SERVER_MEM_TYPES_H__ */
diff --git a/xlators/protocol/server/src/server-messages.h b/xlators/protocol/server/src/server-messages.h
new file mode 100644
index 00000000000..1b2e149cb7d
--- /dev/null
+++ b/xlators/protocol/server/src/server-messages.h
@@ -0,0 +1,168 @@
+/*
+ Copyright (c) 2015 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 _PS_MESSAGES_H__
+#define _PS_MESSAGES_H__
+
+#include <glusterfs/glfs-message-id.h>
+
+/* To add new message IDs, append new identifiers at the end of the list.
+ *
+ * Never remove a message ID. If it's not used anymore, you can rename it or
+ * leave it as it is, but not delete it. This is to prevent reutilization of
+ * IDs by other messages.
+ *
+ * The component name must match one of the entries defined in
+ * glfs-message-id.h.
+ */
+
+GLFS_MSGID(
+ PS, PS_MSG_AUTHENTICATE_ERROR, PS_MSG_VOL_VALIDATE_FAILED,
+ PS_MSG_AUTH_INIT_FAILED, PS_MSG_REMOTE_CLIENT_REFUSED,
+ PS_MSG_GFID_RESOLVE_FAILED, PS_MSG_ANONYMOUS_FD_CREATE_FAILED,
+ PS_MSG_NO_MEMORY, PS_MSG_FD_NOT_FOUND, PS_MSG_INVALID_ENTRY,
+ PS_MSG_GET_UID_FAILED, PS_MSG_UID_NOT_FOUND, PS_MSG_MAPPING_ERROR,
+ PS_MSG_FD_CLEANUP, PS_MSG_SERVER_CTX_GET_FAILED, PS_MSG_FDENTRY_NULL,
+ PS_MSG_DIR_NOT_FOUND, PS_MSG_SERVER_MSG, PS_MSG_DICT_SERIALIZE_FAIL,
+ PS_MSG_RW_STAT, PS_MSG_DICT_GET_FAILED, PS_MSG_LOGIN_ERROR,
+ PS_MSG_REMOUNT_CLIENT_REQD, PS_MSG_DEFAULTING_FILE,
+ PS_MSG_VOL_FILE_OPEN_FAILED, PS_MSG_STAT_ERROR, PS_MSG_SSL_NAME_SET_FAILED,
+ PS_MSG_ASPRINTF_FAILED, PS_MSG_CLIENT_VERSION_NOT_SET,
+ PS_MSG_CLIENT_ACCEPTED, PS_MSG_CLIENT_LK_VERSION_ERROR,
+ PS_MSG_GRACE_TIMER_EXPD, PS_MSG_SERIALIZE_REPLY_FAILED,
+ PS_MSG_AUTH_IP_ERROR, PS_MSG_SKIP_FORMAT_CHK, PS_MSG_INTERNET_ADDR_ERROR,
+ PS_MSG_CLIENT_DISCONNECTING, PS_MSG_GRACE_TIMER_START,
+ PS_MSG_STATEDUMP_PATH_ERROR, PS_MSG_GRP_CACHE_ERROR, PS_MSG_RPC_CONF_ERROR,
+ PS_MSG_TRANSPORT_ERROR, PS_MSG_SUBVOL_NULL, PS_MSG_PARENT_VOL_ERROR,
+ PS_MSG_RPCSVC_CREATE_FAILED, PS_MSG_RPCSVC_LISTENER_CREATE_FAILED,
+ PS_MSG_RPCSVC_NOTIFY, PS_MSG_PGM_REG_FAILED, PS_MSG_ULIMIT_SET_FAILED,
+ PS_MSG_STATFS, PS_MSG_LOOKUP_INFO, PS_MSG_LK_INFO, PS_MSG_LOCK_ERROR,
+ PS_MSG_INODELK_INFO, PS_MSG_ENTRYLK_INFO, PS_MSG_ACCESS_INFO,
+ PS_MSG_DIR_INFO, PS_MSG_MKNOD_INFO, PS_MSG_REMOVEXATTR_INFO,
+ PS_MSG_GETXATTR_INFO, PS_MSG_SETXATTR_INFO, PS_MSG_RENAME_INFO,
+ PS_MSG_LINK_INFO, PS_MSG_TRUNCATE_INFO, PS_MSG_FSTAT_INFO,
+ PS_MSG_FLUSH_INFO, PS_MSG_SYNC_INFO, PS_MSG_WRITE_INFO, PS_MSG_READ_INFO,
+ PS_MSG_CHKSUM_INFO, PS_MSG_OPEN_INFO, PS_MSG_CREATE_INFO,
+ PS_MSG_SETATTR_INFO, PS_MSG_XATTROP_INFO, PS_MSG_ALLOC_INFO,
+ PS_MSG_DISCARD_INFO, PS_MSG_ZEROFILL_INFO, PS_MSG_FD_CREATE_FAILED,
+ PS_MSG_WRONG_STATE, PS_MSG_CONF_DIR_INVALID, PS_MSG_MOUNT_PT_FAIL,
+ PS_MSG_STAT_INFO, PS_MSG_FILE_OP_FAILED, PS_MSG_GRACE_TIMER_CANCELLED,
+ PS_MSG_ENCODE_MSG_FAILED, PS_MSG_REPLY_SUBMIT_FAILED,
+ PS_MSG_RPC_NOTIFY_ERROR, PS_MSG_SERVER_EVENT_UPCALL_FAILED,
+ PS_MSG_SERVER_IPC_INFO, PS_MSG_SEEK_INFO, PS_MSG_COMPOUND_INFO,
+ PS_MSG_CLIENT_OPVERSION_GET_FAILED, PS_MSG_CHILD_STATUS_FAILED,
+ PS_MSG_PUT_INFO, PS_MSG_UNAUTHORIZED_CLIENT, PS_MSG_RECONFIGURE_FAILED,
+ PS_MSG_SET_STATEDUMP_PATH_ERROR, PS_MSG_INIT_GRP_CACHE_ERROR,
+ PS_MSG_RPC_CONFIGURE_FAILED, PS_MSG_TRANSPORT_TYPE_NOT_SET,
+ PS_MSG_GET_TOTAL_AVAIL_TRANSPORT_FAILED, PS_MSG_INVLAID_UPCALL_EVENT,
+ PS_MSG_SERVER_CHILD_EVENT_FAILED, PS_MSG_SETACTIVELK_INFO,
+ PS_MSG_GETACTIVELK_INFO, PS_MSG_WRONG_VALUE, PS_MSG_PASSWORD_NOT_FOUND,
+ PS_MSG_REMOTE_SUBVOL_NOT_SPECIFIED, PS_MSG_NO_MEM);
+
+#define PS_MSG_SERIALIZE_REPLY_FAILED_STR "Failed to serialize reply"
+#define PS_MSG_AUTH_IP_ERROR_STR "assuming 'auth.ip' to be 'auth.addr'"
+#define PS_MSG_SKIP_FORMAT_CHK_STR "skip format check for non-addr auth option"
+#define PS_MSG_INTERNET_ADDR_ERROR_STR \
+ "internet address does not confirm to standards"
+#define PS_MSG_AUTHENTICATE_ERROR_STR \
+ "volume defined as subvolume, but no authentication defined for the same"
+#define PS_MSG_CLIENT_DISCONNECTING_STR "disconnecting connection"
+#define PS_MSG_DICT_GET_FAILED_STR "failed to get"
+#define PS_MSG_NO_MEMORY_STR "Memory accounting init failed"
+#define PS_MSG_INVALID_ENTRY_STR \
+ "'trace' takes on only boolean values. Neglecting option"
+#define PS_MSG_STATEDUMP_PATH_ERROR_STR \
+ "Error while reconfiguring statedump path"
+#define PS_MSG_GRP_CACHE_ERROR_STR "Failed to reconfigure group cache."
+#define PS_MSG_RPC_CONF_ERROR_STR "No rpc_conf !!!!"
+#define PS_MSG_CLIENT_ACCEPTED_STR \
+ "authorized client, hence we continue with this connection"
+#define PS_MSG_UNAUTHORIZED_CLIENT_STR \
+ "unauthorized client, hence terminating the connection"
+#define PS_MSG_RECONFIGURE_FAILED_STR \
+ "Failed to reconfigure outstanding-rpc-limit"
+#define PS_MSG_TRANSPORT_ERROR_STR "Reconfigure not found for transport"
+#define PS_MSG_SUBVOL_NULL_STR "protocol/server should have subvolume"
+#define PS_MSG_PARENT_VOL_ERROR_STR \
+ "protocol/server should not have parent volumes"
+#define PS_MSG_SET_STATEDUMP_PATH_ERROR_STR "Error setting statedump path"
+#define PS_MSG_INIT_GRP_CACHE_ERROR_STR "Failed to initialize group cache."
+#define PS_MSG_RPCSVC_CREATE_FAILED_STR "creation of rpcsvc failed"
+#define PS_MSG_RPC_CONFIGURE_FAILED_STR \
+ "Failed to configure outstanding-rpc-limit"
+#define PS_MSG_TRANSPORT_TYPE_NOT_SET_STR "option transport-type not set"
+#define PS_MSG_GET_TOTAL_AVAIL_TRANSPORT_FAILED_STR \
+ "failed to get total number of available tranpsorts"
+#define PS_MSG_RPCSVC_LISTENER_CREATE_FAILED_STR "creation of listener failed"
+#define PS_MSG_RPCSVC_NOTIFY_STR "registration of notify with rpcsvc failed"
+#define PS_MSG_PGM_REG_FAILED_STR "registration of program failed"
+#define PS_MSG_ULIMIT_SET_FAILED_STR "WARNING: Failed to set 'ulimit -n 1M'"
+#define PS_MSG_FD_NOT_FOUND_STR "Failed to set max open fd to 64k"
+#define PS_MSG_VOL_FILE_OPEN_FAILED_STR \
+ "volfile-id argument not given. This is mandatory argument, defaulting " \
+ "to 'gluster'"
+#define PS_MSG_INVLAID_UPCALL_EVENT_STR "Received invalid upcall event"
+#define PS_MSG_CHILD_STATUS_FAILED_STR "No xlator is found in child status list"
+#define PS_MSG_SERVER_EVENT_UPCALL_FAILED_STR \
+ "server_process_event_upcall failed"
+#define PS_MSG_SERVER_CHILD_EVENT_FAILED_STR "server_process_child_event failed"
+#define PS_MSG_STATFS_STR "STATFS"
+#define PS_MSG_LOOKUP_INFO_STR "LOOKUP info"
+#define PS_MSG_LK_INFO_STR "LEASE info"
+#define PS_MSG_INODELK_INFO_STR "INODELK info"
+#define PS_MSG_DIR_INFO_STR "MKDIR info"
+#define PS_MSG_MKNOD_INFO_STR "MKNOD info"
+#define PS_MSG_REMOVEXATTR_INFO_STR "REMOVEXATTR info"
+#define PS_MSG_GETXATTR_INFO_STR "GETXATTR info"
+#define PS_MSG_SETXATTR_INFO_STR "SETXATTR info"
+#define PS_MSG_RENAME_INFO_STR "RENAME inf"
+#define PS_MSG_LINK_INFO_STR "LINK info"
+#define PS_MSG_TRUNCATE_INFO_STR "TRUNCATE info"
+#define PS_MSG_STAT_INFO_STR "STAT info"
+#define PS_MSG_FLUSH_INFO_STR "FLUSH info"
+#define PS_MSG_SYNC_INFO_STR "SYNC info"
+#define PS_MSG_WRITE_INFO_STR "WRITE info"
+#define PS_MSG_READ_INFO_STR "READ info"
+#define PS_MSG_CHKSUM_INFO_STR "CHKSUM info"
+#define PS_MSG_OPEN_INFO_STR "OPEN info"
+#define PS_MSG_XATTROP_INFO_STR "XATTROP info"
+#define PS_MSG_ALLOC_INFO_STR "ALLOC info"
+#define PS_MSG_DISCARD_INFO_STR "DISCARD info"
+#define PS_MSG_ZEROFILL_INFO_STR "ZEROFILL info"
+#define PS_MSG_SERVER_IPC_INFO_STR "IPC info"
+#define PS_MSG_SEEK_INFO_STR "SEEK info"
+#define PS_MSG_SETACTIVELK_INFO_STR "SETACTIVELK info"
+#define PS_MSG_CREATE_INFO_STR "CREATE info"
+#define PS_MSG_PUT_INFO_STR "PUT info"
+#define PS_MSG_FD_CREATE_FAILED_STR "could not create the fd"
+#define PS_MSG_GETACTIVELK_INFO_STR "GETACTIVELK info"
+#define PS_MSG_ENTRYLK_INFO_STR "ENTRYLK info"
+#define PS_MSG_ACCESS_INFO_STR "ACCESS info"
+#define PS_MSG_SETATTR_INFO_STR "SETATTR info"
+#define PS_MSG_SERVER_CTX_GET_FAILED_STR "server_ctx_get() failed"
+#define PS_MSG_LOCK_ERROR_STR "Unknown lock type"
+#define PS_MSG_GET_UID_FAILED_STR "getpwuid_r failed"
+#define PS_MSG_UID_NOT_FOUND_STR "getpwuid_r found nothing"
+#define PS_MSG_MAPPING_ERROR_STR "could not map to group list"
+#define PS_MSG_FD_CLEANUP_STR "fd cleanup"
+#define PS_MSG_FDENTRY_NULL_STR "no fdentry to clean"
+#define PS_MSG_WRONG_VALUE_STR \
+ "wrong value for 'verify-volfile-checksum', Neglecting option"
+#define PS_MSG_DIR_NOT_FOUND_STR "Directory doesnot exist"
+#define PS_MSG_CONF_DIR_INVALID_STR "invalid conf_dir"
+#define PS_MSG_SERVER_MSG_STR "server msg"
+#define PS_MSG_DICT_SERIALIZE_FAIL_STR "failed to serialize reply dict"
+#define PS_MSG_MOUNT_PT_FAIL_STR "mount point fail"
+#define PS_MSG_RW_STAT_STR "stat"
+#define PS_MSG_PASSWORD_NOT_FOUND_STR "password not found, returning DONT-CARE"
+#define PS_MSG_REMOTE_SUBVOL_NOT_SPECIFIED_STR "remote-subvolume not specified"
+#define PS_MSG_LOGIN_ERROR_STR "wrong password for user"
+#define PS_MSG_NO_MEM_STR "No memory"
+#endif /* !_PS_MESSAGES_H__ */
diff --git a/xlators/protocol/server/src/server-protocol.c b/xlators/protocol/server/src/server-protocol.c
deleted file mode 100644
index 1153a545100..00000000000
--- a/xlators/protocol/server/src/server-protocol.c
+++ /dev/null
@@ -1,8318 +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"
-
-
-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,
- dict_t *refs)
-{
- server_state_t *state = NULL;
- xlator_t *bound_xl = NULL;
- transport_t *trans = NULL;
-
- 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);
-
- transport_submit (trans, (char *)hdr, hdrlen, vector, count, refs);
- /* TODO: If transport submit fails, there is no reply sent to client,
- * its bailed out as of now.. loggically, only this frame should fail.
- */
-
- STACK_DESTROY (frame->root);
-
- if (state)
- free_state (state);
-
-}
-
-
-/*
- * server_fchmod_cbk
- */
-int32_t
-server_fchmod_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_fchmod_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": FCHMOD %"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_FCHMOD,
- hdr, hdrlen, NULL, 0, NULL);
-
- return 0;
-}
-
-/*
- * server_fchmod
- *
- */
-int32_t
-server_fchmod (call_frame_t *frame,
- xlator_t *bound_xl,
- gf_hdr_common_t *hdr, size_t hdrlen,
- char *buf, size_t buflen)
-{
- server_connection_t *conn = NULL;
- gf_fop_fchmod_req_t *req = 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->mode = ntoh32 (req->mode);
- }
-
- GF_VALIDATE_OR_GOTO(bound_xl->name, state->fd, fail);
-
- STACK_WIND (frame,
- server_fchmod_cbk,
- BOUND_XL(frame),
- BOUND_XL(frame)->fops->fchmod,
- state->fd,
- state->mode);
-
- return 0;
-fail:
- server_fchmod_cbk (frame, NULL, frame->this,
- -1, EINVAL, NULL);
- return 0;
-}
-
-
-/*
- * server_fchown_cbk
- */
-int32_t
-server_fchown_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_fchown_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": FCHOWN %"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_FCHOWN,
- hdr, hdrlen, NULL, 0, NULL);
-
- return 0;
-}
-
-/*
- * server_fchown
- *
- */
-int32_t
-server_fchown (call_frame_t *frame,
- xlator_t *bound_xl,
- gf_hdr_common_t *hdr, size_t hdrlen,
- char *buf, size_t buflen)
-{
- server_connection_t *conn = NULL;
- gf_fop_fchown_req_t *req = 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->uid = ntoh32 (req->uid);
- state->gid = ntoh32 (req->gid);
- }
-
- GF_VALIDATE_OR_GOTO(bound_xl->name, state->fd, fail);
-
- STACK_WIND (frame,
- server_fchown_cbk,
- BOUND_XL(frame),
- BOUND_XL(frame)->fops->fchown,
- state->fd,
- state->uid,
- state->gid);
-
- return 0;
-fail:
- server_fchown_cbk (frame, NULL, frame->this,
- -1, EINVAL, NULL);
- return 0;
-}
-
-/*
- * server_setdents_cbk - writedir callback for server protocol
- * @frame: call frame
- * @cookie:
- * @this:
- * @op_ret: return value
- * @op_errno: errno
- *
- * not for external reference
- */
-int32_t
-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
- */
-int32_t
-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_DEBUG,
- "%"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;
-}
-
-
-int32_t
-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_DEBUG,
- "%"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;
-}
-
-
-int32_t
-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_DEBUG,
- "%"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
- */
-int32_t
-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_DEBUG,
- "%"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;
-}
-
-
-int32_t
-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_DEBUG,
- "%"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
- */
-int32_t
-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_utimens_cbk - utimens callback for server protocol
- * @frame: call frame
- * @cookie:
- * @this:
- * @op_ret:
- * @op_errno:
- * @stbuf:
- *
- * not for external reference
- */
-int32_t
-server_utimens_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_utimens_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);
-
- server_loc_wipe (&(state->loc));
-
- protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_FOP_UTIMENS,
- hdr, hdrlen, NULL, 0, NULL);
-
- return 0;
-}
-
-/*
- * server_chmod_cbk - chmod callback for server protocol
- * @frame: call frame
- * @cookie:
- * @this:
- * @op_ret:
- * @op_errno:
- * @stbuf:
- *
- * not for external reference
- */
-int32_t
-server_chmod_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_chmod_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);
-
- server_loc_wipe (&(state->loc));
-
- protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_FOP_CHMOD,
- hdr, hdrlen, NULL, 0, NULL);
-
- return 0;
-}
-
-/*
- * server_chown_cbk - chown callback for server protocol
- * @frame: call frame
- * @cookie:
- * @this:
- * @op_ret:
- * @op_errno:
- * @stbuf:
- *
- * not for external reference
- */
-int32_t
-server_chown_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_chown_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);
-
- server_loc_wipe (&(state->loc));
-
- protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_FOP_CHOWN,
- 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
- */
-int32_t
-server_rmdir_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_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);
- } else {
- gf_log (this->name, GF_LOG_DEBUG,
- "%"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);
-
- 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
- */
-int32_t
-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)
-{
- 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_DEBUG,
- "%"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
- */
-int32_t
-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)
-{
- 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_DEBUG,
- "%"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
- */
-int32_t
-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_DEBUG,
- "%"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
- */
-int32_t
-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;
- int32_t ret = -1;
- dict_t *reply_dict = NULL;
- char *buffer = NULL;
- size_t buflen = 0;
- struct iovec vector[1];
- server_state_t *state = NULL;
-
- state = CALL_STATE(frame);
-
- if (op_ret >= 0) {
- buflen = gf_direntry_to_bin (entries, &buffer);
- 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;
- }
-
- reply_dict = dict_new ();
- if (reply_dict == NULL) {
- gf_log (this->name, GF_LOG_ERROR,
- "fd - %"PRId64" (%"PRId64"): failed to get new dict",
- state->fd_no, state->fd->inode->ino);
- op_ret = -1;
- op_errno = ENOMEM;
- goto out;
- }
-
- ret = dict_set_dynptr (reply_dict, NULL,
- buffer, buflen);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "fd - %"PRId64" (%"PRId64"): failed to set read buffer "
- "to reply dictionary",
- state->fd_no, state->fd->inode->ino);
- op_ret = -1;
- op_errno = -ret;
- goto out;
- }
- frame->root->rsp_refs = reply_dict;
- vector[0].iov_base = buffer;
- vector[0].iov_len = buflen;
- vec_count = 1;
- } else {
- gf_log (this->name, GF_LOG_DEBUG,
- "%"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,
- frame->root->rsp_refs);
-
- if (reply_dict)
- dict_unref (reply_dict);
-
- return 0;
-}
-
-
-/*
- * server_readdir_cbk - getdents callback for server protocol
- * @frame: call frame
- * @cookie:
- * @this:
- * @op_ret:
- * @op_errno:
- *
- * not for external reference
- */
-int32_t
-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_DEBUG,
- "%"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
- */
-int32_t
-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
- */
-int32_t
-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_DEBUG,
- "%"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
- */
-int32_t
-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
- */
-int32_t
-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
- */
-int32_t
-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;
-}
-
-
-int32_t
-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
- */
-int32_t
-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;
-}
-
-
-int32_t
-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
- */
-int32_t
-server_rename_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_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_DEBUG,
- "%"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);
- }
-
- 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
- */
-int32_t
-server_unlink_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_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_DEBUG,
- "%"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);
- } 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);
-
- 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
- */
-int32_t
-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)
-{
- 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
- */
-int32_t
-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)
-{
- 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_DEBUG,
- "%"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
- */
-int32_t
-server_truncate_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_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->stat, stbuf);
- } 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
- */
-int32_t
-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
- */
-int32_t
-server_ftruncate_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_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->stat, stbuf);
- } 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
- */
-int32_t
-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
- */
-int32_t
-server_fsync_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_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);
-
- 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_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
- */
-int32_t
-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
- */
-
-int32_t
-server_writev_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_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->stat, stbuf);
- } 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
- */
-int32_t
-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)
-{
- 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,
- frame->root->rsp_refs);
-
- return 0;
-}
-
-
-/*
- * server_open_cbk - open callback for server protocol
- * @frame: call frame
- * @cookie:
- * @this:
- * @op_ret:
- * @op_errno:
- * @fd:
- *
- * not for external reference
- */
-int32_t
-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
- */
-int32_t
-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)
-{
- 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_DEBUG,
- "%"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
- */
-int32_t
-server_readlink_cbk (call_frame_t *frame,
- void *cookie,
- xlator_t *this,
- int32_t op_ret,
- int32_t op_errno,
- const char *buf)
-{
- 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)
- 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
- */
-int32_t
-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_forget_cbk - forget callback for server protocol
- * @frame: call frame
- * @cookie:
- * @this:
- * @op_ret:
- * @op_errno:
- *
- * not for external reference
- */
-int32_t
-server_forget_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_forget_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_FORGET,
- 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
- */
-int32_t
-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)
-{
- 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;
-
- state = CALL_STATE(frame);
- if ((op_errno == ESTALE) && (op_ret == -1)) {
- /* Send lookup again with new ctx dictionary */
- loc_t loc = {0,};
-
- 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);
-
- if (inode->ino == 0) {
- inode_link (inode, state->loc.parent,
- state->loc.name, stbuf);
- inode_lookup (inode);
- }
- } else {
- gf_log (this->name, 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;
-}
-
-int32_t
-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;
-}
-
-int32_t
-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
- */
-int32_t
-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 = inode;
-
- if (!stub) {
- return 0;
- }
- switch (stub->fop)
- {
- case GF_FOP_RENAME:
- if (stub->args.rename.old.inode == NULL) {
- loc_t *newloc = NULL;
- /* now we are called by lookup of oldpath. */
- if (op_ret < 0) {
- gf_log (stub->frame->this->name, GF_LOG_ERROR,
- "%"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);
- server_loc_wipe (&stub->args.rename.old);
- server_loc_wipe (&stub->args.rename.new);
- FREE (stub);
- return 0;
- }
-
- 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_ERROR,
- "%"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);
- 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_ERROR,
- "%"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_ERROR,
- "%"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_ERROR,
- "%"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);
- 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_ERROR,
- "%"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);
- 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_ERROR,
- "%"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);
- 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_CHMOD:
- {
- if (op_ret < 0) {
- gf_log (stub->frame->this->name, GF_LOG_ERROR,
- "%"PRId64": CHMOD (%s) on %s returning error: "
- "%"PRId32" (%"PRId32")",
- stub->frame->root->unique,
- stub->args.chmod.loc.path,
- BOUND_XL(stub->frame)->name,
- op_ret, op_errno);
- server_chmod_cbk (stub->frame,
- NULL,
- stub->frame->this,
- -1,
- ENOENT,
- NULL);
- server_loc_wipe (&stub->args.chmod.loc);
- FREE (stub);
- return 0;
- }
-
- if (stub->args.chmod.loc.parent == NULL)
- stub->args.chmod.loc.parent = inode_ref (parent);
-
- if (server_inode && (stub->args.chmod.loc.inode == NULL)) {
- stub->args.chmod.loc.inode = inode_ref (server_inode);
- stub->args.chmod.loc.ino = server_inode->ino;
- }
- call_resume (stub);
- break;
- }
-
- case GF_FOP_CHOWN:
- {
- if (op_ret < 0) {
- gf_log (stub->frame->this->name, GF_LOG_ERROR,
- "%"PRId64": CHOWN (%s) on %s returning ENOENT: "
- "%"PRId32" (%"PRId32")",
- stub->frame->root->unique,
- stub->args.chown.loc.path,
- BOUND_XL(stub->frame)->name,
- op_ret, op_errno);
- server_chown_cbk (stub->frame,
- NULL,
- stub->frame->this,
- -1,
- ENOENT,
- NULL);
- server_loc_wipe (&stub->args.chown.loc);
- FREE (stub);
- return 0;
- }
-
- if (stub->args.chown.loc.parent == NULL)
- stub->args.chown.loc.parent = inode_ref (parent);
-
- if (server_inode && (stub->args.chown.loc.inode == NULL)) {
- stub->args.chown.loc.inode = inode_ref (server_inode);
- stub->args.chown.loc.ino = server_inode->ino;
- }
- call_resume (stub);
- break;
- }
-
- case GF_FOP_LINK:
- {
- if (stub->args.link.oldloc.inode == NULL) {
- if (op_ret < 0) {
- gf_log (stub->frame->this->name, GF_LOG_ERROR,
- "%"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);
- 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_ERROR,
- "%"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);
-
- 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_ERROR,
- "%"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);
- 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_ERROR,
- "%"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_t *dict = stub->args.setxattr.dict;
- if (op_ret < 0) {
- gf_log (stub->frame->this->name, GF_LOG_ERROR,
- "%"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_ERROR,
- "%"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_ERROR,
- "%"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_ERROR,
- "%"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_ERROR,
- "%"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_UTIMENS:
- {
- if (op_ret < 0) {
- gf_log (stub->frame->this->name, GF_LOG_ERROR,
- "%"PRId64": UTIMENS (%s) on %s returning error: "
- "%"PRId32" (%"PRId32")",
- stub->frame->root->unique,
- stub->args.utimens.loc.path,
- BOUND_XL(stub->frame)->name,
- op_ret, op_errno);
-
- server_utimens_cbk (stub->frame,
- NULL,
- stub->frame->this,
- -1, ENOENT,
- NULL);
- server_loc_wipe (&stub->args.utimens.loc);
- FREE (stub);
- return 0;
- }
-
- if (stub->args.utimens.loc.parent == NULL)
- stub->args.utimens.loc.parent = inode_ref (parent);
-
- if (server_inode && (stub->args.utimens.loc.inode == NULL)) {
- stub->args.utimens.loc.inode =
- inode_ref (server_inode);
- stub->args.utimens.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_ERROR,
- "%"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);
- 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_ERROR,
- "%"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);
- 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_ERROR,
- "%"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);
- 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_ERROR,
- "%"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);
- 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_ERROR,
- "%"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_ERROR,
- "%"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;
- }
- default:
- call_resume (stub);
- }
-
- return 0;
-}
-
-static 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_DEBUG,
- "%"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,
- char *buf, size_t buflen)
-{
- 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, 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 request buffer to dictionary",
- frame->root->unique, state->loc.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);
- if (xattr_req)
- dict_unref (xattr_req);
-
- return 0;
-}
-
-
-/*
- * server_forget - forget function for server protocol
- * @frame: call frame
- * @bound_xl:
- * @params: parameter dictionary
- *
- * not for external reference
- */
-int32_t
-server_forget (call_frame_t *frame, xlator_t *bound_xl,
- gf_hdr_common_t *hdr, size_t hdrlen,
- char *buf, size_t buflen)
-{
- int index = 0;
- ino_t ino = 0;
- int32_t count = 0;
- inode_t *inode = NULL;
- gf_cbk_forget_req_t *req = NULL;
-
- req = gf_param (hdr);
- count = ntoh32 (req->count);
-
- for (index = 0; index < count; index++) {
-
- ino = ntoh64 (req->ino_array[index]);
-
- if (!ino)
- continue;
-
- inode = inode_search (bound_xl->itable, ino, NULL);
-
- if (inode) {
- inode_forget (inode, 0);
- inode_unref (inode);
- } else {
- gf_log (bound_xl->name, GF_LOG_DEBUG,
- "%"PRId64": FORGET %"PRId64" not found "
- "in inode table",
- frame->root->unique, ino);
- }
-
- gf_log (bound_xl->name, GF_LOG_DEBUG,
- "%"PRId64": FORGET \'%"PRId64"\'",
- frame->root->unique, ino);
- }
-
- server_forget_cbk (frame, NULL, bound_xl, 0, 0);
-
- return 0;
-}
-
-
-
-int32_t
-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_DEBUG,
- "%"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
- */
-int32_t
-server_stat (call_frame_t *frame,
- xlator_t *bound_xl,
- gf_hdr_common_t *hdr, size_t hdrlen,
- char *buf, size_t buflen)
-{
- 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;
-}
-
-
-int32_t
-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_DEBUG,
- "%"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
- */
-int32_t
-server_readlink (call_frame_t *frame,
- xlator_t *bound_xl,
- gf_hdr_common_t *hdr, size_t hdrlen,
- char *buf, size_t buflen)
-{
- 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);
- return 0;
-}
-
-int32_t
-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 = 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_DEBUG,
- "%"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);
- 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
- */
-int32_t
-server_create (call_frame_t *frame, xlator_t *bound_xl,
- gf_hdr_common_t *hdr, size_t hdrlen,
- char *buf, size_t buflen)
-{
- 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 = 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);
- return 0;
-}
-
-
-int32_t
-server_open_resume (call_frame_t *frame,
- xlator_t *this,
- loc_t *loc,
- int32_t flags,
- fd_t *fd)
-{
- server_state_t *state = CALL_STATE(frame);
- fd_t *new_fd = NULL;
-
- 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_DEBUG,
- "%"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);
-
- 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
- */
-int32_t
-server_open (call_frame_t *frame, xlator_t *bound_xl,
- gf_hdr_common_t *hdr, size_t hdrlen,
- char *buf, size_t buflen)
-{
- 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 = 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);
- 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
- */
-int32_t
-server_readv (call_frame_t *frame, xlator_t *bound_xl,
- gf_hdr_common_t *hdr, size_t hdrlen,
- char *buf, size_t buflen)
-{
- 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_DEBUG,
- "%"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);
- return 0;
-}
-
-
-/*
- * server_writev - writev function for server
- * @frame: call frame
- * @bound_xl:
- * @params: parameter dictionary
- *
- * not for external reference
- */
-int32_t
-server_writev (call_frame_t *frame, xlator_t *bound_xl,
- gf_hdr_common_t *hdr, size_t hdrlen,
- char *buf, size_t buflen)
-{
- server_connection_t *conn = NULL;
- gf_fop_write_req_t *req = NULL;
- struct iovec iov = {0, };
- dict_t *refs = NULL;
- server_state_t *state = 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);
-
- state->offset = ntoh64 (req->offset);
- }
-
- GF_VALIDATE_OR_GOTO(bound_xl->name, state->fd, fail);
-
- iov.iov_base = buf;
- iov.iov_len = buflen;
-
- refs = dict_new ();
- GF_VALIDATE_OR_GOTO(bound_xl->name, refs, fail);
-
- ret = dict_set_dynptr (refs, NULL, buf, buflen);
- if (ret < 0) {
- gf_log (frame->this->name, GF_LOG_ERROR,
- "fd - %"PRId64" (%"PRId64"): failed to set buffer entry "
- "to req_refs",
- state->fd_no, state->fd->inode->ino);
- goto fail;
- } else {
- buf = NULL;
- }
-
- frame->root->req_refs = refs;
-
- gf_log (bound_xl->name, GF_LOG_DEBUG,
- "%"PRId64": WRITEV \'fd=%"PRId64" (%"PRId64"); "
- "offset=%"PRId64"; size=%"PRId64,
- frame->root->unique, state->fd_no, state->fd->inode->ino,
- state->offset, (int64_t)buflen);
-
- STACK_WIND (frame,
- server_writev_cbk,
- BOUND_XL(frame),
- BOUND_XL(frame)->fops->writev,
- state->fd, &iov, 1, state->offset);
-
- if (refs)
- dict_unref (refs);
- return 0;
-fail:
- server_writev_cbk (frame, NULL, frame->this,
- -1, EINVAL, NULL);
-
- if (buf)
- free (buf);
-
- if (refs)
- dict_unref (refs);
-
- return 0;
-}
-
-
-
-/*
- * server_release - release function for server protocol
- * @frame: call frame
- * @bound_xl:
- * @params: parameter dictionary
- *
- * not for external reference
- */
-int32_t
-server_release (call_frame_t *frame, xlator_t *bound_xl,
- gf_hdr_common_t *hdr, size_t hdrlen,
- char *buf, size_t buflen)
-{
- 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);
- state->fd = gf_fd_fdptr_get (conn->fdtable,
- state->fd_no);
-
- GF_VALIDATE_OR_GOTO(bound_xl->name, state->fd, fail);
-
- gf_fd_put (conn->fdtable,
- state->fd_no);
-
- gf_log (bound_xl->name, GF_LOG_DEBUG,
- "%"PRId64": RELEASE \'fd=%"PRId64" (%"PRId64")\'",
- frame->root->unique, state->fd_no, state->fd->inode->ino);
-
- STACK_WIND (frame,
- server_release_cbk,
- BOUND_XL(frame),
- BOUND_XL(frame)->fops->flush,
- state->fd);
- return 0;
-fail:
- server_release_cbk (frame, NULL, frame->this,
- -1, EINVAL);
- return 0;
-}
-
-
-/*
- * server_fsync - fsync function for server protocol
- * @frame: call frame
- * @bound_xl:
- * @params: parameters dictionary
- *
- * not for external reference
- */
-int32_t
-server_fsync (call_frame_t *frame,
- xlator_t *bound_xl,
- gf_hdr_common_t *hdr, size_t hdrlen,
- char *buf, size_t buflen)
-{
- 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_DEBUG,
- "%"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);
-
- return 0;
-}
-
-
-/*
- * server_flush - flush function for server protocol
- * @frame: call frame
- * @bound_xl:
- * @params: parameter dictionary
- *
- * not for external reference
- */
-int32_t
-server_flush (call_frame_t *frame, xlator_t *bound_xl,
- gf_hdr_common_t *hdr, size_t hdrlen,
- char *buf, size_t buflen)
-{
- 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_DEBUG,
- "%"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
- */
-int32_t
-server_ftruncate (call_frame_t *frame,
- xlator_t *bound_xl,
- gf_hdr_common_t *hdr, size_t hdrlen,
- char *buf, size_t buflen)
-{
- 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_DEBUG,
- "%"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);
-
- return 0;
-}
-
-
-/*
- * server_fstat - fstat function for server protocol
- * @frame: call frame
- * @bound_xl:
- * @params: parameter dictionary
- *
- * not for external reference
- */
-int32_t
-server_fstat (call_frame_t *frame,
- xlator_t *bound_xl,
- gf_hdr_common_t *hdr, size_t hdrlen,
- char *buf, size_t buflen)
-{
- 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_ERROR,
- "fd - %"PRId64": unresolved fd",
- state->fd_no);
-
- server_fstat_cbk (frame, NULL, frame->this,
- -1, EINVAL, NULL);
-
- goto out;
- }
-
- gf_log (bound_xl->name, GF_LOG_DEBUG,
- "%"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;
-}
-
-
-int32_t
-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_DEBUG,
- "%"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
- */
-int32_t
-server_truncate (call_frame_t *frame,
- xlator_t *bound_xl,
- gf_hdr_common_t *hdr, size_t hdrlen,
- char *buf, size_t buflen)
-{
- 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;
-}
-
-
-
-
-
-int32_t
-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_DEBUG,
- "%"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
- */
-int32_t
-server_unlink (call_frame_t *frame,
- xlator_t *bound_xl,
- gf_hdr_common_t *hdr, size_t hdrlen,
- char *buf, size_t buflen)
-{
- 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;
-}
-
-
-
-
-
-int32_t
-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_DEBUG,
- "%"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
- */
-
-int32_t
-server_setxattr (call_frame_t *frame,
- xlator_t *bound_xl,
- gf_hdr_common_t *hdr, size_t hdrlen,
- char *buf, size_t buflen)
-{
- 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;
-
-}
-
-
-int32_t
-server_fsetxattr (call_frame_t *frame,
- xlator_t *bound_xl,
- gf_hdr_common_t *hdr, size_t hdrlen,
- char *buf, size_t buflen)
-{
- 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;
-}
-
-
-int32_t
-server_fxattrop (call_frame_t *frame,
- xlator_t *bound_xl,
- gf_hdr_common_t *hdr, size_t hdrlen,
- char *buf, size_t buflen)
-{
- 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_DEBUG,
- "%"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;
-}
-
-int32_t
-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_DEBUG,
- "%"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;
-}
-
-int32_t
-server_xattrop (call_frame_t *frame,
- xlator_t *bound_xl,
- gf_hdr_common_t *hdr, size_t hdrlen,
- char *buf, size_t buflen)
-{
- 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;
-}
-
-
-int32_t
-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_DEBUG,
- "%"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
- */
-int32_t
-server_getxattr (call_frame_t *frame,
- xlator_t *bound_xl,
- gf_hdr_common_t *hdr, size_t hdrlen,
- char *buf, size_t buflen)
-{
- 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;
-}
-
-
-int32_t
-server_fgetxattr (call_frame_t *frame,
- xlator_t *bound_xl,
- gf_hdr_common_t *hdr, size_t hdrlen,
- char *buf, size_t buflen)
-{
- 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;
-}
-
-
-int32_t
-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_DEBUG,
- "%"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
- */
-int32_t
-server_removexattr (call_frame_t *frame,
- xlator_t *bound_xl,
- gf_hdr_common_t *hdr, size_t hdrlen,
- char *buf, size_t buflen)
-{
- 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
- */
-int32_t
-server_statfs (call_frame_t *frame,
- xlator_t *bound_xl,
- gf_hdr_common_t *hdr, size_t hdrlen,
- char *buf, size_t buflen)
-{
- 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_DEBUG,
- "%"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;
-}
-
-
-
-int32_t
-server_opendir_resume (call_frame_t *frame,
- xlator_t *this,
- loc_t *loc,
- fd_t *fd)
-{
- server_state_t *state = CALL_STATE(frame);
- fd_t *new_fd = NULL;
-
- new_fd = fd_create (loc->inode, frame->root->pid);
- state->fd = fd_ref (new_fd);
-
- gf_log (BOUND_XL(frame)->name, GF_LOG_DEBUG,
- "%"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
- */
-int32_t
-server_opendir (call_frame_t *frame, xlator_t *bound_xl,
- gf_hdr_common_t *hdr, size_t hdrlen,
- char *buf, size_t buflen)
-{
- 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
- */
-int32_t
-server_releasedir (call_frame_t *frame, xlator_t *bound_xl,
- gf_hdr_common_t *hdr, size_t hdrlen,
- char *buf, size_t buflen)
-{
- 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, EINVAL);
- goto out;
- }
-
- gf_log (bound_xl->name, GF_LOG_DEBUG,
- "%"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
- */
-int32_t
-server_getdents (call_frame_t *frame,
- xlator_t *bound_xl,
- gf_hdr_common_t *hdr, size_t hdrlen,
- char *buf, size_t buflen)
-{
- 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, EINVAL, NULL, 0);
-
- goto out;
- }
-
- gf_log (bound_xl->name, GF_LOG_DEBUG,
- "%"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_readdir - readdir function for server protocol
- * @frame: call frame
- * @bound_xl:
- * @params: parameter dictionary
- *
- * not for external reference
- */
-int32_t
-server_readdir (call_frame_t *frame, xlator_t *bound_xl,
- gf_hdr_common_t *hdr, size_t hdrlen,
- char *buf, size_t buflen)
-{
- 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, EINVAL, NULL);
-
- goto out;
- }
-
- gf_log (bound_xl->name, GF_LOG_DEBUG,
- "%"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
- */
-int32_t
-server_fsyncdir (call_frame_t *frame,
- xlator_t *bound_xl,
- gf_hdr_common_t *hdr, size_t hdrlen,
- char *buf, size_t buflen)
-{
- 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, EINVAL);
- goto out;
- }
-
- gf_log (bound_xl->name, GF_LOG_DEBUG,
- "%"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;
-}
-
-
-int32_t
-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_DEBUG,
- "%"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
- */
-int32_t
-server_mknod (call_frame_t *frame,
- xlator_t *bound_xl,
- gf_hdr_common_t *hdr, size_t hdrlen,
- char *buf, size_t buflen)
-{
- 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;
-}
-
-int32_t
-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_DEBUG,
- "%"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
- */
-int32_t
-server_mkdir (call_frame_t *frame,
- xlator_t *bound_xl,
- gf_hdr_common_t *hdr, size_t hdrlen,
- char *buf, size_t buflen)
-{
- 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;
-}
-
-
-int32_t
-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_DEBUG,
- "%"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
- */
-int32_t
-server_rmdir (call_frame_t *frame,
- xlator_t *bound_xl,
- gf_hdr_common_t *hdr, size_t hdrlen,
- char *buf, size_t buflen)
-{
- 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;
-}
-
-
-
-int32_t
-server_chown_resume (call_frame_t *frame,
- xlator_t *this,
- loc_t *loc,
- uid_t uid,
- gid_t gid)
-{
- server_state_t *state = NULL;
-
- state = CALL_STATE(frame);
-
- gf_log (BOUND_XL(frame)->name, GF_LOG_DEBUG,
- "%"PRId64": CHOWN \'%s (%"PRId64")\'",
- frame->root->unique, state->path, state->ino);
-
- STACK_WIND (frame, server_chown_cbk,
- BOUND_XL(frame),
- BOUND_XL(frame)->fops->chown,
- loc, uid, gid);
- return 0;
-}
-
-
-/*
- * server_chown - chown function for server protocol
- * @frame: call frame
- * @bound_xl:
- * @params: parameter dictionary
- *
- * not for external reference
- */
-int32_t
-server_chown (call_frame_t *frame,
- xlator_t *bound_xl,
- gf_hdr_common_t *hdr, size_t hdrlen,
- char *buf, size_t buflen)
-{
- call_stub_t *chown_stub = NULL;
- gf_fop_chown_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->uid = ntoh32 (req->uid);
- state->gid = ntoh32 (req->gid);
- }
-
-
- ret = server_loc_fill (&(state->loc), state,
- state->ino, 0, NULL, state->path);
-
- chown_stub = fop_chown_stub (frame,
- server_chown_resume,
- &(state->loc),
- state->uid,
- state->gid);
-
- if (((state->loc.parent == NULL) && IS_NOT_ROOT(pathlen)) ||
- (state->loc.inode == NULL)) {
- do_path_lookup (chown_stub, &(state->loc));
- } else {
- call_resume (chown_stub);
- }
-
- return 0;
-}
-
-
-int32_t
-server_chmod_resume (call_frame_t *frame,
- xlator_t *this,
- loc_t *loc,
- mode_t mode)
-{
- server_state_t *state = NULL;
-
- state = CALL_STATE(frame);
-
- gf_log (BOUND_XL(frame)->name, GF_LOG_DEBUG,
- "%"PRId64": CHMOD \'%s (%"PRId64")\'",
- frame->root->unique, state->path, state->ino);
-
- STACK_WIND (frame,
- server_chmod_cbk,
- BOUND_XL(frame),
- BOUND_XL(frame)->fops->chmod,
- loc,
- mode);
- return 0;
-
-}
-
-/*
- * server_chmod - chmod function for server protocol
- * @frame: call frame
- * @bound_xl:
- * @params: parameter dictionary
- *
- * not for external reference
- */
-int32_t
-server_chmod (call_frame_t *frame,
- xlator_t *bound_xl,
- gf_hdr_common_t *hdr, size_t hdrlen,
- char *buf, size_t buflen)
-{
- call_stub_t *chmod_stub = NULL;
- gf_fop_chmod_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->mode = ntoh32 (req->mode);
- }
-
- ret = server_loc_fill (&(state->loc), state,
- state->ino, 0, NULL, state->path);
-
- chmod_stub = fop_chmod_stub (frame,
- server_chmod_resume,
- &(state->loc),
- state->mode);
-
- if (((state->loc.parent == NULL) && IS_NOT_ROOT(pathlen)) ||
- (state->loc.inode == NULL)) {
- do_path_lookup (chmod_stub, &(state->loc));
- } else {
- call_resume (chmod_stub);
- }
-
- return 0;
-}
-
-
-int32_t
-server_utimens_resume (call_frame_t *frame,
- xlator_t *this,
- loc_t *loc,
- struct timespec *tv)
-{
- server_state_t *state = NULL;
-
- state = CALL_STATE(frame);
-
- gf_log (BOUND_XL(frame)->name, GF_LOG_DEBUG,
- "%"PRId64": UTIMENS \'%s (%"PRId64")\'",
- frame->root->unique, state->path, state->ino);
-
- STACK_WIND (frame,
- server_utimens_cbk,
- BOUND_XL(frame),
- BOUND_XL(frame)->fops->utimens,
- loc,
- tv);
- return 0;
-}
-
-/*
- * server_utimens - utimens function for server protocol
- * @frame: call frame
- * @bound_xl:
- * @params: parameter dictionary
- *
- * not for external reference
- */
-int32_t
-server_utimens (call_frame_t *frame,
- xlator_t *bound_xl,
- gf_hdr_common_t *hdr, size_t hdrlen,
- char *buf, size_t buflen)
-{
- call_stub_t *utimens_stub = NULL;
- gf_fop_utimens_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);
-
- gf_timespec_to_timespec (req->tv, state->tv);
- }
-
-
- ret = server_loc_fill (&(state->loc), state,
- state->ino, 0, NULL, state->path);
-
- utimens_stub = fop_utimens_stub (frame,
- server_utimens_resume,
- &(state->loc),
- state->tv);
-
- if (((state->loc.parent == NULL) && IS_NOT_ROOT(pathlen)) ||
- (state->loc.inode == NULL)) {
- do_path_lookup (utimens_stub, &(state->loc));
- } else {
- call_resume (utimens_stub);
- }
-
- return 0;
-}
-
-
-
-int32_t
-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_DEBUG,
- "%"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;
-
-}
-
-
-int32_t
-server_inodelk (call_frame_t *frame,
- xlator_t *bound_xl,
- gf_hdr_common_t *hdr, size_t hdrlen,
- char *buf, size_t buflen)
-{
- 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 = 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.parent == NULL) ||
- (state->loc.inode == NULL)) {
- do_path_lookup (inodelk_stub, &(state->loc));
- } else {
- call_resume (inodelk_stub);
- }
-
- return 0;
-}
-
-
-int32_t
-server_finodelk (call_frame_t *frame,
- xlator_t *bound_xl,
- gf_hdr_common_t *hdr, size_t hdrlen,
- char *buf, size_t buflen)
-{
- 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 = 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, EINVAL);
- return -1;
- }
-
- gf_log (BOUND_XL(frame)->name, GF_LOG_DEBUG,
- "%"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;
-}
-
-
-int32_t
-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_DEBUG,
- "%"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
- */
-int32_t
-server_entrylk (call_frame_t *frame,
- xlator_t *bound_xl,
- gf_hdr_common_t *hdr, size_t hdrlen,
- char *buf, size_t buflen)
-{
- 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 = 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.parent == NULL) && IS_NOT_ROOT(pathlen)) ||
- (state->loc.inode == NULL)) {
- do_path_lookup (entrylk_stub, &(state->loc));
- } else {
- call_resume (entrylk_stub);
- }
-
- return 0;
-}
-
-
-int32_t
-server_fentrylk (call_frame_t *frame,
- xlator_t *bound_xl,
- gf_hdr_common_t *hdr, size_t hdrlen,
- char *buf, size_t buflen)
-{
- 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 = 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, EINVAL);
- return -1;
- }
-
- gf_log (BOUND_XL(frame)->name, GF_LOG_DEBUG,
- "%"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;
-}
-
-
-int32_t
-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_DEBUG,
- "%"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
- */
-int32_t
-server_access (call_frame_t *frame,
- xlator_t *bound_xl,
- gf_hdr_common_t *hdr, size_t hdrlen,
- char *buf, size_t buflen)
-{
- 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;
-}
-
-
-int32_t
-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_DEBUG,
- "%"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
- */
-
-int32_t
-server_symlink (call_frame_t *frame,
- xlator_t *bound_xl,
- gf_hdr_common_t *hdr, size_t hdrlen,
- char *buf, size_t buflen)
-{
- 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;
-}
-
-int32_t
-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_DEBUG,
- "%"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
- */
-int32_t
-server_link (call_frame_t *frame,
- xlator_t *this,
- gf_hdr_common_t *hdr, size_t hdrlen,
- char *buf, size_t buflen)
-{
- 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;
-}
-
-
-int32_t
-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_DEBUG,
- "%"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
- */
-int32_t
-server_rename (call_frame_t *frame,
- xlator_t *bound_xl,
- gf_hdr_common_t *hdr, size_t hdrlen,
- char *buf, size_t buflen)
-{
- 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
- */
-
-int32_t
-server_lk (call_frame_t *frame,
- xlator_t *bound_xl,
- gf_hdr_common_t *hdr, size_t hdrlen,
- char *buf, size_t buflen)
-{
- 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, EINVAL, 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_DEBUG,
- "%"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:
- *
- */
-int32_t
-server_setdents (call_frame_t *frame,
- xlator_t *bound_xl,
- gf_hdr_common_t *hdr, size_t hdrlen,
- char *buf, size_t buflen)
-{
- 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, EINVAL);
-
- goto out;
- }
-
- if (buf == 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, EINVAL);
-
- goto out;
- }
-
- entry = CALLOC (1, sizeof (dir_entry_t));
- ERR_ABORT (entry);
- prev = entry;
- buffer_ptr = buf;
-
- 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_DEBUG,
- "%"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:
- 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;
-}
-
-
-char *
-build_volfile_path (xlator_t *this, char *key)
-{
- int ret = -1;
- 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) {
- gf_log (this->name, GF_LOG_ERROR,
- "failed to get corresponding volume file "
- "for the key '%s'.", 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;
- }
- }
-
- return filename;
-}
-
-int
-_validate_volfile_checksum (xlator_t *this, char *key,
- uint32_t checksum)
-{
- char *filename = NULL;
- 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) {
- filename = build_volfile_path (this, key);
- if (NULL == filename)
- 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 (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:
- *
- */
-int32_t
-mop_getspec (call_frame_t *frame,
- xlator_t *bound_xl,
- gf_hdr_common_t *hdr, size_t hdrlen,
- char *buf, size_t buflen)
-{
- 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 = NULL;
- 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;
-
- req = gf_param (hdr);
- flags = ntoh32 (req->flags);
- keylen = ntoh32 (req->keylen);
- if (keylen) {
- key = req->key;
- }
-
- filename = build_volfile_path (frame->this, key);
- if (filename) {
- /* 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;
- }
-
- ret = open (filename, O_RDONLY);
- spec_fd = ret;
- 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;
- 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;
-}
-
-int32_t
-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, ZR_FILENAME_MAX + 1 + ZR_FILENAME_MAX + 1);
- hdr = gf_hdr_new (rsp, ZR_FILENAME_MAX + 1 + ZR_FILENAME_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, ZR_FILENAME_MAX);
- rsp->fchecksum[ZR_FILENAME_MAX] = '\0';
- memcpy (rsp->dchecksum + ZR_FILENAME_MAX,
- dchecksum, ZR_FILENAME_MAX);
- rsp->dchecksum[ZR_FILENAME_MAX + ZR_FILENAME_MAX] = '\0';
- }
-
- protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_FOP_CHECKSUM,
- hdr, hdrlen, NULL, 0, NULL);
-
- return 0;
-}
-
-int32_t
-server_checksum (call_frame_t *frame,
- xlator_t *bound_xl,
- gf_hdr_common_t *hdr, size_t hdrlen,
- char *buf, size_t buflen)
-{
- 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_DEBUG,
- "%"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;
-}
-
-
-/*
- * mop_unlock - unlock management function for server protocol
- * @frame: call frame
- * @bound_xl:
- * @params: parameter dictionary
- *
- */
-int32_t
-mop_getvolume (call_frame_t *frame,
- xlator_t *bound_xl,
- gf_hdr_common_t *hdr, size_t hdrlen,
- char *buf, size_t buflen)
-{
- 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,
- char *req_buf, size_t req_buflen)
-{
- 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;
-
- 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_ERROR,
- "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_ERROR,
- "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, "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_ERROR,
- "failed to set error msg");
-
- op_ret = -1;
- op_errno = EINVAL;
- goto fail;
- }
-
- ret = strcmp (version, PACKAGE_VERSION);
- if (ret != 0) {
- asprintf (&msg,
- "Version mismatch: client(%s) Vs server (%s)",
- version, PACKAGE_VERSION);
- ret = dict_set_dynstr (reply, "ERROR", msg);
- if (ret < 0)
- gf_log (trans->xl->name, GF_LOG_ERROR,
- "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_ERROR,
- "failed to set error msg");
-
- op_ret = -1;
- op_errno = EINVAL;
- goto fail;
- }
-
- xl = get_xlator_by_name (frame->this, name);
- if (xl == NULL) {
- asprintf (&msg, "remote-subvolume \"%s\" is not found", name);
- ret = dict_set_dynstr (reply, "ERROR", msg);
- if (ret < 0)
- gf_log (trans->xl->name, GF_LOG_ERROR,
- "failed to set error msg");
-
- op_ret = -1;
- op_errno = ENOENT;
- goto fail;
- }
-
- 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_ERROR,
- "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_ERROR,
- "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_ERROR,
- "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_ERROR,
- "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_ERROR,
- "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 */
- int32_t lru_limit = 1024;
-
- lru_limit = INODE_LRU_LIMIT (frame->this);
-
- gf_log (trans->xl->name, GF_LOG_DEBUG,
- "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);
-
-fail:
- dict_len = dict_serialized_length (reply);
- if (dict_len < 0) {
- gf_log (xl->name, GF_LOG_ERROR,
- "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_ERROR,
- "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
- */
-
-int32_t
-server_mop_stats_cbk (call_frame_t *frame,
- void *cookie,
- xlator_t *xl,
- 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
- *
- */
-static int32_t
-mop_stats (call_frame_t *frame,
- xlator_t *bound_xl,
- gf_hdr_common_t *hdr, size_t hdrlen,
- char *buf, size_t buflen)
-{
- 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;
-}
-
-int32_t
-mop_ping (call_frame_t *frame,
- xlator_t *bound_xl,
- gf_hdr_common_t *hdr, size_t hdrlen,
- char *buf, size_t buflen)
-{
- 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;
-}
-/*
- * 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:
- *
- */
-
-int32_t
-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,
- char *buf, size_t buflen);
-
-
-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_CHMOD] = server_chmod,
- [GF_FOP_CHOWN] = server_chown,
- [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_UTIMENS] = server_utimens,
- [GF_FOP_FCHMOD] = server_fchmod,
- [GF_FOP_FCHOWN] = server_fchown,
- [GF_FOP_LOOKUP] = server_lookup,
- [GF_FOP_SETDENTS] = server_setdents,
- [GF_FOP_READDIR] = server_readdir,
- [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_XATTROP] = server_xattrop,
- [GF_FOP_FXATTROP] = server_fxattrop,
-};
-
-
-
-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,
-};
-
-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, char *buf,
- size_t buflen)
-{
- 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, buf, buflen);
- 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, buf, buflen);
- 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, buf, buflen);
- 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;
-}
-
-
-static void
-get_auth_types (dict_t *this,
- char *key,
- data_t *value,
- void *data)
-{
- dict_t *auth_dict = data;
- char *saveptr = NULL, *tmp = NULL;
- char *key_cpy = NULL;
- int32_t ret = -1;
-
- 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_ERROR,
- "failed to dict_set_dynptr");
- }
- }
-
- FREE (key_cpy);
-out:
- return;
-}
-
-
-static 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, *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;
-
- 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_DEBUG,
- "defaulting limits.transaction-size to %d",
- DEFAULT_BLOCK_SIZE);
- conf->max_block_size = DEFAULT_BLOCK_SIZE;
- }
-
-#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_ERROR,
- "Failed to set max open fd to 64k: %s",
- strerror(errno));
- } else {
- gf_log (this->name, GF_LOG_ERROR,
- "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;
- char *buf = NULL;
- size_t buflen = 0;
- int ret = -1;
-
-
- ret = transport_receive (trans, &hdr, &hdrlen, &buf, &buflen);
-
- if (ret == 0)
- ret = protocol_server_interpret (this, trans, hdr,
- hdrlen, buf, buflen);
-
- /* 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;
-
- switch (event) {
- case GF_EVENT_POLLIN:
- ret = protocol_server_pollin (this, trans);
- break;
- case GF_EVENT_POLLERR:
- {
- peer_info_t *peerinfo = NULL;
-
- peerinfo = &(trans->peerinfo);
- gf_log (trans->xl->name, GF_LOG_INFO, "%s disconnected",
- peerinfo->identifier);
-
- ret = -1;
- transport_disconnect (trans);
- }
- break;
-
- case GF_EVENT_TRANSPORT_CLEANUP:
- {
- if (trans->xl_private)
- server_connection_put (this, trans->xl_private);
- }
- break;
-
- default:
- default_notify (this, event, data);
- break;
- }
-
- return ret;
-}
-
-
-struct xlator_mops mops = {
-};
-
-struct xlator_fops fops = {
-};
-
-struct xlator_cbks cbks = {
-};
-
-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 = {NULL} },
-};
diff --git a/xlators/protocol/server/src/server-protocol.h b/xlators/protocol/server/src/server-protocol.h
deleted file mode 100644
index f00b584fb25..00000000000
--- a/xlators/protocol/server/src/server-protocol.h
+++ /dev/null
@@ -1,153 +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;
- 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_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;
-} 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;
- uid_t uid;
- gid_t gid;
- 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;
- struct timespec tv[2];
- 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 00000000000..ec768acba44
--- /dev/null
+++ b/xlators/protocol/server/src/server-resolve.c
@@ -0,0 +1,683 @@
+/*
+ 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.
+*/
+
+#include "server.h"
+#include "server-helpers.h"
+#include "server-messages.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;
+
+ state = CALL_STATE(frame);
+
+ resolve = state->resolve_now;
+ loc = state->loc_now;
+
+ loc_touchup(loc, resolve->bname);
+ 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) {
+ if (op_errno == ENOENT) {
+ gf_msg_debug(this->name, 0, "%s/%s: failed to resolve (%s)",
+ uuid_utoa(resolve_loc->pargfid), resolve_loc->name,
+ strerror(op_errno));
+ if (resolve->type == RESOLVE_NOT) {
+ do {
+ inode = inode_grep(state->itable, resolve_loc->parent,
+ resolve->bname);
+
+ if (inode) {
+ gf_msg_debug(this->name, 0,
+ "%s/%s: "
+ "removing stale dentry",
+ uuid_utoa(resolve_loc->pargfid),
+ resolve->bname);
+ inode_unlink(inode, resolve_loc->parent,
+ resolve->bname);
+ }
+ } while (inode);
+ }
+ } else {
+ gf_msg(this->name, GF_LOG_WARNING, op_errno,
+ PS_MSG_GFID_RESOLVE_FAILED,
+ "%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;
+ dict_t *dict = NULL;
+
+ state = CALL_STATE(frame);
+ resolve = state->resolve_now;
+ resolve_loc = &resolve->resolve_loc;
+
+ if (op_ret == -1) {
+ if (op_errno == ENOENT) {
+ gf_msg_debug(this->name, GF_LOG_DEBUG, "%s: failed to resolve (%s)",
+ uuid_utoa(resolve_loc->gfid), strerror(op_errno));
+ } else {
+ gf_msg(this->name, GF_LOG_WARNING, op_errno,
+ PS_MSG_GFID_RESOLVE_FAILED, "%s: failed to resolve (%s)",
+ uuid_utoa(resolve_loc->gfid), strerror(op_errno));
+ }
+ loc_wipe(&resolve->resolve_loc);
+ goto out;
+ }
+
+ link_inode = inode_link(inode, NULL, NULL, buf);
+
+ if (!link_inode) {
+ loc_wipe(resolve_loc);
+ goto out;
+ }
+
+ inode_lookup(link_inode);
+
+ /* wipe the loc only after the inode has been linked to the inode
+ table. Otherwise before inode gets linked to the inode table,
+ inode would have been unrefed (this might have been destroyed
+ if refcount becomes 0, and put back to mempool). So once the
+ inode gets destroyed, inode_link is a redundant operation. But
+ without knowing that the destroyed inode's pointer is saved in
+ the resolved_loc as parent (while constructing loc for resolving
+ the entry) and the inode_new call for resolving the entry will
+ return the same pointer to the inode as the parent (because in
+ reality the inode is a free inode present in cold list of the
+ inode mem-pool).
+ */
+ loc_wipe(resolve_loc);
+
+ if (gf_uuid_is_null(resolve->pargfid)) {
+ inode_unref(link_inode);
+ goto out;
+ }
+
+ resolve_loc->parent = link_inode;
+ gf_uuid_copy(resolve_loc->pargfid, resolve_loc->parent->gfid);
+
+ resolve_loc->name = resolve->bname;
+
+ resolve_loc->inode = server_inode_new(state->itable, resolve_loc->gfid);
+
+ inode_path(resolve_loc->parent, resolve_loc->name,
+ (char **)&resolve_loc->path);
+
+ if (state->xdata) {
+ dict = dict_copy_with_ref(state->xdata, NULL);
+ if (!dict)
+ gf_msg(this->name, GF_LOG_ERROR, ENOMEM, PS_MSG_NO_MEMORY,
+ "BUG: dict allocation failed (pargfid: %s, name: %s), "
+ "still continuing",
+ uuid_utoa(resolve_loc->gfid), resolve_loc->name);
+ }
+
+ STACK_WIND(frame, resolve_gfid_entry_cbk, frame->root->client->bound_xl,
+ frame->root->client->bound_xl->fops->lookup,
+ &resolve->resolve_loc, dict);
+ if (dict)
+ dict_unref(dict);
+ 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;
+ dict_t *xdata = NULL;
+
+ state = CALL_STATE(frame);
+ this = frame->this;
+ resolve = state->resolve_now;
+ resolve_loc = &resolve->resolve_loc;
+
+ if (!gf_uuid_is_null(resolve->pargfid))
+ gf_uuid_copy(resolve_loc->gfid, resolve->pargfid);
+ else if (!gf_uuid_is_null(resolve->gfid))
+ gf_uuid_copy(resolve_loc->gfid, resolve->gfid);
+
+ resolve_loc->inode = server_inode_new(state->itable, resolve_loc->gfid);
+ (void)loc_path(resolve_loc, NULL);
+
+ if (state->xdata) {
+ xdata = dict_copy_with_ref(state->xdata, NULL);
+ if (!xdata)
+ gf_msg(this->name, GF_LOG_ERROR, ENOMEM, PS_MSG_NO_MEMORY,
+ "BUG: dict allocation failed (gfid: %s), "
+ "still continuing",
+ uuid_utoa(resolve_loc->gfid));
+ }
+
+ STACK_WIND(frame, resolve_gfid_cbk, frame->root->client->bound_xl,
+ frame->root->client->bound_xl->fops->lookup,
+ &resolve->resolve_loc, xdata);
+
+ if (xdata)
+ dict_unref(xdata);
+
+ 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 (!gf_uuid_is_null(resolve->pargfid))
+ ret = resolve_entry_simple(frame);
+ else if (!gf_uuid_is_null(resolve->gfid))
+ ret = resolve_inode_simple(frame);
+ if (ret)
+ gf_msg_debug(this->name, 0,
+ "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 = ESTALE;
+ ret = 1;
+ goto out;
+ }
+
+ if (parent->ia_type != IA_IFDIR) {
+ /* Parent type should be 'directory', and nothing else */
+ gf_msg(this->name, GF_LOG_ERROR, EPERM, PS_MSG_GFID_RESOLVE_FAILED,
+ "%s: parent type not directory (%d)", uuid_utoa(parent->gfid),
+ parent->ia_type);
+ resolve->op_ret = -1;
+ resolve->op_errno = EPERM;
+ ret = 1;
+ goto out;
+ }
+
+ /* expected @parent was found from the inode cache */
+ gf_uuid_copy(state->loc_now->pargfid, resolve->pargfid);
+ state->loc_now->parent = inode_ref(parent);
+ if (strchr(resolve->bname, '/')) {
+ /* basename should be a string (without '/') in a directory,
+ it can't span multiple levels. This can also lead to
+ resolving outside the parent's tree, which is not allowed */
+ gf_msg(this->name, GF_LOG_ERROR, EPERM, PS_MSG_GFID_RESOLVE_FAILED,
+ "%s: basename sent by client not allowed", resolve->bname);
+ resolve->op_ret = -1;
+ resolve->op_errno = EPERM;
+ ret = 1;
+ goto out;
+ }
+
+ 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_msg_debug(this->name, 0,
+ "inode (pointer: %p gfid:%s found"
+ " for path (%s) while type is RESOLVE_NOT. "
+ "Performing lookup on backend to rule out any "
+ "possible stale dentries in inode table",
+ 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 = ESTALE;
+ ret = 1;
+ goto out;
+ }
+
+ ret = 0;
+
+ state->loc_now->inode = inode_ref(inode);
+ gf_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;
+
+ if (frame->root->op == GF_FOP_READ || frame->root->op == GF_FOP_WRITE)
+ state->fd = fd_anonymous_with_flags(inode, state->flags);
+ else
+ state->fd = fd_anonymous(inode);
+out:
+ if (inode)
+ inode_unref(inode);
+
+ if (ret != 0)
+ gf_msg_debug("server", 0,
+ "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_msg("", GF_LOG_INFO, ENOMEM, PS_MSG_NO_MEMORY,
+ "server_ctx_get() failed");
+ resolve->op_ret = -1;
+ resolve->op_errno = ENOMEM;
+ return 0;
+ }
+
+ /*
+ * With copy_file_range, there will be 2 fds to resolve.
+ * This same function is called to resolve both the source
+ * fd and the destination fd. As of now, this function does
+ * not have any mechanism to distinguish between the 2 fds
+ * being resolved except for checking the value of state->fd.
+ * The assumption is that, if source fd the one which is
+ * being resolved here, then state->fd would be NULL. If it
+ * is not NULL, then it is the destination fd which is being
+ * resolved.
+ * This method (provided the above assumption is true) is
+ * to achieve the ability to distinguish between 2 fds with
+ * minimum changes being done to this function. If this way
+ * is not correct, then more changes might be needed.
+ */
+ if (!state->fd) {
+ state->fd = gf_fd_fdptr_get(serv_ctx->fdtable, fd_no);
+ if (!state->fd) {
+ gf_msg("", GF_LOG_INFO, EBADF, PS_MSG_FD_NOT_FOUND,
+ "fd not "
+ "found in context");
+ resolve->op_ret = -1;
+ resolve->op_errno = EBADF;
+ }
+ } else {
+ state->fd_out = gf_fd_fdptr_get(serv_ctx->fdtable, fd_no);
+ if (!state->fd_out) {
+ gf_msg("", GF_LOG_INFO, EBADF, PS_MSG_FD_NOT_FOUND,
+ "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 (!gf_uuid_is_null(resolve->pargfid)) {
+ server_resolve_entry(frame);
+
+ } else if (!gf_uuid_is_null(resolve->gfid)) {
+ server_resolve_inode(frame);
+
+ } else {
+ if (resolve == &state->resolve)
+ gf_msg(frame->this->name, GF_LOG_WARNING, 0, PS_MSG_INVALID_ENTRY,
+ "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_msg(this->name, GF_LOG_ERROR, EINVAL, PS_MSG_INVALID_ENTRY,
+ "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 00000000000..4d8b7be5a34
--- /dev/null
+++ b/xlators/protocol/server/src/server-rpc-fops.c
@@ -0,0 +1,6084 @@
+/*
+ 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.
+*/
+
+#include <openssl/md5.h>
+
+#include "server.h"
+#include "server-helpers.h"
+#include "rpc-common-xdr.h"
+#include "glusterfs3-xdr.h"
+#include "glusterfs3.h"
+#include <glusterfs/compat-errno.h>
+#include "server-messages.h"
+#include <glusterfs/defaults.h>
+#include <glusterfs/default-args.h>
+#include "server-common.h"
+#include <glusterfs/xlator.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)
+
+void
+forget_inode_if_no_dentry(inode_t *inode)
+{
+ if (!inode) {
+ return;
+ }
+
+ if (!inode_has_dentry(inode))
+ inode_forget(inode, 0);
+
+ return;
+}
+
+void
+set_resolve_gfid(client_t *client, uuid_t resolve_gfid, char *on_wire_gfid)
+{
+ if (client->subdir_mount && __is_root_gfid((unsigned char *)on_wire_gfid)) {
+ /* set the subdir_mount's gfid for proper resolution */
+ gf_uuid_copy(resolve_gfid, client->subdir_gfid);
+ } else {
+ memcpy(resolve_gfid, on_wire_gfid, 16);
+ }
+}
+
+/* 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_msg(this->name, GF_LOG_WARNING, op_errno, PS_MSG_STATFS,
+ "%" PRId64 ": STATFS, client: %s, error-xlator: %s",
+ frame->root->unique, STACK_CLIENT_NAME(frame->root),
+ STACK_ERR_XL_NAME(frame->root));
+ goto out;
+ }
+
+ server_post_statfs(&rsp, 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;
+ loc_t fresh_loc = {
+ 0,
+ };
+ gfs3_lookup_rsp rsp = {
+ 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 = server_inode_new(state->itable, fresh_loc.gfid);
+
+ 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);
+ /**
+ * If the entry is not present, then just
+ * unlinking the associated dentry is not
+ * suffecient. This condition should be
+ * treated as unlink of the entry. So along
+ * with deleting the entry, its also important
+ * to forget the inode for it (if the dentry
+ * being considered was the last dentry).
+ * Otherwise it might lead to inode leak.
+ * It also might lead to wrong decisions being
+ * taken if the future lookups on this inode are
+ * successful since they are able to find the
+ * inode in the inode table (at least gfid based
+ * lookups will be successful, if the lookup
+ * is a soft lookup)
+ */
+ forget_inode_if_no_dentry(state->loc.inode);
+ }
+ }
+ goto out;
+ }
+
+ server_post_lookup(&rsp, frame, state, inode, stbuf, postparent);
+out:
+ rsp.op_ret = op_ret;
+ rsp.op_errno = gf_errno_to_error(op_errno);
+
+ if (op_ret) {
+ if (state->resolve.bname) {
+ gf_msg(this->name, fop_log_level(GF_FOP_LOOKUP, op_errno), op_errno,
+ PS_MSG_LOOKUP_INFO,
+ "%" PRId64
+ ": LOOKUP %s (%s/%s), client: %s, "
+ "error-xlator: %s",
+ frame->root->unique, state->loc.path,
+ uuid_utoa(state->resolve.pargfid), state->resolve.bname,
+ STACK_CLIENT_NAME(frame->root),
+ STACK_ERR_XL_NAME(frame->root));
+ } else {
+ gf_msg(this->name, fop_log_level(GF_FOP_LOOKUP, op_errno), op_errno,
+ PS_MSG_LOOKUP_INFO,
+ "%" PRId64
+ ": LOOKUP %s (%s), client: %s, "
+ "error-xlator: %s",
+ frame->root->unique, state->loc.path,
+ uuid_utoa(state->resolve.gfid),
+ STACK_CLIENT_NAME(frame->root),
+ STACK_ERR_XL_NAME(frame->root));
+ }
+ }
+
+ 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_lease_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct gf_lease *lease,
+ dict_t *xdata)
+{
+ gfs3_lease_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_msg(this->name, fop_log_level(GF_FOP_LEASE, op_errno), op_errno,
+ PS_MSG_LK_INFO,
+ "%" PRId64 ": LEASE %s (%s), client: %s, error-xlator: %s",
+ frame->root->unique, state->loc.path,
+ uuid_utoa(state->resolve.gfid), STACK_CLIENT_NAME(frame->root),
+ STACK_ERR_XL_NAME(frame->root));
+ goto out;
+ }
+ server_post_lease(&rsp, lease);
+
+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_lease_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) {
+ state = CALL_STATE(frame);
+ gf_msg(this->name, fop_log_level(GF_FOP_LK, op_errno), op_errno,
+ PS_MSG_LK_INFO,
+ "%" PRId64 ": LK %" PRId64
+ " (%s), client: %s, "
+ "error-xlator: %s",
+ frame->root->unique, state->resolve.fd_no,
+ uuid_utoa(state->resolve.gfid), STACK_CLIENT_NAME(frame->root),
+ STACK_ERR_XL_NAME(frame->root));
+ goto out;
+ }
+
+ server_post_lk(this, &rsp, 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) {
+ gf_msg(this->name, fop_log_level(GF_FOP_INODELK, op_errno), op_errno,
+ PS_MSG_INODELK_INFO,
+ "%" PRId64
+ ": INODELK %s (%s), client: %s, "
+ "error-xlator: %s",
+ frame->root->unique, state->loc.path,
+ uuid_utoa(state->resolve.gfid), STACK_CLIENT_NAME(frame->root),
+ STACK_ERR_XL_NAME(frame->root));
+ 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) {
+ gf_msg(this->name, fop_log_level(GF_FOP_FINODELK, op_errno), op_errno,
+ PS_MSG_INODELK_INFO,
+ "%" PRId64 ": FINODELK %" PRId64
+ " (%s), client: %s, "
+ "error-xlator: %s",
+ frame->root->unique, state->resolve.fd_no,
+ uuid_utoa(state->resolve.gfid), STACK_CLIENT_NAME(frame->root),
+ STACK_ERR_XL_NAME(frame->root));
+ 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) {
+ gf_msg(this->name, fop_log_level(GF_FOP_ENTRYLK, op_errno), op_errno,
+ PS_MSG_ENTRYLK_INFO,
+ "%" PRId64
+ ": ENTRYLK %s (%s), client: %s, "
+ "error-xlator: %s",
+ frame->root->unique, state->loc.path,
+ uuid_utoa(state->resolve.gfid), STACK_CLIENT_NAME(frame->root),
+ STACK_ERR_XL_NAME(frame->root));
+ 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) {
+ gf_msg(this->name, fop_log_level(GF_FOP_FENTRYLK, op_errno), op_errno,
+ PS_MSG_ENTRYLK_INFO,
+ "%" PRId64 ": FENTRYLK %" PRId64
+ " (%s), client: %s, "
+ "error-xlator: %s",
+ frame->root->unique, state->resolve.fd_no,
+ uuid_utoa(state->resolve.gfid), STACK_CLIENT_NAME(frame->root),
+ STACK_ERR_XL_NAME(frame->root));
+ 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_msg(this->name, GF_LOG_INFO, op_errno, PS_MSG_ACCESS_INFO,
+ "%" PRId64
+ ": ACCESS %s (%s), client: %s, "
+ "error-xlator: %s",
+ frame->root->unique, (state->loc.path) ? state->loc.path : "",
+ uuid_utoa(state->resolve.gfid), STACK_CLIENT_NAME(frame->root),
+ STACK_ERR_XL_NAME(frame->root));
+ 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;
+ 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_msg(this->name, GF_LOG_INFO, op_errno, PS_MSG_DIR_INFO,
+ "%" PRId64
+ ": RMDIR %s (%s/%s), client: %s, "
+ "error-xlator: %s",
+ frame->root->unique, (state->loc.path) ? state->loc.path : "",
+ uuid_utoa(state->resolve.pargfid), state->resolve.bname,
+ STACK_CLIENT_NAME(frame->root), STACK_ERR_XL_NAME(frame->root));
+ goto out;
+ }
+
+ server_post_rmdir(state, &rsp, preparent, 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;
+ 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_msg(this->name, fop_log_level(GF_FOP_MKDIR, op_errno), op_errno,
+ PS_MSG_DIR_INFO,
+ "%" PRId64
+ ": MKDIR %s (%s/%s) client: %s, "
+ "error-xlator: %s",
+ frame->root->unique, (state->loc.path) ? state->loc.path : "",
+ uuid_utoa(state->resolve.pargfid), state->resolve.bname,
+ STACK_CLIENT_NAME(frame->root), STACK_ERR_XL_NAME(frame->root));
+ goto out;
+ }
+
+ server_post_mkdir(state, &rsp, inode, stbuf, preparent, postparent, xdata);
+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;
+ 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_msg(this->name, fop_log_level(GF_FOP_MKNOD, op_errno), op_errno,
+ PS_MSG_MKNOD_INFO,
+ "%" PRId64
+ ": MKNOD %s (%s/%s), client: %s, "
+ "error-xlator: %s",
+ frame->root->unique, state->loc.path,
+ uuid_utoa(state->resolve.pargfid), state->resolve.bname,
+ STACK_CLIENT_NAME(frame->root), STACK_ERR_XL_NAME(frame->root));
+ goto out;
+ }
+
+ server_post_mknod(state, &rsp, stbuf, preparent, postparent, 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_msg(this->name, fop_log_level(GF_FOP_FSYNCDIR, op_errno), op_errno,
+ PS_MSG_DIR_INFO,
+ "%" PRId64 ": FSYNCDIR %" PRId64
+ " (%s), client: %s, "
+ "error-xlator: %s",
+ frame->root->unique, state->resolve.fd_no,
+ uuid_utoa(state->resolve.gfid), STACK_CLIENT_NAME(frame->root),
+ STACK_ERR_XL_NAME(frame->root));
+ 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_msg(this->name, fop_log_level(GF_FOP_READDIR, op_errno), op_errno,
+ PS_MSG_DIR_INFO,
+ "%" PRId64 ": READDIR %" PRId64
+ " (%s), client: %s, "
+ "error-xlator: %s",
+ frame->root->unique, state->resolve.fd_no,
+ uuid_utoa(state->resolve.gfid), STACK_CLIENT_NAME(frame->root),
+ STACK_ERR_XL_NAME(frame->root));
+ goto out;
+ }
+
+ /* (op_ret == 0) is valid, and means EOF */
+ if (op_ret) {
+ ret = server_post_readdir(&rsp, entries);
+ 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;
+ 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_msg(this->name, fop_log_level(GF_FOP_OPENDIR, op_errno), op_errno,
+ PS_MSG_DIR_INFO,
+ "%" PRId64
+ ": OPENDIR %s (%s), client: %s, "
+ "error-xlator: %s",
+ frame->root->unique, (state->loc.path) ? state->loc.path : "",
+ uuid_utoa(state->resolve.gfid), STACK_CLIENT_NAME(frame->root),
+ STACK_ERR_XL_NAME(frame->root));
+ goto out;
+ }
+
+ op_ret = server_post_opendir(frame, this, &rsp, fd);
+ if (op_ret)
+ goto out;
+out:
+ if (op_ret)
+ 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_loglevel_t loglevel = GF_LOG_NONE;
+
+ if (gf_replace_old_iatt_in_dict(xdata)) {
+ op_errno = errno;
+ op_ret = -1;
+ goto out;
+ }
+
+ 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 (ENODATA == op_errno || ENOATTR == op_errno)
+ loglevel = GF_LOG_DEBUG;
+ else
+ loglevel = GF_LOG_INFO;
+
+ gf_msg(this->name, loglevel, op_errno, PS_MSG_REMOVEXATTR_INFO,
+ "%" PRId64
+ ": REMOVEXATTR %s (%s) of key %s, client: %s, "
+ "error-xlator: %s",
+ frame->root->unique, state->loc.path,
+ uuid_utoa(state->resolve.gfid), state->name,
+ STACK_CLIENT_NAME(frame->root), STACK_ERR_XL_NAME(frame->root));
+ 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;
+
+ if (gf_replace_old_iatt_in_dict(xdata)) {
+ op_errno = errno;
+ op_ret = -1;
+ goto out;
+ }
+
+ 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_msg(this->name, fop_log_level(GF_FOP_FREMOVEXATTR, op_errno),
+ op_errno, PS_MSG_REMOVEXATTR_INFO,
+ "%" PRId64 ": FREMOVEXATTR %" PRId64
+ " (%s) (%s), "
+ "client: %s, error-xlator: %s",
+ frame->root->unique, state->resolve.fd_no,
+ uuid_utoa(state->resolve.gfid), state->name,
+ STACK_CLIENT_NAME(frame->root), STACK_ERR_XL_NAME(frame->root));
+ 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_msg(this->name, fop_log_level(GF_FOP_GETXATTR, op_errno), op_errno,
+ PS_MSG_GETXATTR_INFO,
+ "%" PRId64
+ ": GETXATTR %s (%s) (%s), client: %s, "
+ "error-xlator: %s",
+ frame->root->unique, state->loc.path,
+ uuid_utoa(state->resolve.gfid), state->name,
+ STACK_CLIENT_NAME(frame->root), STACK_ERR_XL_NAME(frame->root));
+ 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_msg(this->name, fop_log_level(GF_FOP_FGETXATTR, op_errno), op_errno,
+ PS_MSG_GETXATTR_INFO,
+ "%" PRId64 ": FGETXATTR %" PRId64
+ " (%s) (%s), "
+ "client: %s, error-xlator: %s",
+ frame->root->unique, state->resolve.fd_no,
+ uuid_utoa(state->resolve.gfid), state->name,
+ STACK_CLIENT_NAME(frame->root), STACK_ERR_XL_NAME(frame->root));
+ 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 */
+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_msg(THIS->name, GF_LOG_INFO, 0, PS_MSG_SETXATTR_INFO,
+ "%" PRId64
+ ": SETXATTR %s (%s) ==> %s, client: %s, "
+ "error-xlator: %s",
+ frame->root->unique, state->loc.path, uuid_utoa(state->resolve.gfid),
+ k, STACK_CLIENT_NAME(frame->root), STACK_ERR_XL_NAME(frame->root));
+ 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;
+
+ if (gf_replace_old_iatt_in_dict(xdata)) {
+ op_errno = errno;
+ op_ret = -1;
+ goto out;
+ }
+
+ 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);
+
+ if (op_errno == ENOTSUP) {
+ gf_msg_debug(THIS->name, 0, "%s", strerror(op_errno));
+ } else {
+ gf_msg(THIS->name, GF_LOG_INFO, op_errno, PS_MSG_SETXATTR_INFO,
+ "client: %s, "
+ "error-xlator: %s",
+ STACK_CLIENT_NAME(frame->root),
+ STACK_ERR_XL_NAME(frame->root));
+ }
+ 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_msg(THIS->name, GF_LOG_INFO, 0, PS_MSG_SETXATTR_INFO,
+ "%" PRId64 ": FSETXATTR %" PRId64
+ " (%s) ==> %s, client: %s, "
+ "error-xlator: %s",
+ frame->root->unique, state->resolve.fd_no,
+ uuid_utoa(state->resolve.gfid), k, STACK_CLIENT_NAME(frame->root),
+ STACK_ERR_XL_NAME(frame->root));
+
+ 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;
+
+ if (gf_replace_old_iatt_in_dict(xdata)) {
+ op_errno = errno;
+ op_ret = -1;
+ goto out;
+ }
+
+ 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);
+ }
+ if (op_errno == ENOTSUP) {
+ gf_msg_debug(THIS->name, 0, "%s", strerror(op_errno));
+ } else {
+ gf_msg(THIS->name, GF_LOG_INFO, op_errno, PS_MSG_SETXATTR_INFO,
+ "client: %s, "
+ "error-xlator: %s",
+ STACK_CLIENT_NAME(frame->root),
+ STACK_ERR_XL_NAME(frame->root));
+ }
+ 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;
+ 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.pargfid, oldpar_str);
+ uuid_utoa_r(state->resolve2.pargfid, newpar_str);
+ gf_msg(this->name, GF_LOG_INFO, op_errno, PS_MSG_RENAME_INFO,
+ "%" PRId64
+ ": RENAME %s (%s/%s) -> %s (%s/%s), "
+ "client: %s, error-xlator: %s",
+ frame->root->unique, state->loc.path, oldpar_str,
+ state->resolve.bname, state->loc2.path, newpar_str,
+ state->resolve2.bname, STACK_CLIENT_NAME(frame->root),
+ STACK_ERR_XL_NAME(frame->root));
+ goto out;
+ }
+
+ server_post_rename(frame, state, &rsp, stbuf, preoldparent, postoldparent,
+ prenewparent, 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;
+ rpcsvc_request_t *req = NULL;
+
+ if (gf_replace_old_iatt_in_dict(xdata)) {
+ op_errno = errno;
+ op_ret = -1;
+ goto out;
+ }
+
+ 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_msg(this->name, fop_log_level(GF_FOP_UNLINK, op_errno), op_errno,
+ PS_MSG_LINK_INFO,
+ "%" PRId64
+ ": UNLINK %s (%s/%s), client: %s, "
+ "error-xlator: %s",
+ frame->root->unique, state->loc.path,
+ uuid_utoa(state->resolve.pargfid), state->resolve.bname,
+ STACK_CLIENT_NAME(frame->root), STACK_ERR_XL_NAME(frame->root));
+ goto out;
+ }
+
+ /* TODO: log gfid of the inodes */
+ gf_msg_trace(frame->root->client->bound_xl->name, 0,
+ "%" PRId64
+ ": "
+ "UNLINK_CBK %s",
+ frame->root->unique, state->loc.name);
+
+ server_post_unlink(state, &rsp, preparent, 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;
+ 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_msg(this->name, GF_LOG_INFO, op_errno, PS_MSG_LINK_INFO,
+ "%" PRId64
+ ": SYMLINK %s (%s/%s), client: %s, "
+ "error-xlator:%s",
+ frame->root->unique, (state->loc.path) ? state->loc.path : "",
+ uuid_utoa(state->resolve.pargfid), state->resolve.bname,
+ STACK_CLIENT_NAME(frame->root), STACK_ERR_XL_NAME(frame->root));
+ goto out;
+ }
+
+ server_post_symlink(state, &rsp, inode, stbuf, preparent, postparent,
+ xdata);
+
+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;
+ 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_msg(this->name, GF_LOG_INFO, op_errno, PS_MSG_LINK_INFO,
+ "%" PRId64
+ ": LINK %s (%s) -> %s/%s, client: %s, "
+ "error-xlator: %s",
+ frame->root->unique, state->loc.path, gfid_str, newpar_str,
+ state->resolve2.bname, STACK_CLIENT_NAME(frame->root),
+ STACK_ERR_XL_NAME(frame->root));
+ goto out;
+ }
+
+ server_post_link(state, &rsp, inode, stbuf, preparent, postparent, xdata);
+
+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_msg(this->name, GF_LOG_INFO, op_errno, PS_MSG_TRUNCATE_INFO,
+ "%" PRId64
+ ": TRUNCATE %s (%s), client: %s, "
+ "error-xlator: %s",
+ frame->root->unique, state->loc.path,
+ uuid_utoa(state->resolve.gfid), STACK_CLIENT_NAME(frame->root),
+ STACK_ERR_XL_NAME(frame->root));
+ goto out;
+ }
+
+ server_post_truncate(&rsp, prebuf, 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);
+
+ state = CALL_STATE(frame);
+ if (op_ret) {
+ gf_msg(this->name, fop_log_level(GF_FOP_FSTAT, op_errno), op_errno,
+ PS_MSG_STAT_INFO,
+ "%" PRId64 ": FSTAT %" PRId64
+ " (%s), client: %s, "
+ "error-xlator: %s",
+ frame->root->unique, state->resolve.fd_no,
+ uuid_utoa(state->resolve.gfid), STACK_CLIENT_NAME(frame->root),
+ STACK_ERR_XL_NAME(frame->root));
+ goto out;
+ }
+
+ server_post_fstat(state, &rsp, 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_msg(this->name, fop_log_level(GF_FOP_FTRUNCATE, op_errno), op_errno,
+ PS_MSG_TRUNCATE_INFO,
+ "%" PRId64 ": FTRUNCATE %" PRId64
+ " (%s), client: %s, "
+ "error-xlator: %s",
+ frame->root->unique, state->resolve.fd_no,
+ uuid_utoa(state->resolve.gfid), STACK_CLIENT_NAME(frame->root),
+ STACK_ERR_XL_NAME(frame->root));
+ goto out;
+ }
+
+ server_post_ftruncate(&rsp, prebuf, 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_msg(this->name, fop_log_level(GF_FOP_FLUSH, op_errno), op_errno,
+ PS_MSG_FLUSH_INFO,
+ "%" PRId64 ": FLUSH %" PRId64
+ " (%s), client: %s, "
+ "error-xlator: %s",
+ frame->root->unique, state->resolve.fd_no,
+ uuid_utoa(state->resolve.gfid), STACK_CLIENT_NAME(frame->root),
+ STACK_ERR_XL_NAME(frame->root));
+ 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_msg(this->name, fop_log_level(GF_FOP_FSYNC, op_errno), op_errno,
+ PS_MSG_SYNC_INFO,
+ "%" PRId64 ": FSYNC %" PRId64
+ " (%s), client: %s, "
+ "error-xlator: %s",
+ frame->root->unique, state->resolve.fd_no,
+ uuid_utoa(state->resolve.gfid), STACK_CLIENT_NAME(frame->root),
+ STACK_ERR_XL_NAME(frame->root));
+ goto out;
+ }
+
+ server_post_fsync(&rsp, prebuf, 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_msg(this->name, fop_log_level(GF_FOP_WRITE, op_errno), op_errno,
+ PS_MSG_WRITE_INFO,
+ "%" PRId64 ": WRITEV %" PRId64
+ " (%s), client: %s, "
+ "error-xlator: %s",
+ frame->root->unique, state->resolve.fd_no,
+ uuid_utoa(state->resolve.gfid), STACK_CLIENT_NAME(frame->root),
+ STACK_ERR_XL_NAME(frame->root));
+ goto out;
+ }
+
+ server_post_writev(&rsp, prebuf, 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_msg(this->name, fop_log_level(GF_FOP_READ, op_errno), op_errno,
+ PS_MSG_READ_INFO,
+ "%" PRId64 ": READV %" PRId64
+ " (%s), client: %s, "
+ "error-xlator: %s",
+ frame->root->unique, state->resolve.fd_no,
+ uuid_utoa(state->resolve.gfid), STACK_CLIENT_NAME(frame->root),
+ STACK_ERR_XL_NAME(frame->root));
+ goto out;
+ }
+
+ server_post_readv(&rsp, stbuf, 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_msg(this->name, fop_log_level(GF_FOP_RCHECKSUM, op_errno), op_errno,
+ PS_MSG_CHKSUM_INFO,
+ "%" PRId64 ": RCHECKSUM %" PRId64
+ " (%s), client: %s, "
+ "error-xlator: %s",
+ frame->root->unique, state->resolve.fd_no,
+ uuid_utoa(state->resolve.gfid), STACK_CLIENT_NAME(frame->root),
+ STACK_ERR_XL_NAME(frame->root));
+ goto out;
+ }
+
+ server_post_rchecksum(&rsp, weak_checksum, strong_checksum);
+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;
+ rpcsvc_request_t *req = NULL;
+ 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_msg(this->name, fop_log_level(GF_FOP_OPEN, op_errno), op_errno,
+ PS_MSG_OPEN_INFO,
+ "%" PRId64 ": OPEN %s (%s), client: %s, error-xlator: %s",
+ frame->root->unique, state->loc.path,
+ uuid_utoa(state->resolve.gfid), STACK_CLIENT_NAME(frame->root),
+ STACK_ERR_XL_NAME(frame->root));
+ goto out;
+ }
+
+ op_ret = server_post_open(frame, this, &rsp, fd);
+ if (op_ret)
+ 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_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;
+ 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_msg(this->name, GF_LOG_INFO, op_errno, PS_MSG_CREATE_INFO,
+ "%" PRId64
+ ": CREATE %s (%s/%s), client: %s, "
+ "error-xlator: %s",
+ frame->root->unique, state->loc.path,
+ uuid_utoa(state->resolve.pargfid), state->resolve.bname,
+ STACK_CLIENT_NAME(frame->root), STACK_ERR_XL_NAME(frame->root));
+ goto out;
+ }
+
+ /* TODO: log gfid too */
+ gf_msg_trace(frame->root->client->bound_xl->name, 0,
+ "%" PRId64
+ ": "
+ "CREATE %s (%s)",
+ frame->root->unique, state->loc.name,
+ uuid_utoa(stbuf->ia_gfid));
+
+ op_ret = server_post_create(frame, &rsp, state, this, fd, inode, stbuf,
+ preparent, postparent);
+ if (op_ret) {
+ op_errno = -op_ret;
+ op_ret = -1;
+ goto out;
+ }
+
+out:
+ if (op_ret)
+ 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_msg(this->name, GF_LOG_INFO, op_errno, PS_MSG_LINK_INFO,
+ "%" PRId64
+ ": READLINK %s (%s), client: %s, "
+ "error-xlator: %s",
+ frame->root->unique, state->loc.path,
+ uuid_utoa(state->resolve.gfid), STACK_CLIENT_NAME(frame->root),
+ STACK_ERR_XL_NAME(frame->root));
+ goto out;
+ }
+
+ server_post_readlink(&rsp, stbuf, 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);
+
+ state = CALL_STATE(frame);
+ if (op_ret) {
+ gf_msg(this->name, fop_log_level(GF_FOP_STAT, op_errno), op_errno,
+ PS_MSG_STAT_INFO,
+ "%" PRId64 ": STAT %s (%s), client: %s, error-xlator: %s",
+ frame->root->unique, (state->loc.path) ? state->loc.path : "",
+ uuid_utoa(state->resolve.gfid), STACK_CLIENT_NAME(frame->root),
+ STACK_ERR_XL_NAME(frame->root));
+ goto out;
+ }
+
+ server_post_stat(state, &rsp, 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_msg(this->name, GF_LOG_INFO, op_errno, PS_MSG_SETATTR_INFO,
+ "%" PRId64
+ ": SETATTR %s (%s), client: %s, "
+ "error-xlator: %s",
+ frame->root->unique, (state->loc.path) ? state->loc.path : "",
+ uuid_utoa(state->resolve.gfid), STACK_CLIENT_NAME(frame->root),
+ STACK_ERR_XL_NAME(frame->root));
+ goto out;
+ }
+
+ server_post_setattr(&rsp, statpre, 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_msg(this->name, fop_log_level(GF_FOP_FSETATTR, op_errno), op_errno,
+ PS_MSG_SETATTR_INFO,
+ "%" PRId64 ": FSETATTR %" PRId64
+ " (%s), client: %s, "
+ "error-xlator: %s",
+ frame->root->unique, state->resolve.fd_no,
+ uuid_utoa(state->resolve.gfid), STACK_CLIENT_NAME(frame->root),
+ STACK_ERR_XL_NAME(frame->root));
+ goto out;
+ }
+
+ server_post_fsetattr(&rsp, statpre, 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_msg(this->name, fop_log_level(GF_FOP_XATTROP, op_errno), op_errno,
+ PS_MSG_XATTROP_INFO,
+ "%" PRId64
+ ": XATTROP %s (%s), client: %s, "
+ "error-xlator: %s",
+ frame->root->unique, state->loc.path,
+ uuid_utoa(state->resolve.gfid), STACK_CLIENT_NAME(frame->root),
+ STACK_ERR_XL_NAME(frame->root));
+ 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_msg(this->name, fop_log_level(GF_FOP_FXATTROP, op_errno), op_errno,
+ PS_MSG_XATTROP_INFO,
+ "%" PRId64 ": FXATTROP %" PRId64
+ " (%s), client: %s, "
+ "error-xlator: %s",
+ frame->root->unique, state->resolve.fd_no,
+ uuid_utoa(state->resolve.gfid), STACK_CLIENT_NAME(frame->root),
+ STACK_ERR_XL_NAME(frame->root));
+ 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;
+
+ state = CALL_STATE(frame);
+
+ 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_msg(this->name, fop_log_level(GF_FOP_READDIRP, op_errno), op_errno,
+ PS_MSG_DIR_INFO,
+ "%" PRId64 ": READDIRP %" PRId64
+ " (%s), client: %s, "
+ "error-xlator: %s",
+ frame->root->unique, state->resolve.fd_no,
+ uuid_utoa(state->resolve.gfid), STACK_CLIENT_NAME(frame->root),
+ STACK_ERR_XL_NAME(frame->root));
+ goto out;
+ }
+
+ /* (op_ret == 0) is valid, and means EOF */
+ if (op_ret) {
+ ret = server_post_readdirp(&rsp, entries);
+ if (ret == -1) {
+ op_ret = -1;
+ op_errno = ENOMEM;
+ goto out;
+ }
+ }
+
+ 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_msg(this->name, fop_log_level(GF_FOP_FALLOCATE, op_errno), op_errno,
+ PS_MSG_ALLOC_INFO,
+ "%" PRId64 ": FALLOCATE %" PRId64
+ " (%s), client: %s, "
+ "error-xlator: %s",
+ frame->root->unique, state->resolve.fd_no,
+ uuid_utoa(state->resolve.gfid), STACK_CLIENT_NAME(frame->root),
+ STACK_ERR_XL_NAME(frame->root));
+ goto out;
+ }
+
+ server_post_fallocate(&rsp, statpre, 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_msg(this->name, fop_log_level(GF_FOP_DISCARD, op_errno), op_errno,
+ PS_MSG_DISCARD_INFO,
+ "%" PRId64 ": DISCARD %" PRId64
+ " (%s), client: %s, "
+ "error-xlator: %s",
+ frame->root->unique, state->resolve.fd_no,
+ uuid_utoa(state->resolve.gfid), STACK_CLIENT_NAME(frame->root),
+ STACK_ERR_XL_NAME(frame->root));
+ goto out;
+ }
+
+ server_post_discard(&rsp, statpre, 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_msg(this->name, fop_log_level(GF_FOP_ZEROFILL, op_errno), op_errno,
+ PS_MSG_ZEROFILL_INFO,
+ "%" PRId64 ": ZEROFILL%" PRId64
+ " (%s), client: %s, "
+ "error-xlator: %s",
+ frame->root->unique, state->resolve.fd_no,
+ uuid_utoa(state->resolve.gfid), STACK_CLIENT_NAME(frame->root),
+ STACK_ERR_XL_NAME(frame->root));
+ goto out;
+ }
+
+ server_post_zerofill(&rsp, statpre, 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;
+}
+
+int
+server_ipc_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;
+
+ 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_msg(this->name, GF_LOG_INFO, op_errno, PS_MSG_SERVER_IPC_INFO,
+ "%" PRId64 ": IPC%" PRId64
+ " (%s), client: %s, "
+ "error-xlator: %s",
+ frame->root->unique, state->resolve.fd_no,
+ uuid_utoa(state->resolve.gfid), STACK_CLIENT_NAME(frame->root),
+ STACK_ERR_XL_NAME(frame->root));
+ goto out;
+ }
+
+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_gf_common_rsp);
+
+ GF_FREE(rsp.xdata.xdata_val);
+
+ return 0;
+}
+
+int
+server_seek_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, off_t offset, dict_t *xdata)
+{
+ struct gfs3_seek_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_msg(this->name, fop_log_level(GF_FOP_SEEK, op_errno), op_errno,
+ PS_MSG_SEEK_INFO,
+ "%" PRId64 ": SEEK%" PRId64
+ " (%s), client: %s, "
+ "error-xlator: %s",
+ frame->root->unique, state->resolve.fd_no,
+ uuid_utoa(state->resolve.gfid), STACK_CLIENT_NAME(frame->root),
+ STACK_ERR_XL_NAME(frame->root));
+ goto out;
+ }
+
+ server_post_seek(&rsp, offset);
+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_seek_rsp);
+
+ GF_FREE(rsp.xdata.xdata_val);
+
+ return 0;
+}
+
+static int
+server_setactivelk_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata)
+{
+ gfs3_setactivelk_rsp rsp = {
+ 0,
+ };
+ server_state_t *state = NULL;
+ rpcsvc_request_t *req = NULL;
+
+ state = CALL_STATE(frame);
+
+ 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_msg(this->name, GF_LOG_INFO, op_errno, 0,
+ "%" PRId64
+ ": SETACTIVELK %s (%s), client: %s, "
+ "error-xlator: %s",
+ frame->root->unique, state->loc.path,
+ uuid_utoa(state->resolve.gfid), STACK_CLIENT_NAME(frame->root),
+ STACK_ERR_XL_NAME(frame->root));
+ 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_setactivelk_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_lease_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_lease_cbk, bound_xl, bound_xl->fops->lease,
+ &state->loc, &state->lease, state->xdata);
+
+ return 0;
+
+err:
+ server_lease_cbk(frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, 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_msg_debug(bound_xl->name, 0, "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_msg_debug(bound_xl->name, 0, "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_msg("server", GF_LOG_ERROR, 0, PS_MSG_FD_CREATE_FAILED,
+ "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_msg("server", GF_LOG_ERROR, 0, PS_MSG_FD_CREATE_FAILED,
+ "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 = server_inode_new(state->itable, state->loc.gfid);
+ 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;
+}
+
+int
+server_seek_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_seek_cbk, bound_xl, bound_xl->fops->seek,
+ state->fd, state->offset, state->what, state->xdata);
+ return 0;
+err:
+ server_seek_cbk(frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, 0, NULL);
+
+ return 0;
+}
+
+static int
+server_getactivelk_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno,
+ lock_migration_info_t *locklist, dict_t *xdata)
+{
+ gfs3_getactivelk_rsp rsp = {
+ 0,
+ };
+ server_state_t *state = NULL;
+ rpcsvc_request_t *req = NULL;
+ int ret = 0;
+
+ state = CALL_STATE(frame);
+
+ 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_msg(this->name, GF_LOG_INFO, op_errno, 0,
+ "%" PRId64
+ ": GETACTIVELK %s (%s), client: %s, "
+ "error-xlator: %s",
+ frame->root->unique, state->loc.path,
+ uuid_utoa(state->resolve.gfid), STACK_CLIENT_NAME(frame->root),
+ STACK_ERR_XL_NAME(frame->root));
+
+ goto out;
+ }
+
+ /* (op_ret == 0) means there are no locks on the file*/
+ if (op_ret > 0) {
+ ret = serialize_rsp_locklist(locklist, &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_getactivelk_rsp);
+
+ GF_FREE(rsp.xdata.xdata_val);
+
+ getactivelkinfo_rsp_cleanup(&rsp);
+
+ return 0;
+}
+
+int
+server_getactivelk_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_getactivelk_cbk, bound_xl,
+ bound_xl->fops->getactivelk, &state->loc, state->xdata);
+ return 0;
+err:
+ server_getactivelk_cbk(frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, NULL);
+ return 0;
+}
+
+int
+server_setactivelk_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_setactivelk_cbk, bound_xl,
+ bound_xl->fops->setactivelk, &state->loc, &state->locklist,
+ state->xdata);
+ return 0;
+err:
+ server_setactivelk_cbk(frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL);
+ return 0;
+}
+
+/* Fop section */
+int
+rpc_receive_common(rpcsvc_request_t *req, call_frame_t **fr,
+ server_state_t **st, ssize_t *xdrlen, void *args,
+ void *xdrfn, glusterfs_fop_t fop)
+{
+ int ret = -1;
+ ssize_t len = 0;
+
+ len = xdr_to_generic(req->msg[0], args, (xdrproc_t)xdrfn);
+ if (len < 0) {
+ /* failed to decode msg; */
+ SERVER_REQ_SET_ERROR(req, ret);
+ goto out;
+ }
+
+ /* Few fops use the xdr size to get the vector sizes */
+ if (xdrlen)
+ *xdrlen = len;
+
+ *fr = get_frame_from_request(req);
+ if (!(*fr)) {
+ /* something wrong, mostly no memory */
+ SERVER_REQ_SET_ERROR(req, ret);
+ goto out;
+ }
+ (*fr)->root->op = fop;
+
+ *st = CALL_STATE((*fr));
+ if (!(*fr)->root->client->bound_xl) {
+ /* auth failure, mostly setvolume is not successful */
+ SERVER_REQ_SET_ERROR(req, ret);
+ goto out;
+ }
+
+ if (!(*fr)->root->client->bound_xl->itable) {
+ /* inode_table is not allocated successful in server_setvolume */
+ SERVER_REQ_SET_ERROR(req, ret);
+ goto out;
+ }
+
+ ret = 0;
+
+out:
+ return ret;
+}
+
+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 = rpc_receive_common(req, &frame, &state, NULL, &args,
+ xdr_gfs3_stat_req, GF_FOP_STAT);
+ if (ret != 0) {
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ set_resolve_gfid(frame->root->client, state->resolve.gfid, args.gfid);
+
+ 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 = rpc_receive_common(req, &frame, &state, NULL, &args,
+ xdr_gfs3_setattr_req, GF_FOP_SETATTR);
+ if (ret != 0) {
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ set_resolve_gfid(frame->root->client, state->resolve.gfid, args.gfid);
+
+ 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 = rpc_receive_common(req, &frame, &state, NULL, &args,
+ xdr_gfs3_fsetattr_req, GF_FOP_FSETATTR);
+ if (ret != 0) {
+ 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 = rpc_receive_common(req, &frame, &state, NULL, &args,
+ xdr_gfs3_fallocate_req, GF_FOP_FALLOCATE);
+ if (ret != 0) {
+ 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 = rpc_receive_common(req, &frame, &state, NULL, &args,
+ xdr_gfs3_discard_req, GF_FOP_DISCARD);
+ if (ret != 0) {
+ 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 = rpc_receive_common(req, &frame, &state, NULL, &args,
+ xdr_gfs3_zerofill_req, GF_FOP_ZEROFILL);
+ if (ret != 0) {
+ 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_ipc(rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfs3_ipc_req args = {
+ 0,
+ };
+ int ret = -1;
+ int op_errno = 0;
+ xlator_t *bound_xl = NULL;
+
+ if (!req)
+ return ret;
+
+ ret = rpc_receive_common(req, &frame, &state, NULL, &args, xdr_gfs3_ipc_req,
+ GF_FOP_IPC);
+ if (ret != 0) {
+ goto out;
+ }
+
+ bound_xl = frame->root->client->bound_xl;
+ GF_PROTOCOL_DICT_UNSERIALIZE(bound_xl, state->xdata, args.xdata.xdata_val,
+ args.xdata.xdata_len, ret, op_errno, out);
+
+ ret = 0;
+ STACK_WIND(frame, server_ipc_cbk, bound_xl, bound_xl->fops->ipc, args.op,
+ state->xdata);
+
+out:
+ free(args.xdata.xdata_val);
+
+ if (op_errno)
+ req->rpc_err = GARBAGE_ARGS;
+
+ return ret;
+}
+
+int
+server3_3_seek(rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfs3_seek_req args = {
+ {
+ 0,
+ },
+ };
+ int ret = -1;
+ int op_errno = 0;
+ xlator_t *bound_xl = NULL;
+
+ if (!req)
+ return ret;
+
+ ret = rpc_receive_common(req, &frame, &state, NULL, &args,
+ xdr_gfs3_seek_req, GF_FOP_SEEK);
+ if (ret != 0) {
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ state->resolve.fd_no = args.fd;
+
+ state->offset = args.offset;
+ state->what = args.what;
+ memcpy(state->resolve.gfid, args.gfid, 16);
+
+ bound_xl = frame->root->client->bound_xl;
+ GF_PROTOCOL_DICT_UNSERIALIZE(bound_xl, state->xdata, args.xdata.xdata_val,
+ args.xdata.xdata_len, ret, op_errno, out);
+
+ ret = 0;
+ resolve_and_resume(frame, server_seek_resume);
+
+out:
+ free(args.xdata.xdata_val);
+
+ if (op_errno)
+ SERVER_REQ_SET_ERROR(req, ret);
+
+ 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 = rpc_receive_common(req, &frame, &state, NULL, &args,
+ xdr_gfs3_readlink_req, GF_FOP_READLINK);
+ if (ret != 0) {
+ 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;
+
+ ret = rpc_receive_common(req, &frame, &state, NULL, &args,
+ xdr_gfs3_create_req, GF_FOP_CREATE);
+ if (ret != 0) {
+ 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);
+
+ set_resolve_gfid(frame->root->client, state->resolve.pargfid, args.pargfid);
+
+ 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);
+ free(args.bname);
+
+ 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 = rpc_receive_common(req, &frame, &state, NULL, &args,
+ xdr_gfs3_open_req, GF_FOP_OPEN);
+ if (ret != 0) {
+ 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 = rpc_receive_common(req, &frame, &state, NULL, &args,
+ xdr_gfs3_read_req, GF_FOP_READ);
+ if (ret != 0) {
+ 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;
+
+ ret = rpc_receive_common(req, &frame, &state, &len, &args,
+ xdr_gfs3_write_req, GF_FOP_WRITE);
+ if (ret != 0) {
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ state->resolve.fd_no = args.fd;
+ state->offset = args.offset;
+ state->size = args.size;
+ 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];
+ }
+
+ len = iov_length(state->payload_vector, state->payload_count);
+
+ GF_ASSERT(state->size == 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_to_log(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 = gf_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_msg("server", GF_LOG_ERROR, 0, PS_MSG_WRONG_STATE,
+ "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_msg(req->trans->name, GF_LOG_INFO, 0, PS_MSG_SERVER_CTX_GET_FAILED,
+ "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:
+ free(args.xdata.xdata_val);
+ 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_msg(req->trans->name, GF_LOG_INFO, 0, PS_MSG_SERVER_CTX_GET_FAILED,
+ "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:
+ free(args.xdata.xdata_val);
+ 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 = rpc_receive_common(req, &frame, &state, NULL, &args,
+ xdr_gfs3_fsync_req, GF_FOP_FSYNC);
+ if (ret != 0) {
+ 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 = rpc_receive_common(req, &frame, &state, NULL, &args,
+ xdr_gfs3_flush_req, GF_FOP_FLUSH);
+ if (ret != 0) {
+ 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 = rpc_receive_common(req, &frame, &state, NULL, &args,
+ xdr_gfs3_ftruncate_req, GF_FOP_FTRUNCATE);
+ if (ret != 0) {
+ 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 = rpc_receive_common(req, &frame, &state, NULL, &args,
+ xdr_gfs3_fstat_req, GF_FOP_FSTAT);
+ if (ret != 0) {
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ state->resolve.fd_no = args.fd;
+ set_resolve_gfid(frame->root->client, state->resolve.gfid, args.gfid);
+
+ 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 = rpc_receive_common(req, &frame, &state, NULL, &args,
+ xdr_gfs3_truncate_req, GF_FOP_TRUNCATE);
+ if (ret != 0) {
+ 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;
+
+ ret = rpc_receive_common(req, &frame, &state, NULL, &args,
+ xdr_gfs3_unlink_req, GF_FOP_UNLINK);
+ if (ret != 0) {
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ state->resolve.bname = gf_strdup(args.bname);
+
+ set_resolve_gfid(frame->root->client, state->resolve.pargfid, args.pargfid);
+
+ 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);
+ free(args.bname);
+
+ 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;
+
+ ret = rpc_receive_common(req, &frame, &state, NULL, &args,
+ xdr_gfs3_setxattr_req, GF_FOP_SETXATTR);
+ if (ret != 0) {
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ state->flags = args.flags;
+ set_resolve_gfid(frame->root->client, state->resolve.gfid, args.gfid);
+
+ 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);
+
+ /* 'dict' will be destroyed later when 'state' is not needed anymore */
+ dict = NULL;
+
+out:
+ free(args.xdata.xdata_val);
+ free(args.dict.dict_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;
+
+ ret = rpc_receive_common(req, &frame, &state, NULL, &args,
+ xdr_gfs3_fsetxattr_req, GF_FOP_FSETXATTR);
+ if (ret != 0) {
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ state->resolve.fd_no = args.fd;
+ state->flags = args.flags;
+ set_resolve_gfid(frame->root->client, state->resolve.gfid, args.gfid);
+
+ 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);
+
+ /* 'dict' will be destroyed later when 'state' is not needed anymore */
+ dict = NULL;
+
+out:
+ free(args.xdata.xdata_val);
+ free(args.dict.dict_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;
+
+ ret = rpc_receive_common(req, &frame, &state, NULL, &args,
+ xdr_gfs3_fxattrop_req, GF_FOP_FXATTROP);
+ if (ret != 0) {
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ state->resolve.fd_no = args.fd;
+ state->flags = args.flags;
+ set_resolve_gfid(frame->root->client, state->resolve.gfid, args.gfid);
+
+ 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);
+
+ /* 'dict' will be destroyed later when 'state' is not needed anymore */
+ dict = NULL;
+
+out:
+ free(args.xdata.xdata_val);
+ free(args.dict.dict_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;
+
+ ret = rpc_receive_common(req, &frame, &state, NULL, &args,
+ xdr_gfs3_xattrop_req, GF_FOP_XATTROP);
+ if (ret != 0) {
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ state->flags = args.flags;
+ set_resolve_gfid(frame->root->client, state->resolve.gfid, args.gfid);
+
+ 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);
+
+ /* 'dict' will be destroyed later when 'state' is not needed anymore */
+ dict = NULL;
+
+out:
+ free(args.xdata.xdata_val);
+ free(args.dict.dict_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;
+
+ ret = rpc_receive_common(req, &frame, &state, NULL, &args,
+ xdr_gfs3_getxattr_req, GF_FOP_GETXATTR);
+ if (ret != 0) {
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ set_resolve_gfid(frame->root->client, state->resolve.gfid, args.gfid);
+
+ 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);
+ free(args.name);
+
+ 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;
+
+ ret = rpc_receive_common(req, &frame, &state, NULL, &args,
+ xdr_gfs3_fgetxattr_req, GF_FOP_FGETXATTR);
+ if (ret != 0) {
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ state->resolve.fd_no = args.fd;
+ set_resolve_gfid(frame->root->client, state->resolve.gfid, args.gfid);
+ 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);
+ free(args.name);
+
+ 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;
+
+ ret = rpc_receive_common(req, &frame, &state, NULL, &args,
+ xdr_gfs3_removexattr_req, GF_FOP_REMOVEXATTR);
+ if (ret != 0) {
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ set_resolve_gfid(frame->root->client, state->resolve.gfid, args.gfid);
+ 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);
+ free(args.name);
+
+ 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;
+
+ ret = rpc_receive_common(req, &frame, &state, NULL, &args,
+ xdr_gfs3_fremovexattr_req, GF_FOP_FREMOVEXATTR);
+ if (ret != 0) {
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ state->resolve.fd_no = args.fd;
+ set_resolve_gfid(frame->root->client, state->resolve.gfid, args.gfid);
+ 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);
+ free(args.name);
+
+ 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 = rpc_receive_common(req, &frame, &state, NULL, &args,
+ xdr_gfs3_opendir_req, GF_FOP_OPENDIR);
+ if (ret != 0) {
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ set_resolve_gfid(frame->root->client, state->resolve.gfid, args.gfid);
+
+ 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 = rpc_receive_common(req, &frame, &state, NULL, &args,
+ xdr_gfs3_readdirp_req, GF_FOP_READDIRP);
+ if (ret != 0) {
+ 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;
+ set_resolve_gfid(frame->root->client, state->resolve.gfid, args.gfid);
+
+ /* 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 = rpc_receive_common(req, &frame, &state, NULL, &args,
+ xdr_gfs3_readdir_req, GF_FOP_READDIR);
+ if (ret != 0) {
+ 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;
+ set_resolve_gfid(frame->root->client, state->resolve.gfid, args.gfid);
+
+ 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 = rpc_receive_common(req, &frame, &state, NULL, &args,
+ xdr_gfs3_fsyncdir_req, GF_FOP_FSYNCDIR);
+ if (ret != 0) {
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ state->resolve.fd_no = args.fd;
+ state->flags = args.data;
+ set_resolve_gfid(frame->root->client, state->resolve.gfid, args.gfid);
+
+ 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;
+
+ ret = rpc_receive_common(req, &frame, &state, NULL, &args,
+ xdr_gfs3_mknod_req, GF_FOP_MKNOD);
+ if (ret != 0) {
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_NOT;
+ set_resolve_gfid(frame->root->client, state->resolve.pargfid, args.pargfid);
+
+ 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);
+ free(args.bname);
+
+ 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;
+
+ ret = rpc_receive_common(req, &frame, &state, NULL, &args,
+ xdr_gfs3_mkdir_req, GF_FOP_MKDIR);
+ if (ret != 0) {
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_NOT;
+ set_resolve_gfid(frame->root->client, state->resolve.pargfid, args.pargfid);
+ 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);
+ free(args.bname);
+
+ 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;
+
+ ret = rpc_receive_common(req, &frame, &state, NULL, &args,
+ xdr_gfs3_rmdir_req, GF_FOP_RMDIR);
+ if (ret != 0) {
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ set_resolve_gfid(frame->root->client, state->resolve.pargfid, args.pargfid);
+ 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);
+ free(args.bname);
+
+ 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;
+
+ ret = rpc_receive_common(req, &frame, &state, NULL, &args,
+ xdr_gfs3_inodelk_req, GF_FOP_INODELK);
+ if (ret != 0) {
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_EXACT;
+ set_resolve_gfid(frame->root->client, state->resolve.gfid, args.gfid);
+
+ 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.volume);
+
+ 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;
+
+ ret = rpc_receive_common(req, &frame, &state, NULL, &args,
+ xdr_gfs3_finodelk_req, GF_FOP_FINODELK);
+ if (ret != 0) {
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_EXACT;
+ state->volume = gf_strdup(args.volume);
+ state->resolve.fd_no = args.fd;
+ state->cmd = args.cmd;
+ set_resolve_gfid(frame->root->client, state->resolve.gfid, args.gfid);
+
+ 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.volume);
+
+ 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;
+
+ ret = rpc_receive_common(req, &frame, &state, NULL, &args,
+ xdr_gfs3_entrylk_req, GF_FOP_ENTRYLK);
+ if (ret != 0) {
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_EXACT;
+ set_resolve_gfid(frame->root->client, state->resolve.gfid, args.gfid);
+
+ 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);
+ free(args.volume);
+ free(args.name);
+
+ 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;
+
+ ret = rpc_receive_common(req, &frame, &state, NULL, &args,
+ xdr_gfs3_fentrylk_req, GF_FOP_FENTRYLK);
+ if (ret != 0) {
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_EXACT;
+ state->resolve.fd_no = args.fd;
+ state->cmd = args.cmd;
+ state->type = args.type;
+ set_resolve_gfid(frame->root->client, state->resolve.gfid, args.gfid);
+
+ 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);
+ free(args.volume);
+ free(args.name);
+
+ 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 = rpc_receive_common(req, &frame, &state, NULL, &args,
+ xdr_gfs3_access_req, GF_FOP_ACCESS);
+ if (ret != 0) {
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ set_resolve_gfid(frame->root->client, state->resolve.gfid, args.gfid);
+ 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;
+
+ ret = rpc_receive_common(req, &frame, &state, NULL, &args,
+ xdr_gfs3_symlink_req, GF_FOP_SYMLINK);
+ if (ret != 0) {
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_NOT;
+ set_resolve_gfid(frame->root->client, state->resolve.pargfid, args.pargfid);
+ 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);
+ free(args.linkname);
+ free(args.bname);
+
+ 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;
+
+ ret = rpc_receive_common(req, &frame, &state, NULL, &args,
+ xdr_gfs3_link_req, GF_FOP_LINK);
+ if (ret != 0) {
+ 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);
+ set_resolve_gfid(frame->root->client, state->resolve2.pargfid,
+ args.newgfid);
+
+ 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);
+ free(args.newbname);
+
+ 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;
+
+ ret = rpc_receive_common(req, &frame, &state, NULL, &args,
+ xdr_gfs3_rename_req, GF_FOP_RENAME);
+ if (ret != 0) {
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ state->resolve.bname = gf_strdup(args.oldbname);
+ set_resolve_gfid(frame->root->client, state->resolve.pargfid, args.oldgfid);
+
+ state->resolve2.type = RESOLVE_MAY;
+ state->resolve2.bname = gf_strdup(args.newbname);
+ set_resolve_gfid(frame->root->client, state->resolve2.pargfid,
+ args.newgfid);
+
+ 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);
+ free(args.newbname);
+ free(args.oldbname);
+
+ if (op_errno)
+ SERVER_REQ_SET_ERROR(req, ret);
+
+ return ret;
+}
+
+int
+server3_3_lease(rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfs3_lease_req args = {
+ {
+ 0,
+ },
+ };
+ int ret = -1;
+ int op_errno = 0;
+
+ if (!req)
+ return ret;
+
+ ret = rpc_receive_common(req, &frame, &state, NULL, &args,
+ xdr_gfs3_lease_req, GF_FOP_LEASE);
+ if (ret != 0) {
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ set_resolve_gfid(frame->root->client, state->resolve.gfid, args.gfid);
+ gf_proto_lease_to_lease(&args.lease, &state->lease);
+
+ 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_lease_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 = rpc_receive_common(req, &frame, &state, NULL, &args, xdr_gfs3_lk_req,
+ GF_FOP_LK);
+ if (ret != 0) {
+ goto out;
+ }
+
+ state->resolve.fd_no = args.fd;
+ state->cmd = args.cmd;
+ state->type = args.type;
+ set_resolve_gfid(frame->root->client, state->resolve.gfid, args.gfid);
+
+ 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_msg(frame->root->client->bound_xl->name, GF_LOG_ERROR, 0,
+ PS_MSG_LOCK_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 = rpc_receive_common(req, &frame, &state, NULL, &args,
+ xdr_gfs3_rchecksum_req, GF_FOP_RCHECKSUM);
+ if (ret != 0) {
+ 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;
+
+ GF_VALIDATE_OR_GOTO("server", req, err);
+
+ ret = rpc_receive_common(req, &frame, &state, NULL, &args,
+ xdr_gfs3_lookup_req, GF_FOP_LOOKUP);
+ if (ret != 0) {
+ goto err;
+ }
+
+ state->resolve.type = RESOLVE_DONTCARE;
+
+ if (args.bname && strcmp(args.bname, "")) {
+ set_resolve_gfid(frame->root->client, state->resolve.pargfid,
+ args.pargfid);
+ state->resolve.bname = gf_strdup(args.bname);
+ } else {
+ set_resolve_gfid(frame->root->client, state->resolve.gfid, args.gfid);
+ }
+
+ GF_PROTOCOL_DICT_UNSERIALIZE(frame->root->client->bound_xl, state->xdata,
+ args.xdata.xdata_val, args.xdata.xdata_len,
+ ret, ret, out);
+
+ ret = 0;
+ resolve_and_resume(frame, server_lookup_resume);
+
+ free(args.bname);
+ free(args.xdata.xdata_val);
+
+ return ret;
+out:
+ free(args.bname);
+ free(args.xdata.xdata_val);
+
+ 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 = rpc_receive_common(req, &frame, &state, NULL, &args,
+ xdr_gfs3_statfs_req, GF_FOP_STATFS);
+ if (ret != 0) {
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ set_resolve_gfid(frame->root->client, state->resolve.gfid, args.gfid);
+
+ 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:
+ free(args.xdata.xdata_val);
+
+ if (op_errno)
+ SERVER_REQ_SET_ERROR(req, ret);
+
+ return ret;
+}
+
+static int
+server3_3_getactivelk(rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfs3_getactivelk_req args = {
+ {
+ 0,
+ },
+ };
+ int ret = -1;
+ int op_errno = 0;
+
+ if (!req)
+ return ret;
+
+ ret = rpc_receive_common(req, &frame, &state, NULL, &args,
+ xdr_gfs3_getactivelk_req, GF_FOP_GETACTIVELK);
+ if (ret != 0) {
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ set_resolve_gfid(frame->root->client, state->resolve.gfid, args.gfid);
+
+ /* here, dict itself works as xdata */
+ 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_getactivelk_resume);
+out:
+ free(args.xdata.xdata_val);
+
+ if (op_errno)
+ SERVER_REQ_SET_ERROR(req, ret);
+
+ return ret;
+}
+
+static int
+server3_3_setactivelk(rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfs3_setactivelk_req args = {
+ {
+ 0,
+ },
+ };
+ int ret = -1;
+ int op_errno = 0;
+
+ if (!req)
+ return ret;
+
+ ret = rpc_receive_common(req, &frame, &state, NULL, &args,
+ xdr_gfs3_setactivelk_req, GF_FOP_SETACTIVELK);
+ if (ret != 0) {
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ set_resolve_gfid(frame->root->client, state->resolve.gfid, args.gfid);
+
+ /* here, dict itself works as xdata */
+ GF_PROTOCOL_DICT_UNSERIALIZE(frame->root->client->bound_xl, state->xdata,
+ (args.xdata.xdata_val), (args.xdata.xdata_len),
+ ret, op_errno, out);
+
+ ret = unserialize_req_locklist(&args, &state->locklist);
+ if (ret)
+ goto out;
+
+ ret = 0;
+
+ resolve_and_resume(frame, server_setactivelk_resume);
+out:
+ free(args.xdata.xdata_val);
+
+ if (op_errno)
+ SERVER_REQ_SET_ERROR(req, ret);
+
+ return ret;
+}
+
+int
+server3_3_compound(rpcsvc_request_t *req)
+{
+ int ret = -1;
+ SERVER_REQ_SET_ERROR(req, ret);
+ return ret;
+}
+
+static rpcsvc_actor_t glusterfs3_3_fop_actors[GLUSTER_FOP_PROCCNT] = {
+ [GFS3_OP_NULL] = {"NULL", server_null, NULL, GFS3_OP_NULL, DRC_NA, 0},
+ [GFS3_OP_STAT] = {"STAT", server3_3_stat, NULL, GFS3_OP_STAT, DRC_NA, 0},
+ [GFS3_OP_READLINK] = {"READLINK", server3_3_readlink, NULL,
+ GFS3_OP_READLINK, DRC_NA, 0},
+ [GFS3_OP_MKNOD] = {"MKNOD", server3_3_mknod, NULL, GFS3_OP_MKNOD, DRC_NA,
+ 0},
+ [GFS3_OP_MKDIR] = {"MKDIR", server3_3_mkdir, NULL, GFS3_OP_MKDIR, DRC_NA,
+ 0},
+ [GFS3_OP_UNLINK] = {"UNLINK", server3_3_unlink, NULL, GFS3_OP_UNLINK,
+ DRC_NA, 0},
+ [GFS3_OP_RMDIR] = {"RMDIR", server3_3_rmdir, NULL, GFS3_OP_RMDIR, DRC_NA,
+ 0},
+ [GFS3_OP_SYMLINK] = {"SYMLINK", server3_3_symlink, NULL, GFS3_OP_SYMLINK,
+ DRC_NA, 0},
+ [GFS3_OP_RENAME] = {"RENAME", server3_3_rename, NULL, GFS3_OP_RENAME,
+ DRC_NA, 0},
+ [GFS3_OP_LINK] = {"LINK", server3_3_link, NULL, GFS3_OP_LINK, DRC_NA, 0},
+ [GFS3_OP_TRUNCATE] = {"TRUNCATE", server3_3_truncate, NULL,
+ GFS3_OP_TRUNCATE, DRC_NA, 0},
+ [GFS3_OP_OPEN] = {"OPEN", server3_3_open, NULL, GFS3_OP_OPEN, DRC_NA, 0},
+ [GFS3_OP_READ] = {"READ", server3_3_readv, NULL, GFS3_OP_READ, DRC_NA, 0},
+ [GFS3_OP_WRITE] = {"WRITE", server3_3_writev, server3_3_writev_vecsizer,
+ GFS3_OP_WRITE, DRC_NA, 0},
+ [GFS3_OP_STATFS] = {"STATFS", server3_3_statfs, NULL, GFS3_OP_STATFS,
+ DRC_NA, 0},
+ [GFS3_OP_FLUSH] = {"FLUSH", server3_3_flush, NULL, GFS3_OP_FLUSH, DRC_NA,
+ 0},
+ [GFS3_OP_FSYNC] = {"FSYNC", server3_3_fsync, NULL, GFS3_OP_FSYNC, DRC_NA,
+ 0},
+ [GFS3_OP_SETXATTR] = {"SETXATTR", server3_3_setxattr, NULL,
+ GFS3_OP_SETXATTR, DRC_NA, 0},
+ [GFS3_OP_GETXATTR] = {"GETXATTR", server3_3_getxattr, NULL,
+ GFS3_OP_GETXATTR, DRC_NA, 0},
+ [GFS3_OP_REMOVEXATTR] = {"REMOVEXATTR", server3_3_removexattr, NULL,
+ GFS3_OP_REMOVEXATTR, DRC_NA, 0},
+ [GFS3_OP_OPENDIR] = {"OPENDIR", server3_3_opendir, NULL, GFS3_OP_OPENDIR,
+ DRC_NA, 0},
+ [GFS3_OP_FSYNCDIR] = {"FSYNCDIR", server3_3_fsyncdir, NULL,
+ GFS3_OP_FSYNCDIR, DRC_NA, 0},
+ [GFS3_OP_ACCESS] = {"ACCESS", server3_3_access, NULL, DRC_NA, 0},
+ [GFS3_OP_CREATE] = {"CREATE", server3_3_create, NULL, GFS3_OP_ACCESS,
+ DRC_NA, 0},
+ [GFS3_OP_FTRUNCATE] = {"FTRUNCATE", server3_3_ftruncate, NULL,
+ GFS3_OP_FTRUNCATE, DRC_NA, 0},
+ [GFS3_OP_FSTAT] = {"FSTAT", server3_3_fstat, NULL, GFS3_OP_FSTAT, DRC_NA,
+ 0},
+ [GFS3_OP_LK] = {"LK", server3_3_lk, NULL, GFS3_OP_LK, DRC_NA, 0},
+ [GFS3_OP_LOOKUP] = {"LOOKUP", server3_3_lookup, NULL, GFS3_OP_LOOKUP,
+ DRC_NA, 0},
+ [GFS3_OP_READDIR] = {"READDIR", server3_3_readdir, NULL, GFS3_OP_READDIR,
+ DRC_NA, 0},
+ [GFS3_OP_INODELK] = {"INODELK", server3_3_inodelk, NULL, GFS3_OP_INODELK,
+ DRC_NA, 0},
+ [GFS3_OP_FINODELK] = {"FINODELK", server3_3_finodelk, NULL,
+ GFS3_OP_FINODELK, DRC_NA, 0},
+ [GFS3_OP_ENTRYLK] = {"ENTRYLK", server3_3_entrylk, NULL, GFS3_OP_ENTRYLK,
+ DRC_NA, 0},
+ [GFS3_OP_FENTRYLK] = {"FENTRYLK", server3_3_fentrylk, NULL,
+ GFS3_OP_FENTRYLK, DRC_NA, 0},
+ [GFS3_OP_XATTROP] = {"XATTROP", server3_3_xattrop, NULL, GFS3_OP_XATTROP,
+ DRC_NA, 0},
+ [GFS3_OP_FXATTROP] = {"FXATTROP", server3_3_fxattrop, NULL,
+ GFS3_OP_FXATTROP, DRC_NA, 0},
+ [GFS3_OP_FGETXATTR] = {"FGETXATTR", server3_3_fgetxattr, NULL,
+ GFS3_OP_FGETXATTR, DRC_NA, 0},
+ [GFS3_OP_FSETXATTR] = {"FSETXATTR", server3_3_fsetxattr, NULL,
+ GFS3_OP_FSETXATTR, DRC_NA, 0},
+ [GFS3_OP_RCHECKSUM] = {"RCHECKSUM", server3_3_rchecksum, NULL,
+ GFS3_OP_RCHECKSUM, DRC_NA, 0},
+ [GFS3_OP_SETATTR] = {"SETATTR", server3_3_setattr, NULL, GFS3_OP_SETATTR,
+ DRC_NA, 0},
+ [GFS3_OP_FSETATTR] = {"FSETATTR", server3_3_fsetattr, NULL,
+ GFS3_OP_FSETATTR, DRC_NA, 0},
+ [GFS3_OP_READDIRP] = {"READDIRP", server3_3_readdirp, NULL,
+ GFS3_OP_READDIRP, DRC_NA, 0},
+ [GFS3_OP_RELEASE] = {"RELEASE", server3_3_release, NULL, GFS3_OP_RELEASE,
+ DRC_NA, 0},
+ [GFS3_OP_RELEASEDIR] =
+ {
+ "RELEASEDIR",
+ server3_3_releasedir,
+ NULL,
+ GFS3_OP_RELEASEDIR,
+ DRC_NA,
+ 0,
+ },
+ [GFS3_OP_FREMOVEXATTR] = {"FREMOVEXATTR", server3_3_fremovexattr, NULL,
+ GFS3_OP_FREMOVEXATTR, DRC_NA, 0},
+ [GFS3_OP_FALLOCATE] = {"FALLOCATE", server3_3_fallocate, NULL,
+ GFS3_OP_FALLOCATE, DRC_NA, 0},
+ [GFS3_OP_DISCARD] = {"DISCARD", server3_3_discard, NULL, GFS3_OP_DISCARD,
+ DRC_NA, 0},
+ [GFS3_OP_ZEROFILL] = {"ZEROFILL", server3_3_zerofill, NULL,
+ GFS3_OP_ZEROFILL, DRC_NA, 0},
+ [GFS3_OP_IPC] = {"IPC", server3_3_ipc, NULL, GFS3_OP_IPC, DRC_NA, 0},
+ [GFS3_OP_SEEK] = {"SEEK", server3_3_seek, NULL, GFS3_OP_SEEK, DRC_NA, 0},
+ [GFS3_OP_LEASE] = {"LEASE", server3_3_lease, NULL, GFS3_OP_LEASE, DRC_NA,
+ 0},
+ [GFS3_OP_GETACTIVELK] = {"GETACTIVELK", server3_3_getactivelk, NULL,
+ GFS3_OP_GETACTIVELK, DRC_NA, 0},
+ [GFS3_OP_SETACTIVELK] = {"SETACTIVELK", server3_3_setactivelk, NULL,
+ GFS3_OP_SETACTIVELK, DRC_NA, 0},
+ [GFS3_OP_COMPOUND] = {"COMPOUND", server3_3_compound, NULL,
+ GFS3_OP_COMPOUND, DRC_NA, 0},
+};
+
+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,
+ .ownthread = _gf_true,
+};
diff --git a/xlators/protocol/server/src/server-rpc-fops_v2.c b/xlators/protocol/server/src/server-rpc-fops_v2.c
new file mode 100644
index 00000000000..c267f8f7832
--- /dev/null
+++ b/xlators/protocol/server/src/server-rpc-fops_v2.c
@@ -0,0 +1,6031 @@
+/*
+ Copyright (c) 2017 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.
+*/
+
+#include <openssl/md5.h>
+
+#include "server.h"
+#include "server-helpers.h"
+#include "rpc-common-xdr.h"
+#include "glusterfs4-xdr.h"
+#include "glusterfs3.h"
+#include <glusterfs/compat-errno.h>
+#include "server-messages.h"
+#include <glusterfs/defaults.h>
+#include <glusterfs/default-args.h>
+#include "server-common.h"
+#include <glusterfs/xlator.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)
+
+extern int
+server3_3_getxattr(rpcsvc_request_t *req);
+
+extern void
+set_resolve_gfid(client_t *client, uuid_t resolve_gfid, char *on_wire_gfid);
+extern int
+_gf_server_log_setxattr_failure(dict_t *d, char *k, data_t *v, void *tmp);
+extern int
+rpc_receive_common(rpcsvc_request_t *req, call_frame_t **fr,
+ server_state_t **st, ssize_t *xdrlen, void *args,
+ void *xdrfn, glusterfs_fop_t fop);
+
+/* Callback function section */
+int
+server4_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)
+{
+ gfx_statfs_rsp rsp = {
+ 0,
+ };
+ rpcsvc_request_t *req = NULL;
+
+ dict_to_xdr(xdata, &rsp.xdata);
+
+ if (op_ret < 0) {
+ gf_smsg(this->name, GF_LOG_WARNING, op_errno, PS_MSG_STATFS,
+ "frame=%" PRId64, frame->root->unique, "client=%s",
+ STACK_CLIENT_NAME(frame->root), "error-xlator=%s",
+ STACK_ERR_XL_NAME(frame->root), NULL);
+ goto out;
+ }
+
+ server4_post_statfs(&rsp, 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_gfx_statfs_rsp);
+
+ GF_FREE(rsp.xdata.pairs.pairs_val);
+
+ return 0;
+}
+
+int
+server4_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;
+ loc_t fresh_loc = {
+ 0,
+ };
+ gfx_common_2iatt_rsp rsp = {
+ 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 = server_inode_new(state->itable, fresh_loc.gfid);
+
+ STACK_WIND(frame, server4_lookup_cbk, frame->root->client->bound_xl,
+ frame->root->client->bound_xl->fops->lookup, &fresh_loc,
+ state->xdata);
+
+ loc_wipe(&fresh_loc);
+ return 0;
+ }
+
+ gfx_stat_from_iattx(&rsp.poststat, postparent);
+
+ dict_to_xdr(xdata, &rsp.xdata);
+
+ 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);
+ /**
+ * If the entry is not present, then just
+ * unlinking the associated dentry is not
+ * suffecient. This condition should be
+ * treated as unlink of the entry. So along
+ * with deleting the entry, its also important
+ * to forget the inode for it (if the dentry
+ * being considered was the last dentry).
+ * Otherwise it might lead to inode leak.
+ * It also might lead to wrong decisions being
+ * taken if the future lookups on this inode are
+ * successful since they are able to find the
+ * inode in the inode table (at least gfid based
+ * lookups will be successful, if the lookup
+ * is a soft lookup)
+ */
+ forget_inode_if_no_dentry(state->loc.inode);
+ }
+ }
+ goto out;
+ }
+
+ server4_post_lookup(&rsp, frame, state, inode, stbuf);
+out:
+ rsp.op_ret = op_ret;
+ rsp.op_errno = gf_errno_to_error(op_errno);
+
+ if (op_ret) {
+ if (state->resolve.bname) {
+ gf_smsg(this->name, fop_log_level(GF_FOP_LOOKUP, op_errno),
+ op_errno, PS_MSG_LOOKUP_INFO, "frame=%" PRId64,
+ frame->root->unique, "path=%s", state->loc.path,
+ "uuid_utoa=%s", uuid_utoa(state->resolve.pargfid),
+ "bname=%s", state->resolve.bname, "client=%s",
+ STACK_CLIENT_NAME(frame->root), "error-xlator=%s",
+ STACK_ERR_XL_NAME(frame->root), NULL);
+ } else {
+ gf_smsg(this->name, fop_log_level(GF_FOP_LOOKUP, op_errno),
+ op_errno, PS_MSG_LOOKUP_INFO, "frame=%" PRId64,
+ frame->root->unique, "path=%s", state->loc.path,
+ "uuid_utoa=%s", uuid_utoa(state->resolve.gfid), "client=%s",
+ STACK_CLIENT_NAME(frame->root), "error-xlator=%s",
+ STACK_ERR_XL_NAME(frame->root), NULL);
+ }
+ }
+
+ req = frame->local;
+ server_submit_reply(frame, req, &rsp, NULL, 0, NULL,
+ (xdrproc_t)xdr_gfx_common_2iatt_rsp);
+
+ GF_FREE(rsp.xdata.pairs.pairs_val);
+
+ return 0;
+}
+
+int
+server4_lease_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct gf_lease *lease,
+ dict_t *xdata)
+{
+ gfx_lease_rsp rsp = {
+ 0,
+ };
+ rpcsvc_request_t *req = NULL;
+ server_state_t *state = NULL;
+
+ dict_to_xdr(xdata, &rsp.xdata);
+
+ if (op_ret) {
+ state = CALL_STATE(frame);
+ gf_smsg(this->name, fop_log_level(GF_FOP_LEASE, op_errno), op_errno,
+ PS_MSG_LK_INFO, "frame=%" PRId64, frame->root->unique,
+ "path=%s", state->loc.path, "uuid_utoa=%s",
+ uuid_utoa(state->resolve.gfid), "client=%s",
+ STACK_CLIENT_NAME(frame->root), "error-xlator=%s",
+ STACK_ERR_XL_NAME(frame->root), NULL);
+ }
+ server4_post_lease(&rsp, lease);
+
+ 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_gfx_lease_rsp);
+
+ GF_FREE(rsp.xdata.pairs.pairs_val);
+
+ return 0;
+}
+
+int
+server4_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)
+{
+ gfx_lk_rsp rsp = {
+ 0,
+ };
+ rpcsvc_request_t *req = NULL;
+ server_state_t *state = NULL;
+
+ dict_to_xdr(xdata, &rsp.xdata);
+
+ if (op_ret) {
+ state = CALL_STATE(frame);
+ gf_smsg(this->name, fop_log_level(GF_FOP_LK, op_errno), op_errno,
+ PS_MSG_LK_INFO, "frame=%" PRId64, frame->root->unique,
+ "fd_no=%" PRId64, state->resolve.fd_no, "uuid_utoa=%s",
+ uuid_utoa(state->resolve.gfid), "client=%s",
+ STACK_CLIENT_NAME(frame->root), "error-xlator=%s",
+ STACK_ERR_XL_NAME(frame->root), NULL);
+ goto out;
+ }
+
+ server4_post_lk(this, &rsp, 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_gfx_lk_rsp);
+
+ GF_FREE(rsp.xdata.pairs.pairs_val);
+
+ return 0;
+}
+
+int
+server4_inodelk_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata)
+{
+ gfx_common_rsp rsp = {
+ 0,
+ };
+ server_state_t *state = NULL;
+ rpcsvc_request_t *req = NULL;
+
+ dict_to_xdr(xdata, &rsp.xdata);
+
+ state = CALL_STATE(frame);
+
+ if (op_ret < 0) {
+ gf_smsg(this->name, fop_log_level(GF_FOP_INODELK, op_errno), op_errno,
+ PS_MSG_INODELK_INFO, "frame=%" PRId64, frame->root->unique,
+ "path=%s", state->loc.path, "uuuid_utoa=%s",
+ uuid_utoa(state->resolve.gfid), "client=%s",
+ STACK_CLIENT_NAME(frame->root), "error-xlator=%s",
+ STACK_ERR_XL_NAME(frame->root), NULL);
+ 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_gfx_common_rsp);
+
+ GF_FREE(rsp.xdata.pairs.pairs_val);
+
+ return 0;
+}
+
+int
+server4_finodelk_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata)
+{
+ gfx_common_rsp rsp = {
+ 0,
+ };
+ server_state_t *state = NULL;
+ rpcsvc_request_t *req = NULL;
+
+ dict_to_xdr(xdata, &rsp.xdata);
+
+ state = CALL_STATE(frame);
+
+ if (op_ret < 0) {
+ gf_smsg(this->name, fop_log_level(GF_FOP_FINODELK, op_errno), op_errno,
+ PS_MSG_INODELK_INFO, "frame=%" PRId64, frame->root->unique,
+ "FINODELK_fd_no=%" PRId64, state->resolve.fd_no, "uuid_utoa=%s",
+ uuid_utoa(state->resolve.gfid), "client=%s",
+ STACK_CLIENT_NAME(frame->root), "error-xlator=%s",
+ STACK_ERR_XL_NAME(frame->root), NULL);
+ 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_gfx_common_rsp);
+
+ GF_FREE(rsp.xdata.pairs.pairs_val);
+
+ return 0;
+}
+
+int
+server4_entrylk_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata)
+{
+ gfx_common_rsp rsp = {
+ 0,
+ };
+ server_state_t *state = NULL;
+ rpcsvc_request_t *req = NULL;
+
+ dict_to_xdr(xdata, &rsp.xdata);
+
+ state = CALL_STATE(frame);
+
+ if (op_ret < 0) {
+ gf_smsg(this->name, fop_log_level(GF_FOP_ENTRYLK, op_errno), op_errno,
+ PS_MSG_ENTRYLK_INFO, "frame=%" PRId64, frame->root->unique,
+ "path=%s", state->loc.path, "uuid_utoa=%s",
+ uuid_utoa(state->resolve.gfid), "client=%s",
+ STACK_CLIENT_NAME(frame->root), "error-xlator=%s",
+ STACK_ERR_XL_NAME(frame->root), NULL);
+ 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_gfx_common_rsp);
+
+ GF_FREE(rsp.xdata.pairs.pairs_val);
+
+ return 0;
+}
+
+int
+server4_fentrylk_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata)
+{
+ gfx_common_rsp rsp = {
+ 0,
+ };
+ server_state_t *state = NULL;
+ rpcsvc_request_t *req = NULL;
+
+ dict_to_xdr(xdata, &rsp.xdata);
+
+ state = CALL_STATE(frame);
+
+ if (op_ret < 0) {
+ gf_smsg(this->name, fop_log_level(GF_FOP_FENTRYLK, op_errno), op_errno,
+ PS_MSG_ENTRYLK_INFO, "frame=%" PRId64, frame->root->unique,
+ "FENTRYLK_fd_no=%" PRId64, state->resolve.fd_no, "uuid_utoa=%s",
+ uuid_utoa(state->resolve.gfid), "client=%s",
+ STACK_CLIENT_NAME(frame->root), "error-xlator: %s",
+ STACK_ERR_XL_NAME(frame->root), NULL);
+ 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_gfx_common_rsp);
+
+ GF_FREE(rsp.xdata.pairs.pairs_val);
+
+ return 0;
+}
+
+int
+server4_access_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata)
+{
+ gfx_common_rsp rsp = {
+ 0,
+ };
+ rpcsvc_request_t *req = NULL;
+ server_state_t *state = NULL;
+
+ dict_to_xdr(xdata, &rsp.xdata);
+
+ if (op_ret) {
+ state = CALL_STATE(frame);
+ gf_smsg(this->name, GF_LOG_INFO, op_errno, PS_MSG_ACCESS_INFO,
+ "frame=%" PRId64, frame->root->unique, "path=%s",
+ (state->loc.path) ? state->loc.path : "", "uuid_utoa=%s",
+ uuid_utoa(state->resolve.gfid), "client=%s",
+ STACK_CLIENT_NAME(frame->root), "error-xlator=%s",
+ STACK_ERR_XL_NAME(frame->root), NULL);
+ 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_gfx_common_rsp);
+
+ GF_FREE(rsp.xdata.pairs.pairs_val);
+
+ return 0;
+}
+
+int
+server4_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)
+{
+ gfx_common_2iatt_rsp rsp = {
+ 0,
+ };
+ server_state_t *state = NULL;
+ rpcsvc_request_t *req = NULL;
+
+ dict_to_xdr(xdata, &rsp.xdata);
+
+ state = CALL_STATE(frame);
+
+ if (op_ret) {
+ gf_smsg(this->name, GF_LOG_INFO, op_errno, PS_MSG_DIR_INFO,
+ "frame=%" PRId64, frame->root->unique, "RMDIR_pat=%s",
+ (state->loc.path) ? state->loc.path : "", "uuid_utoa=%s",
+ uuid_utoa(state->resolve.pargfid), "bname=%s",
+ state->resolve.bname, "client=%s",
+ STACK_CLIENT_NAME(frame->root), "error-xlator=%s",
+ STACK_ERR_XL_NAME(frame->root), NULL);
+ goto out;
+ }
+
+ server4_post_entry_remove(state, &rsp, preparent, 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_gfx_common_2iatt_rsp);
+
+ GF_FREE(rsp.xdata.pairs.pairs_val);
+
+ return 0;
+}
+
+int
+server4_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)
+{
+ gfx_common_3iatt_rsp rsp = {
+ 0,
+ };
+ server_state_t *state = NULL;
+ rpcsvc_request_t *req = NULL;
+
+ dict_to_xdr(xdata, &rsp.xdata);
+
+ state = CALL_STATE(frame);
+
+ if (op_ret < 0) {
+ gf_smsg(this->name, fop_log_level(GF_FOP_MKDIR, op_errno), op_errno,
+ PS_MSG_DIR_INFO, "frame=%" PRId64, frame->root->unique,
+ "MKDIR_path=%s", (state->loc.path) ? state->loc.path : "",
+ "uuid_utoa=%s", uuid_utoa(state->resolve.pargfid), "bname=%s",
+ state->resolve.bname, "client=%s",
+ STACK_CLIENT_NAME(frame->root), "error-xlator=%s",
+ STACK_ERR_XL_NAME(frame->root), NULL);
+ goto out;
+ }
+
+ server4_post_common_3iatt(state, &rsp, inode, stbuf, preparent, 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_gfx_common_3iatt_rsp);
+
+ GF_FREE(rsp.xdata.pairs.pairs_val);
+
+ return 0;
+}
+
+int
+server4_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)
+{
+ gfx_common_3iatt_rsp rsp = {
+ 0,
+ };
+ server_state_t *state = NULL;
+ rpcsvc_request_t *req = NULL;
+
+ dict_to_xdr(xdata, &rsp.xdata);
+
+ state = CALL_STATE(frame);
+
+ if (op_ret < 0) {
+ gf_smsg(this->name, fop_log_level(GF_FOP_MKNOD, op_errno), op_errno,
+ PS_MSG_MKNOD_INFO, "frame=%" PRId64, frame->root->unique,
+ "path=%s", state->loc.path, "uuid_utoa=%s",
+ uuid_utoa(state->resolve.pargfid), "bname=%s",
+ state->resolve.bname, "client=%s",
+ STACK_CLIENT_NAME(frame->root), "error-xlator=%s",
+ STACK_ERR_XL_NAME(frame->root), NULL);
+ goto out;
+ }
+
+ server4_post_common_3iatt(state, &rsp, inode, stbuf, preparent, 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_gfx_common_3iatt_rsp);
+
+ GF_FREE(rsp.xdata.pairs.pairs_val);
+
+ return 0;
+}
+
+int
+server4_fsyncdir_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata)
+{
+ gfx_common_rsp rsp = {
+ 0,
+ };
+ server_state_t *state = NULL;
+ rpcsvc_request_t *req = NULL;
+
+ dict_to_xdr(xdata, &rsp.xdata);
+
+ if (op_ret < 0) {
+ state = CALL_STATE(frame);
+ gf_smsg(this->name, fop_log_level(GF_FOP_FSYNCDIR, op_errno), op_errno,
+ PS_MSG_DIR_INFO, "frame=%" PRId64, frame->root->unique,
+ "FSYNCDIR_fd_no=%" PRId64, state->resolve.fd_no, "uuid_utoa=%s",
+ uuid_utoa(state->resolve.gfid), "client=%s",
+ STACK_CLIENT_NAME(frame->root), "error-xlator=%s",
+ STACK_ERR_XL_NAME(frame->root), NULL);
+ 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_gfx_common_rsp);
+
+ GF_FREE(rsp.xdata.pairs.pairs_val);
+
+ return 0;
+}
+
+int
+server4_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)
+{
+ gfx_readdir_rsp rsp = {
+ 0,
+ };
+ server_state_t *state = NULL;
+ rpcsvc_request_t *req = NULL;
+ int ret = 0;
+
+ dict_to_xdr(xdata, &rsp.xdata);
+
+ if (op_ret < 0) {
+ state = CALL_STATE(frame);
+ gf_smsg(this->name, fop_log_level(GF_FOP_READDIR, op_errno), op_errno,
+ PS_MSG_DIR_INFO, "frame=%" PRId64, frame->root->unique,
+ "READDIR_fd_no=%" PRId64, state->resolve.fd_no, "uuid_utoa=%s",
+ uuid_utoa(state->resolve.gfid), "client=%s",
+ STACK_CLIENT_NAME(frame->root), "error-xlator=%s",
+ STACK_ERR_XL_NAME(frame->root), NULL);
+ goto out;
+ }
+
+ /* (op_ret == 0) is valid, and means EOF */
+ if (op_ret) {
+ ret = server4_post_readdir(&rsp, entries);
+ 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_gfx_readdir_rsp);
+
+ GF_FREE(rsp.xdata.pairs.pairs_val);
+
+ readdir_rsp_cleanup_v2(&rsp);
+
+ return 0;
+}
+
+int
+server4_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;
+ rpcsvc_request_t *req = NULL;
+ gfx_open_rsp rsp = {
+ 0,
+ };
+ uint64_t fd_no = 0;
+
+ dict_to_xdr(xdata, &rsp.xdata);
+
+ if (op_ret < 0) {
+ state = CALL_STATE(frame);
+ gf_smsg(this->name, fop_log_level(GF_FOP_OPENDIR, op_errno), op_errno,
+ PS_MSG_DIR_INFO, "frame=%" PRId64, frame->root->unique,
+ "OPENDIR_path=%s", (state->loc.path) ? state->loc.path : "",
+ "uuid_utoa=%s", uuid_utoa(state->resolve.gfid), "client=%s",
+ STACK_CLIENT_NAME(frame->root), "error-xlator=%s",
+ STACK_ERR_XL_NAME(frame->root), NULL);
+ goto out;
+ }
+
+ op_ret = server4_post_open(frame, this, &rsp, fd);
+ if (op_ret)
+ goto out;
+out:
+ if (op_ret)
+ 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_gfx_open_rsp);
+
+ GF_FREE(rsp.xdata.pairs.pairs_val);
+
+ return 0;
+}
+
+int
+server4_removexattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata)
+{
+ gfx_common_rsp rsp = {
+ 0,
+ };
+ rpcsvc_request_t *req = NULL;
+ server_state_t *state = NULL;
+ gf_loglevel_t loglevel = GF_LOG_NONE;
+
+ dict_to_xdr(xdata, &rsp.xdata);
+
+ if (op_ret == -1) {
+ state = CALL_STATE(frame);
+ if (ENODATA == op_errno || ENOATTR == op_errno)
+ loglevel = GF_LOG_DEBUG;
+ else
+ loglevel = GF_LOG_INFO;
+
+ gf_smsg(this->name, loglevel, op_errno, PS_MSG_REMOVEXATTR_INFO,
+ "frame=%" PRId64, frame->root->unique, "path=%s",
+ state->loc.path, "uuid_utoa=%s", uuid_utoa(state->resolve.gfid),
+ "name=%s", state->name, "client=%s",
+ STACK_CLIENT_NAME(frame->root), "error-xlator=%s",
+ STACK_ERR_XL_NAME(frame->root), NULL);
+ 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_gfx_common_rsp);
+
+ GF_FREE(rsp.xdata.pairs.pairs_val);
+
+ return 0;
+}
+
+int
+server4_fremovexattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata)
+{
+ gfx_common_rsp rsp = {
+ 0,
+ };
+ rpcsvc_request_t *req = NULL;
+ server_state_t *state = NULL;
+
+ dict_to_xdr(xdata, &rsp.xdata);
+
+ if (op_ret == -1) {
+ state = CALL_STATE(frame);
+ gf_smsg(this->name, fop_log_level(GF_FOP_FREMOVEXATTR, op_errno),
+ op_errno, PS_MSG_REMOVEXATTR_INFO, "frame=%" PRId64,
+ frame->root->unique, "FREMOVEXATTR_fd_no%" PRId64,
+ state->resolve.fd_no, "uuid_utoa=%s",
+ uuid_utoa(state->resolve.gfid), "name=%s", state->name,
+ "client=%s", STACK_CLIENT_NAME(frame->root), "error-xlator: %s",
+ STACK_ERR_XL_NAME(frame->root), NULL);
+ 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_gfx_common_rsp);
+
+ GF_FREE(rsp.xdata.pairs.pairs_val);
+
+ return 0;
+}
+
+int
+server4_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)
+{
+ gfx_common_dict_rsp rsp = {
+ 0,
+ };
+ rpcsvc_request_t *req = NULL;
+ server_state_t *state = NULL;
+
+ dict_to_xdr(xdata, &rsp.xdata);
+
+ if (op_ret == -1) {
+ state = CALL_STATE(frame);
+ gf_smsg(this->name, fop_log_level(GF_FOP_GETXATTR, op_errno), op_errno,
+ PS_MSG_GETXATTR_INFO, "frame=%" PRId64, frame->root->unique,
+ "path=%s", state->loc.path, "uuid_utoa=%s",
+ uuid_utoa(state->resolve.gfid), "name=%s", state->name,
+ "client=%s", STACK_CLIENT_NAME(frame->root), "error-xlator=%s",
+ STACK_ERR_XL_NAME(frame->root), NULL);
+ goto out;
+ }
+
+ dict_to_xdr(dict, &rsp.dict);
+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_gfx_common_dict_rsp);
+
+ GF_FREE(rsp.dict.pairs.pairs_val);
+
+ GF_FREE(rsp.xdata.pairs.pairs_val);
+
+ return 0;
+}
+
+int
+server4_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)
+{
+ gfx_common_dict_rsp rsp = {
+ 0,
+ };
+ server_state_t *state = NULL;
+ rpcsvc_request_t *req = NULL;
+
+ dict_to_xdr(xdata, &rsp.xdata);
+
+ if (op_ret == -1) {
+ state = CALL_STATE(frame);
+ gf_smsg(this->name, fop_log_level(GF_FOP_FGETXATTR, op_errno), op_errno,
+ PS_MSG_GETXATTR_INFO, "frame=%" PRId64, frame->root->unique,
+ "FGETXATTR_fd_no=%" PRId64, state->resolve.fd_no,
+ "uuid_utoa=%s", uuid_utoa(state->resolve.gfid), "name=%s",
+ state->name, "client=%s", STACK_CLIENT_NAME(frame->root),
+ "error-xlator=%s", STACK_ERR_XL_NAME(frame->root), NULL);
+ goto out;
+ }
+
+ dict_to_xdr(dict, &rsp.dict);
+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_gfx_common_dict_rsp);
+
+ GF_FREE(rsp.dict.pairs.pairs_val);
+
+ GF_FREE(rsp.xdata.pairs.pairs_val);
+
+ return 0;
+}
+
+int
+server4_setxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata)
+{
+ gfx_common_rsp rsp = {
+ 0,
+ };
+ rpcsvc_request_t *req = NULL;
+ server_state_t *state = NULL;
+
+ dict_to_xdr(xdata, &rsp.xdata);
+
+ if (op_ret == -1) {
+ state = CALL_STATE(frame);
+ if (op_errno != ENOTSUP)
+ dict_foreach(state->dict, _gf_server_log_setxattr_failure, frame);
+
+ if (op_errno == ENOTSUP) {
+ gf_msg_debug(THIS->name, 0, "%s", strerror(op_errno));
+ } else {
+ gf_smsg(THIS->name, GF_LOG_INFO, op_errno, PS_MSG_SETXATTR_INFO,
+ "client=%s", STACK_CLIENT_NAME(frame->root),
+ "error-xlator=%s", STACK_ERR_XL_NAME(frame->root), NULL);
+ }
+ 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_gfx_common_rsp);
+
+ GF_FREE(rsp.xdata.pairs.pairs_val);
+
+ return 0;
+}
+
+int
+server4_fsetxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata)
+{
+ gfx_common_rsp rsp = {
+ 0,
+ };
+ rpcsvc_request_t *req = NULL;
+ server_state_t *state = NULL;
+
+ dict_to_xdr(xdata, &rsp.xdata);
+
+ if (op_ret == -1) {
+ state = CALL_STATE(frame);
+ if (op_errno != ENOTSUP) {
+ dict_foreach(state->dict, _gf_server_log_setxattr_failure, frame);
+ }
+ if (op_errno == ENOTSUP) {
+ gf_msg_debug(THIS->name, 0, "%s", strerror(op_errno));
+ } else {
+ gf_smsg(THIS->name, GF_LOG_INFO, op_errno, PS_MSG_SETXATTR_INFO,
+ "client=%s", STACK_CLIENT_NAME(frame->root),
+ "error-xlator=%s", STACK_ERR_XL_NAME(frame->root), NULL);
+ }
+ 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_gfx_common_rsp);
+
+ GF_FREE(rsp.xdata.pairs.pairs_val);
+
+ return 0;
+}
+
+int
+server4_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)
+{
+ gfx_rename_rsp rsp = {
+ 0,
+ };
+ server_state_t *state = NULL;
+ rpcsvc_request_t *req = NULL;
+ char oldpar_str[50] = {
+ 0,
+ };
+ char newpar_str[50] = {
+ 0,
+ };
+
+ dict_to_xdr(xdata, &rsp.xdata);
+
+ state = CALL_STATE(frame);
+
+ if (op_ret == -1) {
+ uuid_utoa_r(state->resolve.pargfid, oldpar_str);
+ uuid_utoa_r(state->resolve2.pargfid, newpar_str);
+ gf_smsg(this->name, GF_LOG_INFO, op_errno, PS_MSG_RENAME_INFO,
+ "frame=%" PRId64, frame->root->unique, "loc.path=%s",
+ state->loc.path, "oldpar_str=%s", oldpar_str, "resolve-name=%s",
+ state->resolve.bname, "loc2.path=%s", state->loc2.path,
+ "newpar_str=%s", newpar_str, "resolve2=%s",
+ state->resolve2.bname, "client=%s",
+ STACK_CLIENT_NAME(frame->root), "error-xlator=%s",
+ STACK_ERR_XL_NAME(frame->root), NULL);
+ goto out;
+ }
+
+ server4_post_rename(frame, state, &rsp, stbuf, preoldparent, postoldparent,
+ prenewparent, 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_gfx_rename_rsp);
+
+ GF_FREE(rsp.xdata.pairs.pairs_val);
+
+ return 0;
+}
+
+int
+server4_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)
+{
+ gfx_common_2iatt_rsp rsp = {
+ 0,
+ };
+ server_state_t *state = NULL;
+ rpcsvc_request_t *req = NULL;
+
+ dict_to_xdr(xdata, &rsp.xdata);
+
+ state = CALL_STATE(frame);
+
+ if (op_ret) {
+ gf_smsg(this->name, fop_log_level(GF_FOP_UNLINK, op_errno), op_errno,
+ PS_MSG_LINK_INFO, "frame=%" PRId64, frame->root->unique,
+ "UNLINK_path=%s", state->loc.path, "uuid_utoa=%s",
+ uuid_utoa(state->resolve.pargfid), "bname=%s",
+ state->resolve.bname, "client=%s",
+ STACK_CLIENT_NAME(frame->root), "error-xlator: %s",
+ STACK_ERR_XL_NAME(frame->root), NULL);
+ goto out;
+ }
+
+ /* TODO: log gfid of the inodes */
+ gf_msg_trace(frame->root->client->bound_xl->name, 0,
+ "%" PRId64
+ ": "
+ "UNLINK_CBK %s",
+ frame->root->unique, state->loc.name);
+
+ server4_post_entry_remove(state, &rsp, preparent, 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_gfx_common_2iatt_rsp);
+
+ GF_FREE(rsp.xdata.pairs.pairs_val);
+
+ return 0;
+}
+
+int
+server4_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)
+{
+ gfx_common_3iatt_rsp rsp = {
+ 0,
+ };
+ server_state_t *state = NULL;
+ rpcsvc_request_t *req = NULL;
+
+ dict_to_xdr(xdata, &rsp.xdata);
+
+ state = CALL_STATE(frame);
+
+ if (op_ret < 0) {
+ gf_smsg(this->name, GF_LOG_INFO, op_errno, PS_MSG_LINK_INFO,
+ "frame=%" PRId64, frame->root->unique, "SYMLINK_path= %s",
+ (state->loc.path) ? state->loc.path : "", "uuid_utoa=%s",
+ uuid_utoa(state->resolve.pargfid), "bname=%s",
+ state->resolve.bname, "client=%s",
+ STACK_CLIENT_NAME(frame->root), "error-xlator=%s",
+ STACK_ERR_XL_NAME(frame->root), NULL);
+ goto out;
+ }
+
+ server4_post_common_3iatt(state, &rsp, inode, stbuf, preparent, 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_gfx_common_3iatt_rsp);
+
+ GF_FREE(rsp.xdata.pairs.pairs_val);
+
+ return 0;
+}
+
+int
+server4_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)
+{
+ gfx_common_3iatt_rsp rsp = {
+ 0,
+ };
+ server_state_t *state = NULL;
+ rpcsvc_request_t *req = NULL;
+ char gfid_str[50] = {
+ 0,
+ };
+ char newpar_str[50] = {
+ 0,
+ };
+
+ dict_to_xdr(xdata, &rsp.xdata);
+
+ state = CALL_STATE(frame);
+
+ if (op_ret) {
+ uuid_utoa_r(state->resolve.gfid, gfid_str);
+ uuid_utoa_r(state->resolve2.pargfid, newpar_str);
+
+ gf_smsg(this->name, GF_LOG_INFO, op_errno, PS_MSG_LINK_INFO,
+ "frame=%" PRId64, frame->root->unique, "LINK_path=%s",
+ state->loc.path, "gfid_str=%s", gfid_str, "newpar_str=%s",
+ newpar_str, "resolve2.bname=%s", state->resolve2.bname,
+ "client=%s", STACK_CLIENT_NAME(frame->root), "error-xlator=%s",
+ STACK_ERR_XL_NAME(frame->root), NULL);
+ goto out;
+ }
+
+ server4_post_link(state, &rsp, inode, stbuf, preparent, 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_gfx_common_3iatt_rsp);
+
+ GF_FREE(rsp.xdata.pairs.pairs_val);
+
+ return 0;
+}
+
+int
+server4_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)
+{
+ gfx_common_2iatt_rsp rsp = {
+ 0,
+ };
+ server_state_t *state = NULL;
+ rpcsvc_request_t *req = NULL;
+
+ dict_to_xdr(xdata, &rsp.xdata);
+
+ if (op_ret) {
+ state = CALL_STATE(frame);
+ gf_smsg(this->name, GF_LOG_INFO, op_errno, PS_MSG_TRUNCATE_INFO,
+ "frame=%" PRId64, frame->root->unique, "TRUNCATE_path=%s",
+ state->loc.path, "uuid_utoa=%s", uuid_utoa(state->resolve.gfid),
+ "client=%s", STACK_CLIENT_NAME(frame->root), "error-xlator=%s",
+ STACK_ERR_XL_NAME(frame->root), NULL);
+ goto out;
+ }
+
+ server4_post_common_2iatt(&rsp, prebuf, 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_gfx_common_2iatt_rsp);
+
+ GF_FREE(rsp.xdata.pairs.pairs_val);
+
+ return 0;
+}
+
+int
+server4_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)
+{
+ gfx_common_iatt_rsp rsp = {
+ 0,
+ };
+ server_state_t *state = NULL;
+ rpcsvc_request_t *req = NULL;
+
+ dict_to_xdr(xdata, &rsp.xdata);
+
+ state = CALL_STATE(frame);
+ if (op_ret) {
+ gf_smsg(this->name, fop_log_level(GF_FOP_FSTAT, op_errno), op_errno,
+ PS_MSG_STAT_INFO, "frame=%" PRId64, frame->root->unique,
+ "FSTAT_fd_no=%" PRId64, state->resolve.fd_no, "uuid_utoa=%s",
+ uuid_utoa(state->resolve.gfid), "client=%s",
+ STACK_CLIENT_NAME(frame->root), "error-xlator=%s",
+ STACK_ERR_XL_NAME(frame->root), NULL);
+ goto out;
+ }
+
+ server4_post_common_iatt(state, &rsp, 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_gfx_common_iatt_rsp);
+
+ GF_FREE(rsp.xdata.pairs.pairs_val);
+
+ return 0;
+}
+
+int
+server4_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)
+{
+ gfx_common_2iatt_rsp rsp = {0};
+ server_state_t *state = NULL;
+ rpcsvc_request_t *req = NULL;
+
+ dict_to_xdr(xdata, &rsp.xdata);
+
+ if (op_ret) {
+ state = CALL_STATE(frame);
+ gf_smsg(this->name, fop_log_level(GF_FOP_FTRUNCATE, op_errno), op_errno,
+ PS_MSG_TRUNCATE_INFO, "frame=%" PRId64, frame->root->unique,
+ "FTRUNCATE_fd_no=%" PRId64, state->resolve.fd_no,
+ "uuid_utoa=%s", uuid_utoa(state->resolve.gfid), "client=%s",
+ STACK_CLIENT_NAME(frame->root), "error-xlator=%s",
+ STACK_ERR_XL_NAME(frame->root), NULL);
+ goto out;
+ }
+
+ server4_post_common_2iatt(&rsp, prebuf, 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_gfx_common_2iatt_rsp);
+
+ GF_FREE(rsp.xdata.pairs.pairs_val);
+
+ return 0;
+}
+
+int
+server4_flush_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata)
+{
+ gfx_common_rsp rsp = {
+ 0,
+ };
+ server_state_t *state = NULL;
+ rpcsvc_request_t *req = NULL;
+
+ dict_to_xdr(xdata, &rsp.xdata);
+
+ if (op_ret < 0) {
+ state = CALL_STATE(frame);
+ gf_smsg(this->name, fop_log_level(GF_FOP_FLUSH, op_errno), op_errno,
+ PS_MSG_FLUSH_INFO, "frame=%" PRId64, frame->root->unique,
+ "FLUSH_fd_no=%" PRId64, state->resolve.fd_no, "uuid_utoa=%s",
+ uuid_utoa(state->resolve.gfid), "client=%s",
+ STACK_CLIENT_NAME(frame->root), "error-xlator: %s",
+ STACK_ERR_XL_NAME(frame->root), NULL);
+ 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_gfx_common_rsp);
+
+ GF_FREE(rsp.xdata.pairs.pairs_val);
+
+ return 0;
+}
+
+int
+server4_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)
+{
+ gfx_common_2iatt_rsp rsp = {
+ 0,
+ };
+ server_state_t *state = NULL;
+ rpcsvc_request_t *req = NULL;
+
+ dict_to_xdr(xdata, &rsp.xdata);
+
+ if (op_ret < 0) {
+ state = CALL_STATE(frame);
+ gf_smsg(this->name, fop_log_level(GF_FOP_FSYNC, op_errno), op_errno,
+ PS_MSG_SYNC_INFO, "frame=%" PRId64, frame->root->unique,
+ "FSYNC_fd_no=%" PRId64, state->resolve.fd_no, "uuid_utoa=%s",
+ uuid_utoa(state->resolve.gfid), "client=%s",
+ STACK_CLIENT_NAME(frame->root), "error-xlator: %s",
+ STACK_ERR_XL_NAME(frame->root), NULL);
+ goto out;
+ }
+
+ server4_post_common_2iatt(&rsp, prebuf, 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_gfx_common_2iatt_rsp);
+
+ GF_FREE(rsp.xdata.pairs.pairs_val);
+
+ return 0;
+}
+
+int
+server4_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)
+{
+ gfx_common_2iatt_rsp rsp = {
+ 0,
+ };
+ server_state_t *state = NULL;
+ rpcsvc_request_t *req = NULL;
+
+ dict_to_xdr(xdata, &rsp.xdata);
+
+ if (op_ret < 0) {
+ state = CALL_STATE(frame);
+ gf_smsg(this->name, fop_log_level(GF_FOP_WRITE, op_errno), op_errno,
+ PS_MSG_WRITE_INFO, "frame=%" PRId64, frame->root->unique,
+ "WRITEV_fd_no=%" PRId64, state->resolve.fd_no, "uuid_utoa=%s",
+ uuid_utoa(state->resolve.gfid), "client=%s",
+ STACK_CLIENT_NAME(frame->root), "error-xlator=%s",
+ STACK_ERR_XL_NAME(frame->root), NULL);
+ goto out;
+ }
+
+ server4_post_common_2iatt(&rsp, prebuf, 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_gfx_common_2iatt_rsp);
+
+ GF_FREE(rsp.xdata.pairs.pairs_val);
+
+ return 0;
+}
+
+int
+server4_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)
+{
+ gfx_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
+ dict_to_xdr(xdata, &rsp.xdata);
+
+ if (op_ret < 0) {
+ state = CALL_STATE(frame);
+ gf_smsg(this->name, fop_log_level(GF_FOP_READ, op_errno), op_errno,
+ PS_MSG_READ_INFO, "frame=%" PRId64, frame->root->unique,
+ "READV_fd_no=%" PRId64, state->resolve.fd_no, "uuid_utoa=%s",
+ uuid_utoa(state->resolve.gfid), "client=%s",
+ STACK_CLIENT_NAME(frame->root), "error-xlator=%s",
+ STACK_ERR_XL_NAME(frame->root), NULL);
+ goto out;
+ }
+
+ server4_post_readv(&rsp, stbuf, 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_gfx_read_rsp);
+
+ GF_FREE(rsp.xdata.pairs.pairs_val);
+
+ return 0;
+}
+
+int
+server4_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)
+{
+ gfx_rchecksum_rsp rsp = {
+ 0,
+ };
+ rpcsvc_request_t *req = NULL;
+ server_state_t *state = NULL;
+
+ dict_to_xdr(xdata, &rsp.xdata);
+
+ if (op_ret < 0) {
+ state = CALL_STATE(frame);
+ gf_smsg(this->name, fop_log_level(GF_FOP_RCHECKSUM, op_errno), op_errno,
+ PS_MSG_CHKSUM_INFO, "frame=%" PRId64, frame->root->unique,
+ "RCHECKSUM_fd_no=%" PRId64, state->resolve.fd_no,
+ "uuid_utoa=%s", uuid_utoa(state->resolve.gfid), "client=%s",
+ STACK_CLIENT_NAME(frame->root), "error-xlator=%s",
+ STACK_ERR_XL_NAME(frame->root), NULL);
+ goto out;
+ }
+
+ server4_post_rchecksum(&rsp, weak_checksum, strong_checksum);
+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_gfx_rchecksum_rsp);
+
+ GF_FREE(rsp.xdata.pairs.pairs_val);
+
+ return 0;
+}
+
+int
+server4_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;
+ rpcsvc_request_t *req = NULL;
+ gfx_open_rsp rsp = {
+ 0,
+ };
+
+ dict_to_xdr(xdata, &rsp.xdata);
+
+ if (op_ret < 0) {
+ state = CALL_STATE(frame);
+ gf_smsg(this->name, fop_log_level(GF_FOP_OPEN, op_errno), op_errno,
+ PS_MSG_OPEN_INFO, "frame=%" PRId64, frame->root->unique,
+ "OPEN_path=%s", state->loc.path, "uuid_utoa=%s",
+ uuid_utoa(state->resolve.gfid), "client=%s",
+ STACK_CLIENT_NAME(frame->root), "error-xlator=%s",
+ STACK_ERR_XL_NAME(frame->root), NULL);
+ goto out;
+ }
+
+ op_ret = server4_post_open(frame, this, &rsp, fd);
+ if (op_ret)
+ 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_gfx_open_rsp);
+ GF_FREE(rsp.xdata.pairs.pairs_val);
+
+ return 0;
+}
+
+int
+server4_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;
+ rpcsvc_request_t *req = NULL;
+ uint64_t fd_no = 0;
+ gfx_create_rsp rsp = {
+ 0,
+ };
+
+ dict_to_xdr(xdata, &rsp.xdata);
+
+ state = CALL_STATE(frame);
+
+ if (op_ret < 0) {
+ gf_smsg(
+ this->name, GF_LOG_INFO, op_errno, PS_MSG_CREATE_INFO,
+ "frame=%" PRId64, frame->root->unique, "path=%s", state->loc.path,
+ "uuid_utoa=%s", uuid_utoa(state->resolve.pargfid), "bname=%s",
+ state->resolve.bname, "client=%s", STACK_CLIENT_NAME(frame->root),
+ "error-xlator=%s", STACK_ERR_XL_NAME(frame->root), NULL);
+ goto out;
+ }
+
+ /* TODO: log gfid too */
+ gf_msg_trace(frame->root->client->bound_xl->name, 0,
+ "%" PRId64
+ ": "
+ "CREATE %s (%s)",
+ frame->root->unique, state->loc.name,
+ uuid_utoa(stbuf->ia_gfid));
+
+ op_ret = server4_post_create(frame, &rsp, state, this, fd, inode, stbuf,
+ preparent, postparent);
+ if (op_ret) {
+ op_errno = -op_ret;
+ op_ret = -1;
+ goto out;
+ }
+
+out:
+ if (op_ret)
+ 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_gfx_create_rsp);
+
+ GF_FREE(rsp.xdata.pairs.pairs_val);
+
+ return 0;
+}
+
+int
+server4_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)
+{
+ gfx_readlink_rsp rsp = {
+ 0,
+ };
+ server_state_t *state = NULL;
+ rpcsvc_request_t *req = NULL;
+
+ dict_to_xdr(xdata, &rsp.xdata);
+
+ if (op_ret < 0) {
+ state = CALL_STATE(frame);
+ gf_smsg(this->name, GF_LOG_INFO, op_errno, PS_MSG_LINK_INFO,
+ "frame=%" PRId64, frame->root->unique, "READLINK_path=%s",
+ state->loc.path, "uuid_utoa=%s", uuid_utoa(state->resolve.gfid),
+ "client=%s", STACK_CLIENT_NAME(frame->root), "error-xlator=%s",
+ STACK_ERR_XL_NAME(frame->root), NULL);
+ goto out;
+ }
+
+ server4_post_readlink(&rsp, stbuf, 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_gfx_readlink_rsp);
+
+ GF_FREE(rsp.xdata.pairs.pairs_val);
+
+ return 0;
+}
+
+int
+server4_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)
+{
+ gfx_common_iatt_rsp rsp = {
+ 0,
+ };
+ server_state_t *state = NULL;
+ rpcsvc_request_t *req = NULL;
+
+ dict_to_xdr(xdata, &rsp.xdata);
+
+ state = CALL_STATE(frame);
+ if (op_ret) {
+ gf_smsg(this->name, fop_log_level(GF_FOP_STAT, op_errno), op_errno,
+ PS_MSG_STAT_INFO, "frame=%" PRId64, frame->root->unique,
+ "path=%s", (state->loc.path) ? state->loc.path : "",
+ "uuid_utoa=%s", uuid_utoa(state->resolve.gfid), "client=%s",
+ STACK_CLIENT_NAME(frame->root), "error-xlator=%s",
+ STACK_ERR_XL_NAME(frame->root), NULL);
+ goto out;
+ }
+
+ server4_post_common_iatt(state, &rsp, 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_gfx_common_iatt_rsp);
+
+ GF_FREE(rsp.xdata.pairs.pairs_val);
+
+ return 0;
+}
+
+int
+server4_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)
+{
+ gfx_common_2iatt_rsp rsp = {
+ 0,
+ };
+ server_state_t *state = NULL;
+ rpcsvc_request_t *req = NULL;
+
+ dict_to_xdr(xdata, &rsp.xdata);
+
+ if (op_ret) {
+ state = CALL_STATE(frame);
+ gf_smsg(this->name, GF_LOG_INFO, op_errno, PS_MSG_SETATTR_INFO,
+ "frame=%" PRId64, frame->root->unique, "path=%s",
+ (state->loc.path) ? state->loc.path : "", "uuid_utoa=%s",
+ uuid_utoa(state->resolve.gfid), "client=%s",
+ STACK_CLIENT_NAME(frame->root), "error-xlator=%s",
+ STACK_ERR_XL_NAME(frame->root), NULL);
+ goto out;
+ }
+
+ server4_post_common_2iatt(&rsp, statpre, 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_gfx_common_2iatt_rsp);
+
+ GF_FREE(rsp.xdata.pairs.pairs_val);
+
+ return 0;
+}
+
+int
+server4_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)
+{
+ gfx_common_2iatt_rsp rsp = {
+ 0,
+ };
+ server_state_t *state = NULL;
+ rpcsvc_request_t *req = NULL;
+
+ dict_to_xdr(xdata, &rsp.xdata);
+
+ if (op_ret) {
+ state = CALL_STATE(frame);
+ gf_smsg(this->name, fop_log_level(GF_FOP_FSETATTR, op_errno), op_errno,
+ PS_MSG_SETATTR_INFO, "frame=%" PRId64,
+ "FSETATTR_fd_no=%" PRId64, state->resolve.fd_no, "uuid_utoa=%s",
+ uuid_utoa(state->resolve.gfid), "client=%s",
+ STACK_CLIENT_NAME(frame->root), "error-xlator=%s",
+ STACK_ERR_XL_NAME(frame->root), NULL);
+ goto out;
+ }
+
+ server4_post_common_2iatt(&rsp, statpre, 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_gfx_common_2iatt_rsp);
+
+ GF_FREE(rsp.xdata.pairs.pairs_val);
+
+ return 0;
+}
+
+int
+server4_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)
+{
+ gfx_common_dict_rsp rsp = {
+ 0,
+ };
+ server_state_t *state = NULL;
+ rpcsvc_request_t *req = NULL;
+
+ dict_to_xdr(xdata, &rsp.xdata);
+
+ if (op_ret < 0) {
+ state = CALL_STATE(frame);
+ gf_smsg(this->name, fop_log_level(GF_FOP_XATTROP, op_errno), op_errno,
+ PS_MSG_XATTROP_INFO, "frame=%" PRId64, frame->root->unique,
+ "path=%s", state->loc.path, "uuid_utoa=%s",
+ uuid_utoa(state->resolve.gfid), "client=%s",
+ STACK_CLIENT_NAME(frame->root), "error-xlator=%s",
+ STACK_ERR_XL_NAME(frame->root), NULL);
+ goto out;
+ }
+
+ dict_to_xdr(dict, &rsp.dict);
+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_gfx_common_dict_rsp);
+
+ GF_FREE(rsp.dict.pairs.pairs_val);
+
+ GF_FREE(rsp.xdata.pairs.pairs_val);
+
+ return 0;
+}
+
+int
+server4_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)
+{
+ gfx_common_dict_rsp rsp = {
+ 0,
+ };
+ server_state_t *state = NULL;
+ rpcsvc_request_t *req = NULL;
+
+ dict_to_xdr(xdata, &rsp.xdata);
+
+ if (op_ret < 0) {
+ state = CALL_STATE(frame);
+ gf_smsg(this->name, fop_log_level(GF_FOP_FXATTROP, op_errno), op_errno,
+ PS_MSG_XATTROP_INFO, "frame=%" PRId64, frame->root->unique,
+ "FXATTROP_fd_no=%" PRId64, state->resolve.fd_no, "uuid_utoa=%s",
+ uuid_utoa(state->resolve.gfid), "client=%s",
+ STACK_CLIENT_NAME(frame->root), "error-xlator=%s",
+ STACK_ERR_XL_NAME(frame->root), NULL);
+ goto out;
+ }
+
+ dict_to_xdr(dict, &rsp.dict);
+
+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_gfx_common_dict_rsp);
+
+ GF_FREE(rsp.dict.pairs.pairs_val);
+
+ GF_FREE(rsp.xdata.pairs.pairs_val);
+
+ return 0;
+}
+
+int
+server4_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)
+{
+ gfx_readdirp_rsp rsp = {
+ 0,
+ };
+ server_state_t *state = NULL;
+ rpcsvc_request_t *req = NULL;
+ int ret = 0;
+
+ state = CALL_STATE(frame);
+
+ dict_to_xdr(xdata, &rsp.xdata);
+
+ if (op_ret < 0) {
+ state = CALL_STATE(frame);
+ gf_smsg(this->name, fop_log_level(GF_FOP_READDIRP, op_errno), op_errno,
+ PS_MSG_DIR_INFO, "frame=%" PRId64, frame->root->unique,
+ "READDIRP_fd_no=%" PRId64, state->resolve.fd_no, "uuid_utoa=%s",
+ uuid_utoa(state->resolve.gfid), "client=%s",
+ STACK_CLIENT_NAME(frame->root), "error-xlator=%s",
+ STACK_ERR_XL_NAME(frame->root), NULL);
+ goto out;
+ }
+
+ /* (op_ret == 0) is valid, and means EOF */
+ if (op_ret) {
+ ret = server4_post_readdirp(&rsp, entries);
+ if (ret == -1) {
+ op_ret = -1;
+ op_errno = ENOMEM;
+ goto out;
+ }
+ }
+
+ 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_gfx_readdirp_rsp);
+
+ GF_FREE(rsp.xdata.pairs.pairs_val);
+
+ readdirp_rsp_cleanup_v2(&rsp);
+
+ return 0;
+}
+
+int
+server4_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)
+{
+ gfx_common_2iatt_rsp rsp = {
+ 0,
+ };
+ server_state_t *state = NULL;
+ rpcsvc_request_t *req = NULL;
+
+ dict_to_xdr(xdata, &rsp.xdata);
+
+ if (op_ret) {
+ state = CALL_STATE(frame);
+ gf_smsg(this->name, fop_log_level(GF_FOP_FALLOCATE, op_errno), op_errno,
+ PS_MSG_ALLOC_INFO, "frame=%" PRId64, frame->root->unique,
+ "FALLOCATE_fd_no=%" PRId64, state->resolve.fd_no,
+ "uuid_utoa=%s", uuid_utoa(state->resolve.gfid), "client=%s",
+ STACK_CLIENT_NAME(frame->root), "error-xlator=%s",
+ STACK_ERR_XL_NAME(frame->root), NULL);
+ goto out;
+ }
+
+ server4_post_common_2iatt(&rsp, statpre, 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_gfx_common_2iatt_rsp);
+
+ GF_FREE(rsp.xdata.pairs.pairs_val);
+
+ return 0;
+}
+
+int
+server4_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)
+{
+ gfx_common_2iatt_rsp rsp = {
+ 0,
+ };
+ server_state_t *state = NULL;
+ rpcsvc_request_t *req = NULL;
+
+ dict_to_xdr(xdata, &rsp.xdata);
+
+ if (op_ret) {
+ state = CALL_STATE(frame);
+ gf_smsg(this->name, fop_log_level(GF_FOP_DISCARD, op_errno), op_errno,
+ PS_MSG_DISCARD_INFO, "frame=%" PRId64, frame->root->unique,
+ "fd_no=%" PRId64, state->resolve.fd_no, "uuid_utoa=%s",
+ uuid_utoa(state->resolve.gfid), "client=%s",
+ STACK_CLIENT_NAME(frame->root), "error-xlator: %s",
+ STACK_ERR_XL_NAME(frame->root), NULL);
+ goto out;
+ }
+
+ server4_post_common_2iatt(&rsp, statpre, 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_gfx_common_2iatt_rsp);
+
+ GF_FREE(rsp.xdata.pairs.pairs_val);
+
+ return 0;
+}
+
+int
+server4_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)
+{
+ gfx_common_2iatt_rsp rsp = {
+ 0,
+ };
+ server_state_t *state = NULL;
+ rpcsvc_request_t *req = NULL;
+
+ req = frame->local;
+ state = CALL_STATE(frame);
+
+ dict_to_xdr(xdata, &rsp.xdata);
+
+ if (op_ret) {
+ gf_smsg(this->name, fop_log_level(GF_FOP_ZEROFILL, op_errno), op_errno,
+ PS_MSG_ZEROFILL_INFO, "frame=%" PRId64, frame->root->unique,
+ "fd_no=%" PRId64, state->resolve.fd_no, "uuid_utoa=%s",
+ uuid_utoa(state->resolve.gfid), "client=%s",
+ STACK_CLIENT_NAME(frame->root), "error-xlator=%s",
+ STACK_ERR_XL_NAME(frame->root), NULL);
+ goto out;
+ }
+
+ server4_post_common_2iatt(&rsp, statpre, 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_gfx_common_2iatt_rsp);
+
+ GF_FREE(rsp.xdata.pairs.pairs_val);
+
+ return 0;
+}
+
+int
+server4_ipc_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata)
+{
+ gfx_common_rsp rsp = {
+ 0,
+ };
+ server_state_t *state = NULL;
+ rpcsvc_request_t *req = NULL;
+
+ req = frame->local;
+ state = CALL_STATE(frame);
+
+ dict_to_xdr(xdata, &rsp.xdata);
+
+ if (op_ret) {
+ gf_smsg(this->name, GF_LOG_INFO, op_errno, PS_MSG_SERVER_IPC_INFO,
+ "frame=%" PRId64, frame->root->unique, "IPC=%" PRId64,
+ state->resolve.fd_no, "uuid_utoa=%s",
+ uuid_utoa(state->resolve.gfid), "client=%s",
+ STACK_CLIENT_NAME(frame->root), "error-xlator=%s",
+ STACK_ERR_XL_NAME(frame->root), NULL);
+ goto out;
+ }
+
+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_gfx_common_rsp);
+
+ GF_FREE(rsp.xdata.pairs.pairs_val);
+
+ return 0;
+}
+
+int
+server4_seek_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, off_t offset, dict_t *xdata)
+{
+ struct gfx_seek_rsp rsp = {
+ 0,
+ };
+ server_state_t *state = NULL;
+ rpcsvc_request_t *req = NULL;
+
+ req = frame->local;
+ state = CALL_STATE(frame);
+
+ dict_to_xdr(xdata, &rsp.xdata);
+
+ if (op_ret) {
+ gf_smsg(this->name, fop_log_level(GF_FOP_SEEK, op_errno), op_errno,
+ PS_MSG_SEEK_INFO, "frame=%" PRId64, frame->root->unique,
+ "fd_no=%" PRId64, state->resolve.fd_no, "uuid_utoa=%s",
+ uuid_utoa(state->resolve.gfid), "client=%s",
+ STACK_CLIENT_NAME(frame->root), "error-xlator=%s",
+ STACK_ERR_XL_NAME(frame->root), NULL);
+ goto out;
+ }
+
+ server4_post_seek(&rsp, offset);
+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_gfx_seek_rsp);
+
+ GF_FREE(rsp.xdata.pairs.pairs_val);
+
+ return 0;
+}
+
+static int
+server4_setactivelk_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata)
+{
+ gfx_common_rsp rsp = {
+ 0,
+ };
+ server_state_t *state = NULL;
+ rpcsvc_request_t *req = NULL;
+
+ state = CALL_STATE(frame);
+
+ dict_to_xdr(xdata, &rsp.xdata);
+
+ if (op_ret < 0) {
+ state = CALL_STATE(frame);
+ gf_smsg(this->name, GF_LOG_INFO, op_errno, PS_MSG_SETACTIVELK_INFO,
+ "frame=%" PRId64, frame->root->unique, "path==%s",
+ state->loc.path, "uuid_utoa=%s", uuid_utoa(state->resolve.gfid),
+ "client=%s", STACK_CLIENT_NAME(frame->root), "error-xlator=%s",
+ STACK_ERR_XL_NAME(frame->root), NULL);
+ 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_gfx_common_rsp);
+
+ GF_FREE(rsp.xdata.pairs.pairs_val);
+
+ return 0;
+}
+
+int
+server4_namelink_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)
+{
+ gfx_common_2iatt_rsp rsp = {
+ 0,
+ };
+ rpcsvc_request_t *req = NULL;
+
+ dict_to_xdr(xdata, &rsp.xdata);
+ if (op_ret < 0)
+ goto out;
+
+ gfx_stat_from_iattx(&rsp.prestat, prebuf);
+ gfx_stat_from_iattx(&rsp.poststat, postbuf);
+
+ /**
+ * no point in linking inode here -- there's no stbuf anyway and a
+ * lookup() for this name entry would be a negative lookup.
+ */
+
+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_gfx_common_2iatt_rsp);
+
+ GF_FREE(rsp.xdata.pairs.pairs_val);
+
+ return 0;
+}
+
+int
+server4_icreate_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)
+{
+ server_state_t *state = NULL;
+ inode_t *link_inode = NULL;
+ rpcsvc_request_t *req = NULL;
+ gfx_common_iatt_rsp rsp = {
+ 0,
+ };
+
+ dict_to_xdr(xdata, &rsp.xdata);
+ state = CALL_STATE(frame);
+
+ if (op_ret < 0) {
+ gf_smsg(this->name, GF_LOG_INFO, op_errno, PS_MSG_CREATE_INFO,
+ "frame=%" PRId64, uuid_utoa(state->resolve.gfid),
+ "ICREATE_gfid=%s", uuid_utoa(state->resolve.gfid),
+ "op_errno=%s", strerror(op_errno), NULL);
+ goto out;
+ }
+
+ gf_msg_trace(frame->root->client->bound_xl->name, 0,
+ "%" PRId64
+ ": "
+ "ICREATE [%s]",
+ frame->root->unique, 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;
+ }
+
+ inode_lookup(link_inode);
+ inode_unref(link_inode);
+
+ gfx_stat_from_iattx(&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_gfx_common_iatt_rsp);
+
+ GF_FREE(rsp.xdata.pairs.pairs_val);
+
+ return 0;
+}
+
+int
+server4_put_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)
+{
+ server_state_t *state = NULL;
+ rpcsvc_request_t *req = NULL;
+ gfx_common_3iatt_rsp rsp = {
+ 0,
+ };
+
+ dict_to_xdr(xdata, &rsp.xdata);
+
+ state = CALL_STATE(frame);
+
+ if (op_ret < 0) {
+ gf_smsg(
+ this->name, GF_LOG_INFO, op_errno, PS_MSG_PUT_INFO,
+ "frame=%" PRId64, frame->root->unique, "path=%s", state->loc.path,
+ "uuid_utoa=%s", uuid_utoa(state->resolve.pargfid), "bname=%s",
+ state->resolve.bname, "client=%s", STACK_CLIENT_NAME(frame->root),
+ "error-xlator=%s", STACK_ERR_XL_NAME(frame->root), NULL);
+ goto out;
+ }
+
+ gf_msg_trace(frame->root->client->bound_xl->name, 0,
+ "%" PRId64
+ ": "
+ "PUT %s (%s)",
+ frame->root->unique, state->loc.name,
+ uuid_utoa(stbuf->ia_gfid));
+
+ server4_post_common_3iatt(state, &rsp, inode, stbuf, preparent, 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_gfx_common_3iatt_rsp);
+
+ GF_FREE(rsp.xdata.pairs.pairs_val);
+
+ return 0;
+}
+
+int
+server4_copy_file_range_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno,
+ struct iatt *stbuf, struct iatt *prebuf_dst,
+ struct iatt *postbuf_dst, dict_t *xdata)
+{
+ gfx_common_3iatt_rsp rsp = {
+ 0,
+ };
+ server_state_t *state = NULL;
+ rpcsvc_request_t *req = NULL;
+ char in_gfid[GF_UUID_BUF_SIZE] = {0};
+ char out_gfid[GF_UUID_BUF_SIZE] = {0};
+
+ dict_to_xdr(xdata, &rsp.xdata);
+
+ if (op_ret < 0) {
+ state = CALL_STATE(frame);
+
+ uuid_utoa_r(state->resolve.gfid, in_gfid);
+ uuid_utoa_r(state->resolve2.gfid, out_gfid);
+
+ gf_smsg(this->name, fop_log_level(GF_FOP_COPY_FILE_RANGE, op_errno),
+ op_errno, PS_MSG_WRITE_INFO, "frame=%" PRId64,
+ frame->root->unique, "COPY_FILE_RANGE_fd_no=%" PRId64,
+ state->resolve.fd_no, "in_gfid=%s", in_gfid,
+ "resolve2_fd_no=%" PRId64, state->resolve2.fd_no, "out_gfid=%s",
+ out_gfid, "client=%s", STACK_CLIENT_NAME(frame->root),
+ "error-xlator=%s", STACK_ERR_XL_NAME(frame->root), NULL);
+ goto out;
+ }
+
+ /*
+ * server4_post_common_3iatt (ex: used by server4_put_cbk and some
+ * other cbks) also performs inode linking along with copying of 3
+ * iatt structures to the response. But, for copy_file_range, linking
+ * of inode is not needed. Therefore a new function is used to
+ * construct the response using 3 iatt structures.
+ * @stbuf: iatt or stat of the source file (or fd)
+ * @prebuf_dst: iatt or stat of destination file (or fd) before the fop
+ * @postbuf_dst: iatt or stat of destination file (or fd) after the fop
+ */
+ server4_post_common_3iatt_noinode(&rsp, stbuf, prebuf_dst, postbuf_dst);
+
+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_gfx_common_3iatt_rsp);
+
+ GF_FREE(rsp.xdata.pairs.pairs_val);
+
+ return 0;
+}
+
+/* Resume function section */
+
+int
+server4_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, server4_rchecksum_cbk, bound_xl,
+ bound_xl->fops->rchecksum, state->fd, state->offset, state->size,
+ state->xdata);
+
+ return 0;
+err:
+ server4_rchecksum_cbk(frame, NULL, frame->this, op_ret, op_errno, 0, NULL,
+ NULL);
+
+ return 0;
+}
+
+int
+server4_lease_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, server4_lease_cbk, bound_xl, bound_xl->fops->lease,
+ &state->loc, &state->lease, state->xdata);
+
+ return 0;
+
+err:
+ server4_lease_cbk(frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, NULL);
+ return 0;
+}
+
+int
+server4_put_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, server4_put_cbk, bound_xl, bound_xl->fops->put,
+ &(state->loc), state->mode, state->umask, state->flags,
+ state->payload_vector, state->payload_count, state->offset,
+ state->iobref, state->dict, state->xdata);
+
+ return 0;
+err:
+ server4_put_cbk(frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, NULL, NULL, NULL, NULL);
+ return 0;
+}
+
+int
+server4_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, server4_lk_cbk, bound_xl, bound_xl->fops->lk, state->fd,
+ state->cmd, &state->flock, state->xdata);
+
+ return 0;
+
+err:
+ server4_lk_cbk(frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, NULL);
+ return 0;
+}
+
+int
+server4_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, server4_rename_cbk, bound_xl, bound_xl->fops->rename,
+ &state->loc, &state->loc2, state->xdata);
+ return 0;
+err:
+ server4_rename_cbk(frame, NULL, frame->this, op_ret, op_errno, NULL, NULL,
+ NULL, NULL, NULL, NULL);
+ return 0;
+}
+
+int
+server4_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, server4_link_cbk, bound_xl, bound_xl->fops->link,
+ &state->loc, &state->loc2, state->xdata);
+
+ return 0;
+err:
+ server4_link_cbk(frame, NULL, frame->this, op_ret, op_errno, NULL, NULL,
+ NULL, NULL, NULL);
+ return 0;
+}
+
+int
+server4_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, server4_symlink_cbk, bound_xl, bound_xl->fops->symlink,
+ state->name, &state->loc, state->umask, state->xdata);
+
+ return 0;
+err:
+ server4_symlink_cbk(frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, NULL, NULL, NULL, NULL);
+ return 0;
+}
+
+int
+server4_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, server4_access_cbk, bound_xl, bound_xl->fops->access,
+ &state->loc, state->mask, state->xdata);
+ return 0;
+err:
+ server4_access_cbk(frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL);
+ return 0;
+}
+
+int
+server4_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, server4_fentrylk_cbk, bound_xl, bound_xl->fops->fentrylk,
+ state->volume, state->fd, state->name, state->cmd, state->type,
+ state->xdata);
+
+ return 0;
+err:
+ server4_fentrylk_cbk(frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL);
+ return 0;
+}
+
+int
+server4_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, server4_entrylk_cbk, bound_xl, bound_xl->fops->entrylk,
+ state->volume, &state->loc, state->name, state->cmd, state->type,
+ state->xdata);
+ return 0;
+err:
+ server4_entrylk_cbk(frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL);
+ return 0;
+}
+
+int
+server4_finodelk_resume(call_frame_t *frame, xlator_t *bound_xl)
+{
+ GF_UNUSED int ret = -1;
+ server_state_t *state = NULL;
+
+ gf_msg_debug(bound_xl->name, 0, "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, server4_finodelk_cbk, bound_xl, bound_xl->fops->finodelk,
+ state->volume, state->fd, state->cmd, &state->flock,
+ state->xdata);
+
+ return 0;
+err:
+ server4_finodelk_cbk(frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL);
+
+ return 0;
+}
+
+int
+server4_inodelk_resume(call_frame_t *frame, xlator_t *bound_xl)
+{
+ GF_UNUSED int ret = -1;
+ server_state_t *state = NULL;
+
+ gf_msg_debug(bound_xl->name, 0, "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, server4_inodelk_cbk, bound_xl, bound_xl->fops->inodelk,
+ state->volume, &state->loc, state->cmd, &state->flock,
+ state->xdata);
+ return 0;
+err:
+ server4_inodelk_cbk(frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL);
+ return 0;
+}
+
+int
+server4_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, server4_rmdir_cbk, bound_xl, bound_xl->fops->rmdir,
+ &state->loc, state->flags, state->xdata);
+ return 0;
+err:
+ server4_rmdir_cbk(frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, NULL, NULL);
+ return 0;
+}
+
+int
+server4_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, server4_mkdir_cbk, bound_xl, bound_xl->fops->mkdir,
+ &(state->loc), state->mode, state->umask, state->xdata);
+
+ return 0;
+err:
+ server4_mkdir_cbk(frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, NULL, NULL, NULL, NULL);
+ return 0;
+}
+
+int
+server4_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, server4_mknod_cbk, bound_xl, bound_xl->fops->mknod,
+ &(state->loc), state->mode, state->dev, state->umask,
+ state->xdata);
+
+ return 0;
+err:
+ server4_mknod_cbk(frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, NULL, NULL, NULL, NULL);
+ return 0;
+}
+
+int
+server4_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, server4_fsyncdir_cbk, bound_xl, bound_xl->fops->fsyncdir,
+ state->fd, state->flags, state->xdata);
+ return 0;
+
+err:
+ server4_fsyncdir_cbk(frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL);
+ return 0;
+}
+
+int
+server4_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, server4_readdir_cbk, bound_xl, bound_xl->fops->readdir,
+ state->fd, state->size, state->offset, state->xdata);
+
+ return 0;
+err:
+ server4_readdir_cbk(frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, NULL);
+ return 0;
+}
+
+int
+server4_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, server4_readdirp_cbk, bound_xl, bound_xl->fops->readdirp,
+ state->fd, state->size, state->offset, state->xdata);
+
+ return 0;
+err:
+ server4_readdirp_cbk(frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, NULL);
+ return 0;
+}
+
+int
+server4_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_smsg("server", GF_LOG_ERROR, 0, PS_MSG_FD_CREATE_FAILED, NULL);
+ goto err;
+ }
+
+ STACK_WIND(frame, server4_opendir_cbk, bound_xl, bound_xl->fops->opendir,
+ &state->loc, state->fd, state->xdata);
+ return 0;
+err:
+ server4_opendir_cbk(frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, NULL);
+ return 0;
+}
+
+int
+server4_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, server4_statfs_cbk, bound_xl, bound_xl->fops->statfs,
+ &state->loc, state->xdata);
+ return 0;
+
+err:
+ server4_statfs_cbk(frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, NULL);
+ return 0;
+}
+
+int
+server4_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, server4_removexattr_cbk, bound_xl,
+ bound_xl->fops->removexattr, &state->loc, state->name,
+ state->xdata);
+ return 0;
+err:
+ server4_removexattr_cbk(frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL);
+ return 0;
+}
+
+int
+server4_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, server4_fremovexattr_cbk, bound_xl,
+ bound_xl->fops->fremovexattr, state->fd, state->name,
+ state->xdata);
+ return 0;
+err:
+ server4_fremovexattr_cbk(frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL);
+ return 0;
+}
+
+int
+server4_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, server4_fgetxattr_cbk, bound_xl,
+ bound_xl->fops->fgetxattr, state->fd, state->name, state->xdata);
+ return 0;
+err:
+ server4_fgetxattr_cbk(frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, NULL);
+ return 0;
+}
+
+int
+server4_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, server4_xattrop_cbk, bound_xl, bound_xl->fops->xattrop,
+ &state->loc, state->flags, state->dict, state->xdata);
+ return 0;
+err:
+ server4_xattrop_cbk(frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, NULL);
+ return 0;
+}
+
+int
+server4_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, server4_fxattrop_cbk, bound_xl, bound_xl->fops->fxattrop,
+ state->fd, state->flags, state->dict, state->xdata);
+ return 0;
+err:
+ server4_fxattrop_cbk(frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, NULL);
+ return 0;
+}
+
+int
+server4_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, server4_setxattr_cbk, bound_xl, bound_xl->fops->fsetxattr,
+ state->fd, state->dict, state->flags, state->xdata);
+ return 0;
+err:
+ server4_fsetxattr_cbk(frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL);
+
+ return 0;
+}
+
+int
+server4_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, server4_unlink_cbk, bound_xl, bound_xl->fops->unlink,
+ &state->loc, state->flags, state->xdata);
+ return 0;
+err:
+ server4_unlink_cbk(frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, NULL, NULL);
+ return 0;
+}
+
+int
+server4_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, server4_truncate_cbk, bound_xl, bound_xl->fops->truncate,
+ &state->loc, state->offset, state->xdata);
+ return 0;
+err:
+ server4_truncate_cbk(frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, NULL, NULL);
+ return 0;
+}
+
+int
+server4_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, server4_fstat_cbk, bound_xl, bound_xl->fops->fstat,
+ state->fd, state->xdata);
+ return 0;
+err:
+ server4_fstat_cbk(frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, NULL);
+ return 0;
+}
+
+int
+server4_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, server4_setxattr_cbk, bound_xl, bound_xl->fops->setxattr,
+ &state->loc, state->dict, state->flags, state->xdata);
+ return 0;
+err:
+ server4_setxattr_cbk(frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL);
+
+ return 0;
+}
+
+int
+server4_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, server4_getxattr_cbk, bound_xl, bound_xl->fops->getxattr,
+ &state->loc, state->name, state->xdata);
+ return 0;
+err:
+ server4_getxattr_cbk(frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, NULL);
+ return 0;
+}
+
+int
+server4_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, server4_ftruncate_cbk, bound_xl,
+ bound_xl->fops->ftruncate, state->fd, state->offset,
+ state->xdata);
+ return 0;
+err:
+ server4_ftruncate_cbk(frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, NULL, NULL);
+
+ return 0;
+}
+
+int
+server4_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, server4_flush_cbk, bound_xl, bound_xl->fops->flush,
+ state->fd, state->xdata);
+ return 0;
+err:
+ server4_flush_cbk(frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL);
+
+ return 0;
+}
+
+int
+server4_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, server4_fsync_cbk, bound_xl, bound_xl->fops->fsync,
+ state->fd, state->flags, state->xdata);
+ return 0;
+err:
+ server4_fsync_cbk(frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, NULL, NULL);
+
+ return 0;
+}
+
+int
+server4_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, server4_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:
+ server4_writev_cbk(frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, NULL, NULL);
+ return 0;
+}
+
+int
+server4_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, server4_readv_cbk, bound_xl, bound_xl->fops->readv,
+ state->fd, state->size, state->offset, state->flags,
+ state->xdata);
+
+ return 0;
+err:
+ server4_readv_cbk(frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, 0, NULL, NULL, NULL);
+ return 0;
+}
+
+int
+server4_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_smsg("server", GF_LOG_ERROR, 0, PS_MSG_FD_CREATE_FAILED, "inode=%s",
+ state->loc.inode ? uuid_utoa(state->loc.inode->gfid) : NULL,
+ NULL);
+ state->resolve.op_ret = -1;
+ state->resolve.op_errno = ENOMEM;
+ goto err;
+ }
+ state->fd->flags = state->flags;
+
+ STACK_WIND(frame, server4_create_cbk, bound_xl, bound_xl->fops->create,
+ &(state->loc), state->flags, state->mode, state->umask,
+ state->fd, state->xdata);
+
+ return 0;
+err:
+ server4_create_cbk(frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, NULL, NULL, NULL, NULL,
+ NULL);
+ return 0;
+}
+
+int
+server4_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, server4_open_cbk, bound_xl, bound_xl->fops->open,
+ &state->loc, state->flags, state->fd, state->xdata);
+
+ return 0;
+err:
+ server4_open_cbk(frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, NULL);
+ return 0;
+}
+
+int
+server4_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, server4_readlink_cbk, bound_xl, bound_xl->fops->readlink,
+ &state->loc, state->size, state->xdata);
+ return 0;
+err:
+ server4_readlink_cbk(frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, NULL, NULL);
+ return 0;
+}
+
+int
+server4_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, server4_fsetattr_cbk, bound_xl, bound_xl->fops->fsetattr,
+ state->fd, &state->stbuf, state->valid, state->xdata);
+ return 0;
+err:
+ server4_fsetattr_cbk(frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, NULL, NULL);
+
+ return 0;
+}
+
+int
+server4_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, server4_setattr_cbk, bound_xl, bound_xl->fops->setattr,
+ &state->loc, &state->stbuf, state->valid, state->xdata);
+ return 0;
+err:
+ server4_setattr_cbk(frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, NULL, NULL);
+
+ return 0;
+}
+
+int
+server4_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, server4_stat_cbk, bound_xl, bound_xl->fops->stat,
+ &state->loc, state->xdata);
+ return 0;
+err:
+ server4_stat_cbk(frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, NULL);
+ return 0;
+}
+
+int
+server4_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 = server_inode_new(state->itable, state->loc.gfid);
+ else
+ state->is_revalidate = 1;
+
+ STACK_WIND(frame, server4_lookup_cbk, bound_xl, bound_xl->fops->lookup,
+ &state->loc, state->xdata);
+
+ return 0;
+err:
+ server4_lookup_cbk(frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, NULL, NULL, NULL);
+
+ return 0;
+}
+
+int
+server4_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, server4_fallocate_cbk, bound_xl,
+ bound_xl->fops->fallocate, state->fd, state->flags,
+ state->offset, state->size, state->xdata);
+ return 0;
+err:
+ server4_fallocate_cbk(frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, NULL, NULL);
+
+ return 0;
+}
+
+int
+server4_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, server4_discard_cbk, bound_xl, bound_xl->fops->discard,
+ state->fd, state->offset, state->size, state->xdata);
+ return 0;
+err:
+ server4_discard_cbk(frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, NULL, NULL);
+
+ return 0;
+}
+
+int
+server4_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, server4_zerofill_cbk, bound_xl, bound_xl->fops->zerofill,
+ state->fd, state->offset, state->size, state->xdata);
+ return 0;
+err:
+ server4_zerofill_cbk(frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, NULL, NULL);
+
+ return 0;
+}
+
+int
+server4_seek_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, server4_seek_cbk, bound_xl, bound_xl->fops->seek,
+ state->fd, state->offset, state->what, state->xdata);
+ return 0;
+err:
+ server4_seek_cbk(frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, 0, NULL);
+
+ return 0;
+}
+
+static int
+server4_getactivelk_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno,
+ lock_migration_info_t *locklist, dict_t *xdata)
+{
+ gfx_getactivelk_rsp rsp = {
+ 0,
+ };
+ server_state_t *state = NULL;
+ rpcsvc_request_t *req = NULL;
+ int ret = 0;
+
+ state = CALL_STATE(frame);
+
+ dict_to_xdr(xdata, &rsp.xdata);
+
+ if (op_ret < 0) {
+ state = CALL_STATE(frame);
+
+ gf_smsg(this->name, GF_LOG_INFO, op_errno, PS_MSG_GETACTIVELK_INFO,
+ "frame=%" PRId64, frame->root->unique, "path=%s",
+ state->loc.path, "gfid=%s", uuid_utoa(state->resolve.gfid),
+ "client=%s", STACK_CLIENT_NAME(frame->root), "error-xlator=%s",
+ STACK_ERR_XL_NAME(frame->root), NULL);
+
+ goto out;
+ }
+
+ /* (op_ret == 0) means there are no locks on the file*/
+ if (op_ret > 0) {
+ ret = serialize_rsp_locklist_v2(locklist, &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_gfx_getactivelk_rsp);
+
+ GF_FREE(rsp.xdata.pairs.pairs_val);
+
+ getactivelkinfo_rsp_cleanup_v2(&rsp);
+
+ return 0;
+}
+
+int
+server4_getactivelk_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, server4_getactivelk_cbk, bound_xl,
+ bound_xl->fops->getactivelk, &state->loc, state->xdata);
+ return 0;
+err:
+ server4_getactivelk_cbk(frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, NULL);
+ return 0;
+}
+
+int
+server4_setactivelk_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, server4_setactivelk_cbk, bound_xl,
+ bound_xl->fops->setactivelk, &state->loc, &state->locklist,
+ state->xdata);
+ return 0;
+err:
+ server4_setactivelk_cbk(frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL);
+ return 0;
+}
+int
+server4_namelink_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, server4_namelink_cbk, bound_xl, bound_xl->fops->namelink,
+ &(state->loc), state->xdata);
+ return 0;
+
+err:
+ server4_namelink_cbk(frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, NULL, NULL);
+ return 0;
+}
+
+int
+server4_icreate_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, server4_icreate_cbk, bound_xl, bound_xl->fops->icreate,
+ &(state->loc), state->mode, state->xdata);
+
+ return 0;
+err:
+ server4_icreate_cbk(frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, NULL, NULL);
+ return 0;
+}
+
+int
+server4_copy_file_range_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, server4_copy_file_range_cbk, bound_xl,
+ bound_xl->fops->copy_file_range, state->fd, state->off_in,
+ state->fd_out, state->off_out, state->size, state->flags,
+ state->xdata);
+
+ return 0;
+err:
+ server4_copy_file_range_cbk(frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, NULL, NULL,
+ NULL);
+ return 0;
+}
+
+int
+server4_0_stat(rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfx_stat_req args = {
+ {
+ 0,
+ },
+ };
+ int ret = -1;
+
+ if (!req)
+ return 0;
+
+ /* Initialize args first, then decode */
+ ret = rpc_receive_common(req, &frame, &state, NULL, &args, xdr_gfx_stat_req,
+ GF_FOP_STAT);
+ if (ret != 0) {
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ set_resolve_gfid(frame->root->client, state->resolve.gfid, args.gfid);
+
+ if (xdr_to_dict(&args.xdata, &state->xdata)) {
+ SERVER_REQ_SET_ERROR(req, ret);
+ goto out;
+ }
+
+ ret = 0;
+ resolve_and_resume(frame, server4_stat_resume);
+
+out:
+
+ return ret;
+}
+
+int
+server4_0_setattr(rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfx_setattr_req args = {
+ {
+ 0,
+ },
+ };
+ int ret = -1;
+
+ if (!req)
+ return 0;
+
+ ret = rpc_receive_common(req, &frame, &state, NULL, &args,
+ xdr_gfx_setattr_req, GF_FOP_SETATTR);
+ if (ret != 0) {
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ set_resolve_gfid(frame->root->client, state->resolve.gfid, args.gfid);
+
+ gfx_stat_to_iattx(&args.stbuf, &state->stbuf);
+ state->valid = args.valid;
+
+ if (xdr_to_dict(&args.xdata, &state->xdata)) {
+ SERVER_REQ_SET_ERROR(req, ret);
+ goto out;
+ }
+
+ ret = 0;
+ resolve_and_resume(frame, server4_setattr_resume);
+
+out:
+
+ return ret;
+}
+
+int
+server4_0_fallocate(rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfx_fallocate_req args = {
+ {0},
+ };
+ int ret = -1;
+
+ if (!req)
+ return ret;
+
+ ret = rpc_receive_common(req, &frame, &state, NULL, &args,
+ xdr_gfx_fallocate_req, GF_FOP_FALLOCATE);
+ if (ret != 0) {
+ 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);
+
+ if (xdr_to_dict(&args.xdata, &state->xdata)) {
+ SERVER_REQ_SET_ERROR(req, ret);
+ goto out;
+ }
+
+ ret = 0;
+ resolve_and_resume(frame, server4_fallocate_resume);
+
+out:
+
+ return ret;
+}
+
+int
+server4_0_discard(rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfx_discard_req args = {
+ {0},
+ };
+ int ret = -1;
+
+ if (!req)
+ return ret;
+
+ ret = rpc_receive_common(req, &frame, &state, NULL, &args,
+ xdr_gfx_discard_req, GF_FOP_DISCARD);
+ if (ret != 0) {
+ 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);
+
+ if (xdr_to_dict(&args.xdata, &state->xdata)) {
+ SERVER_REQ_SET_ERROR(req, ret);
+ goto out;
+ }
+
+ ret = 0;
+ resolve_and_resume(frame, server4_discard_resume);
+
+out:
+
+ return ret;
+}
+
+int
+server4_0_zerofill(rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfx_zerofill_req args = {
+ {0},
+ };
+ int ret = -1;
+ int op_errno = 0;
+
+ if (!req)
+ return ret;
+
+ ret = rpc_receive_common(req, &frame, &state, NULL, &args,
+ xdr_gfx_zerofill_req, GF_FOP_ZEROFILL);
+ if (ret != 0) {
+ op_errno = -1;
+ 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);
+
+ if (xdr_to_dict(&args.xdata, &state->xdata)) {
+ SERVER_REQ_SET_ERROR(req, ret);
+ goto out;
+ }
+ ret = 0;
+ resolve_and_resume(frame, server4_zerofill_resume);
+
+out:
+ if (op_errno)
+ req->rpc_err = GARBAGE_ARGS;
+
+ return ret;
+}
+
+int
+server4_0_ipc(rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfx_ipc_req args = {
+ 0,
+ };
+ int ret = -1;
+ xlator_t *bound_xl = NULL;
+
+ if (!req)
+ return ret;
+
+ ret = rpc_receive_common(req, &frame, &state, NULL, &args, xdr_gfx_ipc_req,
+ GF_FOP_IPC);
+ if (ret != 0) {
+ goto out;
+ }
+
+ bound_xl = frame->root->client->bound_xl;
+ if (xdr_to_dict(&args.xdata, &state->xdata)) {
+ SERVER_REQ_SET_ERROR(req, ret);
+ goto out;
+ }
+ ret = 0;
+ STACK_WIND(frame, server4_ipc_cbk, bound_xl, bound_xl->fops->ipc, args.op,
+ state->xdata);
+
+out:
+
+ return ret;
+}
+
+int
+server4_0_seek(rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfx_seek_req args = {
+ {
+ 0,
+ },
+ };
+ int ret = -1;
+
+ if (!req)
+ return ret;
+
+ ret = rpc_receive_common(req, &frame, &state, NULL, &args, xdr_gfx_seek_req,
+ GF_FOP_SEEK);
+ if (ret != 0) {
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ state->resolve.fd_no = args.fd;
+
+ state->offset = args.offset;
+ state->what = args.what;
+ memcpy(state->resolve.gfid, args.gfid, 16);
+
+ if (xdr_to_dict(&args.xdata, &state->xdata)) {
+ SERVER_REQ_SET_ERROR(req, ret);
+ goto out;
+ }
+
+ ret = 0;
+ resolve_and_resume(frame, server4_seek_resume);
+
+out:
+ return ret;
+}
+
+int
+server4_0_readlink(rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfx_readlink_req args = {
+ {
+ 0,
+ },
+ };
+ int ret = -1;
+
+ if (!req)
+ return ret;
+
+ ret = rpc_receive_common(req, &frame, &state, NULL, &args,
+ xdr_gfx_readlink_req, GF_FOP_READLINK);
+ if (ret != 0) {
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ memcpy(state->resolve.gfid, args.gfid, 16);
+
+ state->size = args.size;
+
+ if (xdr_to_dict(&args.xdata, &state->xdata)) {
+ SERVER_REQ_SET_ERROR(req, ret);
+ goto out;
+ }
+
+ ret = 0;
+ resolve_and_resume(frame, server4_readlink_resume);
+
+out:
+
+ return ret;
+}
+
+int
+server4_0_create(rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfx_create_req args = {
+ {
+ 0,
+ },
+ };
+ int ret = -1;
+
+ if (!req)
+ return ret;
+
+ ret = rpc_receive_common(req, &frame, &state, NULL, &args,
+ xdr_gfx_create_req, GF_FOP_CREATE);
+ if (ret != 0) {
+ 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);
+
+ set_resolve_gfid(frame->root->client, state->resolve.pargfid, args.pargfid);
+
+ if (state->flags & O_EXCL) {
+ state->resolve.type = RESOLVE_NOT;
+ } else {
+ state->resolve.type = RESOLVE_DONTCARE;
+ }
+
+ if (xdr_to_dict(&args.xdata, &state->xdata)) {
+ SERVER_REQ_SET_ERROR(req, ret);
+ goto out;
+ }
+
+ ret = 0;
+ resolve_and_resume(frame, server4_create_resume);
+
+out:
+ free(args.bname);
+
+ return ret;
+}
+
+int
+server4_0_open(rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfx_open_req args = {
+ {
+ 0,
+ },
+ };
+ int ret = -1;
+
+ if (!req)
+ return ret;
+
+ ret = rpc_receive_common(req, &frame, &state, NULL, &args, xdr_gfx_open_req,
+ GF_FOP_OPEN);
+ if (ret != 0) {
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ memcpy(state->resolve.gfid, args.gfid, 16);
+
+ state->flags = gf_flags_to_flags(args.flags);
+
+ if (xdr_to_dict(&args.xdata, &state->xdata)) {
+ SERVER_REQ_SET_ERROR(req, ret);
+ goto out;
+ }
+
+ ret = 0;
+ resolve_and_resume(frame, server4_open_resume);
+out:
+ return ret;
+}
+
+int
+server4_0_readv(rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfx_read_req args = {
+ {
+ 0,
+ },
+ };
+ int ret = -1;
+
+ if (!req)
+ goto out;
+
+ ret = rpc_receive_common(req, &frame, &state, NULL, &args, xdr_gfx_read_req,
+ GF_FOP_READ);
+ if (ret != 0) {
+ 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);
+
+ if (xdr_to_dict(&args.xdata, &state->xdata)) {
+ SERVER_REQ_SET_ERROR(req, ret);
+ goto out;
+ }
+
+ ret = 0;
+ resolve_and_resume(frame, server4_readv_resume);
+out:
+ return ret;
+}
+
+int
+server4_0_writev(rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfx_write_req args = {
+ {
+ 0,
+ },
+ };
+ ssize_t len = 0;
+ int i = 0;
+ int ret = -1;
+
+ if (!req)
+ return ret;
+
+ ret = rpc_receive_common(req, &frame, &state, &len, &args,
+ xdr_gfx_write_req, GF_FOP_WRITE);
+ if (ret != 0) {
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ state->resolve.fd_no = args.fd;
+ state->offset = args.offset;
+ state->size = args.size;
+ 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];
+ }
+
+ len = iov_length(state->payload_vector, state->payload_count);
+
+ GF_ASSERT(state->size == len);
+
+ if (xdr_to_dict(&args.xdata, &state->xdata)) {
+ SERVER_REQ_SET_ERROR(req, ret);
+ goto out;
+ }
+
+#ifdef GF_TESTING_IO_XDATA
+ dict_dump_to_log(state->xdata);
+#endif
+
+ ret = 0;
+ resolve_and_resume(frame, server4_writev_resume);
+out:
+
+ return ret;
+}
+
+#define SERVER4_0_VECWRITE_START 0
+#define SERVER4_0_VECWRITE_READING_HDR 1
+#define SERVER4_0_VECWRITE_READING_OPAQUE 2
+
+int
+server4_0_writev_vecsizer(int state, ssize_t *readsize, char *base_addr,
+ char *curr_addr)
+{
+ ssize_t size = 0;
+ int nextstate = 0;
+ gfx_write_req write_req = {
+ {
+ 0,
+ },
+ };
+ XDR xdr;
+
+ switch (state) {
+ case SERVER4_0_VECWRITE_START:
+ size = xdr_sizeof((xdrproc_t)xdr_gfx_write_req, &write_req);
+ *readsize = size;
+
+ nextstate = SERVER4_0_VECWRITE_READING_HDR;
+ break;
+ case SERVER4_0_VECWRITE_READING_HDR:
+ size = xdr_sizeof((xdrproc_t)xdr_gfx_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_gfx_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 = gf_roof(write_req.xdata.xdr_size, 4);
+
+ *readsize = size;
+
+ if (!size)
+ nextstate = SERVER4_0_VECWRITE_START;
+ else
+ nextstate = SERVER4_0_VECWRITE_READING_OPAQUE;
+
+ free(write_req.xdata.pairs.pairs_val);
+
+ break;
+
+ case SERVER4_0_VECWRITE_READING_OPAQUE:
+ *readsize = 0;
+ nextstate = SERVER4_0_VECWRITE_START;
+ break;
+ }
+
+ return nextstate;
+}
+
+int
+server4_0_release(rpcsvc_request_t *req)
+{
+ client_t *client = NULL;
+ server_ctx_t *serv_ctx = NULL;
+ gfx_release_req args = {
+ {
+ 0,
+ },
+ };
+ gfx_common_rsp rsp = {
+ 0,
+ };
+ int ret = -1;
+
+ ret = xdr_to_generic(req->msg[0], &args, (xdrproc_t)xdr_gfx_release_req);
+ if (ret < 0) {
+ 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_smsg(req->trans->name, GF_LOG_INFO, 0, PS_MSG_SERVER_CTX_GET_FAILED,
+ NULL);
+ 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_gfx_common_rsp);
+
+ ret = 0;
+out:
+ return ret;
+}
+
+int
+server4_0_releasedir(rpcsvc_request_t *req)
+{
+ client_t *client = NULL;
+ server_ctx_t *serv_ctx = NULL;
+ gfx_releasedir_req args = {
+ {
+ 0,
+ },
+ };
+ gfx_common_rsp rsp = {
+ 0,
+ };
+ int ret = -1;
+
+ ret = xdr_to_generic(req->msg[0], &args, (xdrproc_t)xdr_gfx_release_req);
+ if (ret < 0) {
+ 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_smsg(req->trans->name, GF_LOG_INFO, 0, PS_MSG_SERVER_CTX_GET_FAILED,
+ NULL);
+ 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_gfx_common_rsp);
+
+ ret = 0;
+out:
+ return ret;
+}
+
+int
+server4_0_fsync(rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfx_fsync_req args = {
+ {
+ 0,
+ },
+ };
+ int ret = -1;
+
+ if (!req)
+ return ret;
+
+ ret = rpc_receive_common(req, &frame, &state, NULL, &args,
+ xdr_gfx_fsync_req, GF_FOP_FSYNC);
+ if (ret != 0) {
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ state->resolve.fd_no = args.fd;
+ state->flags = args.data;
+ memcpy(state->resolve.gfid, args.gfid, 16);
+
+ if (xdr_to_dict(&args.xdata, &state->xdata)) {
+ SERVER_REQ_SET_ERROR(req, ret);
+ goto out;
+ }
+
+ ret = 0;
+ resolve_and_resume(frame, server4_fsync_resume);
+out:
+
+ return ret;
+}
+
+int
+server4_0_flush(rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfx_flush_req args = {
+ {
+ 0,
+ },
+ };
+ int ret = -1;
+
+ if (!req)
+ return ret;
+
+ ret = rpc_receive_common(req, &frame, &state, NULL, &args,
+ xdr_gfx_flush_req, GF_FOP_FLUSH);
+ if (ret != 0) {
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ state->resolve.fd_no = args.fd;
+ memcpy(state->resolve.gfid, args.gfid, 16);
+
+ if (xdr_to_dict(&args.xdata, &state->xdata)) {
+ SERVER_REQ_SET_ERROR(req, ret);
+ goto out;
+ }
+
+ ret = 0;
+ resolve_and_resume(frame, server4_flush_resume);
+out:
+
+ return ret;
+}
+
+int
+server4_0_ftruncate(rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfx_ftruncate_req args = {
+ {
+ 0,
+ },
+ };
+ int ret = -1;
+
+ if (!req)
+ return ret;
+
+ ret = rpc_receive_common(req, &frame, &state, NULL, &args,
+ xdr_gfx_ftruncate_req, GF_FOP_FTRUNCATE);
+ if (ret != 0) {
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ state->resolve.fd_no = args.fd;
+ state->offset = args.offset;
+ memcpy(state->resolve.gfid, args.gfid, 16);
+
+ if (xdr_to_dict(&args.xdata, &state->xdata)) {
+ SERVER_REQ_SET_ERROR(req, ret);
+ goto out;
+ }
+
+ ret = 0;
+ resolve_and_resume(frame, server4_ftruncate_resume);
+out:
+
+ return ret;
+}
+
+int
+server4_0_fstat(rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfx_fstat_req args = {
+ {
+ 0,
+ },
+ };
+ int ret = -1;
+
+ if (!req)
+ return ret;
+
+ ret = rpc_receive_common(req, &frame, &state, NULL, &args,
+ xdr_gfx_fstat_req, GF_FOP_FSTAT);
+ if (ret != 0) {
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ state->resolve.fd_no = args.fd;
+ set_resolve_gfid(frame->root->client, state->resolve.gfid, args.gfid);
+
+ if (xdr_to_dict(&args.xdata, &state->xdata)) {
+ SERVER_REQ_SET_ERROR(req, ret);
+ goto out;
+ }
+
+ ret = 0;
+ resolve_and_resume(frame, server4_fstat_resume);
+out:
+
+ return ret;
+}
+
+int
+server4_0_truncate(rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfx_truncate_req args = {
+ {
+ 0,
+ },
+ };
+ int ret = -1;
+
+ if (!req)
+ return ret;
+
+ ret = rpc_receive_common(req, &frame, &state, NULL, &args,
+ xdr_gfx_truncate_req, GF_FOP_TRUNCATE);
+ if (ret != 0) {
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ memcpy(state->resolve.gfid, args.gfid, 16);
+ state->offset = args.offset;
+
+ if (xdr_to_dict(&args.xdata, &state->xdata)) {
+ SERVER_REQ_SET_ERROR(req, ret);
+ goto out;
+ }
+
+ ret = 0;
+ resolve_and_resume(frame, server4_truncate_resume);
+out:
+
+ return ret;
+}
+
+int
+server4_0_unlink(rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfx_unlink_req args = {
+ {
+ 0,
+ },
+ };
+ int ret = -1;
+
+ if (!req)
+ return ret;
+
+ ret = rpc_receive_common(req, &frame, &state, NULL, &args,
+ xdr_gfx_unlink_req, GF_FOP_UNLINK);
+ if (ret != 0) {
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ state->resolve.bname = gf_strdup(args.bname);
+
+ set_resolve_gfid(frame->root->client, state->resolve.pargfid, args.pargfid);
+
+ state->flags = args.xflags;
+
+ if (xdr_to_dict(&args.xdata, &state->xdata)) {
+ SERVER_REQ_SET_ERROR(req, ret);
+ goto out;
+ }
+
+ ret = 0;
+ resolve_and_resume(frame, server4_unlink_resume);
+out:
+ free(args.bname);
+
+ return ret;
+}
+
+int
+server4_0_setxattr(rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfx_setxattr_req args = {
+ {
+ 0,
+ },
+ };
+ int32_t ret = -1;
+
+ if (!req)
+ return ret;
+
+ ret = rpc_receive_common(req, &frame, &state, NULL, &args,
+ xdr_gfx_setxattr_req, GF_FOP_SETXATTR);
+ if (ret != 0) {
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ state->flags = args.flags;
+ set_resolve_gfid(frame->root->client, state->resolve.gfid, args.gfid);
+
+ if (xdr_to_dict(&args.dict, &state->dict)) {
+ SERVER_REQ_SET_ERROR(req, ret);
+ goto out;
+ }
+
+ /* There can be some commands hidden in key, check and proceed */
+ gf_server_check_setxattr_cmd(frame, state->dict);
+
+ if (xdr_to_dict(&args.xdata, &state->xdata)) {
+ SERVER_REQ_SET_ERROR(req, ret);
+ goto out;
+ }
+
+ ret = 0;
+ resolve_and_resume(frame, server4_setxattr_resume);
+
+out:
+ return ret;
+}
+
+int
+server4_0_fsetxattr(rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfx_fsetxattr_req args = {
+ {
+ 0,
+ },
+ };
+ int32_t ret = -1;
+
+ if (!req)
+ return ret;
+
+ ret = rpc_receive_common(req, &frame, &state, NULL, &args,
+ xdr_gfx_fsetxattr_req, GF_FOP_FSETXATTR);
+ if (ret != 0) {
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ state->resolve.fd_no = args.fd;
+ state->flags = args.flags;
+ set_resolve_gfid(frame->root->client, state->resolve.gfid, args.gfid);
+
+ if (xdr_to_dict(&args.dict, &state->dict)) {
+ SERVER_REQ_SET_ERROR(req, ret);
+ goto out;
+ }
+
+ if (xdr_to_dict(&args.xdata, &state->xdata)) {
+ SERVER_REQ_SET_ERROR(req, ret);
+ goto out;
+ }
+
+ ret = 0;
+ resolve_and_resume(frame, server4_fsetxattr_resume);
+
+out:
+ return ret;
+}
+
+int
+server4_0_fxattrop(rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfx_fxattrop_req args = {
+ {
+ 0,
+ },
+ };
+ int32_t ret = -1;
+
+ if (!req)
+ return ret;
+
+ ret = rpc_receive_common(req, &frame, &state, NULL, &args,
+ xdr_gfx_fxattrop_req, GF_FOP_FXATTROP);
+ if (ret != 0) {
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ state->resolve.fd_no = args.fd;
+ state->flags = args.flags;
+ set_resolve_gfid(frame->root->client, state->resolve.gfid, args.gfid);
+
+ if (xdr_to_dict(&args.dict, &state->dict)) {
+ SERVER_REQ_SET_ERROR(req, ret);
+ goto out;
+ }
+
+ if (xdr_to_dict(&args.xdata, &state->xdata)) {
+ SERVER_REQ_SET_ERROR(req, ret);
+ goto out;
+ }
+
+ ret = 0;
+ resolve_and_resume(frame, server4_fxattrop_resume);
+
+out:
+ return ret;
+}
+
+int
+server4_0_xattrop(rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfx_xattrop_req args = {
+ {
+ 0,
+ },
+ };
+ int32_t ret = -1;
+
+ if (!req)
+ return ret;
+
+ ret = rpc_receive_common(req, &frame, &state, NULL, &args,
+ xdr_gfx_xattrop_req, GF_FOP_XATTROP);
+ if (ret != 0) {
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ state->flags = args.flags;
+ set_resolve_gfid(frame->root->client, state->resolve.gfid, args.gfid);
+
+ if (xdr_to_dict(&args.dict, &state->dict)) {
+ SERVER_REQ_SET_ERROR(req, ret);
+ goto out;
+ }
+
+ if (xdr_to_dict(&args.xdata, &state->xdata)) {
+ SERVER_REQ_SET_ERROR(req, ret);
+ goto out;
+ }
+
+ ret = 0;
+ resolve_and_resume(frame, server4_xattrop_resume);
+
+out:
+ return ret;
+}
+
+int
+server4_0_getxattr(rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfx_getxattr_req args = {
+ {
+ 0,
+ },
+ };
+ int ret = -1;
+
+ if (!req)
+ return ret;
+
+ ret = rpc_receive_common(req, &frame, &state, NULL, &args,
+ xdr_gfx_getxattr_req, GF_FOP_GETXATTR);
+ if (ret != 0) {
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ set_resolve_gfid(frame->root->client, state->resolve.gfid, args.gfid);
+
+ 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);
+ }
+
+ if (xdr_to_dict(&args.xdata, &state->xdata)) {
+ SERVER_REQ_SET_ERROR(req, ret);
+ goto out;
+ }
+
+ ret = 0;
+ resolve_and_resume(frame, server4_getxattr_resume);
+out:
+ free(args.name);
+
+ return ret;
+}
+
+int
+server4_0_fgetxattr(rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfx_fgetxattr_req args = {
+ {
+ 0,
+ },
+ };
+ int ret = -1;
+
+ if (!req)
+ return ret;
+
+ ret = rpc_receive_common(req, &frame, &state, NULL, &args,
+ xdr_gfx_fgetxattr_req, GF_FOP_FGETXATTR);
+ if (ret != 0) {
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ state->resolve.fd_no = args.fd;
+ set_resolve_gfid(frame->root->client, state->resolve.gfid, args.gfid);
+ if (args.namelen)
+ state->name = gf_strdup(args.name);
+
+ if (xdr_to_dict(&args.xdata, &state->xdata)) {
+ SERVER_REQ_SET_ERROR(req, ret);
+ goto out;
+ }
+
+ ret = 0;
+ resolve_and_resume(frame, server4_fgetxattr_resume);
+out:
+ free(args.name);
+
+ return ret;
+}
+
+int
+server4_0_removexattr(rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfx_removexattr_req args = {
+ {
+ 0,
+ },
+ };
+ int ret = -1;
+
+ if (!req)
+ return ret;
+
+ ret = rpc_receive_common(req, &frame, &state, NULL, &args,
+ xdr_gfx_removexattr_req, GF_FOP_REMOVEXATTR);
+ if (ret != 0) {
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ set_resolve_gfid(frame->root->client, state->resolve.gfid, args.gfid);
+ state->name = gf_strdup(args.name);
+
+ if (xdr_to_dict(&args.xdata, &state->xdata)) {
+ SERVER_REQ_SET_ERROR(req, ret);
+ goto out;
+ }
+
+ ret = 0;
+ resolve_and_resume(frame, server4_removexattr_resume);
+out:
+ free(args.name);
+
+ return ret;
+}
+
+int
+server4_0_fremovexattr(rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfx_fremovexattr_req args = {
+ {
+ 0,
+ },
+ };
+ int ret = -1;
+
+ if (!req)
+ return ret;
+
+ ret = rpc_receive_common(req, &frame, &state, NULL, &args,
+ xdr_gfx_fremovexattr_req, GF_FOP_FREMOVEXATTR);
+ if (ret != 0) {
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ state->resolve.fd_no = args.fd;
+ set_resolve_gfid(frame->root->client, state->resolve.gfid, args.gfid);
+ state->name = gf_strdup(args.name);
+
+ if (xdr_to_dict(&args.xdata, &state->xdata)) {
+ SERVER_REQ_SET_ERROR(req, ret);
+ goto out;
+ }
+
+ ret = 0;
+ resolve_and_resume(frame, server4_fremovexattr_resume);
+out:
+ free(args.name);
+
+ return ret;
+}
+
+int
+server4_0_opendir(rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfx_opendir_req args = {
+ {
+ 0,
+ },
+ };
+ int ret = -1;
+
+ if (!req)
+ return ret;
+
+ ret = rpc_receive_common(req, &frame, &state, NULL, &args,
+ xdr_gfx_opendir_req, GF_FOP_OPENDIR);
+ if (ret != 0) {
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ set_resolve_gfid(frame->root->client, state->resolve.gfid, args.gfid);
+
+ if (xdr_to_dict(&args.xdata, &state->xdata)) {
+ SERVER_REQ_SET_ERROR(req, ret);
+ goto out;
+ }
+
+ ret = 0;
+ resolve_and_resume(frame, server4_opendir_resume);
+out:
+
+ return ret;
+}
+
+int
+server4_0_readdirp(rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfx_readdirp_req args = {
+ {
+ 0,
+ },
+ };
+ size_t headers_size = 0;
+ int ret = -1;
+
+ if (!req)
+ return ret;
+
+ ret = rpc_receive_common(req, &frame, &state, NULL, &args,
+ xdr_gfx_readdirp_req, GF_FOP_READDIRP);
+ if (ret != 0) {
+ 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(gfx_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;
+ set_resolve_gfid(frame->root->client, state->resolve.gfid, args.gfid);
+
+ /* here, dict itself works as xdata */
+ if (xdr_to_dict(&args.xdata, &state->xdata)) {
+ SERVER_REQ_SET_ERROR(req, ret);
+ goto out;
+ }
+
+ ret = 0;
+ resolve_and_resume(frame, server4_readdirp_resume);
+out:
+ return ret;
+}
+
+int
+server4_0_readdir(rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfx_readdir_req args = {
+ {
+ 0,
+ },
+ };
+ size_t headers_size = 0;
+ int ret = -1;
+
+ if (!req)
+ return ret;
+
+ ret = rpc_receive_common(req, &frame, &state, NULL, &args,
+ xdr_gfx_readdir_req, GF_FOP_READDIR);
+ if (ret != 0) {
+ 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(gfx_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;
+ set_resolve_gfid(frame->root->client, state->resolve.gfid, args.gfid);
+
+ if (xdr_to_dict(&args.xdata, &state->xdata)) {
+ SERVER_REQ_SET_ERROR(req, ret);
+ goto out;
+ }
+
+ ret = 0;
+ resolve_and_resume(frame, server4_readdir_resume);
+out:
+
+ return ret;
+}
+
+int
+server4_0_fsyncdir(rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfx_fsyncdir_req args = {
+ {
+ 0,
+ },
+ };
+ int ret = -1;
+
+ if (!req)
+ return ret;
+
+ ret = rpc_receive_common(req, &frame, &state, NULL, &args,
+ xdr_gfx_fsyncdir_req, GF_FOP_FSYNCDIR);
+ if (ret != 0) {
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ state->resolve.fd_no = args.fd;
+ state->flags = args.data;
+ set_resolve_gfid(frame->root->client, state->resolve.gfid, args.gfid);
+
+ if (xdr_to_dict(&args.xdata, &state->xdata)) {
+ SERVER_REQ_SET_ERROR(req, ret);
+ goto out;
+ }
+
+ ret = 0;
+ resolve_and_resume(frame, server4_fsyncdir_resume);
+out:
+
+ return ret;
+}
+
+int
+server4_0_mknod(rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfx_mknod_req args = {
+ {
+ 0,
+ },
+ };
+ int ret = -1;
+
+ if (!req)
+ return ret;
+
+ ret = rpc_receive_common(req, &frame, &state, NULL, &args,
+ xdr_gfx_mknod_req, GF_FOP_MKNOD);
+ if (ret != 0) {
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_NOT;
+ set_resolve_gfid(frame->root->client, state->resolve.pargfid, args.pargfid);
+
+ state->resolve.bname = gf_strdup(args.bname);
+
+ state->mode = args.mode;
+ state->dev = args.dev;
+ state->umask = args.umask;
+
+ if (xdr_to_dict(&args.xdata, &state->xdata)) {
+ SERVER_REQ_SET_ERROR(req, ret);
+ goto out;
+ }
+
+ ret = 0;
+ resolve_and_resume(frame, server4_mknod_resume);
+
+out:
+ free(args.bname);
+
+ return ret;
+}
+
+int
+server4_0_mkdir(rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfx_mkdir_req args = {
+ {
+ 0,
+ },
+ };
+ int ret = -1;
+
+ if (!req)
+ return ret;
+
+ ret = rpc_receive_common(req, &frame, &state, NULL, &args,
+ xdr_gfx_mkdir_req, GF_FOP_MKDIR);
+ if (ret != 0) {
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_NOT;
+ set_resolve_gfid(frame->root->client, state->resolve.pargfid, args.pargfid);
+ state->resolve.bname = gf_strdup(args.bname);
+
+ state->mode = args.mode;
+ state->umask = args.umask;
+
+ if (xdr_to_dict(&args.xdata, &state->xdata)) {
+ SERVER_REQ_SET_ERROR(req, ret);
+ goto out;
+ }
+
+ ret = 0;
+ resolve_and_resume(frame, server4_mkdir_resume);
+
+out:
+ free(args.bname);
+
+ return ret;
+}
+
+int
+server4_0_rmdir(rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfx_rmdir_req args = {
+ {
+ 0,
+ },
+ };
+ int ret = -1;
+
+ if (!req)
+ return ret;
+
+ ret = rpc_receive_common(req, &frame, &state, NULL, &args,
+ xdr_gfx_rmdir_req, GF_FOP_RMDIR);
+ if (ret != 0) {
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ set_resolve_gfid(frame->root->client, state->resolve.pargfid, args.pargfid);
+ state->resolve.bname = gf_strdup(args.bname);
+
+ state->flags = args.xflags;
+
+ if (xdr_to_dict(&args.xdata, &state->xdata)) {
+ SERVER_REQ_SET_ERROR(req, ret);
+ goto out;
+ }
+
+ ret = 0;
+ resolve_and_resume(frame, server4_rmdir_resume);
+out:
+ free(args.bname);
+
+ return ret;
+}
+
+int
+server4_0_inodelk(rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfx_inodelk_req args = {
+ {
+ 0,
+ },
+ };
+ int cmd = 0;
+ int ret = -1;
+
+ if (!req)
+ return ret;
+
+ ret = rpc_receive_common(req, &frame, &state, NULL, &args,
+ xdr_gfx_inodelk_req, GF_FOP_INODELK);
+ if (ret != 0) {
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_EXACT;
+ set_resolve_gfid(frame->root->client, state->resolve.gfid, args.gfid);
+
+ 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;
+ }
+
+ if (xdr_to_dict(&args.xdata, &state->xdata)) {
+ SERVER_REQ_SET_ERROR(req, ret);
+ goto out;
+ }
+
+ ret = 0;
+ resolve_and_resume(frame, server4_inodelk_resume);
+out:
+ free(args.volume);
+
+ free(args.flock.lk_owner.lk_owner_val);
+
+ return ret;
+}
+
+int
+server4_0_finodelk(rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfx_finodelk_req args = {
+ {
+ 0,
+ },
+ };
+ int ret = -1;
+
+ if (!req)
+ return ret;
+
+ ret = rpc_receive_common(req, &frame, &state, NULL, &args,
+ xdr_gfx_finodelk_req, GF_FOP_FINODELK);
+ if (ret != 0) {
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_EXACT;
+ state->volume = gf_strdup(args.volume);
+ state->resolve.fd_no = args.fd;
+ state->cmd = args.cmd;
+ set_resolve_gfid(frame->root->client, state->resolve.gfid, args.gfid);
+
+ 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;
+ }
+
+ if (xdr_to_dict(&args.xdata, &state->xdata)) {
+ SERVER_REQ_SET_ERROR(req, ret);
+ goto out;
+ }
+
+ ret = 0;
+ resolve_and_resume(frame, server4_finodelk_resume);
+out:
+ free(args.volume);
+
+ free(args.flock.lk_owner.lk_owner_val);
+
+ return ret;
+}
+
+int
+server4_0_entrylk(rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfx_entrylk_req args = {
+ {
+ 0,
+ },
+ };
+ int ret = -1;
+
+ if (!req)
+ return ret;
+
+ ret = rpc_receive_common(req, &frame, &state, NULL, &args,
+ xdr_gfx_entrylk_req, GF_FOP_ENTRYLK);
+ if (ret != 0) {
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_EXACT;
+ set_resolve_gfid(frame->root->client, state->resolve.gfid, args.gfid);
+
+ if (args.namelen)
+ state->name = gf_strdup(args.name);
+ state->volume = gf_strdup(args.volume);
+
+ state->cmd = args.cmd;
+ state->type = args.type;
+
+ if (xdr_to_dict(&args.xdata, &state->xdata)) {
+ SERVER_REQ_SET_ERROR(req, ret);
+ goto out;
+ }
+
+ ret = 0;
+ resolve_and_resume(frame, server4_entrylk_resume);
+out:
+ free(args.volume);
+ free(args.name);
+
+ return ret;
+}
+
+int
+server4_0_fentrylk(rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfx_fentrylk_req args = {
+ {
+ 0,
+ },
+ };
+ int ret = -1;
+
+ if (!req)
+ return ret;
+
+ ret = rpc_receive_common(req, &frame, &state, NULL, &args,
+ xdr_gfx_fentrylk_req, GF_FOP_FENTRYLK);
+ if (ret != 0) {
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_EXACT;
+ state->resolve.fd_no = args.fd;
+ state->cmd = args.cmd;
+ state->type = args.type;
+ set_resolve_gfid(frame->root->client, state->resolve.gfid, args.gfid);
+
+ if (args.namelen)
+ state->name = gf_strdup(args.name);
+ state->volume = gf_strdup(args.volume);
+
+ if (xdr_to_dict(&args.xdata, &state->xdata)) {
+ SERVER_REQ_SET_ERROR(req, ret);
+ goto out;
+ }
+
+ ret = 0;
+ resolve_and_resume(frame, server4_fentrylk_resume);
+out:
+ free(args.volume);
+ free(args.name);
+
+ return ret;
+}
+
+int
+server4_0_access(rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfx_access_req args = {
+ {
+ 0,
+ },
+ };
+ int ret = -1;
+
+ if (!req)
+ return ret;
+
+ ret = rpc_receive_common(req, &frame, &state, NULL, &args,
+ xdr_gfx_access_req, GF_FOP_ACCESS);
+ if (ret != 0) {
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ set_resolve_gfid(frame->root->client, state->resolve.gfid, args.gfid);
+ state->mask = args.mask;
+
+ if (xdr_to_dict(&args.xdata, &state->xdata)) {
+ SERVER_REQ_SET_ERROR(req, ret);
+ goto out;
+ }
+
+ ret = 0;
+ resolve_and_resume(frame, server4_access_resume);
+out:
+
+ return ret;
+}
+
+int
+server4_0_symlink(rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfx_symlink_req args = {
+ {
+ 0,
+ },
+ };
+ int ret = -1;
+
+ if (!req)
+ return ret;
+
+ ret = rpc_receive_common(req, &frame, &state, NULL, &args,
+ xdr_gfx_symlink_req, GF_FOP_SYMLINK);
+ if (ret != 0) {
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_NOT;
+ set_resolve_gfid(frame->root->client, state->resolve.pargfid, args.pargfid);
+ state->resolve.bname = gf_strdup(args.bname);
+ state->name = gf_strdup(args.linkname);
+ state->umask = args.umask;
+
+ if (xdr_to_dict(&args.xdata, &state->xdata)) {
+ SERVER_REQ_SET_ERROR(req, ret);
+ goto out;
+ }
+
+ ret = 0;
+ resolve_and_resume(frame, server4_symlink_resume);
+
+out:
+ free(args.bname);
+ free(args.linkname);
+
+ return ret;
+}
+
+int
+server4_0_link(rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfx_link_req args = {
+ {
+ 0,
+ },
+ };
+ int ret = -1;
+
+ if (!req)
+ return ret;
+
+ ret = rpc_receive_common(req, &frame, &state, NULL, &args, xdr_gfx_link_req,
+ GF_FOP_LINK);
+ if (ret != 0) {
+ 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);
+ set_resolve_gfid(frame->root->client, state->resolve2.pargfid,
+ args.newgfid);
+
+ if (xdr_to_dict(&args.xdata, &state->xdata)) {
+ SERVER_REQ_SET_ERROR(req, ret);
+ goto out;
+ }
+
+ ret = 0;
+ resolve_and_resume(frame, server4_link_resume);
+out:
+ free(args.newbname);
+
+ return ret;
+}
+
+int
+server4_0_rename(rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfx_rename_req args = {
+ {
+ 0,
+ },
+ };
+ int ret = -1;
+
+ if (!req)
+ return ret;
+
+ ret = rpc_receive_common(req, &frame, &state, NULL, &args,
+ xdr_gfx_rename_req, GF_FOP_RENAME);
+ if (ret != 0) {
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ state->resolve.bname = gf_strdup(args.oldbname);
+ set_resolve_gfid(frame->root->client, state->resolve.pargfid, args.oldgfid);
+
+ state->resolve2.type = RESOLVE_MAY;
+ state->resolve2.bname = gf_strdup(args.newbname);
+ set_resolve_gfid(frame->root->client, state->resolve2.pargfid,
+ args.newgfid);
+
+ if (xdr_to_dict(&args.xdata, &state->xdata)) {
+ SERVER_REQ_SET_ERROR(req, ret);
+ goto out;
+ }
+
+ ret = 0;
+ resolve_and_resume(frame, server4_rename_resume);
+out:
+ free(args.oldbname);
+ free(args.newbname);
+
+ return ret;
+}
+
+int
+server4_0_lease(rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfx_lease_req args = {
+ {
+ 0,
+ },
+ };
+ int ret = -1;
+
+ if (!req)
+ return ret;
+
+ ret = rpc_receive_common(req, &frame, &state, NULL, &args,
+ xdr_gfx_lease_req, GF_FOP_LEASE);
+ if (ret != 0) {
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ set_resolve_gfid(frame->root->client, state->resolve.gfid, args.gfid);
+ gf_proto_lease_to_lease(&args.lease, &state->lease);
+
+ if (xdr_to_dict(&args.xdata, &state->xdata)) {
+ SERVER_REQ_SET_ERROR(req, ret);
+ goto out;
+ }
+
+ ret = 0;
+ resolve_and_resume(frame, server4_lease_resume);
+out:
+
+ return ret;
+}
+
+int
+server4_0_lk(rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfx_lk_req args = {
+ {
+ 0,
+ },
+ };
+ int ret = -1;
+
+ if (!req)
+ return ret;
+
+ ret = rpc_receive_common(req, &frame, &state, NULL, &args, xdr_gfx_lk_req,
+ GF_FOP_LK);
+ if (ret != 0) {
+ goto out;
+ }
+
+ state->resolve.fd_no = args.fd;
+ state->cmd = args.cmd;
+ state->type = args.type;
+ set_resolve_gfid(frame->root->client, state->resolve.gfid, args.gfid);
+
+ 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_smsg(frame->root->client->bound_xl->name, GF_LOG_ERROR, 0,
+ PS_MSG_LOCK_ERROR, "fd=%" PRId64, state->resolve.fd_no,
+ "uuid_utoa=%s", uuid_utoa(state->fd->inode->gfid),
+ "lock type=" PRId32, state->type, NULL);
+ break;
+ }
+
+ if (xdr_to_dict(&args.xdata, &state->xdata)) {
+ SERVER_REQ_SET_ERROR(req, ret);
+ goto out;
+ }
+
+ ret = 0;
+ resolve_and_resume(frame, server4_lk_resume);
+out:
+
+ free(args.flock.lk_owner.lk_owner_val);
+
+ return ret;
+}
+
+int
+server4_0_null(rpcsvc_request_t *req)
+{
+ gfx_common_rsp rsp = {
+ 0,
+ };
+
+ /* Accepted */
+ rsp.op_ret = 0;
+
+ server_submit_reply(NULL, req, &rsp, NULL, 0, NULL,
+ (xdrproc_t)xdr_gfx_common_rsp);
+
+ return 0;
+}
+
+int
+server4_0_lookup(rpcsvc_request_t *req)
+{
+ call_frame_t *frame = NULL;
+ server_state_t *state = NULL;
+ gfx_lookup_req args = {
+ {
+ 0,
+ },
+ };
+ int ret = -1;
+
+ GF_VALIDATE_OR_GOTO("server", req, err);
+
+ ret = rpc_receive_common(req, &frame, &state, NULL, &args,
+ xdr_gfx_lookup_req, GF_FOP_LOOKUP);
+ if (ret != 0) {
+ goto err;
+ }
+
+ state->resolve.type = RESOLVE_DONTCARE;
+
+ if (args.bname && strcmp(args.bname, "")) {
+ set_resolve_gfid(frame->root->client, state->resolve.pargfid,
+ args.pargfid);
+ state->resolve.bname = gf_strdup(args.bname);
+ } else {
+ set_resolve_gfid(frame->root->client, state->resolve.gfid, args.gfid);
+ }
+
+ if (xdr_to_dict(&args.xdata, &state->xdata)) {
+ SERVER_REQ_SET_ERROR(req, ret);
+ goto err;
+ }
+
+ ret = 0;
+ resolve_and_resume(frame, server4_lookup_resume);
+
+err:
+ free(args.bname);
+
+ return ret;
+}
+
+int
+server4_0_statfs(rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfx_statfs_req args = {
+ {
+ 0,
+ },
+ };
+ int ret = -1;
+
+ if (!req)
+ return ret;
+
+ ret = rpc_receive_common(req, &frame, &state, NULL, &args,
+ xdr_gfx_statfs_req, GF_FOP_STATFS);
+ if (ret != 0) {
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ set_resolve_gfid(frame->root->client, state->resolve.gfid, args.gfid);
+
+ if (xdr_to_dict(&args.xdata, &state->xdata)) {
+ SERVER_REQ_SET_ERROR(req, ret);
+ goto out;
+ }
+
+ ret = 0;
+ resolve_and_resume(frame, server4_statfs_resume);
+out:
+
+ return ret;
+}
+
+int
+server4_0_getactivelk(rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfx_getactivelk_req args = {
+ {
+ 0,
+ },
+ };
+ int ret = -1;
+
+ if (!req)
+ return ret;
+
+ ret = rpc_receive_common(req, &frame, &state, NULL, &args,
+ xdr_gfx_getactivelk_req, GF_FOP_GETACTIVELK);
+ if (ret != 0) {
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ set_resolve_gfid(frame->root->client, state->resolve.gfid, args.gfid);
+
+ /* here, dict itself works as xdata */
+ if (xdr_to_dict(&args.xdata, &state->xdata)) {
+ SERVER_REQ_SET_ERROR(req, ret);
+ goto out;
+ }
+
+ ret = 0;
+ resolve_and_resume(frame, server4_getactivelk_resume);
+out:
+
+ return ret;
+}
+
+int
+server4_0_setactivelk(rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfx_setactivelk_req args = {
+ {
+ 0,
+ },
+ };
+ int ret = -1;
+
+ if (!req)
+ return ret;
+
+ ret = rpc_receive_common(req, &frame, &state, NULL, &args,
+ xdr_gfx_setactivelk_req, GF_FOP_SETACTIVELK);
+ if (ret != 0) {
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ set_resolve_gfid(frame->root->client, state->resolve.gfid, args.gfid);
+
+ /* here, dict itself works as xdata */
+ if (xdr_to_dict(&args.xdata, &state->xdata)) {
+ SERVER_REQ_SET_ERROR(req, ret);
+ goto out;
+ }
+
+ ret = unserialize_req_locklist_v2(&args, &state->locklist);
+ if (ret)
+ goto out;
+
+ ret = 0;
+
+ resolve_and_resume(frame, server4_setactivelk_resume);
+out:
+ return ret;
+}
+
+int
+server4_0_namelink(rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfx_namelink_req args = {
+ {
+ 0,
+ },
+ };
+ int ret = -1;
+
+ if (!req)
+ return ret;
+
+ ret = rpc_receive_common(req, &frame, &state, NULL, &args,
+ xdr_gfx_namelink_req, GF_FOP_NAMELINK);
+
+ if (ret != 0)
+ goto out;
+
+ state->resolve.bname = gf_strdup(args.bname);
+ memcpy(state->resolve.pargfid, args.pargfid, sizeof(uuid_t));
+
+ state->resolve.type = RESOLVE_NOT;
+
+ if (xdr_to_dict(&args.xdata, &state->xdata)) {
+ SERVER_REQ_SET_ERROR(req, ret);
+ goto out;
+ }
+ ret = 0;
+ resolve_and_resume(frame, server4_namelink_resume);
+
+out:
+ return ret;
+}
+
+int
+server4_0_icreate(rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfx_icreate_req args = {
+ {
+ 0,
+ },
+ };
+ int ret = -1;
+ uuid_t gfid = {
+ 0,
+ };
+
+ if (!req)
+ return ret;
+
+ ret = rpc_receive_common(req, &frame, &state, NULL, &args,
+ xdr_gfx_icreate_req, GF_FOP_ICREATE);
+
+ if (ret != 0)
+ goto out;
+
+ memcpy(gfid, args.gfid, sizeof(uuid_t));
+
+ state->mode = args.mode;
+ gf_asprintf(&state->resolve.bname, INODE_PATH_FMT, uuid_utoa(gfid));
+
+ /* parent is an auxiliary inode number */
+ memset(state->resolve.pargfid, 0, sizeof(uuid_t));
+ state->resolve.pargfid[15] = GF_AUXILLARY_PARGFID;
+
+ state->resolve.type = RESOLVE_NOT;
+
+ if (xdr_to_dict(&args.xdata, &state->xdata)) {
+ SERVER_REQ_SET_ERROR(req, ret);
+ goto out;
+ }
+ ret = 0;
+ resolve_and_resume(frame, server4_icreate_resume);
+
+out:
+ return ret;
+}
+
+int
+server4_0_fsetattr(rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfx_fsetattr_req args = {
+ {0},
+ };
+ int ret = -1;
+
+ if (!req)
+ return ret;
+
+ ret = rpc_receive_common(req, &frame, &state, NULL, &args,
+ xdr_gfx_fsetattr_req, GF_FOP_FSETATTR);
+ if (ret != 0) {
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ state->resolve.fd_no = args.fd;
+ memcpy(state->resolve.gfid, args.gfid, 16);
+
+ gfx_stat_to_iattx(&args.stbuf, &state->stbuf);
+ state->valid = args.valid;
+
+ if (xdr_to_dict(&args.xdata, &state->xdata)) {
+ SERVER_REQ_SET_ERROR(req, ret);
+ goto out;
+ }
+ ret = 0;
+ resolve_and_resume(frame, server4_fsetattr_resume);
+
+out:
+ return ret;
+}
+
+int
+server4_0_rchecksum(rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfx_rchecksum_req args = {
+ {0},
+ };
+ int ret = -1;
+
+ if (!req)
+ return ret;
+
+ ret = rpc_receive_common(req, &frame, &state, NULL, &args,
+ xdr_gfx_rchecksum_req, GF_FOP_RCHECKSUM);
+ if (ret != 0) {
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MAY;
+ state->resolve.fd_no = args.fd;
+ state->offset = args.offset;
+ state->size = args.len;
+
+ memcpy(state->resolve.gfid, args.gfid, 16);
+
+ if (xdr_to_dict(&args.xdata, &state->xdata)) {
+ SERVER_REQ_SET_ERROR(req, ret);
+ goto out;
+ }
+ ret = 0;
+ resolve_and_resume(frame, server4_rchecksum_resume);
+out:
+ return ret;
+}
+
+int
+server4_0_put(rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfx_put_req args = {
+ {
+ 0,
+ },
+ };
+ int ret = -1;
+ ssize_t len = 0;
+ int i = 0;
+
+ if (!req)
+ return ret;
+
+ ret = rpc_receive_common(req, &frame, &state, &len, &args, xdr_gfx_put_req,
+ GF_FOP_PUT);
+ if (ret != 0) {
+ goto out;
+ }
+
+ state->resolve.bname = gf_strdup(args.bname);
+ state->mode = args.mode;
+ state->umask = args.umask;
+ state->flags = gf_flags_to_flags(args.flag);
+ state->offset = args.offset;
+ state->size = args.size;
+ state->iobref = iobref_ref(req->iobref);
+
+ 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];
+ }
+
+ len = iov_length(state->payload_vector, state->payload_count);
+
+ GF_ASSERT(state->size == len);
+
+ set_resolve_gfid(frame->root->client, state->resolve.pargfid, args.pargfid);
+
+ if (state->flags & O_EXCL) {
+ state->resolve.type = RESOLVE_NOT;
+ } else {
+ state->resolve.type = RESOLVE_DONTCARE;
+ }
+
+ if (xdr_to_dict(&args.xattr, &state->dict)) {
+ SERVER_REQ_SET_ERROR(req, ret);
+ goto out;
+ }
+ if (xdr_to_dict(&args.xdata, &state->xdata)) {
+ SERVER_REQ_SET_ERROR(req, ret);
+ goto out;
+ }
+
+ ret = 0;
+ resolve_and_resume(frame, server4_put_resume);
+
+out:
+ free(args.bname);
+
+ return ret;
+}
+
+int
+server4_0_compound(rpcsvc_request_t *req)
+{
+ int ret = -1;
+ SERVER_REQ_SET_ERROR(req, ret);
+ return ret;
+}
+
+int
+server4_0_copy_file_range(rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfx_copy_file_range_req args = {
+ {
+ 0,
+ },
+ };
+ ssize_t len = 0;
+ int ret = -1;
+
+ if (!req)
+ return ret;
+
+ ret = rpc_receive_common(req, &frame, &state, &len, &args,
+ xdr_gfx_copy_file_range_req,
+ GF_FOP_COPY_FILE_RANGE);
+ if (ret != 0) {
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ state->resolve.fd_no = args.fd_in;
+ state->resolve2.type = RESOLVE_MUST; /*making this resolve must */
+ state->resolve2.fd_no = args.fd_out;
+ state->off_in = args.off_in;
+ state->off_out = args.off_out;
+ state->size = args.size;
+ state->flags = args.flag;
+ memcpy(state->resolve.gfid, args.gfid1, 16);
+ memcpy(state->resolve2.gfid, args.gfid2, 16);
+
+ if (xdr_to_dict(&args.xdata, &state->xdata)) {
+ SERVER_REQ_SET_ERROR(req, ret);
+ goto out;
+ }
+
+ ret = 0;
+ resolve_and_resume(frame, server4_copy_file_range_resume);
+out:
+
+ return ret;
+}
+
+static rpcsvc_actor_t glusterfs4_0_fop_actors[] = {
+ [GFS3_OP_NULL] = {"NULL", server_null, NULL, GFS3_OP_NULL, 0},
+ [GFS3_OP_STAT] = {"STAT", server4_0_stat, NULL, GFS3_OP_STAT, 0},
+ [GFS3_OP_READLINK] = {"READLINK", server4_0_readlink, NULL,
+ GFS3_OP_READLINK, 0},
+ [GFS3_OP_MKNOD] = {"MKNOD", server4_0_mknod, NULL, GFS3_OP_MKNOD, 0},
+ [GFS3_OP_MKDIR] = {"MKDIR", server4_0_mkdir, NULL, GFS3_OP_MKDIR, 0},
+ [GFS3_OP_UNLINK] = {"UNLINK", server4_0_unlink, NULL, GFS3_OP_UNLINK, 0},
+ [GFS3_OP_RMDIR] = {"RMDIR", server4_0_rmdir, NULL, GFS3_OP_RMDIR, 0},
+ [GFS3_OP_SYMLINK] = {"SYMLINK", server4_0_symlink, NULL, GFS3_OP_SYMLINK,
+ 0},
+ [GFS3_OP_RENAME] = {"RENAME", server4_0_rename, NULL, GFS3_OP_RENAME, 0},
+ [GFS3_OP_LINK] = {"LINK", server4_0_link, NULL, GFS3_OP_LINK, 0},
+ [GFS3_OP_TRUNCATE] = {"TRUNCATE", server4_0_truncate, NULL,
+ GFS3_OP_TRUNCATE, 0},
+ [GFS3_OP_OPEN] = {"OPEN", server4_0_open, NULL, GFS3_OP_OPEN, 0},
+ [GFS3_OP_READ] = {"READ", server4_0_readv, NULL, GFS3_OP_READ, 0},
+ [GFS3_OP_WRITE] = {"WRITE", server4_0_writev, server4_0_writev_vecsizer,
+ GFS3_OP_WRITE, 0},
+ [GFS3_OP_STATFS] = {"STATFS", server4_0_statfs, NULL, GFS3_OP_STATFS, 0},
+ [GFS3_OP_FLUSH] = {"FLUSH", server4_0_flush, NULL, GFS3_OP_FLUSH, 0},
+ [GFS3_OP_FSYNC] = {"FSYNC", server4_0_fsync, NULL, GFS3_OP_FSYNC, 0},
+ [GFS3_OP_GETXATTR] = {"GETXATTR", server4_0_getxattr, NULL,
+ GFS3_OP_GETXATTR, 0},
+ [GFS3_OP_SETXATTR] = {"SETXATTR", server4_0_setxattr, NULL,
+ GFS3_OP_SETXATTR, 0},
+ [GFS3_OP_REMOVEXATTR] = {"REMOVEXATTR", server4_0_removexattr, NULL,
+ GFS3_OP_REMOVEXATTR, 0},
+ [GFS3_OP_OPENDIR] = {"OPENDIR", server4_0_opendir, NULL, GFS3_OP_OPENDIR,
+ 0},
+ [GFS3_OP_FSYNCDIR] = {"FSYNCDIR", server4_0_fsyncdir, NULL,
+ GFS3_OP_FSYNCDIR, 0},
+ [GFS3_OP_ACCESS] = {"ACCESS", server4_0_access, NULL, GFS3_OP_ACCESS, 0},
+ [GFS3_OP_CREATE] = {"CREATE", server4_0_create, NULL, GFS3_OP_CREATE, 0},
+ [GFS3_OP_FTRUNCATE] = {"FTRUNCATE", server4_0_ftruncate, NULL,
+ GFS3_OP_FTRUNCATE, 0},
+ [GFS3_OP_FSTAT] = {"FSTAT", server4_0_fstat, NULL, GFS3_OP_FSTAT, 0},
+ [GFS3_OP_LK] = {"LK", server4_0_lk, NULL, GFS3_OP_LK, 0},
+ [GFS3_OP_LOOKUP] = {"LOOKUP", server4_0_lookup, NULL, GFS3_OP_LOOKUP, 0},
+ [GFS3_OP_READDIR] = {"READDIR", server4_0_readdir, NULL, GFS3_OP_READDIR,
+ 0},
+ [GFS3_OP_INODELK] = {"INODELK", server4_0_inodelk, NULL, GFS3_OP_INODELK,
+ 0},
+ [GFS3_OP_FINODELK] = {"FINODELK", server4_0_finodelk, NULL,
+ GFS3_OP_FINODELK, 0},
+ [GFS3_OP_ENTRYLK] = {"ENTRYLK", server4_0_entrylk, NULL, GFS3_OP_ENTRYLK,
+ 0},
+ [GFS3_OP_FENTRYLK] = {"FENTRYLK", server4_0_fentrylk, NULL,
+ GFS3_OP_FENTRYLK, 0},
+ [GFS3_OP_XATTROP] = {"XATTROP", server4_0_xattrop, NULL, GFS3_OP_XATTROP,
+ 0},
+ [GFS3_OP_FXATTROP] = {"FXATTROP", server4_0_fxattrop, NULL,
+ GFS3_OP_FXATTROP, 0},
+ [GFS3_OP_FGETXATTR] = {"FGETXATTR", server4_0_fgetxattr, NULL,
+ GFS3_OP_FGETXATTR, 0},
+ [GFS3_OP_FSETXATTR] = {"FSETXATTR", server4_0_fsetxattr, NULL,
+ GFS3_OP_FSETXATTR, 0},
+ [GFS3_OP_RCHECKSUM] = {"RCHECKSUM", server4_0_rchecksum, NULL,
+ GFS3_OP_RCHECKSUM, 0},
+ [GFS3_OP_SETATTR] = {"SETATTR", server4_0_setattr, NULL, GFS3_OP_SETATTR,
+ 0},
+ [GFS3_OP_FSETATTR] = {"FSETATTR", server4_0_fsetattr, NULL,
+ GFS3_OP_FSETATTR, 0},
+ [GFS3_OP_READDIRP] = {"READDIRP", server4_0_readdirp, NULL,
+ GFS3_OP_READDIRP, 0},
+ [GFS3_OP_RELEASE] = {"RELEASE", server4_0_release, NULL, GFS3_OP_RELEASE,
+ 0},
+ [GFS3_OP_RELEASEDIR] = {"RELEASEDIR", server4_0_releasedir, NULL,
+ GFS3_OP_RELEASEDIR, 0},
+ [GFS3_OP_FREMOVEXATTR] = {"FREMOVEXATTR", server4_0_fremovexattr, NULL,
+ GFS3_OP_FREMOVEXATTR, 0},
+ [GFS3_OP_FALLOCATE] = {"FALLOCATE", server4_0_fallocate, NULL, DRC_NA,
+ GFS3_OP_FALLOCATE, 0},
+ [GFS3_OP_DISCARD] = {"DISCARD", server4_0_discard, NULL, DRC_NA,
+ GFS3_OP_DISCARD, 0},
+ [GFS3_OP_ZEROFILL] = {"ZEROFILL", server4_0_zerofill, NULL, DRC_NA,
+ GFS3_OP_ZEROFILL, 0},
+ [GFS3_OP_IPC] = {"IPC", server4_0_ipc, NULL, DRC_NA, GFS3_OP_IPC, 0},
+ [GFS3_OP_SEEK] = {"SEEK", server4_0_seek, NULL, DRC_NA, GFS3_OP_SEEK, 0},
+ [GFS3_OP_LEASE] = {"LEASE", server4_0_lease, NULL, DRC_NA, GFS3_OP_LEASE,
+ 0},
+ [GFS3_OP_GETACTIVELK] = {"GETACTIVELK", server4_0_getactivelk, NULL, DRC_NA,
+ GFS3_OP_GETACTIVELK, 0},
+ [GFS3_OP_SETACTIVELK] = {"SETACTIVELK", server4_0_setactivelk, NULL, DRC_NA,
+ GFS3_OP_SETACTIVELK, 0},
+ [GFS3_OP_COMPOUND] = {"COMPOUND", server4_0_compound, NULL, DRC_NA,
+ GFS3_OP_COMPOUND, 0},
+ [GFS3_OP_ICREATE] = {"ICREATE", server4_0_icreate, NULL, DRC_NA,
+ GFS3_OP_ICREATE, 0},
+ [GFS3_OP_NAMELINK] = {"NAMELINK", server4_0_namelink, NULL, DRC_NA,
+ GFS3_OP_NAMELINK, 0},
+ [GFS3_OP_COPY_FILE_RANGE] = {"COPY-FILE-RANGE", server4_0_copy_file_range,
+ NULL, DRC_NA, GFS3_OP_COPY_FILE_RANGE, 0},
+};
+
+struct rpcsvc_program glusterfs4_0_fop_prog = {
+ .progname = "GlusterFS 4.x v1",
+ .prognum = GLUSTER_FOP_PROGRAM,
+ .progver = GLUSTER_FOP_VERSION_v2,
+ .numactors = GLUSTER_FOP_PROCCNT,
+ .actors = glusterfs4_0_fop_actors,
+ .ownthread = _gf_true,
+};
diff --git a/xlators/protocol/server/src/server.c b/xlators/protocol/server/src/server.c
new file mode 100644
index 00000000000..721968004a0
--- /dev/null
+++ b/xlators/protocol/server/src/server.c
@@ -0,0 +1,1887 @@
+/*
+ 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.
+*/
+
+#include <sys/time.h>
+#include <sys/resource.h>
+
+#include "server.h"
+#include "server-helpers.h"
+#include "glusterfs3-xdr.h"
+#include <glusterfs/call-stub.h>
+#include <glusterfs/statedump.h>
+#include <glusterfs/defaults.h>
+#include "authenticate.h"
+#include <glusterfs/gf-event.h>
+#include <glusterfs/events.h>
+#include "server-messages.h"
+#include "rpc-clnt.h"
+
+rpcsvc_cbk_program_t server_cbk_prog = {
+ .progname = "Gluster Callback",
+ .prognum = GLUSTER_CBK_PROGRAM,
+ .progver = GLUSTER_CBK_VERSION,
+};
+
+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_msg_callingfn(THIS->name, GF_LOG_ERROR, ENOMEM, PS_MSG_NO_MEMORY,
+ "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_msg_callingfn("", GF_LOG_ERROR, 0, PS_MSG_ENCODE_MSG_FAILED,
+ "Failed to encode message");
+ req->rpc_err = GARBAGE_ARGS;
+ retlen = 0;
+ }
+ }
+ outmsg->iov_len = retlen;
+ret:
+ 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_VALIDATE_OR_GOTO("server", req, ret);
+
+ if (frame) {
+ state = CALL_STATE(frame);
+ frame->local = NULL;
+ client = frame->root->client;
+ }
+
+ if (!iobref) {
+ iobref = iobref_new();
+ if (!iobref) {
+ goto ret;
+ }
+
+ new_iobref = 1;
+ }
+
+ iob = gfs_serialize_reply(req, arg, &rsp, xdrproc);
+ if (!iob) {
+ gf_smsg("", GF_LOG_ERROR, 0, PS_MSG_SERIALIZE_REPLY_FAILED, NULL);
+ goto ret;
+ }
+
+ iobref_add(iobref, iob);
+
+ /* 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_msg_callingfn("", GF_LOG_ERROR, 0, PS_MSG_REPLY_SUBMIT_FAILED,
+ "Reply submission failed");
+ if (frame && client) {
+ server_connection_cleanup(frame->this, client,
+ INTERNAL_LOCKS | POSIX_LOCKS, NULL);
+ } else {
+ gf_msg_callingfn("", GF_LOG_ERROR, 0, PS_MSG_REPLY_SUBMIT_FAILED,
+ "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 (client)
+ gf_client_unref(client);
+
+ if (frame)
+ STACK_DESTROY(frame->root);
+
+ if (new_iobref)
+ iobref_unref(iobref);
+
+ if (state)
+ free_state(state);
+
+ return ret;
+}
+
+int
+server_priv_to_dict(xlator_t *this, dict_t *dict, char *brickname)
+{
+ server_conf_t *conf = NULL;
+ rpc_transport_t *xprt = NULL;
+ peer_info_t *peerinfo = NULL;
+ char key[32] = {
+ 0,
+ };
+ int keylen;
+ 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)
+ {
+ if ((xprt->xl_private) && (xprt->xl_private->bound_xl) &&
+ (xprt->xl_private->bound_xl->name) && (brickname) &&
+ (!strcmp(brickname, xprt->xl_private->bound_xl->name))) {
+ peerinfo = &xprt->peerinfo;
+ keylen = snprintf(key, sizeof(key), "client%d.hostname", count);
+ ret = dict_set_strn(dict, key, keylen, peerinfo->identifier);
+ if (ret)
+ goto unlock;
+
+ snprintf(key, sizeof(key), "client%d.bytesread", count);
+ ret = dict_set_uint64(dict, key, xprt->total_bytes_read);
+ if (ret)
+ goto unlock;
+
+ snprintf(key, sizeof(key), "client%d.byteswrite", count);
+ ret = dict_set_uint64(dict, key, xprt->total_bytes_write);
+ if (ret)
+ goto unlock;
+
+ snprintf(key, sizeof(key), "client%d.opversion", count);
+ ret = dict_set_uint32(dict, key, peerinfo->max_op_version);
+ if (ret)
+ goto unlock;
+
+ keylen = snprintf(key, sizeof(key), "client%d.name", count);
+ ret = dict_set_strn(dict, key, keylen,
+ xprt->xl_private->client_name);
+ if (ret)
+ goto unlock;
+
+ count++;
+ }
+ }
+ }
+unlock:
+ pthread_mutex_unlock(&conf->mutex);
+ if (ret)
+ goto out;
+
+ ret = dict_set_int32_sizen(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("%s", 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);
+
+ rpcsvc_statedump(conf->rpc);
+
+ 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_smsg("server", GF_LOG_WARNING, 0, PS_MSG_AUTH_IP_ERROR, NULL);
+ }
+ ret = dict_set_dynptr(auth_dict, tmp, NULL, 0);
+ if (ret < 0) {
+ gf_msg_debug("server", 0,
+ "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;
+
+ xl = tmp;
+
+ tail = strtail(k, "auth.");
+ if (!tail)
+ goto out;
+
+ if (strncmp(tail, "addr.", 5) != 0) {
+ gf_smsg(xl->name, GF_LOG_TRACE, 0, PS_MSG_SKIP_FORMAT_CHK, "option=%s",
+ k, NULL);
+ goto out;
+ }
+
+ /* fast fwd through 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
+ */
+ ret = xlator_option_validate_addr_list(xl, "auth-*", v->data, NULL,
+ NULL);
+ if (ret)
+ gf_smsg(xl->name, GF_LOG_ERROR, 0, PS_MSG_INTERNET_ADDR_ERROR,
+ "data=%s", v->data, 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_smsg(this->name, GF_LOG_ERROR, 0, PS_MSG_AUTHENTICATE_ERROR,
+ "name=%s", trav->xlator->name, NULL);
+ break;
+ }
+ trav = trav->next;
+ }
+
+out:
+ return error;
+}
+
+void
+server_call_xlator_mem_cleanup(xlator_t *this, char *victim_name)
+{
+ pthread_t th_id = {
+ 0,
+ };
+ int th_ret = -1;
+ server_cleanup_xprt_arg_t *arg = NULL;
+
+ if (!victim_name)
+ return;
+
+ gf_log(this->name, GF_LOG_INFO, "Create graph janitor thread for brick %s",
+ victim_name);
+
+ arg = calloc(1, sizeof(*arg));
+ arg->this = this;
+ arg->victim_name = strdup(victim_name);
+ if (!arg->victim_name) {
+ gf_smsg(this->name, GF_LOG_CRITICAL, ENOMEM, LG_MSG_NO_MEMORY,
+ "Memory allocation is failed");
+ free(arg);
+ return;
+ }
+
+ th_ret = gf_thread_create_detached(&th_id, server_graph_janitor_threads,
+ arg, "graphjanitor");
+ if (th_ret) {
+ gf_log(this->name, GF_LOG_ERROR,
+ "graph janitor Thread"
+ " creation is failed for brick %s",
+ victim_name);
+ free(arg->victim_name);
+ free(arg);
+ }
+}
+
+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;
+ char *auth_path = NULL;
+ int ret = -1;
+ char *xlator_name = NULL;
+ uint64_t xprtrefcount = 0;
+ gf_boolean_t fd_exist = _gf_false;
+
+ this = xl;
+ trans = data;
+
+ if (!this || !data || !this->ctx || !this->ctx->active) {
+ gf_msg_callingfn("server", GF_LOG_WARNING, 0, PS_MSG_RPC_NOTIFY_ERROR,
+ "Calling rpc_notify without initializing");
+ goto out;
+ }
+
+ 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;
+ */
+
+ pthread_mutex_lock(&conf->mutex);
+ rpc_transport_ref(trans);
+ list_add_tail(&trans->list, &conf->xprt_list);
+ pthread_mutex_unlock(&conf->mutex);
+
+ break;
+ }
+ case RPCSVC_EVENT_DISCONNECT:
+
+ /* A DISCONNECT event could come without an ACCEPT event
+ * happening for this transport. This happens when the server is
+ * expecting encrypted connections by the client tries to
+ * connect unecnrypted
+ */
+ if (list_empty(&trans->list)) {
+ break;
+ }
+
+ /* Set the disconnect_progress flag to 1 to avoid races
+ during brick detach while brick mux is enabled
+ */
+ GF_ATOMIC_INIT(trans->disconnect_progress, 1);
+ /* 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);
+ client = trans->xl_private;
+ if (!client)
+ list_del_init(&trans->list);
+ pthread_mutex_unlock(&conf->mutex);
+
+ if (!client)
+ goto unref_transport;
+
+ gf_smsg(this->name, GF_LOG_INFO, 0, PS_MSG_CLIENT_DISCONNECTING,
+ "client-uid=%s", client->client_uid, NULL);
+
+ ret = dict_get_str_sizen(this->options, "auth-path", &auth_path);
+ if (ret) {
+ gf_smsg(this->name, GF_LOG_WARNING, 0, PS_MSG_DICT_GET_FAILED,
+ "type=auth-path", NULL);
+ auth_path = NULL;
+ }
+
+ gf_client_ref(client);
+ gf_client_put(client, &detached);
+ if (detached) {
+ server_connection_cleanup(
+ this, client, INTERNAL_LOCKS | POSIX_LOCKS, &fd_exist);
+ gf_event(EVENT_CLIENT_DISCONNECT,
+ "client_uid=%s;"
+ "client_identifier=%s;server_identifier=%s;"
+ "brick_path=%s",
+ client->client_uid, trans->peerinfo.identifier,
+ trans->myinfo.identifier, auth_path);
+ }
+
+ /*
+ * gf_client_unref will be done while handling
+ * RPC_EVENT_TRANSPORT_DESTROY
+ */
+
+ unref_transport:
+ /* rpc_transport_unref() causes a RPCSVC_EVENT_TRANSPORT_DESTROY
+ * to be called in blocking manner
+ * So no code should ideally be after this unref, Call
+ * rpc_transport_unref only while cleanup_starting flag is not set
+ * otherwise transport_unref will be call by either
+ * server_connection_cleanup_flush_cbk or server_submit_reply at the
+ * time of freeing state
+ */
+ if (!client || !detached || !fd_exist)
+ rpc_transport_unref(trans);
+ break;
+ case RPCSVC_EVENT_TRANSPORT_DESTROY:
+ pthread_mutex_lock(&conf->mutex);
+ client = trans->xl_private;
+ list_del_init(&trans->list);
+ pthread_mutex_unlock(&conf->mutex);
+ if (!client)
+ break;
+
+ if (client->bound_xl && client->bound_xl->cleanup_starting) {
+ xprtrefcount = GF_ATOMIC_GET(client->bound_xl->xprtrefcnt);
+ if (xprtrefcount > 0) {
+ xprtrefcount = GF_ATOMIC_DEC(client->bound_xl->xprtrefcnt);
+ if (xprtrefcount == 0)
+ xlator_name = gf_strdup(client->bound_xl->name);
+ }
+ }
+
+ gf_client_unref(client);
+
+ if (xlator_name) {
+ server_call_xlator_mem_cleanup(this, xlator_name);
+ GF_FREE(xlator_name);
+ }
+
+ trans->xl_private = NULL;
+ break;
+ default:
+ break;
+ }
+
+out:
+ return 0;
+}
+
+void *
+server_graph_janitor_threads(void *data)
+{
+ xlator_t *victim = NULL;
+ xlator_t *this = NULL;
+ server_conf_t *conf = NULL;
+ glusterfs_ctx_t *ctx = NULL;
+ char *victim_name = NULL;
+ server_cleanup_xprt_arg_t *arg = NULL;
+ gf_boolean_t victim_found = _gf_false;
+ xlator_list_t **trav_p = NULL;
+ xlator_t *top = NULL;
+ uint32_t parent_down = 0;
+
+ GF_ASSERT(data);
+
+ arg = data;
+ this = arg->this;
+ victim_name = arg->victim_name;
+ THIS = arg->this;
+ conf = this->private;
+
+ ctx = THIS->ctx;
+ GF_VALIDATE_OR_GOTO(this->name, ctx, out);
+
+ top = this->ctx->active->first;
+ LOCK(&ctx->volfile_lock);
+ for (trav_p = &top->children; *trav_p; trav_p = &(*trav_p)->next) {
+ victim = (*trav_p)->xlator;
+ if (victim->cleanup_starting &&
+ strcmp(victim->name, victim_name) == 0) {
+ parent_down = victim->parent_down;
+ victim->parent_down = 1;
+ if (!parent_down)
+ victim_found = _gf_true;
+ break;
+ }
+ }
+ if (victim_found)
+ glusterfs_delete_volfile_checksum(ctx, victim->volfile_id);
+ UNLOCK(&ctx->volfile_lock);
+ if (!victim_found) {
+ gf_log(this->name, GF_LOG_ERROR,
+ "victim brick %s is not"
+ " found in graph",
+ victim_name);
+ goto out;
+ }
+
+ default_notify(victim, GF_EVENT_PARENT_DOWN, victim);
+ if (victim->notify_down) {
+ gf_log(THIS->name, GF_LOG_INFO,
+ "Start call fini for brick"
+ " %s stack",
+ victim->name);
+ xlator_mem_cleanup(victim);
+ rpcsvc_autoscale_threads(ctx, conf->rpc, -1);
+ }
+
+out:
+ free(arg->victim_name);
+ free(arg);
+ return NULL;
+}
+
+int32_t
+server_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_smsg(this->name, GF_LOG_ERROR, ENOMEM, PS_MSG_NO_MEMORY, NULL);
+ 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", "auth.login.*.allow",
+ "auth.login.*.password", "auth.login.*.ssl-allow", 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", "auth.login.*.allow",
+ "auth.login.*.password", "auth.login.*.ssl-allow", 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_check_event_threads(xlator_t *this, server_conf_t *conf, int32_t new)
+{
+ struct event_pool *pool = this->ctx->event_pool;
+ int target;
+
+ target = new + pool->auto_thread_count;
+ conf->event_threads = new;
+
+ if (target == pool->eventthreadcount) {
+ return 0;
+ }
+
+ return gf_event_reconfigure_threads(pool, target);
+}
+
+int
+server_reconfigure(xlator_t *this, dict_t *options)
+{
+ server_conf_t *conf = NULL;
+ rpcsvc_t *rpc_conf;
+ rpcsvc_listener_t *listeners;
+ rpc_transport_t *xprt = NULL;
+ rpc_transport_t *xp_next = NULL;
+ int inode_lru_limit;
+ gf_boolean_t trace;
+ data_t *data;
+ int ret = 0;
+ char *statedump_path = NULL;
+ int32_t new_nthread = 0;
+ char *auth_path = NULL;
+ char *xprt_path = NULL;
+ xlator_t *oldTHIS;
+ xlator_t *kid;
+
+ /*
+ * Since we're not a fop, we can't really count on THIS being set
+ * correctly, and it needs to be or else GF_OPTION_RECONF won't work
+ * (because it won't find our options list). This is another thing
+ * that "just happened" to work before multiplexing, but now we need to
+ * handle it more explicitly.
+ */
+ oldTHIS = THIS;
+ THIS = this;
+
+ conf = this->private;
+
+ if (!conf) {
+ gf_msg_callingfn(this->name, GF_LOG_DEBUG, EINVAL, PS_MSG_INVALID_ENTRY,
+ "conf == null!!!");
+ goto out;
+ }
+
+ /*
+ * For some of the auth/rpc stuff, we need to operate on the correct
+ * child, but for other stuff we need to operate on the server
+ * translator itself.
+ */
+ kid = NULL;
+ if (dict_get_str_sizen(options, "auth-path", &auth_path) == 0) {
+ kid = get_xlator_by_name(this, auth_path);
+ }
+ if (!kid) {
+ kid = this;
+ }
+
+ if (dict_get_int32_sizen(options, "inode-lru-limit", &inode_lru_limit) ==
+ 0) {
+ conf->inode_lru_limit = inode_lru_limit;
+ gf_msg_trace(this->name, 0,
+ "Reconfigured inode-lru-limit to "
+ "%d",
+ conf->inode_lru_limit);
+
+ /* traverse through the xlator graph. For each xlator in the
+ graph check whether it is a bound_xl or not (bound_xl means
+ the xlator will have its itable pointer set). If so, then
+ set the lru limit for the itable.
+ */
+ xlator_foreach(this, xlator_set_inode_lru_limit, &inode_lru_limit);
+ }
+
+ data = dict_get_sizen(options, "trace");
+ if (data) {
+ ret = gf_string2boolean(data->data, &trace);
+ if (ret != 0) {
+ gf_smsg(this->name, GF_LOG_WARNING, EINVAL, PS_MSG_INVALID_ENTRY,
+ NULL);
+ ret = -1;
+ goto out;
+ }
+ conf->trace = trace;
+ gf_msg_trace(this->name, 0, "Reconfigured trace to %d", conf->trace);
+ }
+
+ GF_OPTION_RECONF("statedump-path", statedump_path, options, path, do_auth);
+ if (!statedump_path) {
+ gf_smsg(this->name, GF_LOG_ERROR, 0, PS_MSG_STATEDUMP_PATH_ERROR, NULL);
+ goto do_auth;
+ }
+ gf_path_strip_trailing_slashes(statedump_path);
+ GF_FREE(this->ctx->statedump_path);
+ this->ctx->statedump_path = gf_strdup(statedump_path);
+
+do_auth:
+ if (!conf->auth_modules)
+ conf->auth_modules = dict_new();
+
+ dict_foreach(options, get_auth_types, conf->auth_modules);
+ ret = validate_auth_options(kid, options);
+ if (ret == -1) {
+ /* logging already done in validate_auth_options function. */
+ goto out;
+ }
+
+ dict_foreach(kid->options, _delete_auth_opt, NULL);
+ dict_foreach(options, _copy_auth_opt, kid->options);
+
+ ret = gf_auth_init(kid, conf->auth_modules);
+ if (ret) {
+ dict_unref(conf->auth_modules);
+ goto out;
+ }
+
+ GF_OPTION_RECONF("manage-gids", conf->server_manage_gids, options, bool,
+ do_rpc);
+
+ GF_OPTION_RECONF("gid-timeout", conf->gid_cache_timeout, options, int32,
+ do_rpc);
+ if (gid_cache_reconf(&conf->gid_cache, conf->gid_cache_timeout) < 0) {
+ gf_smsg(this->name, GF_LOG_ERROR, 0, PS_MSG_GRP_CACHE_ERROR, NULL);
+ goto do_rpc;
+ }
+
+do_rpc:
+ rpc_conf = conf->rpc;
+ if (!rpc_conf) {
+ gf_smsg(this->name, GF_LOG_ERROR, 0, PS_MSG_RPC_CONF_ERROR, NULL);
+ goto out;
+ }
+
+ ret = rpcsvc_auth_reconf(rpc_conf, options);
+ if (ret == -1) {
+ gf_log(GF_RPCSVC, GF_LOG_ERROR, "Failed to reconfigure authentication");
+ goto out;
+ }
+
+ GF_OPTION_RECONF("strict-auth-accept", conf->strict_auth_enabled, options,
+ bool, out);
+
+ GF_OPTION_RECONF("dynamic-auth", conf->dync_auth, options, bool, out);
+
+ if (conf->dync_auth) {
+ pthread_mutex_lock(&conf->mutex);
+ {
+ /*
+ * Disconnecting will (usually) drop the last ref,
+ * which will cause the transport to be unlinked and
+ * freed while we're still traversing, which will cause
+ * us to crash unless we use list_for_each_entry_safe.
+ */
+ list_for_each_entry_safe(xprt, xp_next, &conf->xprt_list, list)
+ {
+ /* check for client authorization */
+ if (!xprt->clnt_options) {
+ /* If clnt_options dictionary is null,
+ * which means for this transport
+ * server_setvolume was not called.
+ *
+ * So here we can skip authentication
+ * because server_setvolume will do
+ * gf_authenticate.
+ *
+ */
+ continue;
+ }
+ /*
+ * Make sure we're only operating on
+ * connections that are relevant to the brick
+ * we're reconfiguring.
+ */
+ if (dict_get_str_sizen(xprt->clnt_options, "remote-subvolume",
+ &xprt_path) != 0) {
+ continue;
+ }
+ if (strcmp(xprt_path, auth_path) != 0) {
+ continue;
+ }
+ ret = gf_authenticate(xprt->clnt_options, options,
+ conf->auth_modules);
+ if (ret == AUTH_ACCEPT) {
+ gf_smsg(kid->name, GF_LOG_TRACE, 0, PS_MSG_CLIENT_ACCEPTED,
+ NULL);
+ } else {
+ gf_event(EVENT_CLIENT_AUTH_REJECT,
+ "client_uid=%s;"
+ "client_identifier=%s;"
+ "server_identifier=%s;"
+ "brick_path=%s",
+ xprt->xl_private->client_uid,
+ xprt->peerinfo.identifier, xprt->myinfo.identifier,
+ auth_path);
+ gf_smsg(this->name, GF_LOG_INFO, EACCES,
+ PS_MSG_UNAUTHORIZED_CLIENT,
+ "peerinfo-identifier=%s", xprt->peerinfo.identifier,
+ NULL);
+ rpc_transport_disconnect(xprt, _gf_false);
+ }
+ }
+ }
+ pthread_mutex_unlock(&conf->mutex);
+ }
+
+ ret = rpcsvc_set_outstanding_rpc_limit(
+ rpc_conf, options, RPCSVC_DEFAULT_OUTSTANDING_RPC_LIMIT);
+ if (ret < 0) {
+ gf_smsg(this->name, GF_LOG_ERROR, 0, PS_MSG_RECONFIGURE_FAILED, NULL);
+ goto out;
+ }
+
+ 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_smsg(this->name, GF_LOG_ERROR, 0, PS_MSG_TRANSPORT_ERROR,
+ NULL);
+ }
+ }
+
+ /*
+ * Update:
+ * We don't need to reset auto_thread_count since it has been derived
+ * out of the total bricks attached. We can reconfigure event threads
+ * but not auto threads.
+ */
+
+ GF_OPTION_RECONF("event-threads", new_nthread, options, int32, out);
+ ret = server_check_event_threads(this, conf, new_nthread);
+ if (ret)
+ goto out;
+
+out:
+ THIS = oldTHIS;
+ gf_msg_debug("", 0, "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;
+}
+
+int32_t
+server_dump_metrics(xlator_t *this, int fd)
+{
+ rpc_transport_t *xprt = NULL;
+ server_conf_t *conf = NULL;
+ client_t *client = NULL;
+
+ conf = this->private;
+
+ pthread_mutex_lock(&conf->mutex);
+
+ list_for_each_entry(xprt, &conf->xprt_list, list)
+ {
+ client = xprt->xl_private;
+
+ if (!client)
+ continue;
+
+ dprintf(fd, "%s.total.rpc.%s.bytes_read %" PRIu64 "\n", this->name,
+ client->client_uid, xprt->total_bytes_read);
+ dprintf(fd, "%s.total.rpc.%s.bytes_write %" PRIu64 "\n", this->name,
+ client->client_uid, xprt->total_bytes_write);
+ dprintf(fd, "%s.total.rpc.%s.outstanding %d\n", this->name,
+ client->client_uid, xprt->outstanding_rpc_count);
+ }
+
+ pthread_mutex_unlock(&conf->mutex);
+
+ return 0;
+}
+
+void
+server_cleanup(xlator_t *this, server_conf_t *conf)
+{
+ if (!this || !conf)
+ return;
+
+ LOCK_DESTROY(&conf->itable_lock);
+ pthread_mutex_destroy(&conf->mutex);
+
+ if (this->ctx->event_pool) {
+ /* Free the event pool */
+ (void)gf_event_pool_destroy(this->ctx->event_pool);
+ }
+
+ if (dict_get_sizen(this->options, "config-directory")) {
+ GF_FREE(conf->conf_dir);
+ conf->conf_dir = NULL;
+ }
+
+ if (conf->child_status) {
+ GF_FREE(conf->child_status);
+ conf->child_status = NULL;
+ }
+
+ if (this->ctx->statedump_path) {
+ GF_FREE(this->ctx->statedump_path);
+ this->ctx->statedump_path = NULL;
+ }
+
+ if (conf->auth_modules) {
+ gf_auth_fini(conf->auth_modules);
+ dict_unref(conf->auth_modules);
+ }
+
+ if (conf->rpc) {
+ (void)rpcsvc_destroy(conf->rpc);
+ conf->rpc = NULL;
+ }
+
+ GF_FREE(conf);
+ this->private = NULL;
+}
+
+int
+server_init(xlator_t *this)
+{
+ int32_t ret = -1;
+ server_conf_t *conf = NULL;
+ char *transport_type = NULL;
+ char *statedump_path = NULL;
+ int total_transport = 0;
+
+ GF_VALIDATE_OR_GOTO("init", this, out);
+
+ if (this->children == NULL) {
+ gf_smsg(this->name, GF_LOG_ERROR, 0, PS_MSG_SUBVOL_NULL, NULL);
+ goto out;
+ }
+
+ if (this->parents != NULL) {
+ gf_smsg(this->name, GF_LOG_ERROR, 0, PS_MSG_PARENT_VOL_ERROR, NULL);
+ 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);
+
+ LOCK_INIT(&conf->itable_lock);
+
+ /* Set event threads to the configured default */
+ GF_OPTION_INIT("event-threads", conf->event_threads, int32, out);
+ ret = server_check_event_threads(this, conf, conf->event_threads);
+ if (ret)
+ goto out;
+
+ ret = server_build_config(this, conf);
+ if (ret)
+ goto out;
+
+ ret = dict_get_str_sizen(this->options, "config-directory",
+ &conf->conf_dir);
+ if (ret)
+ conf->conf_dir = CONFDIR;
+
+ conf->child_status = GF_CALLOC(1, sizeof(struct _child_status),
+ gf_server_mt_child_status);
+ INIT_LIST_HEAD(&conf->child_status->status_list);
+
+ 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_smsg(this->name, GF_LOG_ERROR, 0, PS_MSG_SET_STATEDUMP_PATH_ERROR,
+ NULL);
+ 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);
+ conf->auth_modules = NULL;
+ goto out;
+ }
+
+ ret = dict_get_str_boolean(this->options, "manage-gids", _gf_false);
+ if (ret == -1)
+ conf->server_manage_gids = _gf_false;
+ else
+ conf->server_manage_gids = ret;
+
+ GF_OPTION_INIT("gid-timeout", conf->gid_cache_timeout, int32, out);
+ if (gid_cache_init(&conf->gid_cache, conf->gid_cache_timeout) < 0) {
+ gf_smsg(this->name, GF_LOG_ERROR, 0, PS_MSG_INIT_GRP_CACHE_ERROR, NULL);
+ goto out;
+ }
+
+ ret = dict_get_str_boolean(this->options, "strict-auth-accept", _gf_false);
+ if (ret == -1)
+ conf->strict_auth_enabled = _gf_false;
+ else
+ conf->strict_auth_enabled = ret;
+
+ ret = dict_get_str_boolean(this->options, "dynamic-auth", _gf_true);
+ if (ret == -1)
+ conf->dync_auth = _gf_true;
+ else
+ conf->dync_auth = ret;
+
+ /* RPC related */
+ conf->rpc = rpcsvc_init(this, this->ctx, this->options, 0);
+ if (conf->rpc == NULL) {
+ gf_smsg(this->name, GF_LOG_ERROR, 0, PS_MSG_RPCSVC_CREATE_FAILED, NULL);
+ ret = -1;
+ goto out;
+ }
+
+ ret = rpcsvc_set_outstanding_rpc_limit(
+ conf->rpc, this->options, RPCSVC_DEFAULT_OUTSTANDING_RPC_LIMIT);
+ if (ret < 0) {
+ gf_smsg(this->name, GF_LOG_ERROR, 0, PS_MSG_RPC_CONFIGURE_FAILED, NULL);
+ goto out;
+ }
+
+ /*
+ * This is the only place where we want secure_srvr to reflect
+ * the data-plane setting.
+ */
+ this->ctx->secure_srvr = MGMT_SSL_COPY_IO;
+
+ ret = dict_get_str_sizen(this->options, "transport-type", &transport_type);
+ if (ret) {
+ gf_smsg(this->name, GF_LOG_ERROR, 0, PS_MSG_TRANSPORT_TYPE_NOT_SET,
+ NULL);
+ ret = -1;
+ goto out;
+ }
+ total_transport = rpc_transport_count(transport_type);
+ if (total_transport <= 0) {
+ gf_smsg(this->name, GF_LOG_ERROR, 0,
+ PS_MSG_GET_TOTAL_AVAIL_TRANSPORT_FAILED, NULL);
+ ret = -1;
+ goto out;
+ }
+
+ ret = dict_set_int32_sizen(this->options, "notify-poller-death", 1);
+
+ ret = rpcsvc_create_listeners(conf->rpc, this->options, this->name);
+ if (ret < 1) {
+ gf_smsg(this->name, GF_LOG_WARNING, 0,
+ PS_MSG_RPCSVC_LISTENER_CREATE_FAILED, NULL);
+ if (ret != -EADDRINUSE)
+ ret = -1;
+ goto out;
+ } else if (ret < total_transport) {
+ gf_smsg(this->name, GF_LOG_ERROR, 0,
+ PS_MSG_RPCSVC_LISTENER_CREATE_FAILED, "number=%d",
+ "continuing with succeeded transport", (total_transport - ret),
+ NULL);
+ }
+
+ ret = rpcsvc_register_notify(conf->rpc, server_rpc_notify, this);
+ if (ret) {
+ gf_smsg(this->name, GF_LOG_WARNING, 0, PS_MSG_RPCSVC_NOTIFY, NULL);
+ goto out;
+ }
+
+ glusterfs3_3_fop_prog.options = this->options;
+ /* make sure we register the fop program at the head to optimize
+ * lookup
+ */
+ ret = rpcsvc_program_register(conf->rpc, &glusterfs3_3_fop_prog, _gf_true);
+ if (ret) {
+ gf_smsg(this->name, GF_LOG_WARNING, 0, PS_MSG_PGM_REG_FAILED, "name=%s",
+ glusterfs3_3_fop_prog.progname, "prognum=%d",
+ glusterfs3_3_fop_prog.prognum, "progver=%d",
+ glusterfs3_3_fop_prog.progver, NULL);
+ goto out;
+ }
+
+ glusterfs4_0_fop_prog.options = this->options;
+ ret = rpcsvc_program_register(conf->rpc, &glusterfs4_0_fop_prog, _gf_true);
+ if (ret) {
+ gf_log(this->name, GF_LOG_WARNING,
+ "registration of program (name:%s, prognum:%d, "
+ "progver:%d) failed",
+ glusterfs4_0_fop_prog.progname, glusterfs4_0_fop_prog.prognum,
+ glusterfs4_0_fop_prog.progver);
+ rpcsvc_program_unregister(conf->rpc, &glusterfs3_3_fop_prog);
+ goto out;
+ }
+
+ gluster_handshake_prog.options = this->options;
+ ret = rpcsvc_program_register(conf->rpc, &gluster_handshake_prog,
+ _gf_false);
+ if (ret) {
+ gf_smsg(this->name, GF_LOG_WARNING, 0, PS_MSG_PGM_REG_FAILED, "name=%s",
+ gluster_handshake_prog.progname, "prognum=%d",
+ gluster_handshake_prog.prognum, "progver=%d",
+ gluster_handshake_prog.progver, NULL);
+ rpcsvc_program_unregister(conf->rpc, &glusterfs3_3_fop_prog);
+ rpcsvc_program_unregister(conf->rpc, &glusterfs4_0_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_smsg(this->name, GF_LOG_WARNING, errno, PS_MSG_ULIMIT_SET_FAILED,
+ "errno=%s", strerror(errno), NULL);
+ lim.rlim_cur = 65536;
+ lim.rlim_max = 65536;
+
+ if (setrlimit(RLIMIT_NOFILE, &lim) == -1) {
+ gf_smsg(this->name, GF_LOG_WARNING, errno, PS_MSG_FD_NOT_FOUND,
+ "errno=%s", strerror(errno), NULL);
+ } else {
+ gf_msg_trace(this->name, 0,
+ "max open fd set "
+ "to 64k");
+ }
+ }
+ }
+#endif
+ if (!this->ctx->cmd_args.volfile_id) {
+ /* In some use cases this is a valid case, but
+ document this to be annoying log in that case */
+ gf_smsg(this->name, GF_LOG_WARNING, EINVAL, PS_MSG_VOL_FILE_OPEN_FAILED,
+ NULL);
+ this->ctx->cmd_args.volfile_id = gf_strdup("gluster");
+ }
+ FIRST_CHILD(this)->volfile_id = gf_strdup(this->ctx->cmd_args.volfile_id);
+
+ this->private = conf;
+ ret = 0;
+
+out:
+ if (ret) {
+ if (this != NULL) {
+ this->fini(this);
+ }
+ server_cleanup(this, conf);
+ }
+
+ return ret;
+}
+
+void
+server_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
+server_process_event_upcall(xlator_t *this, void *data)
+{
+ int ret = -1;
+ server_conf_t *conf = NULL;
+ client_t *client = NULL;
+ char *client_uid = NULL;
+ struct gf_upcall *upcall_data = NULL;
+ void *up_req = NULL;
+ rpc_transport_t *xprt = NULL;
+ enum gf_cbk_procnum cbk_procnum = GF_CBK_NULL;
+ gfs3_cbk_cache_invalidation_req gf_c_req = {
+ 0,
+ };
+ gfs3_recall_lease_req gf_recall_lease = {
+ {
+ 0,
+ },
+ };
+ gfs4_inodelk_contention_req gf_inodelk_contention = {
+ {0},
+ };
+ gfs4_entrylk_contention_req gf_entrylk_contention = {
+ {0},
+ };
+ xdrproc_t xdrproc;
+
+ GF_VALIDATE_OR_GOTO(this->name, data, out);
+
+ conf = this->private;
+ GF_VALIDATE_OR_GOTO(this->name, conf, out);
+
+ upcall_data = (struct gf_upcall *)data;
+ client_uid = upcall_data->client_uid;
+ /* client_uid could be NULL if the upcall was intended for a server's
+ * child xlator (so no client_uid available) but it hasn't handled
+ * the notification. For this reason we silently ignore any upcall
+ * request with a NULL client_uid, but -1 will be returned.
+ */
+ if (client_uid == NULL) {
+ gf_msg_debug(this->name, 0, "NULL client_uid for an upcall request");
+ goto out;
+ }
+
+ switch (upcall_data->event_type) {
+ case GF_UPCALL_CACHE_INVALIDATION:
+ ret = gf_proto_cache_invalidation_from_upcall(this, &gf_c_req,
+ upcall_data);
+ if (ret < 0)
+ goto out;
+
+ up_req = &gf_c_req;
+ cbk_procnum = GF_CBK_CACHE_INVALIDATION;
+ xdrproc = (xdrproc_t)xdr_gfs3_cbk_cache_invalidation_req;
+ break;
+ case GF_UPCALL_RECALL_LEASE:
+ ret = gf_proto_recall_lease_from_upcall(this, &gf_recall_lease,
+ upcall_data);
+ if (ret < 0)
+ goto out;
+
+ up_req = &gf_recall_lease;
+ cbk_procnum = GF_CBK_RECALL_LEASE;
+ xdrproc = (xdrproc_t)xdr_gfs3_recall_lease_req;
+ break;
+ case GF_UPCALL_INODELK_CONTENTION:
+ ret = gf_proto_inodelk_contention_from_upcall(
+ this, &gf_inodelk_contention, upcall_data);
+ if (ret < 0)
+ goto out;
+
+ up_req = &gf_inodelk_contention;
+ cbk_procnum = GF_CBK_INODELK_CONTENTION;
+ xdrproc = (xdrproc_t)xdr_gfs4_inodelk_contention_req;
+ break;
+ case GF_UPCALL_ENTRYLK_CONTENTION:
+ ret = gf_proto_entrylk_contention_from_upcall(
+ this, &gf_entrylk_contention, upcall_data);
+ if (ret < 0)
+ goto out;
+
+ up_req = &gf_entrylk_contention;
+ cbk_procnum = GF_CBK_ENTRYLK_CONTENTION;
+ xdrproc = (xdrproc_t)xdr_gfs4_entrylk_contention_req;
+ break;
+ default:
+ gf_smsg(this->name, GF_LOG_WARNING, EINVAL,
+ PS_MSG_INVLAID_UPCALL_EVENT, "event-type=%d",
+ upcall_data->event_type, NULL);
+ goto out;
+ }
+
+ pthread_mutex_lock(&conf->mutex);
+ {
+ list_for_each_entry(xprt, &conf->xprt_list, list)
+ {
+ client = xprt->xl_private;
+
+ /* 'client' is not atomically added during xprt entry
+ * addition to the list. */
+ if (!client || strcmp(client->client_uid, client_uid))
+ continue;
+
+ ret = rpcsvc_request_submit(conf->rpc, xprt, &server_cbk_prog,
+ cbk_procnum, up_req, this->ctx,
+ xdrproc);
+ if (ret < 0) {
+ gf_msg_debug(this->name, 0,
+ "Failed to send "
+ "upcall to client:%s upcall "
+ "event:%d",
+ client_uid, upcall_data->event_type);
+ }
+ break;
+ }
+ }
+ pthread_mutex_unlock(&conf->mutex);
+ ret = 0;
+out:
+ GF_FREE((gf_c_req.xdata).xdata_val);
+ GF_FREE((gf_recall_lease.xdata).xdata_val);
+ GF_FREE((gf_inodelk_contention.xdata).xdata_val);
+ GF_FREE((gf_entrylk_contention.xdata).xdata_val);
+
+ return ret;
+}
+
+int
+server_process_child_event(xlator_t *this, int32_t event, void *data,
+ enum gf_cbk_procnum cbk_procnum)
+{
+ int ret = -1;
+ server_conf_t *conf = NULL;
+ rpc_transport_t *xprt = NULL;
+ xlator_t *victim = NULL;
+ struct _child_status *tmp = NULL;
+
+ GF_VALIDATE_OR_GOTO(this->name, data, out);
+
+ conf = this->private;
+ GF_VALIDATE_OR_GOTO(this->name, conf, out);
+
+ victim = data;
+ pthread_mutex_lock(&conf->mutex);
+ {
+ if (cbk_procnum == GF_CBK_CHILD_UP) {
+ list_for_each_entry(tmp, &conf->child_status->status_list,
+ status_list)
+ {
+ if (tmp->name == NULL)
+ break;
+ if (strcmp(tmp->name, victim->name) == 0)
+ break;
+ }
+ if (tmp->name) {
+ tmp->child_up = _gf_true;
+ } else {
+ tmp = GF_CALLOC(1, sizeof(struct _child_status),
+ gf_server_mt_child_status);
+ INIT_LIST_HEAD(&tmp->status_list);
+ tmp->name = gf_strdup(victim->name);
+ tmp->child_up = _gf_true;
+ memcpy(tmp->volume_id, victim->graph->volume_id,
+ GF_UUID_BUF_SIZE);
+ list_add_tail(&tmp->status_list,
+ &conf->child_status->status_list);
+ }
+ }
+
+ if (cbk_procnum == GF_CBK_CHILD_DOWN) {
+ list_for_each_entry(tmp, &conf->child_status->status_list,
+ status_list)
+ {
+ if (strcmp(tmp->name, victim->name) == 0) {
+ tmp->child_up = _gf_false;
+ break;
+ }
+ }
+
+ if (!tmp->name)
+ gf_smsg(this->name, GF_LOG_ERROR, 0, PS_MSG_CHILD_STATUS_FAILED,
+ "name=%s", victim->name, NULL);
+ }
+ list_for_each_entry(xprt, &conf->xprt_list, list)
+ {
+ if (!xprt->xl_private) {
+ continue;
+ }
+ if (xprt->xl_private->bound_xl == data) {
+ rpcsvc_callback_submit(conf->rpc, xprt, &server_cbk_prog,
+ cbk_procnum, NULL, 0, NULL);
+ }
+ }
+ }
+ pthread_mutex_unlock(&conf->mutex);
+ ret = 0;
+out:
+ return ret;
+}
+
+int
+server_notify(xlator_t *this, int32_t event, void *data, ...)
+{
+ int ret = -1;
+ server_conf_t *conf = NULL;
+ rpc_transport_t *xprt = NULL;
+ rpc_transport_t *xp_next = NULL;
+ xlator_t *victim = NULL;
+ xlator_t *top = NULL;
+ xlator_t *travxl = NULL;
+ xlator_list_t **trav_p = NULL;
+ struct _child_status *tmp = NULL;
+ gf_boolean_t victim_found = _gf_false;
+ glusterfs_ctx_t *ctx = NULL;
+ gf_boolean_t xprt_found = _gf_false;
+ uint64_t totxprt = 0;
+ uint64_t totdisconnect = 0;
+
+ GF_VALIDATE_OR_GOTO(THIS->name, this, out);
+ conf = this->private;
+ GF_VALIDATE_OR_GOTO(this->name, conf, out);
+ victim = data;
+ ctx = THIS->ctx;
+
+ switch (event) {
+ case GF_EVENT_UPCALL: {
+ GF_VALIDATE_OR_GOTO(this->name, data, out);
+
+ ret = server_process_event_upcall(this, data);
+ if (ret) {
+ gf_smsg(this->name, GF_LOG_ERROR, 0,
+ PS_MSG_SERVER_EVENT_UPCALL_FAILED, NULL);
+ goto out;
+ }
+ break;
+ }
+
+ case GF_EVENT_PARENT_UP: {
+ conf = this->private;
+
+ conf->parent_up = _gf_true;
+
+ default_notify(this, event, data);
+ break;
+ }
+
+ case GF_EVENT_CHILD_UP: {
+ ret = server_process_child_event(this, event, data,
+ GF_CBK_CHILD_UP);
+ if (ret) {
+ gf_smsg(this->name, GF_LOG_ERROR, 0,
+ PS_MSG_SERVER_CHILD_EVENT_FAILED, NULL);
+ goto out;
+ }
+ default_notify(this, event, data);
+ break;
+ }
+
+ case GF_EVENT_CHILD_DOWN: {
+ if (victim->cleanup_starting) {
+ victim->notify_down = 1;
+ gf_log(this->name, GF_LOG_INFO,
+ "Getting CHILD_DOWN event for brick %s", victim->name);
+ }
+
+ ret = server_process_child_event(this, event, data,
+ GF_CBK_CHILD_DOWN);
+ if (ret) {
+ gf_smsg(this->name, GF_LOG_ERROR, 0,
+ PS_MSG_SERVER_CHILD_EVENT_FAILED, NULL);
+ goto out;
+ }
+ default_notify(this, event, data);
+ break;
+ }
+
+ case GF_EVENT_CLEANUP:
+ conf = this->private;
+ pthread_mutex_lock(&conf->mutex);
+ /* Calculate total no. of xprt available in list for this
+ brick xlator
+ */
+ list_for_each_entry_safe(xprt, xp_next, &conf->xprt_list, list)
+ {
+ if (!xprt->xl_private) {
+ continue;
+ }
+
+ if (GF_ATOMIC_GET(xprt->disconnect_progress))
+ continue;
+
+ if (xprt->xl_private->bound_xl == data) {
+ totxprt++;
+ }
+ }
+
+ list_for_each_entry(tmp, &conf->child_status->status_list,
+ status_list)
+ {
+ if (strcmp(tmp->name, victim->name) == 0) {
+ tmp->child_up = _gf_false;
+ GF_ATOMIC_INIT(victim->xprtrefcnt, totxprt);
+ break;
+ }
+ }
+
+ /*
+ * Disconnecting will (usually) drop the last ref, which will
+ * cause the transport to be unlinked and freed while we're
+ * still traversing, which will cause us to crash unless we use
+ * list_for_each_entry_safe.
+ */
+ list_for_each_entry_safe(xprt, xp_next, &conf->xprt_list, list)
+ {
+ if (!xprt->xl_private) {
+ continue;
+ }
+
+ if (GF_ATOMIC_GET(xprt->disconnect_progress))
+ continue;
+
+ if (xprt->xl_private->bound_xl == data) {
+ gf_log(this->name, GF_LOG_INFO, "disconnecting %s",
+ xprt->peerinfo.identifier);
+ xprt_found = _gf_true;
+ totdisconnect++;
+ rpc_transport_disconnect(xprt, _gf_false);
+ }
+ }
+
+ if (totxprt > totdisconnect)
+ GF_ATOMIC_SUB(victim->xprtrefcnt, (totxprt - totdisconnect));
+
+ pthread_mutex_unlock(&conf->mutex);
+ if (this->ctx->active) {
+ top = this->ctx->active->first;
+ LOCK(&ctx->volfile_lock);
+ for (trav_p = &top->children; *trav_p;
+ trav_p = &(*trav_p)->next) {
+ travxl = (*trav_p)->xlator;
+ if (!travxl->call_cleanup &&
+ strcmp(travxl->name, victim->name) == 0) {
+ victim_found = _gf_true;
+ break;
+ }
+ }
+ if (victim_found)
+ glusterfs_delete_volfile_checksum(ctx, victim->volfile_id);
+ UNLOCK(&ctx->volfile_lock);
+
+ rpc_clnt_mgmt_pmap_signout(ctx, victim->name);
+
+ if (!xprt_found && victim_found) {
+ server_call_xlator_mem_cleanup(this, victim->name);
+ }
+ }
+ break;
+
+ default:
+ default_notify(this, event, data);
+ break;
+ }
+ ret = 0;
+out:
+ return ret;
+}
+
+struct xlator_fops server_fops;
+
+struct xlator_cbks server_cbks = {
+ .client_destroy = client_destroy_cbk,
+};
+
+struct xlator_dumpops server_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 server_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,
+ .default_value = "{{ volume.transport }}"},
+ {
+ .key = {"transport.listen-backlog"},
+ .type = GF_OPTION_TYPE_INT,
+ .default_value = "10",
+ },
+ {
+ .key = {"volume-filename.*"},
+ .type = GF_OPTION_TYPE_PATH,
+ },
+ {
+ .key = {"transport.tcp-user-timeout"},
+ .type = GF_OPTION_TYPE_TIME,
+ .min = 0,
+ .max = 1013,
+ .default_value = TOSTRING(GF_NETWORK_TIMEOUT),
+ },
+ {
+ .key = {"transport.*"},
+ .type = GF_OPTION_TYPE_ANY,
+ },
+ {.key = {"inode-lru-limit"},
+ .type = GF_OPTION_TYPE_INT,
+ .min = 0,
+ .max = 1048576,
+ .default_value = "16384",
+ .description = "Specifies the limit on the number of inodes "
+ "in the lru list of the inode cache.",
+ .op_version = {1},
+ .flags = OPT_FLAG_SETTABLE | OPT_FLAG_DOC},
+ {.key = {"trace"}, .type = GF_OPTION_TYPE_BOOL},
+ {
+ .key = {"config-directory", "conf-dir"},
+ .type = GF_OPTION_TYPE_PATH,
+ },
+ {.key = {"rpc-auth-allow-insecure", "allow-insecure"},
+ .type = GF_OPTION_TYPE_BOOL,
+ .default_value = "on",
+ .op_version = {1},
+ .flags = OPT_FLAG_SETTABLE | OPT_FLAG_DOC},
+ {.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.",
+ .op_version = {2},
+ .flags = OPT_FLAG_SETTABLE | OPT_FLAG_DOC},
+ {.key = {"all-squash"},
+ .type = GF_OPTION_TYPE_BOOL,
+ .default_value = "off",
+ .description = "Map requests from any uid/gid 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.",
+ .op_version = {GD_OP_VERSION_6_0},
+ .flags = OPT_FLAG_SETTABLE | OPT_FLAG_DOC},
+ {.key = {"anonuid"},
+ .type = GF_OPTION_TYPE_INT,
+ .default_value = "65534", /* RPC_NOBODY_UID */
+ .min = 0,
+ .max = (uint32_t)-1,
+ .description = "value of the uid used for the anonymous "
+ "user/nfsnobody when root-squash/all-squash is enabled.",
+ .op_version = {3},
+ .flags = OPT_FLAG_SETTABLE | OPT_FLAG_DOC},
+ {.key = {"anongid"},
+ .type = GF_OPTION_TYPE_INT,
+ .default_value = "65534", /* RPC_NOBODY_GID */
+ .min = 0,
+ .max = (uint32_t)-1,
+ .description = "value of the gid used for the anonymous "
+ "user/nfsnobody when root-squash/all-squash is enabled.",
+ .op_version = {3},
+ .flags = OPT_FLAG_SETTABLE | OPT_FLAG_DOC},
+ {.key = {"statedump-path"},
+ .type = GF_OPTION_TYPE_PATH,
+ .default_value = DEFAULT_VAR_RUN_DIRECTORY,
+ .description = "Specifies directory in which gluster should save its"
+ " statedumps.",
+ .op_version = {1},
+ .flags = OPT_FLAG_SETTABLE | OPT_FLAG_DOC},
+ {.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.",
+ .op_version = {1},
+ .flags = OPT_FLAG_SETTABLE},
+
+ /* 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", "auth.allow"},
+ .setkey = "auth.addr.{{ brick.path }}.allow",
+ .default_value = "*",
+ .type = GF_OPTION_TYPE_INTERNET_ADDRESS_LIST,
+ .flags = OPT_FLAG_SETTABLE | OPT_FLAG_DOC,
+ .description = "Allow a comma separated list of addresses and/or "
+ "hostnames to connect to the server. Option "
+ "auth.reject overrides this option. By default, all "
+ "connections are allowed."},
+ {.key = {"auth.addr.*.reject", "auth.reject"},
+ .setkey = "auth.addr.{{ brick.path }}.reject",
+ .type = GF_OPTION_TYPE_INTERNET_ADDRESS_LIST,
+ .flags = OPT_FLAG_SETTABLE | OPT_FLAG_DOC,
+ .description = "Reject a comma separated list of addresses and/or "
+ "hostnames to connect to the server. This option "
+ "overrides the auth.allow option. By default, all"
+ " connections are allowed."},
+ {.key = {"ssl-allow"},
+ .setkey = "auth.login.{{ brick.path }}.ssl-allow",
+ .default_value = "*",
+ .type = GF_OPTION_TYPE_INTERNET_ADDRESS_LIST,
+ .flags = OPT_FLAG_SETTABLE | OPT_FLAG_DOC,
+ .description = "Allow a comma separated list of common names (CN) of"
+ "the clients that are allowed to access the server."
+ "By default, all TLS authenticated clients are"
+ "allowed to access the server."},
+ /* This is not a valid path w.r.t daemons, hence it's string */
+ {.key = {"auth-path"},
+ .type = GF_OPTION_TYPE_STR,
+ .default_value = "{{ brick.path }}"},
+ {.key = {"rpc.outstanding-rpc-limit"},
+ .type = GF_OPTION_TYPE_INT,
+ .min = RPCSVC_MIN_OUTSTANDING_RPC_LIMIT,
+ .max = RPCSVC_MAX_OUTSTANDING_RPC_LIMIT,
+ .default_value = TOSTRING(RPCSVC_DEFAULT_OUTSTANDING_RPC_LIMIT),
+ .description = "Parameter to throttle the number of incoming RPC "
+ "requests from a client. 0 means no limit (can "
+ "potentially run out of memory)",
+ .op_version = {1},
+ .flags = OPT_FLAG_SETTABLE | OPT_FLAG_DOC | OPT_FLAG_GLOBAL},
+ {.key = {"manage-gids"},
+ .type = GF_OPTION_TYPE_BOOL,
+ .default_value = "off",
+ .description = "Resolve groups on the server-side.",
+ .op_version = {GD_OP_VERSION_3_6_0},
+ .flags = OPT_FLAG_SETTABLE | OPT_FLAG_DOC},
+ {.key = {"gid-timeout"},
+ .type = GF_OPTION_TYPE_INT,
+ .default_value = "300",
+ .description = "Timeout in seconds for the cached groups to expire.",
+ .op_version = {GD_OP_VERSION_3_6_0},
+ .flags = OPT_FLAG_SETTABLE | OPT_FLAG_DOC},
+ {.key = {"event-threads"},
+ .type = GF_OPTION_TYPE_INT,
+ .min = 1,
+ .max = 1024,
+ .default_value = "2",
+ .description = "Specifies the number of event threads to execute "
+ "in parallel. Larger values would help process"
+ " responses faster, depending on available processing"
+ " power.",
+ .op_version = {GD_OP_VERSION_3_7_0},
+ .flags = OPT_FLAG_SETTABLE | OPT_FLAG_DOC},
+ {.key = {"dynamic-auth"},
+ .type = GF_OPTION_TYPE_BOOL,
+ .default_value = "on",
+ .description = "When 'on' perform dynamic authentication of volume "
+ "options in order to allow/terminate client "
+ "transport connection immediately in response to "
+ "*.allow | *.reject volume set options.",
+ .op_version = {GD_OP_VERSION_3_7_5},
+ .flags = OPT_FLAG_SETTABLE | OPT_FLAG_DOC},
+ {.key = {"strict-auth-accept"},
+ .type = GF_OPTION_TYPE_BOOL,
+ .default_value = "off",
+ .description = "strict-auth-accept reject connection with out"
+ "a valid username and password."},
+ {.key = {NULL}},
+};
+
+xlator_api_t xlator_api = {
+ .init = server_init,
+ .fini = server_fini,
+ .notify = server_notify,
+ .reconfigure = server_reconfigure,
+ .mem_acct_init = server_mem_acct_init,
+ .dump_metrics = server_dump_metrics,
+ .op_version = {1}, /* Present from the initial version */
+ .dumpops = &server_dumpops,
+ .fops = &server_fops,
+ .cbks = &server_cbks,
+ .options = server_options,
+ .identifier = "server",
+ .category = GF_MAINTAINED,
+};
diff --git a/xlators/protocol/server/src/server.h b/xlators/protocol/server/src/server.h
new file mode 100644
index 00000000000..821290b62d8
--- /dev/null
+++ b/xlators/protocol/server/src/server.h
@@ -0,0 +1,222 @@
+/*
+ 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 <glusterfs/fd.h>
+#include "rpcsvc.h"
+
+#include <glusterfs/fd.h>
+#include "protocol-common.h"
+#include "server-mem-types.h"
+#include "glusterfs3.h"
+#include <glusterfs/timer.h>
+#include <glusterfs/client_t.h>
+#include <glusterfs/gidcache.h>
+#include <glusterfs/defaults.h>
+#include "authenticate.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)
+
+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 _child_status {
+ struct list_head status_list;
+ char *name;
+ char volume_id[GF_UUID_BUF_SIZE];
+ gf_boolean_t child_up;
+};
+struct server_conf {
+ rpcsvc_t *rpc;
+ struct rpcsvc_config rpc_conf;
+ int inode_lru_limit;
+ gf_boolean_t verify_volfile;
+ gf_boolean_t trace;
+ char *conf_dir;
+ struct _volfile_ctx *volfile;
+ dict_t *auth_modules;
+ pthread_mutex_t mutex;
+ struct list_head xprt_list;
+ pthread_t barrier_th;
+
+ gf_boolean_t server_manage_gids; /* resolve gids on brick */
+ gid_cache_t gid_cache;
+ int32_t gid_cache_timeout;
+
+ int event_threads; /* # of event threads
+ * configured */
+
+ gf_boolean_t parent_up;
+ gf_boolean_t dync_auth; /* if set authenticate dynamically,
+ * in case if volume set options
+ * (say *.allow | *.reject) are
+ * tweeked */
+ struct _child_status *child_status;
+ gf_lock_t itable_lock;
+ gf_boolean_t strict_auth_enabled;
+};
+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;
+
+ /*
+ * this fd is used in all the fd based operations PLUS
+ * as a source fd in copy_file_range
+ */
+ fd_t *fd;
+ fd_t *fd_out; /* destination fd in copy_file_range */
+ 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;
+ /*
+ * According to the man page of copy_file_range,
+ * the offsets for source and destination file
+ * are of type loff_t. But the type loff_t is
+ * linux specific and is actual a typedef of
+ * off64_t.
+ */
+ off64_t off_in; /* source offset in copy_file_range */
+ off64_t off_out; /* destination offset in copy_file_range */
+ 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;
+ gf_seek_what_t what;
+
+ dict_t *xdata;
+ mode_t umask;
+ struct gf_lease lease;
+ lock_migration_info_t locklist;
+
+ struct iovec rsp_vector[MAX_IOVEC];
+ int rsp_count;
+ struct iobuf *rsp_iobuf;
+ struct iobref *rsp_iobref;
+
+ /* subdir mount */
+ client_t *client;
+};
+
+extern struct rpcsvc_program gluster_handshake_prog;
+extern struct rpcsvc_program glusterfs3_3_fop_prog;
+extern struct rpcsvc_program glusterfs4_0_fop_prog;
+
+typedef struct _server_ctx {
+ gf_lock_t fdtable_lock;
+ fdtable_t *fdtable;
+} server_ctx_t;
+
+typedef struct server_cleanup_xprt_arg {
+ xlator_t *this;
+ char *victim_name;
+} server_cleanup_xprt_arg_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);
+
+void
+forget_inode_if_no_dentry(inode_t *inode);
+
+void *
+server_graph_janitor_threads(void *);
+
+server_ctx_t *
+server_ctx_get(client_t *client, xlator_t *xlator);
+#endif /* !_SERVER_H */