summaryrefslogtreecommitdiffstats
path: root/xlators/protocol/client/src
diff options
context:
space:
mode:
Diffstat (limited to 'xlators/protocol/client/src')
-rw-r--r--xlators/protocol/client/src/Makefile.am18
-rw-r--r--xlators/protocol/client/src/client-callback.c56
-rw-r--r--xlators/protocol/client/src/client-handshake.c1960
-rw-r--r--xlators/protocol/client/src/client-helpers.c349
-rw-r--r--xlators/protocol/client/src/client-lk.c573
-rw-r--r--xlators/protocol/client/src/client-mem-types.h25
-rw-r--r--xlators/protocol/client/src/client-protocol.c6403
-rw-r--r--xlators/protocol/client/src/client-protocol.h173
-rw-r--r--xlators/protocol/client/src/client-rpc-fops.c6203
-rw-r--r--xlators/protocol/client/src/client.c2867
-rw-r--r--xlators/protocol/client/src/client.h257
-rw-r--r--xlators/protocol/client/src/saved-frames.c191
-rw-r--r--xlators/protocol/client/src/saved-frames.h79
13 files changed, 12301 insertions, 6853 deletions
diff --git a/xlators/protocol/client/src/Makefile.am b/xlators/protocol/client/src/Makefile.am
index fb720942c..cf89d42da 100644
--- a/xlators/protocol/client/src/Makefile.am
+++ b/xlators/protocol/client/src/Makefile.am
@@ -2,15 +2,19 @@
xlator_LTLIBRARIES = client.la
xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/protocol
-client_la_LDFLAGS = -module -avoidversion
+client_la_LDFLAGS = -module -avoid-version
-client_la_SOURCES = client-protocol.c saved-frames.c
-client_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la
+client_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la \
+ $(top_builddir)/rpc/rpc-lib/src/libgfrpc.la \
+ $(top_builddir)/rpc/xdr/src/libgfxdr.la
-noinst_HEADERS = client-protocol.h saved-frames.h
+client_la_SOURCES = client.c client-helpers.c client-rpc-fops.c \
+ client-handshake.c client-callback.c client-lk.c
-AM_CFLAGS = -fPIC -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE -Wall -D$(GF_HOST_OS) \
- -I$(top_srcdir)/libglusterfs/src -shared -nostartfiles $(GF_CFLAGS)
+noinst_HEADERS = client.h client-mem-types.h
-CLEANFILES =
+AM_CPPFLAGS = $(GF_CPPFLAGS) \
+ -I$(top_srcdir)/libglusterfs/src \
+ -I$(top_srcdir)/rpc/xdr/src -I$(top_srcdir)/rpc/rpc-lib/src/
+AM_CFLAGS = -Wall $(GF_CFLAGS)
diff --git a/xlators/protocol/client/src/client-callback.c b/xlators/protocol/client/src/client-callback.c
new file mode 100644
index 000000000..d886862f7
--- /dev/null
+++ b/xlators/protocol/client/src/client-callback.c
@@ -0,0 +1,56 @@
+/*
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
+ This file is part of GlusterFS.
+
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
+*/
+
+#ifndef _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+#include "client.h"
+#include "rpc-clnt.h"
+
+int
+client_cbk_null (struct rpc_clnt *rpc, void *mydata, void *data)
+{
+ gf_log (THIS->name, GF_LOG_WARNING,
+ "this function should not be called");
+ return 0;
+}
+
+int
+client_cbk_fetchspec (struct rpc_clnt *rpc, void *mydata, void *data)
+{
+ gf_log (THIS->name, GF_LOG_WARNING,
+ "this function should not be called");
+ return 0;
+}
+
+int
+client_cbk_ino_flush (struct rpc_clnt *rpc, void *mydata, void *data)
+{
+ gf_log (THIS->name, GF_LOG_WARNING,
+ "this function should not be called");
+ return 0;
+}
+
+rpcclnt_cb_actor_t gluster_cbk_actors[] = {
+ [GF_CBK_NULL] = {"NULL", GF_CBK_NULL, client_cbk_null },
+ [GF_CBK_FETCHSPEC] = {"FETCHSPEC", GF_CBK_FETCHSPEC, client_cbk_fetchspec },
+ [GF_CBK_INO_FLUSH] = {"INO_FLUSH", GF_CBK_INO_FLUSH, client_cbk_ino_flush },
+};
+
+
+struct rpcclnt_cb_program gluster_cbk_prog = {
+ .progname = "GlusterFS Callback",
+ .prognum = GLUSTER_CBK_PROGRAM,
+ .progver = GLUSTER_CBK_VERSION,
+ .actors = gluster_cbk_actors,
+ .numactors = GF_CBK_MAXVALUE,
+};
diff --git a/xlators/protocol/client/src/client-handshake.c b/xlators/protocol/client/src/client-handshake.c
new file mode 100644
index 000000000..5668fea53
--- /dev/null
+++ b/xlators/protocol/client/src/client-handshake.c
@@ -0,0 +1,1960 @@
+/*
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
+ This file is part of GlusterFS.
+
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
+*/
+
+#ifndef _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+#include "fd-lk.h"
+#include "client.h"
+#include "xlator.h"
+#include "defaults.h"
+#include "glusterfs.h"
+#include "statedump.h"
+#include "compat-errno.h"
+
+#include "glusterfs3.h"
+#include "portmap-xdr.h"
+#include "rpc-common-xdr.h"
+
+#define CLIENT_REOPEN_MAX_ATTEMPTS 1024
+extern rpc_clnt_prog_t clnt3_3_fop_prog;
+extern rpc_clnt_prog_t clnt_pmap_prog;
+
+int client_ping_cbk (struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe);
+
+int client_set_lk_version_cbk (struct rpc_req *req, struct iovec *iov,
+ int count, void *myframe);
+
+int client_set_lk_version (xlator_t *this);
+
+typedef struct client_fd_lk_local {
+ int ref;
+ gf_boolean_t error;
+ gf_lock_t lock;
+ clnt_fd_ctx_t *fdctx;
+}clnt_fd_lk_local_t;
+
+/* Handshake */
+
+void
+rpc_client_ping_timer_expired (void *data)
+{
+ rpc_transport_t *trans = NULL;
+ rpc_clnt_connection_t *conn = NULL;
+ int disconnect = 0;
+ int transport_activity = 0;
+ struct timespec timeout = {0, };
+ struct timeval current = {0, };
+ struct rpc_clnt *clnt = NULL;
+ xlator_t *this = NULL;
+ clnt_conf_t *conf = NULL;
+
+ this = data;
+
+ if (!this || !this->private) {
+ gf_log (THIS->name, GF_LOG_WARNING, "xlator initialization not done");
+ goto out;
+ }
+
+ conf = this->private;
+
+ clnt = conf->rpc;
+ if (!clnt) {
+ gf_log (this->name, GF_LOG_WARNING, "rpc not initialized");
+ goto out;
+ }
+
+ conn = &clnt->conn;
+ trans = conn->trans;
+
+ if (!trans) {
+ gf_log (this->name, GF_LOG_WARNING, "transport not initialized");
+ goto out;
+ }
+
+ pthread_mutex_lock (&conn->lock);
+ {
+ if (conn->ping_timer)
+ gf_timer_call_cancel (this->ctx,
+ conn->ping_timer);
+ gettimeofday (&current, NULL);
+
+ if (((current.tv_sec - conn->last_received.tv_sec) <
+ conf->opt.ping_timeout)
+ || ((current.tv_sec - conn->last_sent.tv_sec) <
+ conf->opt.ping_timeout)) {
+ transport_activity = 1;
+ }
+
+ if (transport_activity) {
+ gf_log (trans->name, GF_LOG_TRACE,
+ "ping timer expired but transport activity "
+ "detected - not bailing transport");
+ timeout.tv_sec = conf->opt.ping_timeout;
+ timeout.tv_nsec = 0;
+
+ conn->ping_timer =
+ gf_timer_call_after (this->ctx, timeout,
+ rpc_client_ping_timer_expired,
+ (void *) this);
+ if (conn->ping_timer == NULL)
+ gf_log (trans->name, GF_LOG_WARNING,
+ "unable to setup ping timer");
+
+ } else {
+ conn->ping_started = 0;
+ conn->ping_timer = NULL;
+ disconnect = 1;
+ }
+ }
+ pthread_mutex_unlock (&conn->lock);
+
+ if (disconnect) {
+ gf_log (trans->name, GF_LOG_CRITICAL,
+ "server %s has not responded in the last %d "
+ "seconds, disconnecting.",
+ conn->trans->peerinfo.identifier,
+ conf->opt.ping_timeout);
+
+ rpc_transport_disconnect (conn->trans);
+ }
+
+out:
+ return;
+}
+
+void
+client_start_ping (void *data)
+{
+ xlator_t *this = NULL;
+ clnt_conf_t *conf = NULL;
+ rpc_clnt_connection_t *conn = NULL;
+ int32_t ret = -1;
+ struct timespec timeout = {0, };
+ call_frame_t *frame = NULL;
+ int frame_count = 0;
+
+ this = data;
+ if (!this || !this->private) {
+ gf_log (THIS->name, GF_LOG_WARNING, "xlator not initialized");
+ goto fail;
+ }
+
+ conf = this->private;
+ if (!conf->rpc) {
+ gf_log (this->name, GF_LOG_WARNING, "rpc not initialized");
+ goto fail;
+ }
+ conn = &conf->rpc->conn;
+
+ if (conf->opt.ping_timeout == 0) {
+ gf_log (this->name, GF_LOG_INFO, "ping timeout is 0, returning");
+ return;
+ }
+
+ pthread_mutex_lock (&conn->lock);
+ {
+ if (conn->ping_timer)
+ gf_timer_call_cancel (this->ctx, conn->ping_timer);
+
+ conn->ping_timer = NULL;
+ conn->ping_started = 0;
+
+ if (conn->saved_frames)
+ /* treat the case where conn->saved_frames is NULL
+ as no pending frames */
+ frame_count = conn->saved_frames->count;
+
+ if ((frame_count == 0) || !conn->connected) {
+ /* using goto looked ugly here,
+ * hence getting out this way */
+ /* unlock */
+ gf_log (this->name, GF_LOG_DEBUG,
+ "returning as transport is already disconnected"
+ " OR there are no frames (%d || %d)",
+ frame_count, !conn->connected);
+
+ pthread_mutex_unlock (&conn->lock);
+ return;
+ }
+
+ if (frame_count < 0) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "saved_frames->count is %"PRId64,
+ conn->saved_frames->count);
+ conn->saved_frames->count = 0;
+ }
+
+ timeout.tv_sec = conf->opt.ping_timeout;
+ timeout.tv_nsec = 0;
+
+ conn->ping_timer =
+ gf_timer_call_after (this->ctx, timeout,
+ rpc_client_ping_timer_expired,
+ (void *) this);
+
+ if (conn->ping_timer == NULL) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "unable to setup ping timer");
+ } else {
+ conn->ping_started = 1;
+ }
+ }
+ pthread_mutex_unlock (&conn->lock);
+
+ frame = create_frame (this, this->ctx->pool);
+ if (!frame)
+ goto fail;
+
+ ret = client_submit_request (this, NULL, frame, conf->handshake,
+ GF_HNDSK_PING, client_ping_cbk, NULL,
+ NULL, 0, NULL, 0, NULL, (xdrproc_t)NULL);
+ if (ret) {
+ gf_log (THIS->name, GF_LOG_ERROR,
+ "failed to start ping timer");
+ }
+
+ return;
+
+fail:
+ if (frame) {
+ STACK_DESTROY (frame->root);
+ }
+
+ return;
+}
+
+
+int
+client_ping_cbk (struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ xlator_t *this = NULL;
+ rpc_clnt_connection_t *conn = NULL;
+ struct timespec timeout = {0, };
+ call_frame_t *frame = NULL;
+ clnt_conf_t *conf = NULL;
+
+ if (!myframe) {
+ gf_log (THIS->name, GF_LOG_WARNING,
+ "frame with the request is NULL");
+ goto out;
+ }
+ frame = myframe;
+ this = frame->this;
+ if (!this || !this->private) {
+ gf_log (THIS->name, GF_LOG_WARNING,
+ "xlator private is not set");
+ goto out;
+ }
+
+ conf = this->private;
+ conn = &conf->rpc->conn;
+
+ pthread_mutex_lock (&conn->lock);
+ {
+ if (req->rpc_status == -1) {
+ if (conn->ping_timer != NULL) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "socket or ib related error");
+ gf_timer_call_cancel (this->ctx,
+ conn->ping_timer);
+ conn->ping_timer = NULL;
+ } else {
+ /* timer expired and transport bailed out */
+ gf_log (this->name, GF_LOG_WARNING,
+ "timer must have expired");
+ }
+
+ goto unlock;
+ }
+
+
+ timeout.tv_sec = conf->opt.ping_timeout;
+ timeout.tv_nsec = 0;
+
+ gf_timer_call_cancel (this->ctx,
+ conn->ping_timer);
+
+ conn->ping_timer =
+ gf_timer_call_after (this->ctx, timeout,
+ client_start_ping, (void *)this);
+
+ if (conn->ping_timer == NULL)
+ gf_log (this->name, GF_LOG_WARNING,
+ "failed to set the ping timer");
+ }
+unlock:
+ pthread_mutex_unlock (&conn->lock);
+out:
+ if (frame)
+ STACK_DESTROY (frame->root);
+ return 0;
+}
+
+
+int
+client3_getspec_cbk (struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ gf_getspec_rsp rsp = {0,};
+ call_frame_t *frame = NULL;
+ int ret = 0;
+
+ frame = myframe;
+
+ if (!frame || !frame->this) {
+ gf_log (THIS->name, GF_LOG_ERROR, "frame not found with the request, "
+ "returning EINVAL");
+ rsp.op_ret = -1;
+ rsp.op_errno = EINVAL;
+ goto out;
+ }
+ if (-1 == req->rpc_status) {
+ gf_log (frame->this->name, GF_LOG_WARNING,
+ "received RPC status error, returning ENOTCONN");
+ rsp.op_ret = -1;
+ rsp.op_errno = ENOTCONN;
+ goto out;
+ }
+
+ ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_getspec_rsp);
+ if (ret < 0) {
+ gf_log (frame->this->name, GF_LOG_ERROR,
+ "XDR decoding failed, returning EINVAL");
+ rsp.op_ret = -1;
+ rsp.op_errno = EINVAL;
+ goto out;
+ }
+
+ if (-1 == rsp.op_ret) {
+ gf_log (frame->this->name, GF_LOG_WARNING,
+ "failed to get the 'volume file' from server");
+ goto out;
+ }
+
+out:
+ CLIENT_STACK_UNWIND (getspec, frame, rsp.op_ret, rsp.op_errno,
+ rsp.spec);
+
+ /* Don't use 'GF_FREE', this is allocated by libc */
+ free (rsp.spec);
+
+ return 0;
+}
+
+int32_t client3_getspec (call_frame_t *frame, xlator_t *this, void *data)
+{
+ clnt_conf_t *conf = NULL;
+ clnt_args_t *args = NULL;
+ gf_getspec_req req = {0,};
+ int op_errno = ESTALE;
+ int ret = 0;
+
+ if (!frame || !this || !data)
+ goto unwind;
+
+ args = data;
+ conf = this->private;
+ req.flags = args->flags;
+ req.key = (char *)args->name;
+
+ ret = client_submit_request (this, &req, frame, conf->handshake,
+ GF_HNDSK_GETSPEC, client3_getspec_cbk,
+ NULL, NULL, 0, NULL, 0, NULL,
+ (xdrproc_t)xdr_gf_getspec_req);
+
+ if (ret) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "failed to send the request");
+ }
+
+ return 0;
+unwind:
+ CLIENT_STACK_UNWIND (getspec, frame, -1, op_errno, NULL);
+ return 0;
+
+}
+
+int
+client_notify_parents_child_up (xlator_t *this)
+{
+ clnt_conf_t *conf = NULL;
+ int ret = 0;
+
+ conf = this->private;
+ ret = default_notify (this, GF_EVENT_CHILD_UP, NULL);
+ if (ret)
+ gf_log (this->name, GF_LOG_INFO,
+ "notify of CHILD_UP failed");
+
+ conf->last_sent_event = GF_EVENT_CHILD_UP;
+ return 0;
+}
+
+int
+clnt_fd_lk_reacquire_failed (xlator_t *this, clnt_fd_ctx_t *fdctx,
+ clnt_conf_t *conf)
+{
+ int ret = -1;
+
+ GF_VALIDATE_OR_GOTO ("client", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, conf, out);
+ GF_VALIDATE_OR_GOTO (this->name, fdctx, out);
+
+ pthread_mutex_lock (&conf->lock);
+ {
+ fdctx->remote_fd = -1;
+ fdctx->lk_heal_state = GF_LK_HEAL_DONE;
+ }
+ pthread_mutex_unlock (&conf->lock);
+
+ ret = 0;
+out:
+ return ret;
+}
+
+int
+client_set_lk_version_cbk (struct rpc_req *req, struct iovec *iov,
+ int count, void *myframe)
+{
+ int32_t ret = -1;
+ call_frame_t *fr = NULL;
+ gf_set_lk_ver_rsp rsp = {0,};
+
+ fr = (call_frame_t *) myframe;
+ GF_VALIDATE_OR_GOTO ("client", fr, out);
+
+ if (req->rpc_status == -1) {
+ gf_log (fr->this->name, GF_LOG_WARNING,
+ "received RPC status error");
+ goto out;
+ }
+
+ ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_set_lk_ver_rsp);
+ if (ret < 0)
+ gf_log (fr->this->name, GF_LOG_WARNING,
+ "xdr decoding failed");
+ else
+ gf_log (fr->this->name, GF_LOG_INFO,
+ "Server lk version = %d", rsp.lk_ver);
+
+ ret = 0;
+out:
+ if (fr)
+ STACK_DESTROY (fr->root);
+
+ return ret;
+}
+
+//TODO: Check for all released fdctx and destroy them
+int
+client_set_lk_version (xlator_t *this)
+{
+ int ret = -1;
+ clnt_conf_t *conf = NULL;
+ call_frame_t *frame = NULL;
+ gf_set_lk_ver_req req = {0, };
+
+ GF_VALIDATE_OR_GOTO ("client", this, err);
+
+ conf = (clnt_conf_t *) this->private;
+
+ req.lk_ver = client_get_lk_ver (conf);
+ ret = gf_asprintf (&req.uid, "%s-%s-%d",
+ this->ctx->process_uuid, this->name,
+ this->graph->id);
+ if (ret == -1)
+ goto err;
+
+ frame = create_frame (this, this->ctx->pool);
+ if (!frame) {
+ ret = -1;
+ goto out;
+ }
+
+ gf_log (this->name, GF_LOG_DEBUG, "Sending SET_LK_VERSION");
+
+ ret = client_submit_request (this, &req, frame,
+ conf->handshake,
+ GF_HNDSK_SET_LK_VER,
+ client_set_lk_version_cbk,
+ NULL, NULL, 0, NULL, 0, NULL,
+ (xdrproc_t)xdr_gf_set_lk_ver_req);
+out:
+ GF_FREE (req.uid);
+ return ret;
+err:
+ gf_log (this->name, GF_LOG_WARNING,
+ "Failed to send SET_LK_VERSION to server");
+
+ return ret;
+}
+
+int
+client_fd_lk_count (fd_lk_ctx_t *lk_ctx)
+{
+ int count = 0;
+ fd_lk_ctx_node_t *fd_lk = NULL;
+
+ GF_VALIDATE_OR_GOTO ("client", lk_ctx, err);
+
+ LOCK (&lk_ctx->lock);
+ {
+ list_for_each_entry (fd_lk, &lk_ctx->lk_list, next)
+ count++;
+ }
+ UNLOCK (&lk_ctx->lock);
+
+ return count;
+err:
+ return -1;
+}
+
+clnt_fd_lk_local_t *
+clnt_fd_lk_local_ref (xlator_t *this, clnt_fd_lk_local_t *local)
+{
+ GF_VALIDATE_OR_GOTO (this->name, local, out);
+
+ LOCK (&local->lock);
+ {
+ local->ref++;
+ }
+ UNLOCK (&local->lock);
+out:
+ return local;
+}
+
+int
+clnt_fd_lk_local_unref (xlator_t *this, clnt_fd_lk_local_t *local)
+{
+ int ref = -1;
+
+ GF_VALIDATE_OR_GOTO (this->name, local, out);
+
+ LOCK (&local->lock);
+ {
+ ref = --local->ref;
+ }
+ UNLOCK (&local->lock);
+
+ if (ref == 0) {
+ LOCK_DESTROY (&local->lock);
+ GF_FREE (local);
+ }
+out:
+ return ref;
+}
+
+clnt_fd_lk_local_t *
+clnt_fd_lk_local_create (clnt_fd_ctx_t *fdctx)
+{
+ clnt_fd_lk_local_t *local = NULL;
+
+ local = GF_CALLOC (1, sizeof (clnt_fd_lk_local_t),
+ gf_client_mt_clnt_fd_lk_local_t);
+ if (!local)
+ goto out;
+
+ local->ref = 1;
+ local->error = _gf_false;
+ local->fdctx = fdctx;
+
+ LOCK_INIT (&local->lock);
+out:
+ return local;
+}
+
+void
+clnt_mark_fd_bad (clnt_conf_t *conf, clnt_fd_ctx_t *fdctx)
+{
+ pthread_mutex_lock (&conf->lock);
+ {
+ fdctx->remote_fd = -1;
+ }
+ pthread_mutex_unlock (&conf->lock);
+}
+
+int
+clnt_release_reopen_fd_cbk (struct rpc_req *req, struct iovec *iov,
+ int count, void *myframe)
+{
+ xlator_t *this = NULL;
+ call_frame_t *frame = NULL;
+ clnt_conf_t *conf = NULL;
+ clnt_fd_ctx_t *fdctx = NULL;
+
+ frame = myframe;
+ this = frame->this;
+ fdctx = (clnt_fd_ctx_t *) frame->local;
+ conf = (clnt_conf_t *) this->private;
+
+ clnt_fd_lk_reacquire_failed (this, fdctx, conf);
+
+ fdctx->reopen_done (fdctx, this);
+
+ frame->local = NULL;
+ STACK_DESTROY (frame->root);
+
+ return 0;
+}
+
+int
+clnt_release_reopen_fd (xlator_t *this, clnt_fd_ctx_t *fdctx)
+{
+ int ret = -1;
+ clnt_conf_t *conf = NULL;
+ call_frame_t *frame = NULL;
+ gfs3_release_req req = {{0,},};
+
+ conf = (clnt_conf_t *) this->private;
+
+ frame = create_frame (this, this->ctx->pool);
+ if (!frame)
+ goto out;
+
+ frame->local = (void *) fdctx;
+ req.fd = fdctx->remote_fd;
+
+ ret = client_submit_request (this, &req, frame, conf->fops,
+ GFS3_OP_RELEASE,
+ clnt_release_reopen_fd_cbk, NULL,
+ NULL, 0, NULL, 0, NULL,
+ (xdrproc_t)xdr_gfs3_releasedir_req);
+ return 0;
+ out:
+ if (ret) {
+ clnt_fd_lk_reacquire_failed (this, fdctx, conf);
+ fdctx->reopen_done (fdctx, this);
+ if (frame) {
+ frame->local = NULL;
+ STACK_DESTROY (frame->root);
+ }
+ }
+ return 0;
+}
+
+int
+clnt_reacquire_lock_error (xlator_t *this, clnt_fd_ctx_t *fdctx,
+ clnt_conf_t *conf)
+{
+ int32_t ret = -1;
+
+ GF_VALIDATE_OR_GOTO ("client", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, fdctx, out);
+ GF_VALIDATE_OR_GOTO (this->name, conf, out);
+
+ clnt_release_reopen_fd (this, fdctx);
+
+ ret = 0;
+out:
+ return ret;
+}
+
+gf_boolean_t
+clnt_fd_lk_local_error_status (xlator_t *this,
+ clnt_fd_lk_local_t *local)
+{
+ gf_boolean_t error = _gf_false;
+
+ LOCK (&local->lock);
+ {
+ error = local->error;
+ }
+ UNLOCK (&local->lock);
+
+ return error;
+}
+
+int
+clnt_fd_lk_local_mark_error (xlator_t *this,
+ clnt_fd_lk_local_t *local)
+{
+ int32_t ret = -1;
+ clnt_conf_t *conf = NULL;
+ gf_boolean_t error = _gf_false;
+
+ GF_VALIDATE_OR_GOTO ("client", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, local, out);
+
+ conf = (clnt_conf_t *) this->private;
+
+ LOCK (&local->lock);
+ {
+ error = local->error;
+ local->error = _gf_true;
+ }
+ UNLOCK (&local->lock);
+
+ if (!error)
+ clnt_reacquire_lock_error (this, local->fdctx, conf);
+ ret = 0;
+out:
+ return ret;
+}
+
+int
+client_reacquire_lock_cbk (struct rpc_req *req, struct iovec *iov,
+ int count, void *myframe)
+{
+ int32_t ret = -1;
+ xlator_t *this = NULL;
+ gfs3_lk_rsp rsp = {0,};
+ call_frame_t *frame = NULL;
+ clnt_conf_t *conf = NULL;
+ clnt_fd_ctx_t *fdctx = NULL;
+ clnt_fd_lk_local_t *local = NULL;
+ struct gf_flock lock = {0,};
+
+ frame = (call_frame_t *) myframe;
+ this = frame->this;
+ local = (clnt_fd_lk_local_t *) frame->local;
+ conf = (clnt_conf_t *) this->private;
+
+ if (req->rpc_status == -1) {
+ gf_log ("client", GF_LOG_WARNING,
+ "request failed at rpc");
+ goto out;
+ }
+
+ ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gfs3_lk_rsp);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "XDR decoding failed");
+ goto out;
+ }
+
+ if (rsp.op_ret == -1) {
+ gf_log (this->name, GF_LOG_ERROR, "lock request failed");
+ ret = -1;
+ goto out;
+ }
+
+ fdctx = local->fdctx;
+
+ gf_proto_flock_to_flock (&rsp.flock, &lock);
+
+ gf_log (this->name, GF_LOG_DEBUG, "%s type lock reacquired on file "
+ "with gfid %s from %"PRIu64 " to %"PRIu64,
+ get_lk_type (lock.l_type), uuid_utoa (fdctx->gfid),
+ lock.l_start, lock.l_start + lock.l_len);
+
+ if (!clnt_fd_lk_local_error_status (this, local) &&
+ clnt_fd_lk_local_unref (this, local) == 0) {
+ pthread_mutex_lock (&conf->lock);
+ {
+ fdctx->lk_heal_state = GF_LK_HEAL_DONE;
+ }
+ pthread_mutex_unlock (&conf->lock);
+
+ fdctx->reopen_done (fdctx, this);
+ }
+
+ ret = 0;
+out:
+ if (ret < 0) {
+ clnt_fd_lk_local_mark_error (this, local);
+
+ clnt_fd_lk_local_unref (this, local);
+ }
+
+ frame->local = NULL;
+ STACK_DESTROY (frame->root);
+
+ return ret;
+}
+
+int
+_client_reacquire_lock (xlator_t *this, clnt_fd_ctx_t *fdctx)
+{
+ int32_t ret = -1;
+ int32_t gf_cmd = 0;
+ int32_t gf_type = 0;
+ gfs3_lk_req req = {{0,},};
+ struct gf_flock flock = {0,};
+ fd_lk_ctx_t *lk_ctx = NULL;
+ clnt_fd_lk_local_t *local = NULL;
+ fd_lk_ctx_node_t *fd_lk = NULL;
+ call_frame_t *frame = NULL;
+ clnt_conf_t *conf = NULL;
+
+ conf = (clnt_conf_t *) this->private;
+ lk_ctx = fdctx->lk_ctx;
+
+ local = clnt_fd_lk_local_create (fdctx);
+ if (!local) {
+ gf_log (this->name, GF_LOG_WARNING, "clnt_fd_lk_local_create "
+ "failed, aborting reacquring of locks on %s.",
+ uuid_utoa (fdctx->gfid));
+ clnt_reacquire_lock_error (this, fdctx, conf);
+ goto out;
+ }
+
+ list_for_each_entry (fd_lk, &lk_ctx->lk_list, next) {
+ memcpy (&flock, &fd_lk->user_flock,
+ sizeof (struct gf_flock));
+
+ /* Always send F_SETLK even if the cmd was F_SETLKW */
+ /* to avoid frame being blocked if lock cannot be granted. */
+ ret = client_cmd_to_gf_cmd (F_SETLK, &gf_cmd);
+ if (ret) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "client_cmd_to_gf_cmd failed, "
+ "aborting reacquiring of locks");
+ break;
+ }
+
+ gf_type = client_type_to_gf_type (flock.l_type);
+ req.fd = fdctx->remote_fd;
+ req.cmd = gf_cmd;
+ req.type = gf_type;
+ (void) gf_proto_flock_from_flock (&req.flock,
+ &flock);
+
+ memcpy (req.gfid, fdctx->gfid, 16);
+
+ frame = create_frame (this, this->ctx->pool);
+ if (!frame) {
+ ret = -1;
+ break;
+ }
+
+ frame->local = clnt_fd_lk_local_ref (this, local);
+ frame->root->lk_owner = fd_lk->user_flock.l_owner;
+
+ ret = client_submit_request (this, &req, frame,
+ conf->fops, GFS3_OP_LK,
+ client_reacquire_lock_cbk,
+ NULL, NULL, 0, NULL, 0, NULL,
+ (xdrproc_t)xdr_gfs3_lk_req);
+ if (ret) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "reacquiring locks failed on file with gfid %s",
+ uuid_utoa (fdctx->gfid));
+ break;
+ }
+
+ ret = 0;
+ frame = NULL;
+ }
+
+ if (local)
+ (void) clnt_fd_lk_local_unref (this, local);
+out:
+ return ret;
+}
+
+int
+client_reacquire_lock (xlator_t *this, clnt_fd_ctx_t *fdctx)
+{
+ int32_t ret = -1;
+ fd_lk_ctx_t *lk_ctx = NULL;
+
+ GF_VALIDATE_OR_GOTO ("client", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, fdctx, out);
+
+ if (client_fd_lk_list_empty (fdctx->lk_ctx, _gf_false)) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "fd lock list is empty");
+ fdctx->reopen_done (fdctx, this);
+ } else {
+ lk_ctx = fdctx->lk_ctx;
+
+ LOCK (&lk_ctx->lock);
+ {
+ (void) _client_reacquire_lock (this, fdctx);
+ }
+ UNLOCK (&lk_ctx->lock);
+ }
+ ret = 0;
+out:
+ return ret;
+}
+
+void
+client_default_reopen_done (clnt_fd_ctx_t *fdctx, xlator_t *this)
+{
+ gf_log_callingfn (this->name, GF_LOG_WARNING,
+ "This function should never be called");
+}
+
+void
+client_reopen_done (clnt_fd_ctx_t *fdctx, xlator_t *this)
+{
+ clnt_conf_t *conf = NULL;
+ gf_boolean_t destroy = _gf_false;
+
+ conf = this->private;
+
+ pthread_mutex_lock (&conf->lock);
+ {
+ fdctx->reopen_attempts = 0;
+ if (!fdctx->released)
+ list_add_tail (&fdctx->sfd_pos, &conf->saved_fds);
+ else
+ destroy = _gf_true;
+ fdctx->reopen_done = client_default_reopen_done;
+ }
+ pthread_mutex_unlock (&conf->lock);
+
+ if (destroy)
+ client_fdctx_destroy (this, fdctx);
+}
+
+void
+client_child_up_reopen_done (clnt_fd_ctx_t *fdctx, xlator_t *this)
+{
+ clnt_conf_t *conf = NULL;
+ uint64_t fd_count = 0;
+
+ conf = this->private;
+
+ LOCK (&conf->rec_lock);
+ {
+ fd_count = --(conf->reopen_fd_count);
+ }
+ UNLOCK (&conf->rec_lock);
+
+ client_reopen_done (fdctx, this);
+ if (fd_count == 0) {
+ gf_log (this->name, GF_LOG_INFO,
+ "last fd open'd/lock-self-heal'd - notifying CHILD-UP");
+ client_set_lk_version (this);
+ client_notify_parents_child_up (this);
+ }
+}
+
+int
+client3_3_reopen_cbk (struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ int32_t ret = -1;
+ gfs3_open_rsp rsp = {0,};
+ gf_boolean_t attempt_lock_recovery = _gf_false;
+ clnt_local_t *local = NULL;
+ clnt_conf_t *conf = NULL;
+ clnt_fd_ctx_t *fdctx = NULL;
+ call_frame_t *frame = NULL;
+ xlator_t *this = NULL;
+
+ frame = myframe;
+ this = frame->this;
+ conf = this->private;
+ local = frame->local;
+ fdctx = local->fdctx;
+
+ if (-1 == req->rpc_status) {
+ gf_log (frame->this->name, GF_LOG_WARNING,
+ "received RPC status error, returning ENOTCONN");
+ rsp.op_ret = -1;
+ rsp.op_errno = ENOTCONN;
+ goto out;
+ }
+
+ ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gfs3_open_rsp);
+ if (ret < 0) {
+ gf_log (frame->this->name, GF_LOG_ERROR, "XDR decoding failed");
+ rsp.op_ret = -1;
+ rsp.op_errno = EINVAL;
+ goto out;
+ }
+
+ if (rsp.op_ret < 0) {
+ gf_log (frame->this->name, GF_LOG_WARNING,
+ "reopen on %s failed (%s)",
+ local->loc.path, strerror (rsp.op_errno));
+ } else {
+ gf_log (frame->this->name, GF_LOG_DEBUG,
+ "reopen on %s succeeded (remote-fd = %"PRId64")",
+ local->loc.path, rsp.fd);
+ }
+
+ if (rsp.op_ret == -1) {
+ ret = -1;
+ goto out;
+ }
+
+ pthread_mutex_lock (&conf->lock);
+ {
+ fdctx->remote_fd = rsp.fd;
+ if (!fdctx->released) {
+ if (conf->lk_heal &&
+ !client_fd_lk_list_empty (fdctx->lk_ctx,
+ _gf_false)) {
+ attempt_lock_recovery = _gf_true;
+ fdctx->lk_heal_state = GF_LK_HEAL_IN_PROGRESS;
+ }
+ }
+ }
+ pthread_mutex_unlock (&conf->lock);
+
+ ret = 0;
+
+ if (attempt_lock_recovery) {
+ /* Delay decrementing the reopen fd count untill all the
+ locks corresponding to this fd are acquired.*/
+ gf_log (this->name, GF_LOG_DEBUG, "acquiring locks "
+ "on %s", local->loc.path);
+ ret = client_reacquire_lock (frame->this, local->fdctx);
+ if (ret) {
+ clnt_reacquire_lock_error (this, local->fdctx, conf);
+ gf_log (this->name, GF_LOG_WARNING, "acquiring locks "
+ "failed on %s", local->loc.path);
+ }
+ }
+
+out:
+ if (!attempt_lock_recovery)
+ fdctx->reopen_done (fdctx, this);
+
+ frame->local = NULL;
+ STACK_DESTROY (frame->root);
+
+ client_local_wipe (local);
+
+ return 0;
+}
+
+int
+client3_3_reopendir_cbk (struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ int32_t ret = -1;
+ gfs3_open_rsp rsp = {0,};
+ clnt_local_t *local = NULL;
+ clnt_conf_t *conf = NULL;
+ clnt_fd_ctx_t *fdctx = NULL;
+ call_frame_t *frame = NULL;
+
+ frame = myframe;
+ local = frame->local;
+ fdctx = local->fdctx;
+ conf = frame->this->private;
+
+
+ if (-1 == req->rpc_status) {
+ gf_log (frame->this->name, GF_LOG_WARNING,
+ "received RPC status error, returning ENOTCONN");
+ rsp.op_ret = -1;
+ rsp.op_errno = ENOTCONN;
+ goto out;
+ }
+
+ ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gfs3_opendir_rsp);
+ if (ret < 0) {
+ gf_log (frame->this->name, GF_LOG_ERROR, "XDR decoding failed");
+ rsp.op_ret = -1;
+ rsp.op_errno = EINVAL;
+ goto out;
+ }
+
+ if (rsp.op_ret < 0) {
+ gf_log (frame->this->name, GF_LOG_WARNING,
+ "reopendir on %s failed (%s)",
+ local->loc.path, strerror (rsp.op_errno));
+ } else {
+ gf_log (frame->this->name, GF_LOG_INFO,
+ "reopendir on %s succeeded (fd = %"PRId64")",
+ local->loc.path, rsp.fd);
+ }
+
+ if (-1 == rsp.op_ret) {
+ ret = -1;
+ goto out;
+ }
+
+ pthread_mutex_lock (&conf->lock);
+ {
+ fdctx->remote_fd = rsp.fd;
+ }
+ pthread_mutex_unlock (&conf->lock);
+
+out:
+ fdctx->reopen_done (fdctx, frame->this);
+
+ frame->local = NULL;
+ STACK_DESTROY (frame->root);
+ client_local_wipe (local);
+
+ return 0;
+}
+
+static int
+protocol_client_reopendir (clnt_fd_ctx_t *fdctx, xlator_t *this)
+{
+ int ret = -1;
+ gfs3_opendir_req req = {{0,},};
+ clnt_local_t *local = NULL;
+ call_frame_t *frame = NULL;
+ clnt_conf_t *conf = NULL;
+
+ conf = this->private;
+
+ local = mem_get0 (this->local_pool);
+ if (!local) {
+ ret = -1;
+ goto out;
+ }
+ local->fdctx = fdctx;
+
+ uuid_copy (local->loc.gfid, fdctx->gfid);
+ ret = loc_path (&local->loc, NULL);
+ if (ret < 0)
+ goto out;
+
+ frame = create_frame (this, this->ctx->pool);
+ if (!frame) {
+ ret = -1;
+ goto out;
+ }
+
+ memcpy (req.gfid, fdctx->gfid, 16);
+
+ gf_log (frame->this->name, GF_LOG_DEBUG,
+ "attempting reopen on %s", local->loc.path);
+
+ frame->local = local;
+
+ ret = client_submit_request (this, &req, frame, conf->fops,
+ GFS3_OP_OPENDIR,
+ client3_3_reopendir_cbk, NULL,
+ NULL, 0, NULL, 0, NULL,
+ (xdrproc_t)xdr_gfs3_opendir_req);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "failed to send the re-opendir request");
+ }
+
+ return 0;
+
+out:
+ if (frame) {
+ frame->local = NULL;
+ STACK_DESTROY (frame->root);
+ }
+
+ if (local)
+ client_local_wipe (local);
+
+ fdctx->reopen_done (fdctx, this);
+
+ return 0;
+
+}
+
+static int
+protocol_client_reopenfile (clnt_fd_ctx_t *fdctx, xlator_t *this)
+{
+ int ret = -1;
+ gfs3_open_req req = {{0,},};
+ clnt_local_t *local = NULL;
+ call_frame_t *frame = NULL;
+ clnt_conf_t *conf = NULL;
+
+ conf = this->private;
+
+ frame = create_frame (this, this->ctx->pool);
+ if (!frame) {
+ ret = -1;
+ goto out;
+ }
+
+ local = mem_get0 (this->local_pool);
+ if (!local) {
+ ret = -1;
+ goto out;
+ }
+
+ local->fdctx = fdctx;
+ uuid_copy (local->loc.gfid, fdctx->gfid);
+ ret = loc_path (&local->loc, NULL);
+ if (ret < 0)
+ goto out;
+
+ frame->local = local;
+
+ memcpy (req.gfid, fdctx->gfid, 16);
+ req.flags = gf_flags_from_flags (fdctx->flags);
+ req.flags = req.flags & (~(O_TRUNC|O_CREAT|O_EXCL));
+
+ gf_log (frame->this->name, GF_LOG_DEBUG,
+ "attempting reopen on %s", local->loc.path);
+
+ ret = client_submit_request (this, &req, frame, conf->fops,
+ GFS3_OP_OPEN, client3_3_reopen_cbk, NULL,
+ NULL, 0, NULL, 0, NULL,
+ (xdrproc_t)xdr_gfs3_open_req);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "failed to send the re-open request");
+ }
+
+ return 0;
+
+out:
+ if (frame) {
+ frame->local = NULL;
+ STACK_DESTROY (frame->root);
+ }
+
+ if (local)
+ client_local_wipe (local);
+
+ fdctx->reopen_done (fdctx, this);
+
+ return 0;
+
+}
+
+static void
+protocol_client_reopen (clnt_fd_ctx_t *fdctx, xlator_t *this)
+{
+ if (fdctx->is_dir)
+ protocol_client_reopendir (fdctx, this);
+ else
+ protocol_client_reopenfile (fdctx, this);
+}
+
+gf_boolean_t
+__is_fd_reopen_in_progress (clnt_fd_ctx_t *fdctx)
+{
+ if (fdctx->reopen_done == client_default_reopen_done)
+ return _gf_false;
+ return _gf_true;
+}
+
+void
+client_attempt_reopen (fd_t *fd, xlator_t *this)
+{
+ clnt_conf_t *conf = NULL;
+ clnt_fd_ctx_t *fdctx = NULL;
+ gf_boolean_t reopen = _gf_false;
+
+ if (!fd || !this)
+ goto out;
+
+ conf = this->private;
+ pthread_mutex_lock (&conf->lock);
+ {
+ fdctx = this_fd_get_ctx (fd, this);
+ if (!fdctx)
+ goto unlock;
+ if (__is_fd_reopen_in_progress (fdctx))
+ goto unlock;
+ if (fdctx->remote_fd != -1)
+ goto unlock;
+
+ if (fdctx->reopen_attempts == CLIENT_REOPEN_MAX_ATTEMPTS) {
+ reopen = _gf_true;
+ fdctx->reopen_done = client_reopen_done;
+ list_del_init (&fdctx->sfd_pos);
+ } else {
+ fdctx->reopen_attempts++;
+ }
+ }
+unlock:
+ pthread_mutex_unlock (&conf->lock);
+ if (reopen)
+ protocol_client_reopen (fdctx, this);
+out:
+ return;
+}
+
+int
+client_post_handshake (call_frame_t *frame, xlator_t *this)
+{
+ clnt_conf_t *conf = NULL;
+ clnt_fd_ctx_t *tmp = NULL;
+ clnt_fd_ctx_t *fdctx = NULL;
+ struct list_head reopen_head;
+
+ int count = 0;
+
+ if (!this || !this->private)
+ goto out;
+
+ conf = this->private;
+ INIT_LIST_HEAD (&reopen_head);
+
+ pthread_mutex_lock (&conf->lock);
+ {
+ list_for_each_entry_safe (fdctx, tmp, &conf->saved_fds,
+ sfd_pos) {
+ if (fdctx->remote_fd != -1)
+ continue;
+
+ fdctx->reopen_done = client_child_up_reopen_done;
+ list_del_init (&fdctx->sfd_pos);
+ list_add_tail (&fdctx->sfd_pos, &reopen_head);
+ count++;
+ }
+ }
+ pthread_mutex_unlock (&conf->lock);
+
+ /* Delay notifying CHILD_UP to parents
+ until all locks are recovered */
+ if (count > 0) {
+ gf_log (this->name, GF_LOG_INFO,
+ "%d fds open - Delaying child_up until they are re-opened",
+ count);
+ client_save_number_fds (conf, count);
+
+ list_for_each_entry_safe (fdctx, tmp, &reopen_head, sfd_pos) {
+ list_del_init (&fdctx->sfd_pos);
+
+ protocol_client_reopen (fdctx, this);
+ }
+ } else {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "No fds to open - notifying all parents child up");
+ client_set_lk_version (this);
+ client_notify_parents_child_up (this);
+ }
+out:
+ return 0;
+}
+
+int
+client_setvolume_cbk (struct rpc_req *req, struct iovec *iov, int count, void *myframe)
+{
+ call_frame_t *frame = NULL;
+ clnt_conf_t *conf = NULL;
+ xlator_t *this = NULL;
+ dict_t *reply = NULL;
+ char *process_uuid = NULL;
+ char *remote_error = NULL;
+ char *remote_subvol = NULL;
+ gf_setvolume_rsp rsp = {0,};
+ int ret = 0;
+ int32_t op_ret = 0;
+ int32_t op_errno = 0;
+ gf_boolean_t auth_fail = _gf_false;
+ uint32_t lk_ver = 0;
+
+ frame = myframe;
+ this = frame->this;
+ conf = this->private;
+
+ if (-1 == req->rpc_status) {
+ gf_log (frame->this->name, GF_LOG_WARNING,
+ "received RPC status error");
+ op_ret = -1;
+ goto out;
+ }
+
+ ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_setvolume_rsp);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "XDR decoding failed");
+ op_ret = -1;
+ goto out;
+ }
+ op_ret = rsp.op_ret;
+ op_errno = gf_error_to_errno (rsp.op_errno);
+ if (-1 == rsp.op_ret) {
+ gf_log (frame->this->name, GF_LOG_WARNING,
+ "failed to set the volume (%s)",
+ (op_errno)? strerror (op_errno) : "--");
+ }
+
+ reply = dict_new ();
+ if (!reply)
+ goto out;
+
+ if (rsp.dict.dict_len) {
+ ret = dict_unserialize (rsp.dict.dict_val,
+ rsp.dict.dict_len, &reply);
+ if (ret < 0) {
+ gf_log (frame->this->name, GF_LOG_WARNING,
+ "failed to unserialize buffer to dict");
+ goto out;
+ }
+ }
+
+ ret = dict_get_str (reply, "ERROR", &remote_error);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "failed to get ERROR string from reply dict");
+ }
+
+ ret = dict_get_str (reply, "process-uuid", &process_uuid);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "failed to get 'process-uuid' from reply dict");
+ }
+
+ if (op_ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "SETVOLUME on remote-host failed: %s",
+ remote_error ? remote_error : strerror (op_errno));
+ errno = op_errno;
+ if (remote_error &&
+ (strcmp ("Authentication failed", remote_error) == 0)) {
+ auth_fail = _gf_true;
+ op_ret = 0;
+ }
+ if (op_errno == ESTALE) {
+ ret = default_notify (this, GF_EVENT_VOLFILE_MODIFIED, NULL);
+ if (ret)
+ gf_log (this->name, GF_LOG_INFO,
+ "notify of VOLFILE_MODIFIED failed");
+ conf->last_sent_event = GF_EVENT_VOLFILE_MODIFIED;
+ }
+ goto out;
+ }
+
+ ret = dict_get_str (this->options, "remote-subvolume",
+ &remote_subvol);
+ if (ret || !remote_subvol) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "failed to find key 'remote-subvolume' in the options");
+ goto out;
+ }
+
+ ret = dict_get_uint32 (reply, "clnt-lk-version", &lk_ver);
+ if (ret) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "failed to find key 'clnt-lk-version' in the options");
+ goto out;
+ }
+
+ gf_log (this->name, GF_LOG_DEBUG, "clnt-lk-version = %d, "
+ "server-lk-version = %d", client_get_lk_ver (conf), lk_ver);
+ /* TODO: currently setpeer path is broken */
+ /*
+ if (process_uuid && req->conn &&
+ !strcmp (this->ctx->process_uuid, process_uuid)) {
+ rpc_transport_t *peer_trans = NULL;
+ uint64_t peertrans_int = 0;
+
+ ret = dict_get_uint64 (reply, "transport-ptr",
+ &peertrans_int);
+ if (ret)
+ goto out;
+
+ gf_log (this->name, GF_LOG_WARNING,
+ "attaching to the local volume '%s'",
+ remote_subvol);
+
+ peer_trans = (void *) (long) (peertrans_int);
+
+ rpc_transport_setpeer (req->conn->trans, peer_trans);
+ }
+ */
+
+ gf_log (this->name, GF_LOG_INFO,
+ "Connected to %s, attached to remote volume '%s'.",
+ conf->rpc->conn.trans->peerinfo.identifier,
+ remote_subvol);
+
+ rpc_clnt_set_connected (&conf->rpc->conn);
+
+ op_ret = 0;
+ conf->connecting = 0;
+ conf->connected = 1;
+
+ conf->need_different_port = 0;
+
+ if (lk_ver != client_get_lk_ver (conf)) {
+ gf_log (this->name, GF_LOG_INFO, "Server and Client "
+ "lk-version numbers are not same, reopening the fds");
+ client_mark_fd_bad (this);
+ client_post_handshake (frame, frame->this);
+ } else {
+ /*TODO: Traverse the saved fd list, and send
+ release to the server on fd's that were closed
+ during grace period */
+ gf_log (this->name, GF_LOG_INFO, "Server and Client "
+ "lk-version numbers are same, no need to "
+ "reopen the fds");
+ }
+
+out:
+ if (auth_fail) {
+ gf_log (this->name, GF_LOG_INFO, "sending AUTH_FAILED event");
+ ret = default_notify (this, GF_EVENT_AUTH_FAILED, NULL);
+ if (ret)
+ gf_log (this->name, GF_LOG_INFO,
+ "notify of AUTH_FAILED failed");
+ conf->connecting = 0;
+ conf->connected = 0;
+ conf->last_sent_event = GF_EVENT_AUTH_FAILED;
+ ret = -1;
+ }
+ if (-1 == op_ret) {
+ /* Let the connection/re-connection happen in
+ * background, for now, don't hang here,
+ * tell the parents that i am all ok..
+ */
+ gf_log (this->name, GF_LOG_INFO, "sending CHILD_CONNECTING event");
+ ret = default_notify (this, GF_EVENT_CHILD_CONNECTING, NULL);
+ if (ret)
+ gf_log (this->name, GF_LOG_INFO,
+ "notify of CHILD_CONNECTING failed");
+ conf->last_sent_event = GF_EVENT_CHILD_CONNECTING;
+ conf->connecting= 1;
+ ret = 0;
+ }
+
+ free (rsp.dict.dict_val);
+
+ STACK_DESTROY (frame->root);
+
+ if (reply)
+ dict_unref (reply);
+
+ return ret;
+}
+
+int
+client_setvolume (xlator_t *this, struct rpc_clnt *rpc)
+{
+ int ret = 0;
+ gf_setvolume_req req = {{0,},};
+ call_frame_t *fr = NULL;
+ char *process_uuid_xl = NULL;
+ clnt_conf_t *conf = NULL;
+ dict_t *options = NULL;
+
+ options = this->options;
+ conf = this->private;
+
+ if (conf->fops) {
+ ret = dict_set_int32 (options, "fops-version",
+ conf->fops->prognum);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "failed to set version-fops(%d) in handshake msg",
+ conf->fops->prognum);
+ goto fail;
+ }
+ }
+
+ if (conf->mgmt) {
+ ret = dict_set_int32 (options, "mgmt-version", conf->mgmt->prognum);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "failed to set version-mgmt(%d) in handshake msg",
+ conf->mgmt->prognum);
+ goto fail;
+ }
+ }
+
+ /* With multiple graphs possible in the same process, we need a
+ field to bring the uniqueness. Graph-ID should be enough to get the
+ job done
+ */
+ ret = gf_asprintf (&process_uuid_xl, "%s-%s-%d",
+ this->ctx->process_uuid, this->name,
+ this->graph->id);
+ if (-1 == ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "asprintf failed while setting process_uuid");
+ goto fail;
+ }
+
+ ret = dict_set_dynstr (options, "process-uuid", process_uuid_xl);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "failed to set process-uuid(%s) in handshake msg",
+ process_uuid_xl);
+ goto fail;
+ }
+
+ ret = dict_set_str (options, "client-version", PACKAGE_VERSION);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "failed to set client-version(%s) in handshake msg",
+ PACKAGE_VERSION);
+ }
+
+ if (this->ctx->cmd_args.volfile_server) {
+ if (this->ctx->cmd_args.volfile_id) {
+ ret = dict_set_str (options, "volfile-key",
+ this->ctx->cmd_args.volfile_id);
+ if (ret)
+ gf_log (this->name, GF_LOG_ERROR,
+ "failed to set 'volfile-key'");
+ }
+ ret = dict_set_uint32 (options, "volfile-checksum",
+ this->graph->volfile_checksum);
+ if (ret)
+ gf_log (this->name, GF_LOG_ERROR,
+ "failed to set 'volfile-checksum'");
+ }
+
+ ret = dict_set_int16 (options, "clnt-lk-version",
+ client_get_lk_ver (conf));
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "failed to set clnt-lk-version(%"PRIu32") in handshake msg",
+ client_get_lk_ver (conf));
+ }
+
+ ret = dict_serialized_length (options);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "failed to get serialized length of dict");
+ ret = -1;
+ goto fail;
+ }
+ req.dict.dict_len = ret;
+ req.dict.dict_val = GF_CALLOC (1, req.dict.dict_len,
+ gf_client_mt_clnt_req_buf_t);
+ ret = dict_serialize (options, req.dict.dict_val);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "failed to serialize dictionary");
+ goto fail;
+ }
+
+ fr = create_frame (this, this->ctx->pool);
+ if (!fr)
+ goto fail;
+
+ ret = client_submit_request (this, &req, fr, conf->handshake,
+ GF_HNDSK_SETVOLUME, client_setvolume_cbk,
+ NULL, NULL, 0, NULL, 0, NULL,
+ (xdrproc_t)xdr_gf_setvolume_req);
+
+fail:
+ GF_FREE (req.dict.dict_val);
+
+ return ret;
+}
+
+int
+select_server_supported_programs (xlator_t *this, gf_prog_detail *prog)
+{
+ gf_prog_detail *trav = NULL;
+ clnt_conf_t *conf = NULL;
+ int ret = -1;
+
+ if (!this || !prog) {
+ gf_log (THIS->name, GF_LOG_WARNING,
+ "xlator not found OR RPC program not found");
+ goto out;
+ }
+
+ conf = this->private;
+ trav = prog;
+
+ while (trav) {
+ /* Select 'programs' */
+ if ((clnt3_3_fop_prog.prognum == trav->prognum) &&
+ (clnt3_3_fop_prog.progver == trav->progver)) {
+ conf->fops = &clnt3_3_fop_prog;
+ gf_log (this->name, GF_LOG_INFO,
+ "Using Program %s, Num (%"PRId64"), "
+ "Version (%"PRId64")",
+ trav->progname, trav->prognum, trav->progver);
+ ret = 0;
+ }
+ if (ret) {
+ gf_log (this->name, GF_LOG_TRACE,
+ "%s (%"PRId64") not supported", trav->progname,
+ trav->progver);
+ }
+ trav = trav->next;
+ }
+
+out:
+ return ret;
+}
+
+
+int
+server_has_portmap (xlator_t *this, gf_prog_detail *prog)
+{
+ gf_prog_detail *trav = NULL;
+ int ret = -1;
+
+ if (!this || !prog) {
+ gf_log (THIS->name, GF_LOG_WARNING,
+ "xlator not found OR RPC program not found");
+ goto out;
+ }
+
+ trav = prog;
+
+ while (trav) {
+ if ((trav->prognum == GLUSTER_PMAP_PROGRAM) &&
+ (trav->progver == GLUSTER_PMAP_VERSION)) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "detected portmapper on server");
+ ret = 0;
+ break;
+ }
+ trav = trav->next;
+ }
+
+out:
+ return ret;
+}
+
+
+int
+client_query_portmap_cbk (struct rpc_req *req, struct iovec *iov, int count, void *myframe)
+{
+ struct pmap_port_by_brick_rsp rsp = {0,};
+ call_frame_t *frame = NULL;
+ clnt_conf_t *conf = NULL;
+ int ret = -1;
+ struct rpc_clnt_config config = {0, };
+ xlator_t *this = NULL;
+
+ frame = myframe;
+ if (!frame || !frame->this || !frame->this->private) {
+ gf_log (THIS->name, GF_LOG_WARNING,
+ "frame not found with rpc request");
+ goto out;
+ }
+ this = frame->this;
+ conf = frame->this->private;
+
+ if (-1 == req->rpc_status) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "received RPC status error, try again later");
+ goto out;
+ }
+
+ ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_pmap_port_by_brick_rsp);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "XDR decoding failed");
+ goto out;
+ }
+
+ if (-1 == rsp.op_ret) {
+ ret = -1;
+ gf_log (this->name, ((!conf->portmap_err_logged) ?
+ GF_LOG_ERROR : GF_LOG_DEBUG),
+ "failed to get the port number for remote subvolume. "
+ "Please run 'gluster volume status' on server to see "
+ "if brick process is running.");
+ conf->portmap_err_logged = 1;
+ goto out;
+ }
+
+ conf->portmap_err_logged = 0;
+ conf->disconnect_err_logged = 0;
+
+ config.remote_port = rsp.port;
+ rpc_clnt_reconfig (conf->rpc, &config);
+
+ conf->skip_notify = 1;
+ conf->quick_reconnect = 1;
+
+out:
+ if (frame)
+ STACK_DESTROY (frame->root);
+
+ if (conf) {
+ /* Need this to connect the same transport on different port */
+ /* ie, glusterd to glusterfsd */
+ rpc_transport_disconnect (conf->rpc->conn.trans);
+ }
+
+ return ret;
+}
+
+
+int
+client_query_portmap (xlator_t *this, struct rpc_clnt *rpc)
+{
+ int ret = -1;
+ pmap_port_by_brick_req req = {0,};
+ call_frame_t *fr = NULL;
+ clnt_conf_t *conf = NULL;
+ dict_t *options = NULL;
+ char *remote_subvol = NULL;
+ char *xprt = NULL;
+ char brick_name[PATH_MAX] = {0,};
+
+ options = this->options;
+ conf = this->private;
+
+ ret = dict_get_str (options, "remote-subvolume", &remote_subvol);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "remote-subvolume not set in volfile");
+ goto fail;
+ }
+
+ req.brick = remote_subvol;
+
+ /* FIXME: Dirty work around */
+ if (!dict_get_str (options, "transport-type", &xprt)) {
+ /* This logic is required only in case of 'rdma' client
+ transport-type and the volume is of 'tcp,rdma'
+ transport type. */
+ if (!strcmp (xprt, "rdma")) {
+ if (!conf->need_different_port) {
+ snprintf (brick_name, PATH_MAX, "%s.rdma",
+ remote_subvol);
+ req.brick = brick_name;
+ conf->need_different_port = 1;
+ conf->skip_notify = 1;
+ } else {
+ conf->need_different_port = 0;
+ conf->skip_notify = 0;
+ }
+ }
+ }
+
+ fr = create_frame (this, this->ctx->pool);
+ if (!fr) {
+ ret = -1;
+ goto fail;
+ }
+
+ ret = client_submit_request (this, &req, fr, &clnt_pmap_prog,
+ GF_PMAP_PORTBYBRICK,
+ client_query_portmap_cbk,
+ NULL, NULL, 0, NULL, 0, NULL,
+ (xdrproc_t)xdr_pmap_port_by_brick_req);
+
+fail:
+ return ret;
+}
+
+
+int
+client_dump_version_cbk (struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ gf_dump_rsp rsp = {0,};
+ gf_prog_detail *trav = NULL;
+ gf_prog_detail *next = NULL;
+ call_frame_t *frame = NULL;
+ clnt_conf_t *conf = NULL;
+ int ret = 0;
+
+ frame = myframe;
+ conf = frame->this->private;
+
+ if (-1 == req->rpc_status) {
+ gf_log (frame->this->name, GF_LOG_WARNING,
+ "received RPC status error");
+ goto out;
+ }
+
+ ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_dump_rsp);
+ if (ret < 0) {
+ gf_log (frame->this->name, GF_LOG_ERROR, "XDR decoding failed");
+ goto out;
+ }
+ if (-1 == rsp.op_ret) {
+ gf_log (frame->this->name, GF_LOG_WARNING,
+ "failed to get the 'versions' from server");
+ goto out;
+ }
+
+ if (server_has_portmap (frame->this, rsp.prog) == 0) {
+ ret = client_query_portmap (frame->this, conf->rpc);
+ goto out;
+ }
+
+ /* Check for the proper version string */
+ /* Reply in "Name:Program-Number:Program-Version,..." format */
+ ret = select_server_supported_programs (frame->this, rsp.prog);
+ if (ret) {
+ gf_log (frame->this->name, GF_LOG_ERROR,
+ "server doesn't support the version");
+ goto out;
+ }
+
+ client_setvolume (frame->this, conf->rpc);
+
+out:
+ /* don't use GF_FREE, buffer was allocated by libc */
+ if (rsp.prog) {
+ trav = rsp.prog;
+ while (trav) {
+ next = trav->next;
+ free (trav->progname);
+ free (trav);
+ trav = next;
+ }
+ }
+
+ STACK_DESTROY (frame->root);
+
+ if (ret != 0)
+ rpc_transport_disconnect (conf->rpc->conn.trans);
+
+ return ret;
+}
+
+int
+client_handshake (xlator_t *this, struct rpc_clnt *rpc)
+{
+ call_frame_t *frame = NULL;
+ clnt_conf_t *conf = NULL;
+ gf_dump_req req = {0,};
+ int ret = 0;
+
+ conf = this->private;
+ if (!conf->handshake) {
+ gf_log (this->name, GF_LOG_WARNING, "handshake program not found");
+ goto out;
+ }
+
+ frame = create_frame (this, this->ctx->pool);
+ if (!frame)
+ goto out;
+
+ req.gfs_id = 0xbabe;
+ ret = client_submit_request (this, &req, frame, conf->dump,
+ GF_DUMP_DUMP, client_dump_version_cbk,
+ NULL, NULL, 0, NULL, 0,
+ NULL, (xdrproc_t)xdr_gf_dump_req);
+
+out:
+ return ret;
+}
+
+char *clnt_handshake_procs[GF_HNDSK_MAXVALUE] = {
+ [GF_HNDSK_NULL] = "NULL",
+ [GF_HNDSK_SETVOLUME] = "SETVOLUME",
+ [GF_HNDSK_GETSPEC] = "GETSPEC",
+ [GF_HNDSK_PING] = "PING",
+ [GF_HNDSK_SET_LK_VER] = "SET_LK_VER"
+};
+
+rpc_clnt_prog_t clnt_handshake_prog = {
+ .progname = "GlusterFS Handshake",
+ .prognum = GLUSTER_HNDSK_PROGRAM,
+ .progver = GLUSTER_HNDSK_VERSION,
+ .procnames = clnt_handshake_procs,
+};
+
+char *clnt_dump_proc[GF_DUMP_MAXVALUE] = {
+ [GF_DUMP_NULL] = "NULL",
+ [GF_DUMP_DUMP] = "DUMP",
+};
+
+rpc_clnt_prog_t clnt_dump_prog = {
+ .progname = "GF-DUMP",
+ .prognum = GLUSTER_DUMP_PROGRAM,
+ .progver = GLUSTER_DUMP_VERSION,
+ .procnames = clnt_dump_proc,
+};
+
+char *clnt_pmap_procs[GF_PMAP_MAXVALUE] = {
+ [GF_PMAP_PORTBYBRICK] = "PORTBYBRICK",
+};
+
+rpc_clnt_prog_t clnt_pmap_prog = {
+ .progname = "PORTMAP",
+ .prognum = GLUSTER_PMAP_PROGRAM,
+ .progver = GLUSTER_PMAP_VERSION,
+ .procnames = clnt_pmap_procs,
+};
diff --git a/xlators/protocol/client/src/client-helpers.c b/xlators/protocol/client/src/client-helpers.c
new file mode 100644
index 000000000..5d9f00fdc
--- /dev/null
+++ b/xlators/protocol/client/src/client-helpers.c
@@ -0,0 +1,349 @@
+/*
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
+ This file is part of GlusterFS.
+
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
+*/
+
+#ifndef _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+#include "client.h"
+#include "fd.h"
+
+int
+client_fd_lk_list_empty (fd_lk_ctx_t *lk_ctx, gf_boolean_t try_lock)
+{
+ int ret = 1;
+
+ if (!lk_ctx) {
+ ret = -1;
+ goto out;
+ }
+
+ if (try_lock) {
+ ret = TRY_LOCK (&lk_ctx->lock);
+ if (ret != 0) {
+ ret = -1;
+ goto out;
+ }
+ } else {
+ LOCK (&lk_ctx->lock);
+ }
+
+ ret = list_empty (&lk_ctx->lk_list);
+ UNLOCK (&lk_ctx->lock);
+out:
+ return ret;
+}
+
+clnt_fd_ctx_t *
+this_fd_del_ctx (fd_t *file, xlator_t *this)
+{
+ int dict_ret = -1;
+ uint64_t ctxaddr = 0;
+
+ GF_VALIDATE_OR_GOTO ("client", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, file, out);
+
+ dict_ret = fd_ctx_del (file, this, &ctxaddr);
+
+ if (dict_ret < 0) {
+ ctxaddr = 0;
+ }
+
+out:
+ return (clnt_fd_ctx_t *)(unsigned long)ctxaddr;
+}
+
+
+clnt_fd_ctx_t *
+this_fd_get_ctx (fd_t *file, xlator_t *this)
+{
+ int dict_ret = -1;
+ uint64_t ctxaddr = 0;
+
+ GF_VALIDATE_OR_GOTO ("client", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, file, out);
+
+ dict_ret = fd_ctx_get (file, this, &ctxaddr);
+
+ if (dict_ret < 0) {
+ ctxaddr = 0;
+ }
+
+out:
+ return (clnt_fd_ctx_t *)(unsigned long)ctxaddr;
+}
+
+
+void
+this_fd_set_ctx (fd_t *file, xlator_t *this, loc_t *loc, clnt_fd_ctx_t *ctx)
+{
+ uint64_t oldaddr = 0;
+ int32_t ret = -1;
+
+ GF_VALIDATE_OR_GOTO ("client", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, file, out);
+
+ ret = fd_ctx_get (file, this, &oldaddr);
+ if (ret >= 0) {
+ if (loc)
+ gf_log (this->name, GF_LOG_INFO,
+ "%s (%s): trying duplicate remote fd set. ",
+ loc->path, uuid_utoa (loc->inode->gfid));
+ else
+ gf_log (this->name, GF_LOG_INFO,
+ "%p: trying duplicate remote fd set. ", file);
+ }
+
+ ret = fd_ctx_set (file, this, (uint64_t)(unsigned long)ctx);
+ if (ret < 0) {
+ if (loc)
+ gf_log (this->name, GF_LOG_WARNING,
+ "%s (%s): failed to set remote fd",
+ loc->path, uuid_utoa (loc->inode->gfid));
+ else
+ gf_log (this->name, GF_LOG_WARNING,
+ "%p: failed to set remote fd", file);
+ }
+out:
+ return;
+}
+
+
+int
+client_local_wipe (clnt_local_t *local)
+{
+ if (local) {
+ loc_wipe (&local->loc);
+ loc_wipe (&local->loc2);
+
+ if (local->fd) {
+ fd_unref (local->fd);
+ }
+
+ if (local->iobref) {
+ iobref_unref (local->iobref);
+ }
+
+ GF_FREE (local->name);
+
+ mem_put (local);
+ }
+
+ return 0;
+}
+
+int
+unserialize_rsp_dirent (struct gfs3_readdir_rsp *rsp, gf_dirent_t *entries)
+{
+ struct gfs3_dirlist *trav = NULL;
+ gf_dirent_t *entry = NULL;
+ int entry_len = 0;
+ int ret = -1;
+
+ trav = rsp->reply;
+ while (trav) {
+ entry_len = gf_dirent_size (trav->name);
+ entry = GF_CALLOC (1, entry_len, gf_common_mt_gf_dirent_t);
+ if (!entry)
+ goto out;
+
+ entry->d_ino = trav->d_ino;
+ entry->d_off = trav->d_off;
+ entry->d_len = trav->d_len;
+ entry->d_type = trav->d_type;
+
+ strcpy (entry->d_name, trav->name);
+
+ list_add_tail (&entry->list, &entries->list);
+
+ trav = trav->nextentry;
+ }
+
+ ret = 0;
+out:
+ return ret;
+}
+
+int
+unserialize_rsp_direntp (xlator_t *this, fd_t *fd,
+ struct gfs3_readdirp_rsp *rsp, gf_dirent_t *entries)
+{
+ struct gfs3_dirplist *trav = NULL;
+ char *buf = NULL;
+ gf_dirent_t *entry = NULL;
+ inode_table_t *itable = NULL;
+ int entry_len = 0;
+ int ret = -1;
+
+ trav = rsp->reply;
+
+ if (fd)
+ itable = fd->inode->table;
+
+ while (trav) {
+ entry_len = gf_dirent_size (trav->name);
+ entry = GF_CALLOC (1, entry_len, gf_common_mt_gf_dirent_t);
+ if (!entry)
+ goto out;
+
+ entry->d_ino = trav->d_ino;
+ entry->d_off = trav->d_off;
+ entry->d_len = trav->d_len;
+ entry->d_type = trav->d_type;
+
+ gf_stat_to_iatt (&trav->stat, &entry->d_stat);
+
+ strcpy (entry->d_name, trav->name);
+
+ if (trav->dict.dict_val) {
+ /* Dictionary is sent along with response */
+ buf = memdup (trav->dict.dict_val, trav->dict.dict_len);
+ if (!buf)
+ goto out;
+
+ entry->dict = dict_new ();
+
+ ret = dict_unserialize (buf, trav->dict.dict_len,
+ &entry->dict);
+ if (ret < 0) {
+ gf_log (THIS->name, GF_LOG_WARNING,
+ "failed to unserialize xattr dict");
+ errno = EINVAL;
+ goto out;
+ }
+ entry->dict->extra_free = buf;
+ buf = NULL;
+ }
+
+ entry->inode = inode_find (itable, entry->d_stat.ia_gfid);
+ if (!entry->inode)
+ entry->inode = inode_new (itable);
+
+ list_add_tail (&entry->list, &entries->list);
+
+ trav = trav->nextentry;
+ }
+
+ ret = 0;
+out:
+ return ret;
+}
+
+int
+clnt_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;
+ /* on client, the rpc lib allocates this */
+ free (prev->dict.dict_val);
+ free (prev->name);
+ free (prev);
+ prev = trav;
+ }
+
+ return 0;
+}
+
+int
+clnt_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;
+ /* on client, the rpc lib allocates this */
+ free (prev->name);
+ free (prev);
+ prev = trav;
+ }
+
+ return 0;
+}
+
+int
+client_get_remote_fd (xlator_t *this, fd_t *fd, int flags, int64_t *remote_fd)
+{
+ clnt_fd_ctx_t *fdctx = NULL;
+ clnt_conf_t *conf = NULL;
+
+ GF_VALIDATE_OR_GOTO (this->name, fd, out);
+ GF_VALIDATE_OR_GOTO (this->name, remote_fd, out);
+
+ conf = this->private;
+ pthread_mutex_lock (&conf->lock);
+ {
+ fdctx = this_fd_get_ctx (fd, this);
+ if (!fdctx)
+ *remote_fd = GF_ANON_FD_NO;
+ else if (__is_fd_reopen_in_progress (fdctx))
+ *remote_fd = -1;
+ else
+ *remote_fd = fdctx->remote_fd;
+ }
+ pthread_mutex_unlock (&conf->lock);
+
+ if ((flags & FALLBACK_TO_ANON_FD) && (*remote_fd == -1))
+ *remote_fd = GF_ANON_FD_NO;
+
+ return 0;
+out:
+ return -1;
+}
+
+gf_boolean_t
+client_is_reopen_needed (fd_t *fd, xlator_t *this, int64_t remote_fd)
+{
+ clnt_fd_ctx_t *fdctx = NULL;
+
+ fdctx = this_fd_get_ctx (fd, this);
+ if (fdctx && (fdctx->remote_fd == -1) &&
+ (remote_fd == GF_ANON_FD_NO))
+ return _gf_true;
+ return _gf_false;
+}
+
+int
+client_fd_fop_prepare_local (call_frame_t *frame, fd_t *fd, int64_t remote_fd)
+{
+ xlator_t *this = NULL;
+ clnt_conf_t *conf = NULL;
+ clnt_local_t *local = NULL;
+ int ret = 0;
+
+ this = frame->this;
+ conf = this->private;
+
+ if (!frame || !fd) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ frame->local = mem_get0 (this->local_pool);
+ if (frame->local == NULL) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ local = frame->local;
+ local->fd = fd_ref (fd);
+ local->attempt_reopen = client_is_reopen_needed (fd, this, remote_fd);
+ return 0;
+out:
+ return ret;
+}
diff --git a/xlators/protocol/client/src/client-lk.c b/xlators/protocol/client/src/client-lk.c
new file mode 100644
index 000000000..1fd8f0d50
--- /dev/null
+++ b/xlators/protocol/client/src/client-lk.c
@@ -0,0 +1,573 @@
+/*
+ Copyright (c) 2008-2012 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 "common-utils.h"
+#include "xlator.h"
+#include "client.h"
+#include "lkowner.h"
+
+static void
+__insert_and_merge (clnt_fd_ctx_t *fdctx, client_posix_lock_t *lock);
+
+static void
+__dump_client_lock (client_posix_lock_t *lock)
+{
+ xlator_t *this = NULL;
+
+ this = THIS;
+
+ gf_log (this->name, GF_LOG_INFO,
+ "{fd=%p}"
+ "{%s lk-owner:%s %"PRId64" - %"PRId64"}"
+ "{start=%"PRId64" end=%"PRId64"}",
+ lock->fd,
+ lock->fl_type == F_WRLCK ? "Write-Lock" : "Read-Lock",
+ lkowner_utoa (&lock->owner),
+ lock->user_flock.l_start,
+ lock->user_flock.l_len,
+ lock->fl_start,
+ lock->fl_end);
+}
+
+static int
+dump_client_locks_fd (clnt_fd_ctx_t *fdctx)
+{
+ client_posix_lock_t *lock = NULL;
+ int count = 0;
+
+ pthread_mutex_lock (&fdctx->mutex);
+ {
+ list_for_each_entry (lock, &fdctx->lock_list, list) {
+ __dump_client_lock (lock);
+ count++;
+ }
+ }
+ pthread_mutex_unlock (&fdctx->mutex);
+
+ return count;
+
+}
+
+int
+dump_client_locks (inode_t *inode)
+{
+ fd_t *fd = NULL;
+ clnt_conf_t *conf = NULL;
+ xlator_t *this = NULL;
+ clnt_fd_ctx_t *fdctx = NULL;
+
+ int total_count = 0;
+ int locks_fd_count = 0;
+
+ this = THIS;
+ conf = this->private;
+
+ LOCK (&inode->lock);
+ {
+ list_for_each_entry (fd, &inode->fd_list, inode_list) {
+ locks_fd_count = 0;
+
+ pthread_mutex_lock (&conf->lock);
+ {
+ fdctx = this_fd_get_ctx (fd, this);
+ }
+ pthread_mutex_unlock (&conf->lock);
+
+ if (fdctx)
+ locks_fd_count = dump_client_locks_fd (fdctx);
+
+ total_count += locks_fd_count;
+ }
+
+ }
+ UNLOCK (&inode->lock);
+
+ return total_count;
+
+}
+
+static off_t
+__get_lock_length (off_t start, off_t end)
+{
+ if (end == LLONG_MAX)
+ return 0;
+ else
+ return (end - start + 1);
+}
+
+/* Add two locks */
+static client_posix_lock_t *
+add_locks (client_posix_lock_t *l1, client_posix_lock_t *l2)
+{
+ client_posix_lock_t *sum = NULL;
+
+ sum = GF_CALLOC (1, sizeof (*sum), gf_client_mt_clnt_lock_t);
+ if (!sum)
+ return NULL;
+
+ sum->fl_start = min (l1->fl_start, l2->fl_start);
+ sum->fl_end = max (l1->fl_end, l2->fl_end);
+
+ sum->user_flock.l_start = sum->fl_start;
+ sum->user_flock.l_len = __get_lock_length (sum->fl_start,
+ sum->fl_end);
+
+ return sum;
+}
+
+
+/* Return true if the locks overlap, false otherwise */
+static int
+locks_overlap (client_posix_lock_t *l1, client_posix_lock_t *l2)
+{
+ /*
+ Note:
+ FUSE always gives us absolute offsets, so no need to worry
+ about SEEK_CUR or SEEK_END
+ */
+
+ return ((l1->fl_end >= l2->fl_start) &&
+ (l2->fl_end >= l1->fl_start));
+}
+
+static void
+__delete_client_lock (client_posix_lock_t *lock)
+{
+ list_del_init (&lock->list);
+}
+
+/* Destroy a posix_lock */
+static void
+__destroy_client_lock (client_posix_lock_t *lock)
+{
+ GF_FREE (lock);
+}
+
+/* Subtract two locks */
+struct _values {
+ client_posix_lock_t *locks[3];
+};
+
+/* {big} must always be contained inside {small} */
+static struct _values
+subtract_locks (client_posix_lock_t *big, client_posix_lock_t *small)
+{
+ struct _values v = { .locks = {0, 0, 0} };
+
+ if ((big->fl_start == small->fl_start) &&
+ (big->fl_end == small->fl_end)) {
+ /* both edges coincide with big */
+ v.locks[0] = GF_CALLOC (1, sizeof (client_posix_lock_t),
+ gf_client_mt_clnt_lock_t );
+ GF_ASSERT (v.locks[0]);
+ memcpy (v.locks[0], big, sizeof (client_posix_lock_t));
+ v.locks[0]->fl_type = small->fl_type;
+ }
+ else if ((small->fl_start > big->fl_start) &&
+ (small->fl_end < big->fl_end)) {
+ /* both edges lie inside big */
+ v.locks[0] = GF_CALLOC (1, sizeof (client_posix_lock_t),
+ gf_client_mt_clnt_lock_t);
+ GF_ASSERT (v.locks[0]);
+ v.locks[1] = GF_CALLOC (1, sizeof (client_posix_lock_t),
+ gf_client_mt_clnt_lock_t);
+ GF_ASSERT (v.locks[1]);
+ v.locks[2] = GF_CALLOC (1, sizeof (client_posix_lock_t),
+ gf_client_mt_clnt_lock_t);
+ GF_ASSERT (v.locks[2]);
+
+ memcpy (v.locks[0], big, sizeof (client_posix_lock_t));
+ v.locks[0]->fl_end = small->fl_start - 1;
+ v.locks[0]->user_flock.l_len = __get_lock_length (v.locks[0]->fl_start,
+ v.locks[0]->fl_end);
+
+ memcpy (v.locks[1], small, sizeof (client_posix_lock_t));
+ memcpy (v.locks[2], big, sizeof (client_posix_lock_t));
+ v.locks[2]->fl_start = small->fl_end + 1;
+ v.locks[2]->user_flock.l_start = small->fl_end + 1;
+ }
+ /* one edge coincides with big */
+ else if (small->fl_start == big->fl_start) {
+ v.locks[0] = GF_CALLOC (1, sizeof (client_posix_lock_t),
+ gf_client_mt_clnt_lock_t);
+ GF_ASSERT (v.locks[0]);
+ v.locks[1] = GF_CALLOC (1, sizeof (client_posix_lock_t),
+ gf_client_mt_clnt_lock_t);
+ GF_ASSERT (v.locks[1]);
+
+ memcpy (v.locks[0], big, sizeof (client_posix_lock_t));
+ v.locks[0]->fl_start = small->fl_end + 1;
+ v.locks[0]->user_flock.l_start = small->fl_end + 1;
+
+ memcpy (v.locks[1], small, sizeof (client_posix_lock_t));
+ }
+ else if (small->fl_end == big->fl_end) {
+ v.locks[0] = GF_CALLOC (1, sizeof (client_posix_lock_t),
+ gf_client_mt_clnt_lock_t);
+ GF_ASSERT (v.locks[0]);
+ v.locks[1] = GF_CALLOC (1, sizeof (client_posix_lock_t),
+ gf_client_mt_clnt_lock_t);
+ GF_ASSERT (v.locks[1]);
+
+ memcpy (v.locks[0], big, sizeof (client_posix_lock_t));
+ v.locks[0]->fl_end = small->fl_start - 1;
+ v.locks[0]->user_flock.l_len = __get_lock_length (v.locks[0]->fl_start,
+ v.locks[0]->fl_end);
+
+ memcpy (v.locks[1], small, sizeof (client_posix_lock_t));
+ }
+ else {
+ /* LOG-TODO : decide what more info is required here*/
+ gf_log ("client-protocol", GF_LOG_CRITICAL,
+ "Unexpected case in subtract_locks. Please send "
+ "a bug report to gluster-devel@nongnu.org");
+ }
+
+ return v;
+}
+
+static void
+__delete_unlck_locks (clnt_fd_ctx_t *fdctx)
+{
+ client_posix_lock_t *l = NULL;
+ client_posix_lock_t *tmp = NULL;
+
+ list_for_each_entry_safe (l, tmp, &fdctx->lock_list, list) {
+ if (l->fl_type == F_UNLCK) {
+ __delete_client_lock (l);
+ __destroy_client_lock (l);
+ }
+ }
+}
+
+static void
+__insert_lock (clnt_fd_ctx_t *fdctx, client_posix_lock_t *lock)
+{
+ list_add_tail (&lock->list, &fdctx->lock_list);
+
+ return;
+}
+
+static void
+__insert_and_merge (clnt_fd_ctx_t *fdctx, client_posix_lock_t *lock)
+{
+ client_posix_lock_t *conf = NULL;
+ client_posix_lock_t *t = NULL;
+ client_posix_lock_t *sum = NULL;
+ int i = 0;
+ struct _values v = { .locks = {0, 0, 0} };
+
+ list_for_each_entry_safe (conf, t, &fdctx->lock_list, list) {
+ if (!locks_overlap (conf, lock))
+ continue;
+
+ if (is_same_lkowner (&conf->owner, &lock->owner)) {
+ if (conf->fl_type == lock->fl_type) {
+ sum = add_locks (lock, conf);
+
+ sum->fd = lock->fd;
+
+ __delete_client_lock (conf);
+ __destroy_client_lock (conf);
+
+ __destroy_client_lock (lock);
+ __insert_and_merge (fdctx, sum);
+
+ return;
+ } else {
+ sum = add_locks (lock, conf);
+
+ sum->fd = conf->fd;
+ sum->owner = conf->owner;
+
+ v = subtract_locks (sum, lock);
+
+ __delete_client_lock (conf);
+ __destroy_client_lock (conf);
+
+ __delete_client_lock (lock);
+ __destroy_client_lock (lock);
+
+ __destroy_client_lock (sum);
+
+ for (i = 0; i < 3; i++) {
+ if (!v.locks[i])
+ continue;
+
+ INIT_LIST_HEAD (&v.locks[i]->list);
+ __insert_and_merge (fdctx,
+ v.locks[i]);
+ }
+
+ __delete_unlck_locks (fdctx);
+ return;
+ }
+ }
+
+ if (lock->fl_type == F_UNLCK) {
+ continue;
+ }
+
+ if ((conf->fl_type == F_RDLCK) && (lock->fl_type == F_RDLCK)) {
+ __insert_lock (fdctx, lock);
+ return;
+ }
+ }
+
+ /* no conflicts, so just insert */
+ if (lock->fl_type != F_UNLCK) {
+ __insert_lock (fdctx, lock);
+ } else {
+ __destroy_client_lock (lock);
+ }
+}
+
+static void
+client_setlk (clnt_fd_ctx_t *fdctx, client_posix_lock_t *lock)
+{
+ pthread_mutex_lock (&fdctx->mutex);
+ {
+ __insert_and_merge (fdctx, lock);
+ }
+ pthread_mutex_unlock (&fdctx->mutex);
+
+ return;
+}
+
+static void
+destroy_client_lock (client_posix_lock_t *lock)
+{
+ GF_FREE (lock);
+}
+
+int32_t
+delete_granted_locks_owner (fd_t *fd, gf_lkowner_t *owner)
+{
+ clnt_fd_ctx_t *fdctx = NULL;
+ client_posix_lock_t *lock = NULL;
+ client_posix_lock_t *tmp = NULL;
+ xlator_t *this = NULL;
+
+ struct list_head delete_list;
+ int ret = 0;
+ int count = 0;
+
+ INIT_LIST_HEAD (&delete_list);
+ this = THIS;
+ fdctx = this_fd_get_ctx (fd, this);
+ if (!fdctx) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "fdctx not valid");
+ ret = -1;
+ goto out;
+ }
+
+ pthread_mutex_lock (&fdctx->mutex);
+ {
+ list_for_each_entry_safe (lock, tmp, &fdctx->lock_list, list) {
+ if (!is_same_lkowner (&lock->owner, owner)) {
+ list_del_init (&lock->list);
+ list_add_tail (&lock->list, &delete_list);
+ count++;
+ }
+ }
+ }
+ pthread_mutex_unlock (&fdctx->mutex);
+
+ list_for_each_entry_safe (lock, tmp, &delete_list, list) {
+ list_del_init (&lock->list);
+ destroy_client_lock (lock);
+ }
+
+ /* FIXME: Need to actually print the locks instead of count */
+ gf_log (this->name, GF_LOG_TRACE,
+ "Number of locks cleared=%d", count);
+
+out:
+ return ret;
+}
+
+int32_t
+delete_granted_locks_fd (clnt_fd_ctx_t *fdctx)
+{
+ client_posix_lock_t *lock = NULL;
+ client_posix_lock_t *tmp = NULL;
+ xlator_t *this = NULL;
+
+ struct list_head delete_list;
+ int ret = 0;
+ int count = 0;
+
+ INIT_LIST_HEAD (&delete_list);
+ this = THIS;
+
+ pthread_mutex_lock (&fdctx->mutex);
+ {
+ list_splice_init (&fdctx->lock_list, &delete_list);
+ }
+ pthread_mutex_unlock (&fdctx->mutex);
+
+ list_for_each_entry_safe (lock, tmp, &delete_list, list) {
+ list_del_init (&lock->list);
+ count++;
+ destroy_client_lock (lock);
+ }
+
+ /* FIXME: Need to actually print the locks instead of count */
+ gf_log (this->name, GF_LOG_TRACE,
+ "Number of locks cleared=%d", count);
+
+ return ret;
+}
+
+int32_t
+client_cmd_to_gf_cmd (int32_t cmd, int32_t *gf_cmd)
+{
+ int ret = 0;
+
+ if (cmd == F_GETLK || cmd == F_GETLK64)
+ *gf_cmd = GF_LK_GETLK;
+ else if (cmd == F_SETLK || cmd == F_SETLK64)
+ *gf_cmd = GF_LK_SETLK;
+ else if (cmd == F_SETLKW || cmd == F_SETLKW64)
+ *gf_cmd = GF_LK_SETLKW;
+ else if (cmd == F_RESLK_LCK)
+ *gf_cmd = GF_LK_RESLK_LCK;
+ else if (cmd == F_RESLK_LCKW)
+ *gf_cmd = GF_LK_RESLK_LCKW;
+ else if (cmd == F_RESLK_UNLCK)
+ *gf_cmd = GF_LK_RESLK_UNLCK;
+ else if (cmd == F_GETLK_FD)
+ *gf_cmd = GF_LK_GETLK_FD;
+ else
+ ret = -1;
+
+ return ret;
+
+}
+
+static client_posix_lock_t *
+new_client_lock (struct gf_flock *flock, gf_lkowner_t *owner,
+ int32_t cmd, fd_t *fd)
+{
+ client_posix_lock_t *new_lock = NULL;
+
+ new_lock = GF_CALLOC (1, sizeof (*new_lock),
+ gf_client_mt_clnt_lock_t);
+ if (!new_lock) {
+ goto out;
+ }
+
+ INIT_LIST_HEAD (&new_lock->list);
+ new_lock->fd = fd;
+ memcpy (&new_lock->user_flock, flock, sizeof (struct gf_flock));
+
+ new_lock->fl_type = flock->l_type;
+ new_lock->fl_start = flock->l_start;
+
+ if (flock->l_len == 0)
+ new_lock->fl_end = LLONG_MAX;
+ else
+ new_lock->fl_end = flock->l_start + flock->l_len - 1;
+
+ new_lock->owner = *owner;
+
+ new_lock->cmd = cmd; /* Not really useful */
+
+out:
+ return new_lock;
+}
+
+void
+client_save_number_fds (clnt_conf_t *conf, int count)
+{
+ LOCK (&conf->rec_lock);
+ {
+ conf->reopen_fd_count = count;
+ }
+ UNLOCK (&conf->rec_lock);
+}
+
+int
+client_add_lock_for_recovery (fd_t *fd, struct gf_flock *flock,
+ gf_lkowner_t *owner, int32_t cmd)
+{
+ clnt_fd_ctx_t *fdctx = NULL;
+ xlator_t *this = NULL;
+ client_posix_lock_t *lock = NULL;
+ clnt_conf_t *conf = NULL;
+
+ int ret = 0;
+
+ this = THIS;
+ conf = this->private;
+
+ pthread_mutex_lock (&conf->lock);
+ {
+ fdctx = this_fd_get_ctx (fd, this);
+ }
+ pthread_mutex_unlock (&conf->lock);
+
+ if (!fdctx) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "failed to get fd context. sending EBADFD");
+ ret = -EBADFD;
+ goto out;
+ }
+
+ lock = new_client_lock (flock, owner, cmd, fd);
+ if (!lock) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ client_setlk (fdctx, lock);
+
+out:
+ return ret;
+
+}
+
+int32_t
+client_dump_locks (char *name, inode_t *inode,
+ dict_t *dict)
+{
+ int ret = 0;
+ dict_t *new_dict = NULL;
+ char dict_string[256];
+
+ GF_ASSERT (dict);
+ new_dict = dict;
+
+ ret = dump_client_locks (inode);
+ snprintf (dict_string, 256, "%d locks dumped in log file", ret);
+
+ ret = dict_set_dynstr(new_dict, CLIENT_DUMP_LOCKS, dict_string);
+ if (ret) {
+ gf_log (THIS->name, GF_LOG_WARNING,
+ "could not set dict with %s", CLIENT_DUMP_LOCKS);
+ goto out;
+ }
+
+out:
+
+ return ret;
+}
+
+int32_t
+is_client_dump_locks_cmd (char *name)
+{
+ int ret = 0;
+
+ if (strcmp (name, CLIENT_DUMP_LOCKS) == 0)
+ ret = 1;
+
+ return ret;
+}
diff --git a/xlators/protocol/client/src/client-mem-types.h b/xlators/protocol/client/src/client-mem-types.h
new file mode 100644
index 000000000..f6573da2d
--- /dev/null
+++ b/xlators/protocol/client/src/client-mem-types.h
@@ -0,0 +1,25 @@
+/*
+ Copyright (c) 2008-2012 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 __CLIENT_MEM_TYPES_H__
+#define __CLIENT_MEM_TYPES_H__
+
+#include "mem-types.h"
+
+enum gf_client_mem_types_ {
+ gf_client_mt_clnt_conf_t = gf_common_mt_end + 1,
+ gf_client_mt_clnt_req_buf_t,
+ gf_client_mt_clnt_fdctx_t,
+ gf_client_mt_clnt_lock_t,
+ gf_client_mt_clnt_fd_lk_local_t,
+ gf_client_mt_end,
+};
+#endif /* __CLIENT_MEM_TYPES_H__ */
diff --git a/xlators/protocol/client/src/client-protocol.c b/xlators/protocol/client/src/client-protocol.c
deleted file mode 100644
index 3d2d0e5eb..000000000
--- a/xlators/protocol/client/src/client-protocol.c
+++ /dev/null
@@ -1,6403 +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 <inttypes.h>
-
-
-#include "glusterfs.h"
-#include "client-protocol.h"
-#include "compat.h"
-#include "dict.h"
-#include "protocol.h"
-#include "transport.h"
-#include "xlator.h"
-#include "logging.h"
-#include "timer.h"
-#include "defaults.h"
-#include "compat.h"
-#include "compat-errno.h"
-
-#include <sys/resource.h>
-#include <inttypes.h>
-
-/* for default_*_cbk functions */
-#include "defaults.c"
-#include "saved-frames.h"
-#include "common-utils.h"
-
-int protocol_client_cleanup (transport_t *trans);
-int protocol_client_interpret (xlator_t *this, transport_t *trans,
- char *hdr_p, size_t hdrlen,
- struct iobuf *iobuf);
-int
-protocol_client_xfer (call_frame_t *frame, xlator_t *this, transport_t *trans,
- int type, int op,
- gf_hdr_common_t *hdr, size_t hdrlen,
- struct iovec *vector, int count,
- struct iobref *iobref);
-
-static gf_op_t gf_fops[];
-static gf_op_t gf_mops[];
-static gf_op_t gf_cbks[];
-
-
-transport_t *
-client_channel (xlator_t *this, int id)
-{
- transport_t *trans = NULL;
- client_conf_t *conf = NULL;
- int i = 0;
- struct client_connection *conn = NULL;
-
- conf = this->private;
-
- trans = conf->transport[id];
- conn = trans->xl_private;
-
- if (conn->connected == 1)
- goto ret;
-
- for (i = 0; i < CHANNEL_MAX; i++) {
- trans = conf->transport[i];
- conn = trans->xl_private;
- if (conn->connected == 1)
- break;
- }
-
-ret:
- return trans;
-}
-
-
-static int
-this_fd_get (fd_t *file, xlator_t *this, int64_t *remote_fd)
-{
- int ret = 0;
- int dict_ret = -1;
- uint64_t tmp_fd = 0;
-
- GF_VALIDATE_OR_GOTO ("client", this, out);
- GF_VALIDATE_OR_GOTO (this->name, file, out);
- GF_VALIDATE_OR_GOTO (this->name, remote_fd, out);
-
- dict_ret = fd_ctx_get (file, this, &tmp_fd);
-
- if (dict_ret < 0) {
- ret = -1;
- }
- *remote_fd = (int64_t)tmp_fd;
-out:
- return ret;
-}
-
-
-static void
-this_fd_set (fd_t *file, xlator_t *this, loc_t *loc, int64_t fd)
-{
- uint64_t old_fd = 0;
- int32_t ret = -1;
-
- GF_VALIDATE_OR_GOTO ("client", this, out);
- GF_VALIDATE_OR_GOTO (this->name, file, out);
-
- ret = fd_ctx_get (file, this, &old_fd);
- if (ret >= 0) {
- gf_log (this->name, GF_LOG_DEBUG,
- "%s (%"PRId64"): trying duplicate remote fd set. "
- "%"PRId64" over-rides %"PRId64,
- loc->path, loc->inode->ino, fd, old_fd);
- }
-
- ret = fd_ctx_set (file, this, (uint64_t)fd);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_DEBUG,
- "%s (%"PRId64"): failed to set remote fd",
- loc->path, loc->inode->ino);
- }
-out:
- return;
-}
-
-
-static int
-client_local_wipe (client_local_t *local)
-{
- if (local) {
- loc_wipe (&local->loc);
-
- if (local->fd)
- fd_unref (local->fd);
-
- free (local);
- }
-
- return 0;
-}
-
-/*
- * lookup_frame - lookup call frame corresponding to a given callid
- * @trans: transport object
- * @callid: call id of the frame
- *
- * not for external reference
- */
-
-static call_frame_t *
-lookup_frame (transport_t *trans, int32_t op, int8_t type, int64_t callid)
-{
- client_connection_t *conn = NULL;
- call_frame_t *frame = NULL;
-
- conn = trans->xl_private;
-
- pthread_mutex_lock (&conn->lock);
- {
- frame = saved_frames_get (conn->saved_frames,
- op, type, callid);
- }
- pthread_mutex_unlock (&conn->lock);
-
- return frame;
-}
-
-
-static void
-call_bail (void *data)
-{
- client_connection_t *conn = NULL;
- struct timeval current;
- transport_t *trans = NULL;
- struct list_head list;
- struct saved_frame *saved_frame = NULL;
- struct saved_frame *trav = NULL;
- struct saved_frame *tmp = NULL;
- call_frame_t *frame = NULL;
- gf_hdr_common_t hdr = {0, };
- char **gf_op_list = NULL;
- gf_op_t *gf_ops = NULL;
- struct tm frame_sent_tm;
- char frame_sent[32] = {0,};
- struct timeval timeout = {0,};
- gf_timer_cbk_t timer_cbk = NULL;
-
- GF_VALIDATE_OR_GOTO("client", data, out);
- trans = data;
-
- conn = trans->xl_private;
-
- gettimeofday (&current, NULL);
- INIT_LIST_HEAD (&list);
-
- pthread_mutex_lock (&conn->lock);
- {
- /* Chaining to get call-always functionality from
- call-once timer */
- if (conn->timer) {
- timer_cbk = conn->timer->cbk;
-
- timeout.tv_sec = 10;
- timeout.tv_usec = 0;
-
- gf_timer_call_cancel (trans->xl->ctx, conn->timer);
- conn->timer = gf_timer_call_after (trans->xl->ctx,
- timeout,
- timer_cbk,
- trans);
- if (conn->timer == NULL) {
- gf_log (trans->xl->name, GF_LOG_DEBUG,
- "Cannot create bailout timer");
- }
- }
-
- do {
- saved_frame =
- saved_frames_get_timedout (conn->saved_frames,
- GF_OP_TYPE_MOP_REQUEST,
- conn->frame_timeout,
- &current);
- if (saved_frame)
- list_add (&saved_frame->list, &list);
-
- } while (saved_frame);
-
- do {
- saved_frame =
- saved_frames_get_timedout (conn->saved_frames,
- GF_OP_TYPE_FOP_REQUEST,
- conn->frame_timeout,
- &current);
- if (saved_frame)
- list_add (&saved_frame->list, &list);
- } while (saved_frame);
-
- do {
- saved_frame =
- saved_frames_get_timedout (conn->saved_frames,
- GF_OP_TYPE_CBK_REQUEST,
- conn->frame_timeout,
- &current);
- if (saved_frame)
- list_add (&saved_frame->list, &list);
- } while (saved_frame);
- }
- pthread_mutex_unlock (&conn->lock);
-
- hdr.rsp.op_ret = hton32 (-1);
- hdr.rsp.op_errno = hton32 (ENOTCONN);
-
- list_for_each_entry_safe (trav, tmp, &list, list) {
- switch (trav->type)
- {
- case GF_OP_TYPE_FOP_REQUEST:
- gf_ops = gf_fops;
- gf_op_list = gf_fop_list;
- break;
- case GF_OP_TYPE_MOP_REQUEST:
- gf_ops = gf_mops;
- gf_op_list = gf_mop_list;
- break;
- case GF_OP_TYPE_CBK_REQUEST:
- gf_ops = gf_cbks;
- gf_op_list = gf_cbk_list;
- break;
- }
-
- localtime_r (&trav->saved_at.tv_sec, &frame_sent_tm);
- strftime (frame_sent, 32, "%Y-%m-%d %H:%M:%S", &frame_sent_tm);
-
- gf_log (trans->xl->name, GF_LOG_ERROR,
- "bailing out frame %s(%d) "
- "frame sent = %s. frame-timeout = %d",
- gf_op_list[trav->op], trav->op,
- frame_sent, conn->frame_timeout);
-
- hdr.type = hton32 (trav->type);
- hdr.op = hton32 (trav->op);
-
- frame = trav->frame;
-
- gf_ops[trav->op] (frame, &hdr, sizeof (hdr), NULL);
-
- list_del_init (&trav->list);
- FREE (trav);
- }
-out:
- return;
-}
-
-
-void
-save_frame (transport_t *trans, call_frame_t *frame,
- int32_t op, int8_t type, uint64_t callid)
-{
- client_connection_t *conn = NULL;
- struct timeval timeout = {0, };
-
-
- conn = trans->xl_private;
-
- saved_frames_put (conn->saved_frames, frame, op, type, callid);
-
- if (conn->timer == NULL) {
- timeout.tv_sec = 10;
- timeout.tv_usec = 0;
- conn->timer = gf_timer_call_after (trans->xl->ctx, timeout,
- call_bail, (void *) trans);
- }
-}
-
-
-int
-client_get_forgets (xlator_t *this, client_forget_t *forget)
-{
- call_frame_t *fr = NULL;
- gf_hdr_common_t *hdr = NULL;
- size_t hdrlen = 0;
- gf_cbk_forget_req_t *req = NULL;
- int ret = -1;
- client_conf_t *conf = NULL;
- int count = 0;
- int index = 0;
-
- conf = this->private;
-
- if (conf->forget.count > 0) {
- count = conf->forget.count;
-
- hdrlen = gf_hdr_len (req, (count * sizeof (int64_t)));
- hdr = gf_hdr_new (req, (count * sizeof (int64_t)));
- GF_VALIDATE_OR_GOTO (this->name, hdr, out);
-
- req = gf_param (hdr);
-
- req->count = hton32 (count);
- for (index = 0; index < count; index++) {
- req->ino_array[index] =
- hton64 (conf->forget.ino_array[index]);
- }
-
- fr = create_frame (this, this->ctx->pool);
- GF_VALIDATE_OR_GOTO (this->name, fr, out);
-
- conf->forget.frames_in_transit++;
-
- forget->frame = fr;
- forget->hdr = hdr;
- forget->hdrlen = hdrlen;
-
- ret = count;
-
- conf->forget.count = 0;
- }
- out:
- return ret;
-}
-
-
-void
-client_ping_timer_expired (void *data)
-{
- xlator_t *this = NULL;
- transport_t *trans = NULL;
- client_conf_t *conf = NULL;
- client_connection_t *conn = NULL;
- int disconnect = 0;
- int transport_activity = 0;
- struct timeval timeout = {0, };
- struct timeval current = {0, };
-
- trans = data;
- this = trans->xl;
- conf = this->private;
- conn = trans->xl_private;
-
- pthread_mutex_lock (&conn->lock);
- {
- if (conn->ping_timer)
- gf_timer_call_cancel (trans->xl->ctx,
- conn->ping_timer);
- gettimeofday (&current, NULL);
-
- pthread_mutex_lock (&conf->mutex);
- {
- if (((current.tv_sec - conf->last_received.tv_sec) <
- conn->ping_timeout)
- || ((current.tv_sec - conf->last_sent.tv_sec) <
- conn->ping_timeout)) {
- transport_activity = 1;
- }
- }
- pthread_mutex_unlock (&conf->mutex);
-
- if (transport_activity) {
- gf_log (this->name, GF_LOG_TRACE,
- "ping timer expired but transport activity "
- "detected - not bailing transport");
- conn->transport_activity = 0;
- timeout.tv_sec = conn->ping_timeout;
- timeout.tv_usec = 0;
-
- conn->ping_timer =
- gf_timer_call_after (trans->xl->ctx, timeout,
- client_ping_timer_expired,
- (void *) trans);
- if (conn->ping_timer == NULL)
- gf_log (this->name, GF_LOG_DEBUG,
- "unable to setup timer");
-
- } else {
- conn->ping_started = 0;
- conn->ping_timer = NULL;
- disconnect = 1;
- }
- }
- pthread_mutex_unlock (&conn->lock);
- if (disconnect) {
- gf_log (this->name, GF_LOG_ERROR,
- "Server %s has not responded in the last %d "
- "seconds, disconnecting.",
- conf->transport[0]->peerinfo.identifier,
- conn->ping_timeout);
-
- transport_disconnect (conf->transport[0]);
- transport_disconnect (conf->transport[1]);
- }
-}
-
-
-void
-client_start_ping (void *data)
-{
- xlator_t *this = NULL;
- transport_t *trans = NULL;
- client_conf_t *conf = NULL;
- client_connection_t *conn = NULL;
- int32_t ret = -1;
- gf_hdr_common_t *hdr = NULL;
- struct timeval timeout = {0, };
- call_frame_t *dummy_frame = NULL;
- size_t hdrlen = -1;
- gf_mop_ping_req_t *req = NULL;
-
-
- trans = data;
- this = trans->xl;
- conf = this->private;
- conn = trans->xl_private;
-
- pthread_mutex_lock (&conn->lock);
- {
- if ((conn->saved_frames->count == 0) ||
- !conn->connected) {
- /* using goto looked ugly here,
- * hence getting out this way */
- if (conn->ping_timer)
- gf_timer_call_cancel (trans->xl->ctx,
- conn->ping_timer);
- conn->ping_timer = NULL;
- conn->ping_started = 0;
- /* unlock */
- pthread_mutex_unlock (&conn->lock);
- return;
- }
-
- if (conn->saved_frames->count < 0) {
- gf_log (this->name, GF_LOG_DEBUG,
- "saved_frames->count is %"PRId64,
- conn->saved_frames->count);
- conn->saved_frames->count = 0;
- }
- timeout.tv_sec = conn->ping_timeout;
- timeout.tv_usec = 0;
-
- if (conn->ping_timer)
- gf_timer_call_cancel (trans->xl->ctx,
- conn->ping_timer);
-
- conn->ping_timer =
- gf_timer_call_after (trans->xl->ctx, timeout,
- client_ping_timer_expired,
- (void *) trans);
-
- if (conn->ping_timer == NULL) {
- gf_log (this->name, GF_LOG_DEBUG,
- "unable to setup timer");
- } else {
- conn->ping_started = 1;
- }
- }
- pthread_mutex_unlock (&conn->lock);
-
- hdrlen = gf_hdr_len (req, 0);
- hdr = gf_hdr_new (req, 0);
-
- dummy_frame = create_frame (this, this->ctx->pool);
- dummy_frame->local = trans;
-
- ret = protocol_client_xfer (dummy_frame, this, trans,
- GF_OP_TYPE_MOP_REQUEST, GF_MOP_PING,
- hdr, hdrlen, NULL, 0, NULL);
-}
-
-
-int
-client_ping_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen,
- struct iobuf *iobuf)
-{
- xlator_t *this = NULL;
- transport_t *trans = NULL;
- client_connection_t *conn = NULL;
- struct timeval timeout = {0, };
- int op_ret = 0;
-
- trans = frame->local; frame->local = NULL;
- this = trans->xl;
- conn = trans->xl_private;
-
- op_ret = ntoh32 (hdr->rsp.op_ret);
-
- if (op_ret == -1) {
- /* timer expired and transport bailed out */
- gf_log (this->name, GF_LOG_DEBUG, "timer must have expired");
- goto out;
- }
-
- pthread_mutex_lock (&conn->lock);
- {
- timeout.tv_sec = conn->ping_timeout;
- timeout.tv_usec = 0;
-
- gf_timer_call_cancel (trans->xl->ctx,
- conn->ping_timer);
-
- conn->ping_timer =
- gf_timer_call_after (trans->xl->ctx, timeout,
- client_start_ping, (void *)trans);
- if (conn->ping_timer == NULL)
- gf_log (this->name, GF_LOG_DEBUG,
- "gf_timer_call_after() returned NULL");
- }
- pthread_mutex_unlock (&conn->lock);
-out:
- STACK_DESTROY (frame->root);
- return 0;
-}
-
-
-int
-protocol_client_xfer (call_frame_t *frame, xlator_t *this, transport_t *trans,
- int type, int op,
- gf_hdr_common_t *hdr, size_t hdrlen,
- struct iovec *vector, int count,
- struct iobref *iobref)
-{
- client_conf_t *conf = NULL;
- client_connection_t *conn = NULL;
- uint64_t callid = 0;
- int32_t ret = -1;
- int start_ping = 0;
- gf_hdr_common_t rsphdr = {0, };
- client_forget_t forget = {0, };
- uint8_t send_forget = 0;
-
-
- conf = this->private;
-
- if (!trans) {
- /* default to bulk op since it is 'safer' */
- trans = conf->transport[CHANNEL_BULK];
- }
- conn = trans->xl_private;
-
- if (!((type == GF_OP_TYPE_CBK_REQUEST) &&
- (op == GF_CBK_FORGET)))
- {
- LOCK (&conf->forget.lock);
- {
- ret = client_get_forgets (this, &forget);
- if (ret <= 0)
- send_forget = 0;
- else
- send_forget = 1;
- }
- UNLOCK (&conf->forget.lock);
-
- if (send_forget) {
- ret = protocol_client_xfer (forget.frame, this, NULL,
- GF_OP_TYPE_CBK_REQUEST,
- GF_CBK_FORGET,
- forget.hdr, forget.hdrlen,
- NULL, 0, NULL);
- }
- }
-
- pthread_mutex_lock (&conn->lock);
- {
- callid = ++conn->callid;
-
- hdr->callid = hton64 (callid);
- hdr->op = hton32 (op);
- hdr->type = hton32 (type);
-
- if (frame) {
- hdr->req.uid = hton32 (frame->root->uid);
- hdr->req.gid = hton32 (frame->root->gid);
- hdr->req.pid = hton32 (frame->root->pid);
- }
-
- if (conn->connected == 0)
- transport_connect (trans);
-
- ret = -1;
-
- if (conn->connected ||
- ((type == GF_OP_TYPE_MOP_REQUEST) &&
- (op == GF_MOP_SETVOLUME))) {
- ret = transport_submit (trans, (char *)hdr, hdrlen,
- vector, count, iobref);
- }
-
- if ((ret >= 0) && frame) {
- pthread_mutex_lock (&conf->mutex);
- {
- gettimeofday (&conf->last_sent, NULL);
- }
- pthread_mutex_unlock (&conf->mutex);
- save_frame (trans, frame, op, type, callid);
- }
-
- if (!conn->ping_started && (ret >= 0)) {
- start_ping = 1;
- }
- }
- pthread_mutex_unlock (&conn->lock);
-
- if (start_ping)
- client_start_ping ((void *) trans);
-
- if (frame && (ret < 0)) {
- rsphdr.op = op;
- rsphdr.rsp.op_ret = hton32 (-1);
- rsphdr.rsp.op_errno = hton32 (ENOTCONN);
-
- if (type == GF_OP_TYPE_FOP_REQUEST) {
- rsphdr.type = GF_OP_TYPE_FOP_REPLY;
- gf_fops[op] (frame, &rsphdr, sizeof (rsphdr), NULL);
- } else if (type == GF_OP_TYPE_MOP_REQUEST) {
- rsphdr.type = GF_OP_TYPE_MOP_REPLY;
- gf_mops[op] (frame, &rsphdr, sizeof (rsphdr), NULL);
- } else {
- rsphdr.type = GF_OP_TYPE_CBK_REPLY;
- gf_cbks[op] (frame, &rsphdr, sizeof (rsphdr), NULL);
- }
-
- FREE (hdr);
- }
-
- return ret;
-}
-
-
-
-/**
- * client_create - create function for client protocol
- * @frame: call frame
- * @this: this translator structure
- * @path: complete path to file
- * @flags: create flags
- * @mode: create mode
- *
- * external reference through client_protocol_xlator->fops->create
- */
-
-int
-client_create (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,
- mode_t mode, fd_t *fd)
-{
- gf_hdr_common_t *hdr = NULL;
- gf_fop_create_req_t *req = NULL;
- size_t hdrlen = 0;
- size_t pathlen = 0;
- size_t baselen = 0;
- int32_t ret = -1;
- ino_t par = 0;
- client_local_t *local = NULL;
-
-
- local = calloc (1, sizeof (*local));
- GF_VALIDATE_OR_GOTO(this->name, local, unwind);
-
- local->fd = fd_ref (fd);
- loc_copy (&local->loc, loc);
-
- frame->local = local;
-
- pathlen = STRLEN_0(loc->path);
- baselen = STRLEN_0(loc->name);
-
- ret = inode_ctx_get (loc->parent, this, &par);
- if (loc->parent->ino && ret < 0) {
- gf_log (this->name, GF_LOG_DEBUG,
- "CREATE %"PRId64"/%s (%s): failed to get remote inode "
- "number for parent inode",
- loc->parent->ino, loc->name, loc->path);
- }
-
- hdrlen = gf_hdr_len (req, pathlen + baselen);
- hdr = gf_hdr_new (req, pathlen + baselen);
- GF_VALIDATE_OR_GOTO(this->name, hdr, unwind);
-
- req = gf_param (hdr);
-
- req->flags = hton32 (flags);
- req->mode = hton32 (mode);
- req->par = hton64 (par);
- strcpy (req->path, loc->path);
- strcpy (req->bname + pathlen, loc->name);
-
- ret = protocol_client_xfer (frame, this,
- CLIENT_CHANNEL (this, CHANNEL_LOWLAT),
- GF_OP_TYPE_FOP_REQUEST, GF_FOP_CREATE,
- hdr, hdrlen, NULL, 0, NULL);
- return ret;
-unwind:
- if (hdr)
- free (hdr);
- STACK_UNWIND(frame, -1, EINVAL, fd, NULL, NULL);
- return 0;
-
-}
-
-/**
- * client_open - open function for client protocol
- * @frame: call frame
- * @this: this translator structure
- * @loc: location of file
- * @flags: open flags
- * @mode: open modes
- *
- * external reference through client_protocol_xlator->fops->open
- */
-
-int
-client_open (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,
- fd_t *fd)
-{
- int ret = -1;
- gf_hdr_common_t *hdr = NULL;
- size_t hdrlen = 0;
- gf_fop_open_req_t *req = NULL;
- size_t pathlen = 0;
- ino_t ino = 0;
- client_local_t *local = NULL;
-
- local = calloc (1, sizeof (*local));
- GF_VALIDATE_OR_GOTO(this->name, local, unwind);
-
- local->fd = fd_ref (fd);
- loc_copy (&local->loc, loc);
-
- frame->local = local;
-
- pathlen = STRLEN_0(loc->path);
-
- ret = inode_ctx_get (loc->inode, this, &ino);
- if (loc->inode->ino && ret < 0) {
- gf_log (this->name, GF_LOG_DEBUG,
- "OPEN %"PRId64" (%s): "
- "failed to get remote inode number",
- loc->inode->ino, loc->path);
- }
-
- hdrlen = gf_hdr_len (req, pathlen);
- hdr = gf_hdr_new (req, pathlen);
- GF_VALIDATE_OR_GOTO(this->name, hdr, unwind);
-
- req = gf_param (hdr);
-
- req->ino = hton64 (ino);
- req->flags = hton32 (flags);
- strcpy (req->path, loc->path);
-
- ret = protocol_client_xfer (frame, this,
- CLIENT_CHANNEL (this, CHANNEL_LOWLAT),
- GF_OP_TYPE_FOP_REQUEST, GF_FOP_OPEN,
- hdr, hdrlen, NULL, 0, NULL);
-
- return ret;
-unwind:
- if (hdr)
- free (hdr);
- STACK_UNWIND(frame, -1, EINVAL, fd);
- return 0;
-
-}
-
-
-/**
- * client_stat - stat function for client protocol
- * @frame: call frame
- * @this: this translator structure
- * @loc: location
- *
- * external reference through client_protocol_xlator->fops->stat
- */
-
-int
-client_stat (call_frame_t *frame, xlator_t *this, loc_t *loc)
-{
- gf_hdr_common_t *hdr = NULL;
- gf_fop_stat_req_t *req = NULL;
- size_t hdrlen = -1;
- int32_t ret = -1;
- size_t pathlen = 0;
- ino_t ino = 0;
-
- pathlen = STRLEN_0(loc->path);
-
- ret = inode_ctx_get (loc->inode, this, &ino);
- if (loc->inode->ino && ret < 0) {
- gf_log (this->name, GF_LOG_TRACE,
- "STAT %"PRId64" (%s): "
- "failed to get remote inode number",
- loc->inode->ino, loc->path);
- }
-
- hdrlen = gf_hdr_len (req, pathlen);
- hdr = gf_hdr_new (req, pathlen);
- GF_VALIDATE_OR_GOTO(this->name, hdr, unwind);
-
- req = gf_param (hdr);
-
- req->ino = hton64 (ino);
- strcpy (req->path, loc->path);
-
- ret = protocol_client_xfer (frame, this,
- CLIENT_CHANNEL (this, CHANNEL_LOWLAT),
- GF_OP_TYPE_FOP_REQUEST, GF_FOP_STAT,
- hdr, hdrlen, NULL, 0, NULL);
-
- return ret;
-unwind:
- if (hdr)
- free (hdr);
- STACK_UNWIND (frame, -1, EINVAL, NULL);
- return 0;
-
-}
-
-
-/**
- * client_readlink - readlink function for client protocol
- * @frame: call frame
- * @this: this translator structure
- * @loc: location
- * @size:
- *
- * external reference through client_protocol_xlator->fops->readlink
- */
-int
-client_readlink (call_frame_t *frame, xlator_t *this, loc_t *loc, size_t size)
-{
- gf_hdr_common_t *hdr = NULL;
- gf_fop_readlink_req_t *req = NULL;
- size_t hdrlen = -1;
- int ret = -1;
- size_t pathlen = 0;
- ino_t ino = 0;
-
- pathlen = STRLEN_0(loc->path);
-
- ret = inode_ctx_get (loc->inode, this, &ino);
- if (loc->inode->ino && ret < 0) {
- gf_log (this->name, GF_LOG_DEBUG,
- "READLINK %"PRId64" (%s): "
- "failed to get remote inode number",
- loc->inode->ino, loc->path);
- }
-
- hdrlen = gf_hdr_len (req, pathlen);
- hdr = gf_hdr_new (req, pathlen);
- GF_VALIDATE_OR_GOTO(this->name, hdr, unwind);
-
- req = gf_param (hdr);
-
- req->ino = hton64 (ino);
- req->size = hton32 (size);
- strcpy (req->path, loc->path);
-
- ret = protocol_client_xfer (frame, this,
- CLIENT_CHANNEL (this, CHANNEL_LOWLAT),
- GF_OP_TYPE_FOP_REQUEST, GF_FOP_READLINK,
- hdr, hdrlen, NULL, 0, NULL);
-
- return ret;
-unwind:
- if (hdr)
- free (hdr);
- STACK_UNWIND(frame, -1, EINVAL, NULL);
- return 0;
-
-}
-
-
-/**
- * client_mknod - mknod function for client protocol
- * @frame: call frame
- * @this: this translator structure
- * @path: pathname of node
- * @mode:
- * @dev:
- *
- * external reference through client_protocol_xlator->fops->mknod
- */
-int
-client_mknod (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
- dev_t dev)
-{
- gf_hdr_common_t *hdr = NULL;
- gf_fop_mknod_req_t *req = NULL;
- size_t hdrlen = -1;
- int ret = -1;
- size_t pathlen = 0;
- size_t baselen = 0;
- ino_t par = 0;
- client_local_t *local = NULL;
-
- local = calloc (1, sizeof (*local));
- GF_VALIDATE_OR_GOTO(this->name, local, unwind);
-
- loc_copy (&local->loc, loc);
-
- frame->local = local;
-
- pathlen = STRLEN_0(loc->path);
- baselen = STRLEN_0(loc->name);
- ret = inode_ctx_get (loc->parent, this, &par);
- if (loc->parent->ino && ret < 0) {
- gf_log (this->name, GF_LOG_DEBUG,
- "MKNOD %"PRId64"/%s (%s): failed to get remote inode "
- "number for parent",
- loc->parent->ino, loc->name, loc->path);
- }
-
- hdrlen = gf_hdr_len (req, pathlen + baselen);
- hdr = gf_hdr_new (req, pathlen + baselen);
- GF_VALIDATE_OR_GOTO(this->name, hdr, unwind);
-
- req = gf_param (hdr);
-
- req->par = hton64 (par);
- req->mode = hton32 (mode);
- req->dev = hton64 (dev);
- strcpy (req->path, loc->path);
- strcpy (req->bname + pathlen, loc->name);
-
- ret = protocol_client_xfer (frame, this,
- CLIENT_CHANNEL (this, CHANNEL_LOWLAT),
- GF_OP_TYPE_FOP_REQUEST, GF_FOP_MKNOD,
- hdr, hdrlen, NULL, 0, NULL);
-
- return ret;
-unwind:
- if (hdr)
- free (hdr);
- STACK_UNWIND(frame, -1, EINVAL, loc->inode, NULL);
- return 0;
-
-}
-
-
-/**
- * client_mkdir - mkdir function for client protocol
- * @frame: call frame
- * @this: this translator structure
- * @path: pathname of directory
- * @mode:
- *
- * external reference through client_protocol_xlator->fops->mkdir
- */
-int
-client_mkdir (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode)
-{
- gf_hdr_common_t *hdr = NULL;
- gf_fop_mkdir_req_t *req = NULL;
- size_t hdrlen = -1;
- int ret = -1;
- size_t pathlen = 0;
- size_t baselen = 0;
- ino_t par = 0;
- client_local_t *local = NULL;
-
- local = calloc (1, sizeof (*local));
- GF_VALIDATE_OR_GOTO(this->name, local, unwind);
-
- loc_copy (&local->loc, loc);
-
- frame->local = local;
-
- pathlen = STRLEN_0(loc->path);
- baselen = STRLEN_0(loc->name);
- ret = inode_ctx_get (loc->parent, this, &par);
- if (loc->parent->ino && ret < 0) {
- gf_log (this->name, GF_LOG_DEBUG,
- "MKDIR %"PRId64"/%s (%s): failed to get remote inode "
- "number for parent",
- loc->parent->ino, loc->name, loc->path);
- }
-
- hdrlen = gf_hdr_len (req, pathlen + baselen);
- hdr = gf_hdr_new (req, pathlen + baselen);
- GF_VALIDATE_OR_GOTO(this->name, hdr, unwind);
-
- req = gf_param (hdr);
-
- req->par = hton64 (par);
- req->mode = hton32 (mode);
- strcpy (req->path, loc->path);
- strcpy (req->bname + pathlen, loc->name);
-
- ret = protocol_client_xfer (frame, this,
- CLIENT_CHANNEL (this, CHANNEL_LOWLAT),
- GF_OP_TYPE_FOP_REQUEST, GF_FOP_MKDIR,
- hdr, hdrlen, NULL, 0, NULL);
-
- return ret;
-unwind:
- if (hdr)
- free (hdr);
- STACK_UNWIND(frame, -1, EINVAL, loc->inode, NULL);
- return 0;
-
-}
-
-/**
- * client_unlink - unlink function for client protocol
- * @frame: call frame
- * @this: this translator structure
- * @loc: location of file
- *
- * external reference through client_protocol_xlator->fops->unlink
- */
-
-int
-client_unlink (call_frame_t *frame, xlator_t *this, loc_t *loc)
-{
- gf_hdr_common_t *hdr = NULL;
- gf_fop_unlink_req_t *req = NULL;
- size_t hdrlen = -1;
- int ret = -1;
- size_t pathlen = 0;
- size_t baselen = 0;
- ino_t par = 0;
-
- pathlen = STRLEN_0(loc->path);
- baselen = STRLEN_0(loc->name);
- ret = inode_ctx_get (loc->parent, this, &par);
- if (loc->parent->ino && ret < 0) {
- gf_log (this->name, GF_LOG_DEBUG,
- "UNLINK %"PRId64"/%s (%s): failed to get remote inode "
- "number for parent",
- loc->parent->ino, loc->name, loc->path);
- }
-
- hdrlen = gf_hdr_len (req, pathlen + baselen);
- hdr = gf_hdr_new (req, pathlen + baselen);
- GF_VALIDATE_OR_GOTO(this->name, hdr, unwind);
-
- req = gf_param (hdr);
-
- req->par = hton64 (par);
- strcpy (req->path, loc->path);
- strcpy (req->bname + pathlen, loc->name);
-
- ret = protocol_client_xfer (frame, this,
- CLIENT_CHANNEL (this, CHANNEL_BULK),
- GF_OP_TYPE_FOP_REQUEST, GF_FOP_UNLINK,
- hdr, hdrlen, NULL, 0, NULL);
-
- return ret;
-unwind:
- if (hdr)
- free (hdr);
- STACK_UNWIND(frame, -1, EINVAL);
- return 0;
-
-}
-
-/**
- * client_rmdir - rmdir function for client protocol
- * @frame: call frame
- * @this: this translator structure
- * @loc: location
- *
- * external reference through client_protocol_xlator->fops->rmdir
- */
-
-int
-client_rmdir (call_frame_t *frame, xlator_t *this, loc_t *loc)
-{
- gf_hdr_common_t *hdr = NULL;
- gf_fop_rmdir_req_t *req = NULL;
- size_t hdrlen = -1;
- int ret = -1;
- size_t pathlen = 0;
- size_t baselen = 0;
- ino_t par = 0;
-
- pathlen = STRLEN_0(loc->path);
- baselen = STRLEN_0(loc->name);
- ret = inode_ctx_get (loc->parent, this, &par);
- if (loc->parent->ino && ret < 0) {
- gf_log (this->name, GF_LOG_DEBUG,
- "RMDIR %"PRId64"/%s (%s): failed to get remote inode "
- "number for parent",
- loc->parent->ino, loc->name, loc->path);
- }
-
- hdrlen = gf_hdr_len (req, pathlen + baselen);
- hdr = gf_hdr_new (req, pathlen + baselen);
- GF_VALIDATE_OR_GOTO(this->name, hdr, unwind);
-
- req = gf_param (hdr);
-
- req->par = hton64 (par);
- strcpy (req->path, loc->path);
- strcpy (req->bname + pathlen, loc->name);
-
- ret = protocol_client_xfer (frame, this,
- CLIENT_CHANNEL (this, CHANNEL_BULK),
- GF_OP_TYPE_FOP_REQUEST, GF_FOP_RMDIR,
- hdr, hdrlen, NULL, 0, NULL);
-
- return ret;
-unwind:
- if (hdr)
- free (hdr);
- STACK_UNWIND(frame, -1, EINVAL);
- return 0;
-
-}
-
-
-/**
- * client_symlink - symlink function for client protocol
- * @frame: call frame
- * @this: this translator structure
- * @oldpath: pathname of target
- * @newpath: pathname of symlink
- *
- * external reference through client_protocol_xlator->fops->symlink
- */
-
-int
-client_symlink (call_frame_t *frame, xlator_t *this, const char *linkname,
- loc_t *loc)
-{
- int ret = -1;
- gf_hdr_common_t *hdr = NULL;
- gf_fop_symlink_req_t *req = NULL;
- size_t hdrlen = 0;
- size_t pathlen = 0;
- size_t newlen = 0;
- size_t baselen = 0;
- ino_t par = 0;
- client_local_t *local = NULL;
-
- local = calloc (1, sizeof (*local));
- GF_VALIDATE_OR_GOTO(this->name, local, unwind);
-
- loc_copy (&local->loc, loc);
-
- frame->local = local;
-
- pathlen = STRLEN_0 (loc->path);
- baselen = STRLEN_0 (loc->name);
- newlen = STRLEN_0 (linkname);
- ret = inode_ctx_get (loc->parent, this, &par);
- if (loc->parent->ino && ret < 0) {
- gf_log (this->name, GF_LOG_DEBUG,
- "SYMLINK %"PRId64"/%s (%s): failed to get remote inode"
- " number parent",
- loc->parent->ino, loc->name, loc->path);
- }
-
- hdrlen = gf_hdr_len (req, pathlen + baselen + newlen);
- hdr = gf_hdr_new (req, pathlen + baselen + newlen);
- GF_VALIDATE_OR_GOTO(this->name, hdr, unwind);
-
- req = gf_param (hdr);
-
- req->par = hton64 (par);
- strcpy (req->path, loc->path);
- strcpy (req->bname + pathlen, loc->name);
- strcpy (req->linkname + pathlen + baselen, linkname);
-
- ret = protocol_client_xfer (frame, this,
- CLIENT_CHANNEL (this, CHANNEL_LOWLAT),
- GF_OP_TYPE_FOP_REQUEST, GF_FOP_SYMLINK,
- hdr, hdrlen, NULL, 0, NULL);
- return ret;
-unwind:
- if (hdr)
- free (hdr);
- STACK_UNWIND(frame, -1, EINVAL, loc->inode, NULL);
- return 0;
-
-}
-
-/**
- * client_rename - rename function for client protocol
- * @frame: call frame
- * @this: this translator structure
- * @oldloc: location of old pathname
- * @newloc: location of new pathname
- *
- * external reference through client_protocol_xlator->fops->rename
- */
-
-int
-client_rename (call_frame_t *frame, xlator_t *this, loc_t *oldloc,
- loc_t *newloc)
-{
- int ret = -1;
- gf_hdr_common_t *hdr = NULL;
- gf_fop_rename_req_t *req = NULL;
- size_t hdrlen = 0;
- size_t oldpathlen = 0;
- size_t oldbaselen = 0;
- size_t newpathlen = 0;
- size_t newbaselen = 0;
- ino_t oldpar = 0;
- ino_t newpar = 0;
-
- oldpathlen = STRLEN_0(oldloc->path);
- oldbaselen = STRLEN_0(oldloc->name);
- newpathlen = STRLEN_0(newloc->path);
- newbaselen = STRLEN_0(newloc->name);
- ret = inode_ctx_get (oldloc->parent, this, &oldpar);
- if (oldloc->parent->ino && ret < 0) {
- gf_log (this->name, GF_LOG_DEBUG,
- "RENAME %"PRId64"/%s (%s): failed to get remote inode "
- "number for source parent",
- oldloc->parent->ino, oldloc->name, oldloc->path);
- }
-
- ret = inode_ctx_get (newloc->parent, this, &newpar);
- if (newloc->parent->ino && ret < 0) {
- gf_log (this->name, GF_LOG_DEBUG,
- "CREATE %"PRId64"/%s (%s): failed to get remote inode "
- "number for destination parent",
- newloc->parent->ino, newloc->name, newloc->path);
- }
-
- hdrlen = gf_hdr_len (req, (oldpathlen + oldbaselen +
- newpathlen + newbaselen));
- hdr = gf_hdr_new (req, (oldpathlen + oldbaselen +
- newpathlen + newbaselen));
-
- GF_VALIDATE_OR_GOTO(this->name, hdr, unwind);
-
- req = gf_param (hdr);
-
- req->oldpar = hton64 (oldpar);
- req->newpar = hton64 (newpar);
-
- strcpy (req->oldpath, oldloc->path);
- strcpy (req->oldbname + oldpathlen, oldloc->name);
- strcpy (req->newpath + oldpathlen + oldbaselen, newloc->path);
- strcpy (req->newbname + oldpathlen + oldbaselen + newpathlen,
- newloc->name);
-
- ret = protocol_client_xfer (frame, this,
- CLIENT_CHANNEL (this, CHANNEL_LOWLAT),
- GF_OP_TYPE_FOP_REQUEST, GF_FOP_RENAME,
- hdr, hdrlen, NULL, 0, NULL);
- return ret;
-unwind:
- if (hdr)
- free (hdr);
- STACK_UNWIND(frame, -1, EINVAL, NULL);
- return 0;
-
-}
-
-/**
- * client_link - link function for client protocol
- * @frame: call frame
- * @this: this translator structure
- * @oldloc: location of old pathname
- * @newpath: new pathname
- *
- * external reference through client_protocol_xlator->fops->link
- */
-
-int
-client_link (call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc)
-{
- int ret = -1;
- gf_hdr_common_t *hdr = NULL;
- gf_fop_link_req_t *req = NULL;
- size_t hdrlen = 0;
- size_t oldpathlen = 0;
- size_t newpathlen = 0;
- size_t newbaselen = 0;
- ino_t oldino = 0;
- ino_t newpar = 0;
- client_local_t *local = NULL;
-
- local = calloc (1, sizeof (*local));
- GF_VALIDATE_OR_GOTO(this->name, local, unwind);
-
- loc_copy (&local->loc, oldloc);
-
- frame->local = local;
-
- oldpathlen = STRLEN_0(oldloc->path);
- newpathlen = STRLEN_0(newloc->path);
- newbaselen = STRLEN_0(newloc->name);
-
- ret = inode_ctx_get (oldloc->inode, this, &oldino);
- if (oldloc->inode->ino && ret < 0) {
- gf_log (this->name, GF_LOG_DEBUG,
- "LINK %"PRId64"/%s (%s) ==> %"PRId64" (%s): "
- "failed to get remote inode number for source inode",
- newloc->parent->ino, newloc->name, newloc->path,
- oldloc->ino, oldloc->path);
- }
-
- ret = inode_ctx_get (newloc->parent, this, &newpar);
- if (newloc->parent->ino && ret < 0) {
- gf_log (this->name, GF_LOG_DEBUG,
- "LINK %"PRId64"/%s (%s) ==> %"PRId64" (%s): "
- "failed to get remote inode number destination parent",
- newloc->parent->ino, newloc->name, newloc->path,
- oldloc->ino, oldloc->path);
- }
-
- hdrlen = gf_hdr_len (req, oldpathlen + newpathlen + newbaselen);
- hdr = gf_hdr_new (req, oldpathlen + newpathlen + newbaselen);
- GF_VALIDATE_OR_GOTO(this->name, hdr, unwind);
-
- req = gf_param (hdr);
-
- strcpy (req->oldpath, oldloc->path);
- strcpy (req->newpath + oldpathlen, newloc->path);
- strcpy (req->newbname + oldpathlen + newpathlen, newloc->name);
-
- req->oldino = hton64 (oldino);
- req->newpar = hton64 (newpar);
-
- ret = protocol_client_xfer (frame, this,
- CLIENT_CHANNEL (this, CHANNEL_LOWLAT),
- GF_OP_TYPE_FOP_REQUEST, GF_FOP_LINK,
- hdr, hdrlen, NULL, 0, NULL);
- return ret;
-unwind:
- if (hdr)
- free (hdr);
- STACK_UNWIND(frame, -1, EINVAL, oldloc->inode, NULL);
- return 0;
-}
-
-/**
- * client_chmod - chmod function for client protocol
- * @frame: call frame
- * @this: this translator structure
- * @loc: location
- * @mode:
- *
- * external reference through client_protocol_xlator->fops->chmod
- */
-
-int
-client_chmod (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode)
-{
- gf_hdr_common_t *hdr = NULL;
- gf_fop_chmod_req_t *req = NULL;
- size_t hdrlen = -1;
- int ret = -1;
- size_t pathlen = 0;
- ino_t ino = 0;
-
- pathlen = STRLEN_0(loc->path);
-
- ret = inode_ctx_get (loc->inode, this, &ino);
- if (loc->inode->ino && ret < 0) {
- gf_log (this->name, GF_LOG_DEBUG,
- "CHMOD %"PRId64" (%s): "
- "failed to get remote inode number",
- loc->inode->ino, loc->path);
- }
-
- hdrlen = gf_hdr_len (req, pathlen);
- hdr = gf_hdr_new (req, pathlen);
- GF_VALIDATE_OR_GOTO(this->name, hdr, unwind);
-
- req = gf_param (hdr);
-
- req->ino = hton64 (ino);
- req->mode = hton32 (mode);
- strcpy (req->path, loc->path);
-
- ret = protocol_client_xfer (frame, this,
- CLIENT_CHANNEL (this, CHANNEL_LOWLAT),
- GF_OP_TYPE_FOP_REQUEST, GF_FOP_CHMOD,
- hdr, hdrlen, NULL, 0, NULL);
-
- return ret;
-unwind:
- if (hdr)
- free (hdr);
- STACK_UNWIND(frame, -1, EINVAL, NULL);
- return 0;
-
-}
-
-/**
- * client_chown - chown function for client protocol
- * @frame: call frame
- * @this: this translator structure
- * @loc: location
- * @uid: uid of new owner
- * @gid: gid of new owner group
- *
- * external reference through client_protocol_xlator->fops->chown
- */
-
-int
-client_chown (call_frame_t *frame, xlator_t *this, loc_t *loc, uid_t uid,
- gid_t gid)
-{
- gf_hdr_common_t *hdr = NULL;
- gf_fop_chown_req_t *req = NULL;
- size_t hdrlen = -1;
- int ret = -1;
- size_t pathlen = 0;
- ino_t ino = 0;
-
- pathlen = STRLEN_0(loc->path);
-
- ret = inode_ctx_get (loc->inode, this, &ino);
- if (loc->inode->ino && ret < 0) {
- gf_log (this->name, GF_LOG_DEBUG,
- "CHOWN %"PRId64" (%s): "
- "failed to get remote inode number",
- loc->inode->ino, loc->path);
- }
-
- hdrlen = gf_hdr_len (req, pathlen);
- hdr = gf_hdr_new (req, pathlen);
- GF_VALIDATE_OR_GOTO(this->name, hdr, unwind);
-
- req = gf_param (hdr);
-
- req->ino = hton64 (ino);
- req->uid = hton32 (uid);
- req->gid = hton32 (gid);
- strcpy (req->path, loc->path);
-
- ret = protocol_client_xfer (frame, this,
- CLIENT_CHANNEL (this, CHANNEL_LOWLAT),
- GF_OP_TYPE_FOP_REQUEST, GF_FOP_CHOWN,
- hdr, hdrlen, NULL, 0, NULL);
-
- return ret;
-unwind:
- if (hdr)
- free (hdr);
- STACK_UNWIND(frame, -1, EINVAL, NULL);
- return 0;
-
-}
-
-/**
- * client_truncate - truncate function for client protocol
- * @frame: call frame
- * @this: this translator structure
- * @loc: location
- * @offset:
- *
- * external reference through client_protocol_xlator->fops->truncate
- */
-
-int
-client_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset)
-{
- gf_hdr_common_t *hdr = NULL;
- gf_fop_truncate_req_t *req = NULL;
- size_t hdrlen = -1;
- int ret = -1;
- size_t pathlen = 0;
- ino_t ino = 0;
-
- pathlen = STRLEN_0(loc->path);
- ret = inode_ctx_get (loc->inode, this, &ino);
- if (loc->inode->ino && ret < 0) {
- gf_log (this->name, GF_LOG_DEBUG,
- "TRUNCATE %"PRId64" (%s): "
- "failed to get remote inode number",
- loc->inode->ino, loc->path);
- }
-
- hdrlen = gf_hdr_len (req, pathlen);
- hdr = gf_hdr_new (req, pathlen);
- GF_VALIDATE_OR_GOTO(this->name, hdr, unwind);
-
- req = gf_param (hdr);
-
- req->ino = hton64 (ino);
- req->offset = hton64 (offset);
- strcpy (req->path, loc->path);
-
- ret = protocol_client_xfer (frame, this,
- CLIENT_CHANNEL (this, CHANNEL_BULK),
- GF_OP_TYPE_FOP_REQUEST, GF_FOP_TRUNCATE,
- hdr, hdrlen, NULL, 0, NULL);
-
- return ret;
-unwind:
- if (hdr)
- free (hdr);
- STACK_UNWIND(frame, -1, EINVAL, NULL);
- return 0;
-
-}
-
-/**
- * client_utimes - utimes function for client protocol
- * @frame: call frame
- * @this: this translator structure
- * @loc: location
- * @tvp:
- *
- * external reference through client_protocol_xlator->fops->utimes
- */
-
-int
-client_utimens (call_frame_t *frame, xlator_t *this, loc_t *loc,
- struct timespec *tvp)
-{
- gf_hdr_common_t *hdr = NULL;
- gf_fop_utimens_req_t *req = NULL;
- size_t hdrlen = -1;
- int ret = -1;
- size_t pathlen = 0;
- ino_t ino = 0;
-
- pathlen = STRLEN_0(loc->path);
- ret = inode_ctx_get (loc->inode, this, &ino);
- if (loc->inode->ino && ret < 0) {
- gf_log (this->name, GF_LOG_DEBUG,
- "UTIMENS %"PRId64" (%s): "
- "failed to get remote inode number",
- loc->inode->ino, loc->path);
- }
-
- hdrlen = gf_hdr_len (req, pathlen);
- hdr = gf_hdr_new (req, pathlen);
- GF_VALIDATE_OR_GOTO(this->name, hdr, unwind);
-
- req = gf_param (hdr);
-
- req->ino = hton64 (ino);
- gf_timespec_from_timespec (req->tv, tvp);
- strcpy (req->path, loc->path);
-
- ret = protocol_client_xfer (frame, this,
- CLIENT_CHANNEL (this, CHANNEL_LOWLAT),
- GF_OP_TYPE_FOP_REQUEST, GF_FOP_UTIMENS,
- hdr, hdrlen, NULL, 0, NULL);
-
- return ret;
-unwind:
- if (hdr)
- free (hdr);
- STACK_UNWIND(frame, -1, EINVAL, NULL);
- return 0;
-
-}
-
-/**
- * client_readv - readv function for client protocol
- * @frame: call frame
- * @this: this translator structure
- * @fd: file descriptor structure
- * @size:
- * @offset:
- *
- * external reference through client_protocol_xlator->fops->readv
- */
-
-int
-client_readv (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
- off_t offset)
-{
- gf_hdr_common_t *hdr = NULL;
- gf_fop_read_req_t *req = NULL;
- size_t hdrlen = 0;
- int64_t remote_fd = -1;
- int ret = -1;
-
- ret = this_fd_get (fd, this, &remote_fd);
- if (ret == -1) {
- gf_log (this->name, GF_LOG_TRACE,
- "(%"PRId64"): failed to get remote fd, EBADFD",
- fd->inode->ino);
- STACK_UNWIND (frame, -1, EBADFD, NULL, 0, NULL);
- return 0;
- }
-
- hdrlen = gf_hdr_len (req, 0);
- hdr = gf_hdr_new (req, 0);
- GF_VALIDATE_OR_GOTO(this->name, hdr, unwind);
-
- req = gf_param (hdr);
-
- req->fd = hton64 (remote_fd);
- req->size = hton32 (size);
- req->offset = hton64 (offset);
-
- ret = protocol_client_xfer (frame, this,
- CLIENT_CHANNEL (this, CHANNEL_BULK),
- GF_OP_TYPE_FOP_REQUEST, GF_FOP_READ,
- hdr, hdrlen, NULL, 0, NULL);
-
- return 0;
-unwind:
- if (hdr)
- free (hdr);
- STACK_UNWIND(frame, -1, EINVAL, NULL, 0, NULL);
- return 0;
-
-}
-
-/**
- * client_writev - writev function for client protocol
- * @frame: call frame
- * @this: this translator structure
- * @fd: file descriptor structure
- * @vector:
- * @count:
- * @offset:
- *
- * external reference through client_protocol_xlator->fops->writev
- */
-
-int
-client_writev (call_frame_t *frame, xlator_t *this, fd_t *fd,
- struct iovec *vector, int32_t count, off_t offset,
- struct iobref *iobref)
-{
- gf_hdr_common_t *hdr = NULL;
- gf_fop_write_req_t *req = NULL;
- size_t hdrlen = 0;
- int64_t remote_fd = -1;
- int ret = -1;
-
- ret = this_fd_get (fd, this, &remote_fd);
- if (ret == -1) {
- gf_log (this->name, GF_LOG_TRACE,
- "(%"PRId64"): failed to get remote fd. EBADFD",
- fd->inode->ino);
- STACK_UNWIND (frame, -1, EBADFD, NULL);
- return 0;
- }
-
- hdrlen = gf_hdr_len (req, 0);
- hdr = gf_hdr_new (req, 0);
- GF_VALIDATE_OR_GOTO(this->name, hdr, unwind);
-
- req = gf_param (hdr);
-
- req->fd = hton64 (remote_fd);
- req->size = hton32 (iov_length (vector, count));
- req->offset = hton64 (offset);
-
- ret = protocol_client_xfer (frame, this,
- CLIENT_CHANNEL (this, CHANNEL_BULK),
- GF_OP_TYPE_FOP_REQUEST, GF_FOP_WRITE,
- hdr, hdrlen, vector, count, iobref);
- return ret;
-unwind:
- if (hdr)
- free (hdr);
- STACK_UNWIND(frame, -1, EINVAL, NULL);
- return 0;
-
-}
-
-
-/**
- * client_statfs - statfs function for client protocol
- * @frame: call frame
- * @this: this translator structure
- * @loc: location
- *
- * external reference through client_protocol_xlator->fops->statfs
- */
-
-int
-client_statfs (call_frame_t *frame, xlator_t *this, loc_t *loc)
-{
- gf_hdr_common_t *hdr = NULL;
- gf_fop_statfs_req_t *req = NULL;
- size_t hdrlen = -1;
- int ret = -1;
- size_t pathlen = 0;
- ino_t ino = 0;
-
- pathlen = STRLEN_0(loc->path);
-
- if (loc->inode) {
- ret = inode_ctx_get (loc->inode, this, &ino);
- if (loc->inode->ino && ret < 0) {
- gf_log (this->name, GF_LOG_DEBUG,
- "STATFS %"PRId64" (%s): "
- "failed to get remote inode number",
- loc->inode->ino, loc->path);
- }
- }
-
- hdrlen = gf_hdr_len (req, pathlen);
- hdr = gf_hdr_new (req, pathlen);
- GF_VALIDATE_OR_GOTO(this->name, hdr, unwind);
-
- req = gf_param (hdr);
-
- req->ino = hton64 (ino);
- strcpy (req->path, loc->path);
-
- ret = protocol_client_xfer (frame, this,
- CLIENT_CHANNEL (this, CHANNEL_LOWLAT),
- GF_OP_TYPE_FOP_REQUEST, GF_FOP_STATFS,
- hdr, hdrlen, NULL, 0, NULL);
-
- return ret;
-unwind:
- if (hdr)
- free (hdr);
- STACK_UNWIND(frame, -1, EINVAL, NULL);
- return 0;
-
-}
-
-
-/**
- * client_flush - flush function for client protocol
- * @frame: call frame
- * @this: this translator structure
- * @fd: file descriptor structure
- *
- * external reference through client_protocol_xlator->fops->flush
- */
-
-int
-client_flush (call_frame_t *frame, xlator_t *this, fd_t *fd)
-{
- gf_hdr_common_t *hdr = NULL;
- gf_fop_flush_req_t *req = NULL;
- size_t hdrlen = 0;
- int64_t remote_fd = -1;
- int ret = -1;
-
- ret = this_fd_get (fd, this, &remote_fd);
- if (ret == -1) {
- gf_log (this->name, GF_LOG_TRACE,
- "(%"PRId64"): failed to get remote fd. EBADFD",
- fd->inode->ino);
- STACK_UNWIND (frame, -1, EBADFD);
- return 0;
- }
-
- hdrlen = gf_hdr_len (req, 0);
- hdr = gf_hdr_new (req, 0);
- GF_VALIDATE_OR_GOTO(this->name, hdr, unwind);
-
- req = gf_param (hdr);
-
- req->fd = hton64 (remote_fd);
-
- ret = protocol_client_xfer (frame, this,
- CLIENT_CHANNEL (this, CHANNEL_BULK),
- GF_OP_TYPE_FOP_REQUEST, GF_FOP_FLUSH,
- hdr, hdrlen, NULL, 0, NULL);
-
- return 0;
-unwind:
- if (hdr)
- free (hdr);
- STACK_UNWIND(frame, -1, EINVAL);
- return 0;
-
-}
-
-/**
- * client_fsync - fsync function for client protocol
- * @frame: call frame
- * @this: this translator structure
- * @fd: file descriptor structure
- * @flags:
- *
- * external reference through client_protocol_xlator->fops->fsync
- */
-
-int
-client_fsync (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t flags)
-{
- gf_hdr_common_t *hdr = NULL;
- gf_fop_fsync_req_t *req = NULL;
- size_t hdrlen = 0;
- int64_t remote_fd = -1;
- int32_t ret = -1;
-
- ret = this_fd_get (fd, this, &remote_fd);
- if (ret == -1) {
- gf_log (this->name, GF_LOG_TRACE,
- "(%"PRId64"): failed to get remote fd. EBADFD",
- fd->inode->ino);
- STACK_UNWIND(frame, -1, EBADFD);
- return 0;
- }
-
- hdrlen = gf_hdr_len (req, 0);
- hdr = gf_hdr_new (req, 0);
- GF_VALIDATE_OR_GOTO(this->name, hdr, unwind);
-
- req = gf_param (hdr);
-
- req->fd = hton64 (remote_fd);
- req->data = hton32 (flags);
-
- ret = protocol_client_xfer (frame, this,
- CLIENT_CHANNEL (this, CHANNEL_BULK),
- GF_OP_TYPE_FOP_REQUEST, GF_FOP_FSYNC,
- hdr, hdrlen, NULL, 0, NULL);
-
- return ret;
-unwind:
- if (hdr)
- free (hdr);
- STACK_UNWIND(frame, -1, EINVAL);
- return 0;
-
-}
-
-int
-client_xattrop (call_frame_t *frame, xlator_t *this, loc_t *loc,
- gf_xattrop_flags_t flags, dict_t *dict)
-{
- gf_hdr_common_t *hdr = NULL;
- gf_fop_xattrop_req_t *req = NULL;
- size_t hdrlen = 0;
- size_t dict_len = 0;
- int32_t ret = -1;
- size_t pathlen = 0;
- ino_t ino = 0;
-
- GF_VALIDATE_OR_GOTO("client", this, unwind);
-
- GF_VALIDATE_OR_GOTO(this->name, loc, unwind);
-
- if (dict) {
- dict_len = dict_serialized_length (dict);
- if (dict_len < 0) {
- gf_log (this->name, GF_LOG_DEBUG,
- "failed to get serialized length of dict(%p)",
- dict);
- goto unwind;
- }
- }
-
- pathlen = STRLEN_0(loc->path);
-
- ret = inode_ctx_get (loc->inode, this, &ino);
- if (loc->inode->ino && ret < 0) {
- gf_log (this->name, GF_LOG_DEBUG,
- "XATTROP %"PRId64" (%s): "
- "failed to get remote inode number",
- loc->inode->ino, loc->path);
- }
-
- hdrlen = gf_hdr_len (req, dict_len + pathlen);
- hdr = gf_hdr_new (req, dict_len + pathlen);
- GF_VALIDATE_OR_GOTO(this->name, hdr, unwind);
-
- req = gf_param (hdr);
-
- req->flags = hton32 (flags);
- req->dict_len = hton32 (dict_len);
- if (dict) {
- ret = dict_serialize (dict, req->dict);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_DEBUG,
- "failed to serialize dictionary(%p)",
- dict);
- goto unwind;
- }
- }
- req->ino = hton64 (ino);
- strcpy (req->path + dict_len, loc->path);
-
- ret = protocol_client_xfer (frame, this,
- CLIENT_CHANNEL (this, CHANNEL_BULK),
- GF_OP_TYPE_FOP_REQUEST, GF_FOP_XATTROP,
- hdr, hdrlen, NULL, 0, NULL);
- return ret;
-unwind:
- if (hdr)
- free (hdr);
-
- STACK_UNWIND(frame, -1, EINVAL, NULL);
- return 0;
-}
-
-
-int
-client_fxattrop (call_frame_t *frame, xlator_t *this, fd_t *fd,
- gf_xattrop_flags_t flags, dict_t *dict)
-{
- gf_hdr_common_t *hdr = NULL;
- gf_fop_fxattrop_req_t *req = NULL;
- size_t hdrlen = 0;
- size_t dict_len = 0;
- int64_t remote_fd = -1;
- int32_t ret = -1;
- ino_t ino = 0;
-
- if (dict) {
- dict_len = dict_serialized_length (dict);
- if (dict_len < 0) {
- gf_log (this->name, GF_LOG_DEBUG,
- "failed to get serialized length of dict(%p)",
- dict);
- goto unwind;
- }
- }
-
- if (fd) {
- ret = this_fd_get (fd, this, &remote_fd);
- if (ret == -1) {
- gf_log (this->name, GF_LOG_TRACE,
- "(%"PRId64"): failed to get remote fd. "
- "returning EBADFD",
- fd->inode->ino);
- goto unwind;
- }
- ino = fd->inode->ino;
- }
-
- hdrlen = gf_hdr_len (req, dict_len);
- hdr = gf_hdr_new (req, dict_len);
- GF_VALIDATE_OR_GOTO(this->name, hdr, unwind);
-
- req = gf_param (hdr);
-
- req->flags = hton32 (flags);
- req->dict_len = hton32 (dict_len);
- if (dict) {
- ret = dict_serialize (dict, req->dict);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_DEBUG,
- "failed to serialize dictionary(%p)",
- dict);
- goto unwind;
- }
- }
- req->fd = hton64 (remote_fd);
- req->ino = hton64 (ino);
-
- ret = protocol_client_xfer (frame, this,
- CLIENT_CHANNEL (this, CHANNEL_BULK),
- GF_OP_TYPE_FOP_REQUEST, GF_FOP_FXATTROP,
- hdr, hdrlen, NULL, 0, NULL);
- return ret;
-unwind:
- if (hdr)
- free (hdr);
-
- STACK_UNWIND (frame, -1, EBADFD, NULL);
- return 0;
-
-}
-
-/**
- * client_setxattr - setxattr function for client protocol
- * @frame: call frame
- * @this: this translator structure
- * @loc: location
- * @dict: dictionary which contains key:value to be set.
- * @flags:
- *
- * external reference through client_protocol_xlator->fops->setxattr
- */
-
-int
-client_setxattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
- dict_t *dict, int32_t flags)
-{
- gf_hdr_common_t *hdr = NULL;
- gf_fop_setxattr_req_t *req = NULL;
- size_t hdrlen = 0;
- size_t dict_len = 0;
- int ret = -1;
- size_t pathlen = 0;
- ino_t ino = 0;
-
- dict_len = dict_serialized_length (dict);
- if (dict_len < 0) {
- gf_log (this->name, GF_LOG_DEBUG,
- "failed to get serialized length of dict(%p)",
- dict);
- goto unwind;
- }
-
- pathlen = STRLEN_0(loc->path);
-
- ret = inode_ctx_get (loc->inode, this, &ino);
- if (loc->inode->ino && ret < 0) {
- gf_log (this->name, GF_LOG_DEBUG,
- "SETXATTR %"PRId64" (%s): "
- "failed to get remote inode number",
- loc->inode->ino, loc->path);
- }
-
- hdrlen = gf_hdr_len (req, dict_len + pathlen);
- hdr = gf_hdr_new (req, dict_len + pathlen);
- GF_VALIDATE_OR_GOTO(this->name, hdr, unwind);
-
- req = gf_param (hdr);
-
- req->ino = hton64 (ino);
- req->flags = hton32 (flags);
- req->dict_len = hton32 (dict_len);
-
- ret = dict_serialize (dict, req->dict);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_DEBUG,
- "failed to serialize dictionary(%p)",
- dict);
- goto unwind;
- }
-
- strcpy (req->path + dict_len, loc->path);
-
- ret = protocol_client_xfer (frame, this,
- CLIENT_CHANNEL (this, CHANNEL_BULK),
- GF_OP_TYPE_FOP_REQUEST, GF_FOP_SETXATTR,
- hdr, hdrlen, NULL, 0, NULL);
- return ret;
-unwind:
- if (hdr)
- free (hdr);
-
- STACK_UNWIND(frame, -1, EINVAL);
- return 0;
-}
-
-/**
- * client_fsetxattr - fsetxattr function for client protocol
- * @frame: call frame
- * @this: this translator structure
- * @fd: fd
- * @dict: dictionary which contains key:value to be set.
- * @flags:
- *
- * external reference through client_protocol_xlator->fops->fsetxattr
- */
-
-int
-client_fsetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
- dict_t *dict, int32_t flags)
-{
- gf_hdr_common_t *hdr = NULL;
- gf_fop_fsetxattr_req_t *req = NULL;
- size_t hdrlen = 0;
- size_t dict_len = 0;
- ino_t ino;
- int ret = -1;
- int64_t remote_fd = -1;
-
- dict_len = dict_serialized_length (dict);
- if (dict_len < 0) {
- gf_log (this->name, GF_LOG_DEBUG,
- "failed to get serialized length of dict(%p)",
- dict);
- goto unwind;
- }
-
- ret = this_fd_get (fd, this, &remote_fd);
- if (ret == -1) {
- gf_log (this->name, GF_LOG_TRACE,
- "(%"PRId64"): failed to get remote fd. EBADFD",
- fd->inode->ino);
- goto unwind;
- }
- ino = fd->inode->ino;
-
- hdrlen = gf_hdr_len (req, dict_len);
- hdr = gf_hdr_new (req, dict_len);
-
- GF_VALIDATE_OR_GOTO(this->name, hdr, unwind);
-
- req = gf_param (hdr);
-
- req->ino = hton64 (ino);
- req->fd = hton64 (remote_fd);
- req->flags = hton32 (flags);
- req->dict_len = hton32 (dict_len);
-
- ret = dict_serialize (dict, req->dict);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_DEBUG,
- "failed to serialize dictionary(%p)",
- dict);
- goto unwind;
- }
-
- ret = protocol_client_xfer (frame, this,
- CLIENT_CHANNEL (this, CHANNEL_BULK),
- GF_OP_TYPE_FOP_REQUEST, GF_FOP_FSETXATTR,
- hdr, hdrlen, NULL, 0, NULL);
- return ret;
-unwind:
- if (hdr)
- free (hdr);
-
- STACK_UNWIND(frame, -1, EINVAL);
- return 0;
-}
-
-/**
- * client_getxattr - getxattr function for client protocol
- * @frame: call frame
- * @this: this translator structure
- * @loc: location structure
- *
- * external reference through client_protocol_xlator->fops->getxattr
- */
-
-int
-client_getxattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
- const char *name)
-{
- int ret = -1;
- gf_hdr_common_t *hdr = NULL;
- gf_fop_getxattr_req_t *req = NULL;
- size_t hdrlen = 0;
- size_t pathlen = 0;
- size_t namelen = 0;
- ino_t ino = 0;
-
- pathlen = STRLEN_0(loc->path);
- if (name)
- namelen = STRLEN_0(name);
-
- ret = inode_ctx_get (loc->inode, this, &ino);
- if (loc->inode->ino && ret < 0) {
- gf_log (this->name, GF_LOG_DEBUG,
- "GETXATTR %"PRId64" (%s): "
- "failed to get remote inode number",
- loc->inode->ino, loc->path);
- }
-
- hdrlen = gf_hdr_len (req, pathlen + namelen);
- hdr = gf_hdr_new (req, pathlen + namelen);
- GF_VALIDATE_OR_GOTO(frame->this->name, hdr, unwind);
-
- req = gf_param (hdr);
-
- req->ino = hton64 (ino);
- req->namelen = hton32 (namelen);
- strcpy (req->path, loc->path);
- if (name)
- strcpy (req->name + pathlen, name);
-
- ret = protocol_client_xfer (frame, this,
- CLIENT_CHANNEL (this, CHANNEL_LOWLAT),
- GF_OP_TYPE_FOP_REQUEST, GF_FOP_GETXATTR,
- hdr, hdrlen, NULL, 0, NULL);
- return ret;
-unwind:
- if (hdr)
- free (hdr);
-
- STACK_UNWIND(frame, -1, EINVAL, NULL);
- return 0;
-}
-
-
-/**
- * client_fgetxattr - fgetxattr function for client protocol
- * @frame: call frame
- * @this: this translator structure
- * @fd: fd
- *
- * external reference through client_protocol_xlator->fops->fgetxattr
- */
-
-int
-client_fgetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
- const char *name)
-{
- int ret = -1;
- gf_hdr_common_t *hdr = NULL;
- gf_fop_fgetxattr_req_t *req = NULL;
- size_t hdrlen = 0;
- int64_t remote_fd = -1;
- size_t namelen = 0;
- ino_t ino = 0;
-
- if (name)
- namelen = STRLEN_0(name);
-
- ret = this_fd_get (fd, this, &remote_fd);
- if (ret == -1) {
- gf_log (this->name, GF_LOG_TRACE,
- "(%"PRId64"): failed to get remote fd. EBADFD",
- fd->inode->ino);
- goto unwind;
- }
- ino = fd->inode->ino;
-
- hdrlen = gf_hdr_len (req, namelen);
- hdr = gf_hdr_new (req, namelen);
-
- GF_VALIDATE_OR_GOTO(frame->this->name, hdr, unwind);
-
- req = gf_param (hdr);
-
- req->ino = hton64 (ino);
- req->fd = hton64 (remote_fd);
- req->namelen = hton32 (namelen);
-
- if (name)
- strcpy (req->name, name);
-
- ret = protocol_client_xfer (frame, this,
- CLIENT_CHANNEL (this, CHANNEL_LOWLAT),
- GF_OP_TYPE_FOP_REQUEST, GF_FOP_FGETXATTR,
- hdr, hdrlen, NULL, 0, NULL);
- return ret;
-unwind:
- if (hdr)
- free (hdr);
-
- STACK_UNWIND(frame, -1, EINVAL, NULL);
- return 0;
-}
-
-
-/**
- * client_removexattr - removexattr function for client protocol
- * @frame: call frame
- * @this: this translator structure
- * @loc: location structure
- * @name:
- *
- * external reference through client_protocol_xlator->fops->removexattr
- */
-
-int
-client_removexattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
- const char *name)
-{
- int ret = -1;
- gf_hdr_common_t *hdr = NULL;
- gf_fop_removexattr_req_t *req = NULL;
- size_t hdrlen = 0;
- size_t namelen = 0;
- size_t pathlen = 0;
- ino_t ino = 0;
-
- pathlen = STRLEN_0(loc->path);
- namelen = STRLEN_0(name);
-
- ret = inode_ctx_get (loc->inode, this, &ino);
- if (loc->inode->ino && ret < 0) {
- gf_log (this->name, GF_LOG_DEBUG,
- "REMOVEXATTR %"PRId64" (%s): "
- "failed to get remote inode number",
- loc->inode->ino, loc->path);
- }
-
- hdrlen = gf_hdr_len (req, pathlen + namelen);
- hdr = gf_hdr_new (req, pathlen + namelen);
- GF_VALIDATE_OR_GOTO(frame->this->name, hdr, unwind);
-
- req = gf_param (hdr);
-
- req->ino = hton64 (ino);
- strcpy (req->path, loc->path);
- strcpy (req->name + pathlen, name);
-
- ret = protocol_client_xfer (frame, this,
- CLIENT_CHANNEL (this, CHANNEL_LOWLAT),
- GF_OP_TYPE_FOP_REQUEST, GF_FOP_REMOVEXATTR,
- hdr, hdrlen, NULL, 0, NULL);
- return ret;
-unwind:
- if (hdr)
- free (hdr);
- STACK_UNWIND(frame, -1, EINVAL);
- return 0;
-}
-
-/**
- * client_opendir - opendir function for client protocol
- * @frame: call frame
- * @this: this translator structure
- * @loc: location structure
- *
- * external reference through client_protocol_xlator->fops->opendir
- */
-
-int
-client_opendir (call_frame_t *frame, xlator_t *this, loc_t *loc,
- fd_t *fd)
-{
- gf_fop_opendir_req_t *req = NULL;
- gf_hdr_common_t *hdr = NULL;
- size_t hdrlen = 0;
- int ret = -1;
- ino_t ino = 0;
- size_t pathlen = 0;
- client_local_t *local = NULL;
-
- local = calloc (1, sizeof (*local));
- GF_VALIDATE_OR_GOTO(this->name, local, unwind);
-
- loc_copy (&local->loc, loc);
- local->fd = fd_ref (fd);
-
- frame->local = local;
-
- ret = inode_ctx_get (loc->inode, this, &ino);
- if (loc->inode->ino && ret < 0) {
- gf_log (this->name, GF_LOG_DEBUG,
- "OPENDIR %"PRId64" (%s): "
- "failed to get remote inode number",
- loc->inode->ino, loc->path);
- }
-
- pathlen = STRLEN_0(loc->path);
-
- hdrlen = gf_hdr_len (req, pathlen);
- hdr = gf_hdr_new (req, pathlen);
- GF_VALIDATE_OR_GOTO(frame->this->name, hdr, unwind);
-
- req = gf_param (hdr);
-
- req->ino = hton64 (ino);
- strcpy (req->path, loc->path);
-
- ret = protocol_client_xfer (frame, this,
- CLIENT_CHANNEL (this, CHANNEL_LOWLAT),
- GF_OP_TYPE_FOP_REQUEST, GF_FOP_OPENDIR,
- hdr, hdrlen, NULL, 0, NULL);
-
- return ret;
-unwind:
- if (hdr)
- free (hdr);
- STACK_UNWIND(frame, -1, EINVAL, fd);
- return 0;
-
-}
-
-
-/**
- * client_readdir - readdir function for client protocol
- * @frame: call frame
- * @this: this translator structure
- *
- * external reference through client_protocol_xlator->fops->readdir
- */
-
-int
-client_getdents (call_frame_t *frame, xlator_t *this, fd_t *fd,
- size_t size, off_t offset, int32_t flag)
-{
- gf_hdr_common_t *hdr = NULL;
- gf_fop_getdents_req_t *req = NULL;
- size_t hdrlen = 0;
- int64_t remote_fd = -1;
- int ret = -1;
-
- ret = this_fd_get (fd, this, &remote_fd);
- if (ret == -1) {
- gf_log (this->name, GF_LOG_TRACE,
- "(%"PRId64"): failed to get remote fd. EBADFD",
- fd->inode->ino);
- STACK_UNWIND (frame, -1, EBADFD, NULL);
- return 0;
- }
-
- hdrlen = gf_hdr_len (req, 0);
- hdr = gf_hdr_new (req, 0);
- GF_VALIDATE_OR_GOTO(frame->this->name, hdr, unwind);
-
- req = gf_param (hdr);
- GF_VALIDATE_OR_GOTO(frame->this->name, hdr, unwind);
-
- req->fd = hton64 (remote_fd);
- req->size = hton32 (size);
- req->offset = hton64 (offset);
- req->flags = hton32 (flag);
-
- ret = protocol_client_xfer (frame, this,
- CLIENT_CHANNEL (this, CHANNEL_BULK),
- GF_OP_TYPE_FOP_REQUEST, GF_FOP_GETDENTS,
- hdr, hdrlen, NULL, 0, NULL);
-
- return 0;
-unwind:
- STACK_UNWIND(frame, -1, EINVAL, NULL, 0);
- return 0;
-}
-
-/**
- * client_readdir - readdir function for client protocol
- * @frame: call frame
- * @this: this translator structure
- *
- * external reference through client_protocol_xlator->fops->readdir
- */
-
-int
-client_readdir (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
- off_t offset)
-{
- gf_hdr_common_t *hdr = NULL;
- gf_fop_readdir_req_t *req = NULL;
- size_t hdrlen = 0;
- int64_t remote_fd = -1;
- int ret = -1;
-
- ret = this_fd_get (fd, this, &remote_fd);
- if (ret == -1) {
- gf_log (this->name, GF_LOG_TRACE,
- "(%"PRId64"): failed to get remote fd. EBADFD",
- fd->inode->ino);
- goto unwind;
- }
-
- hdrlen = gf_hdr_len (req, 0);
- hdr = gf_hdr_new (req, 0);
- GF_VALIDATE_OR_GOTO(this->name, hdr, unwind);
-
- req = gf_param (hdr);
- GF_VALIDATE_OR_GOTO(this->name, hdr, unwind);
-
- req->fd = hton64 (remote_fd);
- req->size = hton32 (size);
- req->offset = hton64 (offset);
-
- ret = protocol_client_xfer (frame, this,
- CLIENT_CHANNEL (this, CHANNEL_LOWLAT),
- GF_OP_TYPE_FOP_REQUEST, GF_FOP_READDIR,
- hdr, hdrlen, NULL, 0, NULL);
-
- return 0;
-unwind:
- if (hdr)
- free (hdr);
- STACK_UNWIND (frame, -1, EBADFD, NULL);
- return 0;
-
-}
-
-/**
- * client_fsyncdir - fsyncdir function for client protocol
- * @frame: call frame
- * @this: this translator structure
- * @fd: file descriptor structure
- * @flags:
- *
- * external reference through client_protocol_xlator->fops->fsyncdir
- */
-
-int
-client_fsyncdir (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t flags)
-{
- gf_hdr_common_t *hdr = NULL;
- gf_fop_fsyncdir_req_t *req = NULL;
- size_t hdrlen = 0;
- int64_t remote_fd = -1;
- int32_t ret = -1;
-
- ret = this_fd_get (fd, this, &remote_fd);
- if (ret == -1) {
- gf_log (this->name, GF_LOG_TRACE,
- "(%"PRId64"): failed to get remote fd. EBADFD",
- fd->inode->ino);
- goto unwind;
- }
-
- hdrlen = gf_hdr_len (req, 0);
- hdr = gf_hdr_new (req, 0);
- GF_VALIDATE_OR_GOTO(this->name, hdr, unwind);
-
- req = gf_param (hdr);
-
- req->data = hton32 (flags);
- req->fd = hton64 (remote_fd);
-
- ret = protocol_client_xfer (frame, this,
- CLIENT_CHANNEL (this, CHANNEL_BULK),
- GF_OP_TYPE_FOP_REQUEST, GF_FOP_FSYNCDIR,
- hdr, hdrlen, NULL, 0, NULL);
-
- return ret;
-unwind:
- STACK_UNWIND (frame, -1, EBADFD);
- return 0;
-}
-
-/**
- * client_access - access function for client protocol
- * @frame: call frame
- * @this: this translator structure
- * @loc: location structure
- * @mode:
- *
- * external reference through client_protocol_xlator->fops->access
- */
-
-int
-client_access (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t mask)
-{
- gf_hdr_common_t *hdr = NULL;
- gf_fop_access_req_t *req = NULL;
- size_t hdrlen = -1;
- int ret = -1;
- ino_t ino = 0;
- size_t pathlen = 0;
-
- ret = inode_ctx_get (loc->inode, this, &ino);
- if (loc->inode->ino && ret < 0) {
- gf_log (this->name, GF_LOG_DEBUG,
- "ACCESS %"PRId64" (%s): "
- "failed to get remote inode number",
- loc->inode->ino, loc->path);
- }
-
- pathlen = STRLEN_0(loc->path);
-
- hdrlen = gf_hdr_len (req, pathlen);
- hdr = gf_hdr_new (req, pathlen);
- GF_VALIDATE_OR_GOTO(this->name, hdr, unwind);
-
- req = gf_param (hdr);
-
- req->ino = hton64 (ino);
- req->mask = hton32 (mask);
- strcpy (req->path, loc->path);
-
- ret = protocol_client_xfer (frame, this,
- CLIENT_CHANNEL (this, CHANNEL_LOWLAT),
- GF_OP_TYPE_FOP_REQUEST, GF_FOP_ACCESS,
- hdr, hdrlen, NULL, 0, NULL);
-
- return ret;
-unwind:
- if (hdr)
- free (hdr);
-
- STACK_UNWIND(frame, -1, EINVAL);
- return 0;
-
-}
-
-/**
- * client_ftrucate - ftruncate function for client protocol
- * @frame: call frame
- * @this: this translator structure
- * @fd: file descriptor structure
- * @offset: offset to truncate to
- *
- * external reference through client_protocol_xlator->fops->ftruncate
- */
-
-int
-client_ftruncate (call_frame_t *frame, xlator_t *this, fd_t *fd,
- off_t offset)
-{
- gf_hdr_common_t *hdr = NULL;
- gf_fop_ftruncate_req_t *req = NULL;
- int64_t remote_fd = -1;
- size_t hdrlen = -1;
- int ret = -1;
-
- ret = this_fd_get (fd, this, &remote_fd);
- if (ret == -1) {
- gf_log (this->name, GF_LOG_TRACE,
- "(%"PRId64"): failed to get remote fd. EBADFD",
- fd->inode->ino);
- STACK_UNWIND (frame, -1, EBADFD, NULL);
- return 0;
- }
-
- hdrlen = gf_hdr_len (req, 0);
- hdr = gf_hdr_new (req, 0);
- GF_VALIDATE_OR_GOTO(this->name, hdr, unwind);
-
- req = gf_param (hdr);
-
- req->fd = hton64 (remote_fd);
- req->offset = hton64 (offset);
-
- ret = protocol_client_xfer (frame, this,
- CLIENT_CHANNEL (this, CHANNEL_BULK),
- GF_OP_TYPE_FOP_REQUEST, GF_FOP_FTRUNCATE,
- hdr, hdrlen, NULL, 0, NULL);
-
- return ret;
-unwind:
- if (hdr)
- free (hdr);
-
- STACK_UNWIND(frame, -1, EINVAL, NULL);
- return 0;
-
-}
-
-/**
- * client_fstat - fstat function for client protocol
- * @frame: call frame
- * @this: this translator structure
- * @fd: file descriptor structure
- *
- * external reference through client_protocol_xlator->fops->fstat
- */
-
-int
-client_fstat (call_frame_t *frame, xlator_t *this, fd_t *fd)
-{
- gf_hdr_common_t *hdr = NULL;
- gf_fop_fstat_req_t *req = NULL;
- int64_t remote_fd = -1;
- size_t hdrlen = -1;
- int ret = -1;
-
- ret = this_fd_get (fd, this, &remote_fd);
- if (ret == -1) {
- gf_log (this->name, GF_LOG_TRACE,
- "(%"PRId64"): failed to get remote fd. EBADFD",
- fd->inode->ino);
- STACK_UNWIND (frame, -1, EBADFD, NULL);
- return 0;
- }
-
- hdrlen = gf_hdr_len (req, 0);
- hdr = gf_hdr_new (req, 0);
- GF_VALIDATE_OR_GOTO(this->name, hdr, unwind);
-
- req = gf_param (hdr);
-
- req->fd = hton64 (remote_fd);
-
- ret = protocol_client_xfer (frame, this,
- CLIENT_CHANNEL (this, CHANNEL_BULK),
- GF_OP_TYPE_FOP_REQUEST, GF_FOP_FSTAT,
- hdr, hdrlen, NULL, 0, NULL);
-
- return ret;
-unwind:
- if (hdr)
- free (hdr);
-
- STACK_UNWIND(frame, -1, EINVAL, NULL);
- return 0;
-
-}
-
-/**
- * client_lk - lk function for client protocol
- * @frame: call frame
- * @this: this translator structure
- * @fd: file descriptor structure
- * @cmd: lock command
- * @lock:
- *
- * external reference through client_protocol_xlator->fops->lk
- */
-
-int
-client_lk (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t cmd,
- struct flock *flock)
-{
- int ret = -1;
- gf_hdr_common_t *hdr = NULL;
- gf_fop_lk_req_t *req = NULL;
- size_t hdrlen = 0;
- int64_t remote_fd = -1;
- int32_t gf_cmd = 0;
- int32_t gf_type = 0;
-
- ret = this_fd_get (fd, this, &remote_fd);
- if (ret == -1) {
- gf_log (this->name, GF_LOG_TRACE,
- "(%"PRId64"): failed to get remote fd. EBADFD",
- fd->inode->ino);
- STACK_UNWIND(frame, -1, EBADFD, NULL);
- return 0;
- }
-
- if (cmd == F_GETLK || cmd == F_GETLK64)
- gf_cmd = GF_LK_GETLK;
- else if (cmd == F_SETLK || cmd == F_SETLK64)
- gf_cmd = GF_LK_SETLK;
- else if (cmd == F_SETLKW || cmd == F_SETLKW64)
- gf_cmd = GF_LK_SETLKW;
- else {
- gf_log (this->name, GF_LOG_DEBUG,
- "Unknown cmd (%d)!", gf_cmd);
- goto unwind;
- }
-
- switch (flock->l_type) {
- case F_RDLCK:
- gf_type = GF_LK_F_RDLCK;
- break;
- case F_WRLCK:
- gf_type = GF_LK_F_WRLCK;
- break;
- case F_UNLCK:
- gf_type = GF_LK_F_UNLCK;
- break;
- }
-
- hdrlen = gf_hdr_len (req, 0);
- hdr = gf_hdr_new (req, 0);
- GF_VALIDATE_OR_GOTO(this->name, hdr, unwind);
-
- req = gf_param (hdr);
-
- req->fd = hton64 (remote_fd);
- req->cmd = hton32 (gf_cmd);
- req->type = hton32 (gf_type);
- gf_flock_from_flock (&req->flock, flock);
-
- ret = protocol_client_xfer (frame, this,
- CLIENT_CHANNEL (this, CHANNEL_BULK),
- GF_OP_TYPE_FOP_REQUEST, GF_FOP_LK,
- hdr, hdrlen, NULL, 0, NULL);
- return ret;
-unwind:
- if (hdr)
- free (hdr);
-
- STACK_UNWIND(frame, -1, EINVAL, NULL);
- return 0;
-}
-
-/**
- * client_inodelk - inodelk function for client protocol
- * @frame: call frame
- * @this: this translator structure
- * @inode: inode structure
- * @cmd: lock command
- * @lock: flock struct
- *
- * external reference through client_protocol_xlator->fops->inodelk
- */
-
-int
-client_inodelk (call_frame_t *frame, xlator_t *this, const char *volume,
- loc_t *loc, int32_t cmd, struct flock *flock)
-{
- int ret = -1;
- gf_hdr_common_t *hdr = NULL;
- gf_fop_inodelk_req_t *req = NULL;
- size_t hdrlen = 0;
- int32_t gf_cmd = 0;
- int32_t gf_type = 0;
- ino_t ino = 0;
- size_t pathlen = 0;
- size_t vollen = 0;
-
- pathlen = STRLEN_0(loc->path);
- vollen = STRLEN_0(volume);
-
- ret = inode_ctx_get (loc->inode, this, &ino);
- if (loc->inode->ino && ret < 0) {
- gf_log (this->name, GF_LOG_DEBUG,
- "INODELK %"PRId64" (%s): "
- "failed to get remote inode number",
- loc->inode->ino, loc->path);
- }
-
- if (cmd == F_GETLK || cmd == F_GETLK64)
- gf_cmd = GF_LK_GETLK;
- else if (cmd == F_SETLK || cmd == F_SETLK64)
- gf_cmd = GF_LK_SETLK;
- else if (cmd == F_SETLKW || cmd == F_SETLKW64)
- gf_cmd = GF_LK_SETLKW;
- else {
- gf_log (this->name, GF_LOG_DEBUG,
- "Unknown cmd (%d)!", gf_cmd);
- goto unwind;
- }
-
- switch (flock->l_type) {
- case F_RDLCK:
- gf_type = GF_LK_F_RDLCK;
- break;
- case F_WRLCK:
- gf_type = GF_LK_F_WRLCK;
- break;
- case F_UNLCK:
- gf_type = GF_LK_F_UNLCK;
- break;
- }
-
- hdrlen = gf_hdr_len (req, pathlen + vollen);
- hdr = gf_hdr_new (req, pathlen + vollen);
- GF_VALIDATE_OR_GOTO(this->name, hdr, unwind);
-
- req = gf_param (hdr);
-
- strcpy (req->path, loc->path);
- strcpy (req->path + pathlen, volume);
-
- req->ino = hton64 (ino);
-
- req->cmd = hton32 (gf_cmd);
- req->type = hton32 (gf_type);
- gf_flock_from_flock (&req->flock, flock);
-
-
- ret = protocol_client_xfer (frame, this,
- CLIENT_CHANNEL (this, CHANNEL_BULK),
- GF_OP_TYPE_FOP_REQUEST,
- GF_FOP_INODELK,
- hdr, hdrlen, NULL, 0, NULL);
- return ret;
-unwind:
- if (hdr)
- free (hdr);
-
- STACK_UNWIND(frame, -1, EINVAL);
- return 0;
-
-}
-
-
-/**
- * client_finodelk - finodelk function for client protocol
- * @frame: call frame
- * @this: this translator structure
- * @inode: inode structure
- * @cmd: lock command
- * @lock: flock struct
- *
- * external reference through client_protocol_xlator->fops->finodelk
- */
-
-int
-client_finodelk (call_frame_t *frame, xlator_t *this, const char *volume,
- fd_t *fd, int32_t cmd, struct flock *flock)
-{
- int ret = -1;
- gf_hdr_common_t *hdr = NULL;
- gf_fop_finodelk_req_t *req = NULL;
- size_t hdrlen = 0;
- size_t vollen = 0;
- int32_t gf_cmd = 0;
- int32_t gf_type = 0;
- int64_t remote_fd = -1;
-
- vollen = STRLEN_0(volume);
-
- ret = this_fd_get (fd, this, &remote_fd);
- if (ret == -1) {
- gf_log (this->name, GF_LOG_TRACE,
- "(%"PRId64"): failed to get remote fd. EBADFD",
- fd->inode->ino);
- STACK_UNWIND(frame, -1, EBADFD);
- return 0;
- }
-
- if (cmd == F_GETLK || cmd == F_GETLK64)
- gf_cmd = GF_LK_GETLK;
- else if (cmd == F_SETLK || cmd == F_SETLK64)
- gf_cmd = GF_LK_SETLK;
- else if (cmd == F_SETLKW || cmd == F_SETLKW64)
- gf_cmd = GF_LK_SETLKW;
- else {
- gf_log (this->name, GF_LOG_DEBUG,
- "Unknown cmd (%d)!", gf_cmd);
- goto unwind;
- }
-
- switch (flock->l_type) {
- case F_RDLCK:
- gf_type = GF_LK_F_RDLCK;
- break;
- case F_WRLCK:
- gf_type = GF_LK_F_WRLCK;
- break;
- case F_UNLCK:
- gf_type = GF_LK_F_UNLCK;
- break;
- }
-
- hdrlen = gf_hdr_len (req, vollen);
- hdr = gf_hdr_new (req, vollen);
- GF_VALIDATE_OR_GOTO(this->name, hdr, unwind);
-
- req = gf_param (hdr);
-
- strcpy (req->volume, volume);
-
- req->fd = hton64 (remote_fd);
-
- req->cmd = hton32 (gf_cmd);
- req->type = hton32 (gf_type);
- gf_flock_from_flock (&req->flock, flock);
-
- ret = protocol_client_xfer (frame, this,
- CLIENT_CHANNEL (this, CHANNEL_BULK),
- GF_OP_TYPE_FOP_REQUEST,
- GF_FOP_FINODELK,
- hdr, hdrlen, NULL, 0, NULL);
- return ret;
-unwind:
- if (hdr)
- free (hdr);
-
- STACK_UNWIND(frame, -1, EINVAL);
- return 0;
-}
-
-
-int
-client_entrylk (call_frame_t *frame, xlator_t *this, const char *volume,
- loc_t *loc, const char *name, entrylk_cmd cmd,
- entrylk_type type)
-{
- gf_hdr_common_t *hdr = NULL;
- gf_fop_entrylk_req_t *req = NULL;
- size_t pathlen = 0;
- size_t vollen = 0;
- size_t hdrlen = -1;
- int ret = -1;
- ino_t ino = 0;
- size_t namelen = 0;
-
- pathlen = STRLEN_0(loc->path);
- vollen = STRLEN_0(volume);
-
- if (name)
- namelen = STRLEN_0(name);
-
- ret = inode_ctx_get (loc->inode, this, &ino);
- if (loc->inode->ino && ret < 0) {
- gf_log (this->name, GF_LOG_DEBUG,
- "ENTRYLK %"PRId64" (%s): "
- "failed to get remote inode number",
- loc->inode->ino, loc->path);
- }
-
- hdrlen = gf_hdr_len (req, pathlen + vollen + namelen);
- hdr = gf_hdr_new (req, pathlen + vollen + namelen);
- GF_VALIDATE_OR_GOTO(this->name, hdr, unwind);
-
- req = gf_param (hdr);
-
- req->ino = hton64 (ino);
- req->namelen = hton64 (namelen);
-
- strcpy (req->path, loc->path);
- if (name)
- strcpy (req->name + pathlen, name);
- strcpy (req->volume + pathlen + namelen, volume);
-
- req->cmd = hton32 (cmd);
- req->type = hton32 (type);
-
- ret = protocol_client_xfer (frame, this,
- CLIENT_CHANNEL (this, CHANNEL_LOWLAT),
- GF_OP_TYPE_FOP_REQUEST, GF_FOP_ENTRYLK,
- hdr, hdrlen, NULL, 0, NULL);
-
- return ret;
-unwind:
- if (hdr)
- free (hdr);
-
- STACK_UNWIND(frame, -1, EINVAL);
- return 0;
-
-}
-
-
-int
-client_fentrylk (call_frame_t *frame, xlator_t *this, const char *volume,
- fd_t *fd, const char *name, entrylk_cmd cmd,
- entrylk_type type)
-{
- gf_hdr_common_t *hdr = NULL;
- gf_fop_fentrylk_req_t *req = NULL;
- int64_t remote_fd = -1;
- size_t vollen = 0;
- size_t namelen = 0;
- size_t hdrlen = -1;
- int ret = -1;
-
- if (name)
- namelen = STRLEN_0(name);
-
- vollen = STRLEN_0(volume);
-
- ret = this_fd_get (fd, this, &remote_fd);
- if (ret == -1) {
- gf_log (this->name, GF_LOG_DEBUG,
- "(%"PRId64"): failed to get remote fd. EBADFD",
- fd->inode->ino);
- STACK_UNWIND(frame, -1, EBADFD);
- return 0;
- }
-
- hdrlen = gf_hdr_len (req, namelen + vollen);
- hdr = gf_hdr_new (req, namelen + vollen);
- GF_VALIDATE_OR_GOTO(this->name, hdr, unwind);
-
- req = gf_param (hdr);
-
- req->fd = hton64 (remote_fd);
- req->namelen = hton64 (namelen);
-
- if (name)
- strcpy (req->name, name);
-
- strcpy (req->volume + namelen, volume);
-
- req->cmd = hton32 (cmd);
- req->type = hton32 (type);
-
- ret = protocol_client_xfer (frame, this,
- CLIENT_CHANNEL (this, CHANNEL_LOWLAT),
- GF_OP_TYPE_FOP_REQUEST, GF_FOP_FENTRYLK,
- hdr, hdrlen, NULL, 0, NULL);
-
- return ret;
-unwind:
- if (hdr)
- free (hdr);
-
- STACK_UNWIND(frame, -1, EINVAL);
- return 0;
-}
-
-/*
- * client_lookup - lookup function for client protocol
- * @frame: call frame
- * @this:
- * @loc: location
- *
- * not for external reference
- */
-
-int
-client_lookup (call_frame_t *frame, xlator_t *this, loc_t *loc,
- dict_t *xattr_req)
-{
- gf_hdr_common_t *hdr = NULL;
- gf_fop_lookup_req_t *req = NULL;
- size_t hdrlen = -1;
- int ret = -1;
- ino_t ino = 0;
- ino_t par = 0;
- size_t dictlen = 0;
- size_t pathlen = 0;
- size_t baselen = 0;
- int32_t op_ret = -1;
- int32_t op_errno = EINVAL;
- client_local_t *local = NULL;
- char *buf = NULL;
-
- local = calloc (1, sizeof (*local));
- GF_VALIDATE_OR_GOTO(this->name, local, unwind);
-
- loc_copy (&local->loc, loc);
-
- frame->local = local;
-
- GF_VALIDATE_OR_GOTO (this->name, loc, unwind);
- GF_VALIDATE_OR_GOTO (this->name, loc->path, unwind);
-
- if (loc->ino != 1) {
- ret = inode_ctx_get (loc->parent, this, &par);
- if (loc->parent->ino && ret < 0) {
- gf_log (this->name, GF_LOG_TRACE,
- "LOOKUP %"PRId64"/%s (%s): failed to get "
- "remote inode number for parent",
- loc->parent->ino, loc->name, loc->path);
- }
- GF_VALIDATE_OR_GOTO (this->name, loc->name, unwind);
- baselen = STRLEN_0(loc->name);
- } else {
- ino = 1;
- }
-
- pathlen = STRLEN_0(loc->path);
-
- if (xattr_req) {
- ret = dict_allocate_and_serialize (xattr_req, &buf, &dictlen);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_DEBUG,
- "failed to get serialized length of dict(%p)",
- xattr_req);
- goto unwind;
- }
- }
-
- hdrlen = gf_hdr_len (req, pathlen + baselen + dictlen);
- hdr = gf_hdr_new (req, pathlen + baselen + dictlen);
- GF_VALIDATE_OR_GOTO (this->name, hdr, unwind);
-
- req = gf_param (hdr);
-
- req->ino = hton64 (ino);
- req->par = hton64 (par);
- strcpy (req->path, loc->path);
- if (baselen)
- strcpy (req->path + pathlen, loc->name);
-
- if (dictlen > 0) {
- memcpy (req->dict + pathlen + baselen, buf, dictlen);
- FREE (buf);
- }
-
- req->dictlen = hton32 (dictlen);
-
- ret = protocol_client_xfer (frame, this,
- CLIENT_CHANNEL (this, CHANNEL_LOWLAT),
- GF_OP_TYPE_FOP_REQUEST, GF_FOP_LOOKUP,
- hdr, hdrlen, NULL, 0, NULL);
- return ret;
-
-unwind:
- STACK_UNWIND (frame, op_ret, op_errno, loc->inode, NULL, NULL);
- return ret;
-}
-
-
-int
-client_fchmod (call_frame_t *frame, xlator_t *this, fd_t *fd, mode_t mode)
-{
- gf_hdr_common_t *hdr = NULL;
- gf_fop_fchmod_req_t *req = NULL;
- int64_t remote_fd = -1;
- size_t hdrlen = -1;
- int ret = -1;
- int32_t op_errno = EINVAL;
- int32_t op_ret = -1;
-
- GF_VALIDATE_OR_GOTO (this->name, fd, unwind);
-
- ret = this_fd_get (fd, this, &remote_fd);
- if (ret == -1) {
- op_errno = EBADFD;
- gf_log (this->name, GF_LOG_DEBUG,
- "(%"PRId64"): failed to get remote fd. EBADFD",
- fd->inode->ino);
- goto unwind;
- }
-
- hdrlen = gf_hdr_len (req, 0);
- hdr = gf_hdr_new (req, 0);
- GF_VALIDATE_OR_GOTO (this->name, hdr, unwind);
-
- req = gf_param (hdr);
-
- req->fd = hton64 (remote_fd);
- req->mode = hton32 (mode);
-
- ret = protocol_client_xfer (frame, this,
- CLIENT_CHANNEL (this, CHANNEL_LOWLAT),
- GF_OP_TYPE_FOP_REQUEST, GF_FOP_FCHMOD,
- hdr, hdrlen, NULL, 0, NULL);
-
- return 0;
-
-unwind:
- STACK_UNWIND (frame, op_ret, op_errno, NULL);
- return 0;
-}
-
-
-int
-client_fchown (call_frame_t *frame, xlator_t *this, fd_t *fd, uid_t uid,
- gid_t gid)
-{
- gf_hdr_common_t *hdr = NULL;
- gf_fop_fchown_req_t *req = NULL;
- int64_t remote_fd = 0;
- size_t hdrlen = -1;
- int32_t op_ret = -1;
- int32_t op_errno = EINVAL;
- int32_t ret = -1;
-
- GF_VALIDATE_OR_GOTO (this->name, fd, unwind);
-
- ret = this_fd_get (fd, this, &remote_fd);
- if (ret == -1) {
- op_errno = EBADFD;
- gf_log (this->name, GF_LOG_DEBUG,
- "(%"PRId64"): failed to get remote fd. EBADFD",
- fd->inode->ino);
- goto unwind;
- }
-
- hdrlen = gf_hdr_len (req, 0);
- hdr = gf_hdr_new (req, 0);
- GF_VALIDATE_OR_GOTO (this->name, hdr, unwind);
-
- req = gf_param (hdr);
-
- req->fd = hton64 (remote_fd);
- req->uid = hton32 (uid);
- req->gid = hton32 (gid);
-
- ret = protocol_client_xfer (frame, this,
- CLIENT_CHANNEL (this, CHANNEL_LOWLAT),
- GF_OP_TYPE_FOP_REQUEST, GF_FOP_FCHOWN,
- hdr, hdrlen, NULL, 0, NULL);
-
- return 0;
-
-unwind:
- STACK_UNWIND (frame, op_ret, op_errno, NULL);
- return 0;
-
-}
-
-
-int
-client_setdents (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t flags,
- dir_entry_t *entries, int32_t count)
-{
- gf_hdr_common_t *hdr = NULL;
- gf_fop_setdents_req_t *req = NULL;
- int64_t remote_fd = 0;
- char *ptr = NULL;
- dir_entry_t *trav = NULL;
- uint32_t len = 0;
- int32_t buf_len = 0;
- int32_t ret = -1;
- int32_t op_ret = -1;
- int32_t op_errno = EINVAL;
- int32_t vec_count = 0;
- size_t hdrlen = -1;
- struct iovec vector[1];
- struct iobref *iobref = NULL;
- struct iobuf *iobuf = NULL;
-
- GF_VALIDATE_OR_GOTO (this->name, fd, unwind);
-
- ret = this_fd_get (fd, this, &remote_fd);
- if (ret == -1) {
- gf_log (this->name, GF_LOG_DEBUG,
- "(%"PRId64"): failed to get remote fd. EBADFD",
- fd->inode->ino);
- op_errno = EBADFD;
- goto unwind;
- }
-
- GF_VALIDATE_OR_GOTO (this->name, entries, unwind);
- GF_VALIDATE_OR_GOTO (this->name, count, unwind);
-
- trav = entries->next;
- while (trav) {
- len += strlen (trav->name);
- len += 1;
- len += strlen (trav->link);
- len += 1;
- len += 256; // max possible for statbuf;
- trav = trav->next;
- }
- iobuf = iobuf_get (this->ctx->iobuf_pool);
- GF_VALIDATE_OR_GOTO (this->name, iobuf, unwind);
-
- ptr = iobuf->ptr;
-
- trav = entries->next;
- while (trav) {
- int32_t this_len = 0;
- char *tmp_buf = NULL;
- struct stat *stbuf = &trav->buf;
- {
- /* Convert the stat buf to string */
- 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);
- }
- this_len = sprintf (ptr, "%s/%s%s\n",
- trav->name, tmp_buf, trav->link);
-
- FREE (tmp_buf);
- trav = trav->next;
- ptr += this_len;
- }
- buf_len = strlen (iobuf->ptr);
-
- hdrlen = gf_hdr_len (req, 0);
- hdr = gf_hdr_new (req, 0);
- GF_VALIDATE_OR_GOTO (this->name, hdr, unwind);
-
- req = gf_param (hdr);
-
- req->fd = hton64 (remote_fd);
- req->flags = hton32 (flags);
- req->count = hton32 (count);
-
- iobref = iobref_new ();
- iobref_add (iobref, iobuf);
-
- ret = protocol_client_xfer (frame, this,
- CLIENT_CHANNEL (this, CHANNEL_BULK),
- GF_OP_TYPE_FOP_REQUEST, GF_FOP_SETDENTS,
- hdr, hdrlen, vector, vec_count, iobref);
-
- if (iobref)
- iobref_unref (iobref);
-
- if (iobuf)
- iobuf_unref (iobuf);
-
- return ret;
-unwind:
-
- if (iobref)
- iobref_unref (iobref);
-
- if (iobuf)
- iobuf_unref (iobuf);
-
- STACK_UNWIND (frame, op_ret, op_errno);
- return 0;
-}
-
-
-/*
- * CBKs
- */
-/*
- * client_forget - forget function for client protocol
- * @this:
- * @inode:
- *
- * not for external reference
- */
-int
-client_forget (xlator_t *this, inode_t *inode)
-{
- ino_t ino = 0;
- client_conf_t *conf = NULL;
- client_forget_t forget = {0,};
- uint8_t send_forget = 0;
- int32_t ret = -1;
-
- GF_VALIDATE_OR_GOTO ("client", this, out);
- conf = this->private;
-
- GF_VALIDATE_OR_GOTO (this->name, inode, out);
-
- ret = inode_ctx_get (inode, this, &ino);
- if (inode->ino && ret < 0) {
- gf_log (this->name, GF_LOG_DEBUG,
- "FORGET %"PRId64": "
- "failed to get remote inode number",
- inode->ino);
- }
-
- LOCK (&conf->forget.lock);
- {
- conf->forget.ino_array[conf->forget.count++] = ino;
-
- if ((!conf->forget.frames_in_transit) ||
- (conf->forget.count >= CLIENT_PROTO_FORGET_LIMIT)) {
- ret = client_get_forgets (this, &forget);
- if (ret <= 0)
- send_forget = 0;
- else
- send_forget = 1;
- }
- }
- UNLOCK (&conf->forget.lock);
-
- if (send_forget) {
- ret = protocol_client_xfer (forget.frame, this,
- CLIENT_CHANNEL (this,CHANNEL_BULK),
- GF_OP_TYPE_CBK_REQUEST,
- GF_CBK_FORGET,
- forget.hdr, forget.hdrlen,
- NULL, 0, NULL);
- }
-out:
- return 0;
-}
-
-/**
- * client_releasedir - releasedir function for client protocol
- * @this: this translator structure
- * @fd: file descriptor structure
- *
- * external reference through client_protocol_xlator->cbks->releasedir
- */
-
-int
-client_releasedir (xlator_t *this, fd_t *fd)
-{
- call_frame_t *fr = NULL;
- int32_t ret = -1;
- int64_t remote_fd = 0;
- char key[32] = {0,};
- gf_hdr_common_t *hdr = NULL;
- size_t hdrlen = 0;
- gf_cbk_releasedir_req_t *req = NULL;
- client_conf_t *conf = NULL;
-
-
- GF_VALIDATE_OR_GOTO ("client", this, out);
- GF_VALIDATE_OR_GOTO (this->name, fd, out);
-
- conf = this->private;
- ret = this_fd_get (fd, this, &remote_fd);
- if (ret == -1){
- gf_log (this->name, GF_LOG_DEBUG,
- "(%"PRId64"): failed to get remote fd.",
- fd->inode->ino);
- goto out;
- }
-
- hdrlen = gf_hdr_len (req, 0);
- hdr = gf_hdr_new (req, 0);
- GF_VALIDATE_OR_GOTO (this->name, hdr, out);
-
- req = gf_param (hdr);
-
- req->fd = hton64 (remote_fd);
-
- {
- sprintf (key, "%p", fd);
-
- pthread_mutex_lock (&conf->mutex);
- {
- dict_del (conf->saved_fds, key);
- }
- pthread_mutex_unlock (&conf->mutex);
- }
-
- fr = create_frame (this, this->ctx->pool);
- GF_VALIDATE_OR_GOTO (this->name, fr, out);
-
- ret = protocol_client_xfer (fr, this,
- CLIENT_CHANNEL (this, CHANNEL_BULK),
- GF_OP_TYPE_CBK_REQUEST, GF_CBK_RELEASEDIR,
- hdr, hdrlen, NULL, 0, NULL);
-out:
- return ret;
-}
-
-
-/**
- * client_release - release function for client protocol
- * @this: this translator structure
- * @fd: file descriptor structure
- *
- * external reference through client_protocol_xlator->cbks->release
- *
- */
-int
-client_release (xlator_t *this, fd_t *fd)
-{
- call_frame_t *fr = NULL;
- int32_t ret = -1;
- int64_t remote_fd = 0;
- char key[32] = {0,};
- gf_hdr_common_t *hdr = NULL;
- size_t hdrlen = 0;
- gf_cbk_release_req_t *req = NULL;
- client_conf_t *conf = NULL;
-
- GF_VALIDATE_OR_GOTO ("client", this, out);
- GF_VALIDATE_OR_GOTO (this->name, fd, out);
-
- conf = this->private;
-
- ret = this_fd_get (fd, this, &remote_fd);
- if (ret == -1) {
- gf_log (this->name, GF_LOG_DEBUG,
- "(%"PRId64"): failed to get remote fd.",
- fd->inode->ino);
- goto out;
- }
-
- hdrlen = gf_hdr_len (req, 0);
- hdr = gf_hdr_new (req, 0);
- GF_VALIDATE_OR_GOTO (this->name, hdr, out);
- req = gf_param (hdr);
-
- req->fd = hton64 (remote_fd);
-
- {
- sprintf (key, "%p", fd);
-
- pthread_mutex_lock (&conf->mutex);
- {
- dict_del (conf->saved_fds, key);
- }
- pthread_mutex_unlock (&conf->mutex);
- }
-
- fr = create_frame (this, this->ctx->pool);
- GF_VALIDATE_OR_GOTO (this->name, fr, out);
-
- ret = protocol_client_xfer (fr, this,
- CLIENT_CHANNEL (this, CHANNEL_BULK),
- GF_OP_TYPE_CBK_REQUEST, GF_CBK_RELEASE,
- hdr, hdrlen, NULL, 0, NULL);
-out:
- return ret;
-}
-
-/*
- * MGMT_OPS
- */
-
-/**
- * client_stats - stats function for client protocol
- * @frame: call frame
- * @this: this translator structure
- * @flags:
- *
- * external reference through client_protocol_xlator->mops->stats
- */
-
-int
-client_stats (call_frame_t *frame, xlator_t *this, int32_t flags)
-{
- gf_hdr_common_t *hdr = NULL;
- gf_mop_stats_req_t *req = NULL;
- size_t hdrlen = -1;
- int ret = -1;
-
- GF_VALIDATE_OR_GOTO ("client", this, unwind);
-
- hdrlen = gf_hdr_len (req, 0);
- hdr = gf_hdr_new (req, 0);
- GF_VALIDATE_OR_GOTO (this->name, hdr, unwind);
-
- req = gf_param (hdr);
-
- req->flags = hton32 (flags);
-
- ret = protocol_client_xfer (frame, this,
- CLIENT_CHANNEL (this, CHANNEL_BULK),
- GF_OP_TYPE_MOP_REQUEST, GF_MOP_STATS,
- hdr, hdrlen, NULL, 0, NULL);
-
- return ret;
-unwind:
- STACK_UNWIND (frame, -1, EINVAL, NULL);
- return 0;
-}
-
-
-/* Callbacks */
-
-int
-client_fxattrop_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen,
- struct iobuf *iobuf)
-{
- gf_fop_xattrop_rsp_t *rsp = NULL;
- int32_t op_ret = 0;
- int32_t gf_errno = 0;
- int32_t op_errno = 0;
- int32_t dict_len = 0;
- dict_t *dict = NULL;
- int32_t ret = -1;
- char *dictbuf = NULL;
-
- rsp = gf_param (hdr);
- GF_VALIDATE_OR_GOTO(frame->this->name, rsp, fail);
-
- op_ret = ntoh32 (hdr->rsp.op_ret);
-
- if (op_ret >= 0) {
- op_ret = -1;
- dict_len = ntoh32 (rsp->dict_len);
-
- if (dict_len > 0) {
- dictbuf = memdup (rsp->dict, dict_len);
- GF_VALIDATE_OR_GOTO(frame->this->name, dictbuf, fail);
-
- dict = dict_new();
- GF_VALIDATE_OR_GOTO(frame->this->name, dict, fail);
-
- ret = dict_unserialize (dictbuf, dict_len, &dict);
- if (ret < 0) {
- gf_log (frame->this->name, GF_LOG_DEBUG,
- "failed to serialize dictionary(%p)",
- dict);
- op_errno = -ret;
- goto fail;
- } else {
- dict->extra_free = dictbuf;
- dictbuf = NULL;
- }
- }
- op_ret = 0;
- }
- gf_errno = ntoh32 (hdr->rsp.op_errno);
- op_errno = gf_error_to_errno (gf_errno);
-
-fail:
- STACK_UNWIND (frame, op_ret, op_errno, dict);
-
- if (dictbuf)
- free (dictbuf);
-
- if (dict)
- dict_unref (dict);
-
- return 0;
-}
-
-
-int
-client_xattrop_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen,
- struct iobuf *iobuf)
-{
- gf_fop_xattrop_rsp_t *rsp = NULL;
- int32_t op_ret = -1;
- int32_t gf_errno = EINVAL;
- int32_t op_errno = 0;
- int32_t dict_len = 0;
- dict_t *dict = NULL;
- int32_t ret = -1;
- char *dictbuf = NULL;
-
- rsp = gf_param (hdr);
- GF_VALIDATE_OR_GOTO(frame->this->name, rsp, fail);
-
- op_ret = ntoh32 (hdr->rsp.op_ret);
- if (op_ret >= 0) {
- op_ret = -1;
- dict_len = ntoh32 (rsp->dict_len);
-
- if (dict_len > 0) {
- dictbuf = memdup (rsp->dict, dict_len);
- GF_VALIDATE_OR_GOTO(frame->this->name, dictbuf, fail);
-
- dict = get_new_dict();
- GF_VALIDATE_OR_GOTO(frame->this->name, dict, fail);
- dict_ref (dict);
-
- ret = dict_unserialize (dictbuf, dict_len, &dict);
- if (ret < 0) {
- gf_log (frame->this->name, GF_LOG_DEBUG,
- "failed to serialize dictionary(%p)",
- dict);
- goto fail;
- } else {
- dict->extra_free = dictbuf;
- dictbuf = NULL;
- }
- }
- op_ret = 0;
- }
- gf_errno = ntoh32 (hdr->rsp.op_errno);
- op_errno = gf_error_to_errno (gf_errno);
-
-
-fail:
- STACK_UNWIND (frame, op_ret, op_errno, dict);
-
- if (dictbuf)
- free (dictbuf);
- if (dict)
- dict_unref (dict);
-
- return 0;
-}
-
-/*
- * client_chown_cbk -
- *
- * @frame:
- * @args:
- *
- * not for external reference
- */
-
-int
-client_fchown_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen,
- struct iobuf *iobuf)
-{
- struct stat stbuf = {0, };
- gf_fop_fchown_rsp_t *rsp = NULL;
- int32_t op_ret = 0;
- int32_t op_errno = 0;
-
- rsp = gf_param (hdr);
-
- op_ret = ntoh32 (hdr->rsp.op_ret);
- op_errno = gf_error_to_errno (ntoh32 (hdr->rsp.op_errno));
-
- if (op_ret == 0) {
- gf_stat_to_stat (&rsp->stat, &stbuf);
- }
-
- STACK_UNWIND (frame, op_ret, op_errno, &stbuf);
-
- return 0;
-}
-
-
-int
-client_fchmod_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen,
- struct iobuf *iobuf)
-{
- struct stat stbuf = {0, };
- gf_fop_fchmod_rsp_t *rsp = NULL;
- int32_t op_ret = 0;
- int32_t op_errno = 0;
-
- rsp = gf_param (hdr);
-
- op_ret = ntoh32 (hdr->rsp.op_ret);
- op_errno = gf_error_to_errno (ntoh32 (hdr->rsp.op_errno));
-
- if (op_ret == 0) {
- gf_stat_to_stat (&rsp->stat, &stbuf);
- }
-
- STACK_UNWIND (frame, op_ret, op_errno, &stbuf);
-
- return 0;
-}
-
-
-/*
- * client_create_cbk - create callback function for client protocol
- * @frame: call frame
- * @args: arguments in dictionary
- *
- * not for external reference
- */
-
-int
-client_create_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen,
- struct iobuf *iobuf)
-{
- gf_fop_create_rsp_t *rsp = NULL;
- int32_t op_ret = 0;
- int32_t op_errno = 0;
- fd_t *fd = NULL;
- inode_t *inode = NULL;
- struct stat stbuf = {0, };
- int64_t remote_fd = 0;
- char key[32] = {0, };
- int32_t ret = -1;
- client_local_t *local = NULL;
- client_conf_t *conf = NULL;
-
- local = frame->local; frame->local = NULL;
- conf = frame->this->private;
- fd = local->fd;
- inode = local->loc.inode;
-
- rsp = gf_param (hdr);
-
- op_ret = ntoh32 (hdr->rsp.op_ret);
- op_errno = ntoh32 (hdr->rsp.op_errno);
-
- if (op_ret >= 0) {
- remote_fd = ntoh64 (rsp->fd);
- gf_stat_to_stat (&rsp->stat, &stbuf);
- }
-
- if (op_ret >= 0) {
- ret = inode_ctx_put (local->loc.inode, frame->this,
- stbuf.st_ino);
- if (ret < 0) {
- gf_log (frame->this->name, GF_LOG_DEBUG,
- "CREATE %"PRId64"/%s (%s): failed to set "
- "remote inode number to inode ctx",
- local->loc.parent->ino, local->loc.name,
- local->loc.path);
- }
-
- this_fd_set (fd, frame->this, &local->loc, remote_fd);
-
- sprintf (key, "%p", fd);
-
- pthread_mutex_lock (&conf->mutex);
- {
- ret = dict_set_str (conf->saved_fds, key, "");
- }
- pthread_mutex_unlock (&conf->mutex);
-
- if (ret < 0) {
- free (key);
- gf_log (frame->this->name, GF_LOG_DEBUG,
- "%s (%"PRId64"): failed to save remote fd",
- local->loc.path, stbuf.st_ino);
- }
- }
-
- STACK_UNWIND (frame, op_ret, op_errno, fd, inode, &stbuf);
-
- client_local_wipe (local);
-
- return 0;
-}
-
-
-/*
- * client_open_cbk - open callback for client protocol
- * @frame: call frame
- * @args: argument dictionary
- *
- * not for external reference
- */
-int
-client_open_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen,
- struct iobuf *iobuf)
-{
- int32_t op_ret = -1;
- int32_t op_errno = ENOTCONN;
- fd_t *fd = NULL;
- int64_t remote_fd = 0;
- gf_fop_open_rsp_t *rsp = NULL;
- char key[32] = {0,};
- int32_t ret = -1;
- client_local_t *local = NULL;
- client_conf_t *conf = NULL;
-
-
- local = frame->local; frame->local = NULL;
- conf = frame->this->private;
- fd = local->fd;
-
- rsp = gf_param (hdr);
-
- op_ret = ntoh32 (hdr->rsp.op_ret);
- op_errno = ntoh32 (hdr->rsp.op_errno);
-
- if (op_ret >= 0) {
- remote_fd = ntoh64 (rsp->fd);
- }
-
- if (op_ret >= 0) {
- this_fd_set (fd, frame->this, &local->loc, remote_fd);
-
- sprintf (key, "%p", fd);
-
- pthread_mutex_lock (&conf->mutex);
- {
- ret = dict_set_str (conf->saved_fds, key, "");
- }
- pthread_mutex_unlock (&conf->mutex);
-
- if (ret < 0) {
- gf_log (frame->this->name, GF_LOG_DEBUG,
- "%s (%"PRId64"): failed to save remote fd",
- local->loc.path, local->loc.inode->ino);
- free (key);
- }
-
- }
-
- STACK_UNWIND (frame, op_ret, op_errno, fd);
-
- client_local_wipe (local);
-
- return 0;
-}
-
-/*
- * client_stat_cbk - stat callback for client protocol
- * @frame: call frame
- * @args: arguments dictionary
- *
- * not for external reference
- */
-
-int
-client_stat_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen,
- struct iobuf *iobuf)
-{
- struct stat stbuf = {0, };
- gf_fop_stat_rsp_t *rsp = NULL;
- int32_t op_ret = 0;
- int32_t op_errno = 0;
-
- rsp = gf_param (hdr);
-
- op_ret = ntoh32 (hdr->rsp.op_ret);
- op_errno = gf_error_to_errno (ntoh32 (hdr->rsp.op_errno));
-
- if (op_ret == 0) {
- gf_stat_to_stat (&rsp->stat, &stbuf);
- }
-
- STACK_UNWIND (frame, op_ret, op_errno, &stbuf);
-
- return 0;
-}
-
-/*
- * client_utimens_cbk - utimens callback for client protocol
- * @frame: call frame
- * @args: argument dictionary
- *
- * not for external reference
- */
-
-int
-client_utimens_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen,
- struct iobuf *iobuf)
-{
- struct stat stbuf = {0, };
- gf_fop_utimens_rsp_t *rsp = NULL;
- int32_t op_ret = 0;
- int32_t op_errno = 0;
-
- rsp = gf_param (hdr);
-
- op_ret = ntoh32 (hdr->rsp.op_ret);
- op_errno = gf_error_to_errno (ntoh32 (hdr->rsp.op_errno));
-
- if (op_ret == 0) {
- gf_stat_to_stat (&rsp->stat, &stbuf);
- }
-
- STACK_UNWIND (frame, op_ret, op_errno, &stbuf);
-
- return 0;
-}
-
-/*
- * client_chmod_cbk - chmod for client protocol
- * @frame: call frame
- * @args: argument dictionary
- *
- * not for external reference
- */
-
-int
-client_chmod_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen,
- struct iobuf *iobuf)
-{
- struct stat stbuf = {0, };
- gf_fop_chmod_rsp_t *rsp = NULL;
- int32_t op_ret = 0;
- int32_t op_errno = 0;
-
- rsp = gf_param (hdr);
-
- op_ret = ntoh32 (hdr->rsp.op_ret);
- op_errno = gf_error_to_errno (ntoh32 (hdr->rsp.op_errno));
-
- if (op_ret == 0) {
- gf_stat_to_stat (&rsp->stat, &stbuf);
- }
-
- STACK_UNWIND (frame, op_ret, op_errno, &stbuf);
-
- return 0;
-}
-
-/*
- * client_chown_cbk - chown for client protocol
- * @frame: call frame
- * @args: argument dictionary
- *
- * not for external reference
- */
-
-int
-client_chown_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen,
- struct iobuf *iobuf)
-{
- struct stat stbuf = {0, };
- gf_fop_chown_rsp_t *rsp = NULL;
- int32_t op_ret = 0;
- int32_t op_errno = 0;
-
- rsp = gf_param (hdr);
-
- op_ret = ntoh32 (hdr->rsp.op_ret);
- op_errno = gf_error_to_errno (ntoh32 (hdr->rsp.op_errno));
-
- if (op_ret == 0) {
- gf_stat_to_stat (&rsp->stat, &stbuf);
- }
-
- STACK_UNWIND (frame, op_ret, op_errno, &stbuf);
-
- return 0;
-}
-
-/*
- * client_mknod_cbk - mknod callback for client protocol
- * @frame: call frame
- * @args: argument dictionary
- *
- * not for external reference
- */
-
-int
-client_mknod_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen,
- struct iobuf *iobuf)
-{
- gf_fop_mknod_rsp_t *rsp = NULL;
- int32_t op_ret = 0;
- int32_t op_errno = 0;
- struct stat stbuf = {0, };
- inode_t *inode = NULL;
- client_local_t *local = NULL;
- int ret = 0;
-
- local = frame->local;
- frame->local = NULL;
- inode = local->loc.inode;
-
- rsp = gf_param (hdr);
-
- op_ret = ntoh32 (hdr->rsp.op_ret);
- op_errno = gf_error_to_errno (ntoh32 (hdr->rsp.op_errno));
-
- if (op_ret >= 0) {
- gf_stat_to_stat (&rsp->stat, &stbuf);
-
- ret = inode_ctx_put (local->loc.inode, frame->this,
- stbuf.st_ino);
- if (ret < 0) {
- gf_log (frame->this->name, GF_LOG_DEBUG,
- "MKNOD %"PRId64"/%s (%s): failed to set remote"
- " inode number to inode ctx",
- local->loc.parent->ino, local->loc.name,
- local->loc.path);
- }
- }
-
- STACK_UNWIND (frame, op_ret, op_errno, inode, &stbuf);
-
- client_local_wipe (local);
-
- return 0;
-}
-
-/*
- * client_symlink_cbk - symlink callback for client protocol
- * @frame: call frame
- * @args: argument dictionary
- *
- * not for external reference
- */
-
-int
-client_symlink_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen,
- struct iobuf *iobuf)
-{
- gf_fop_symlink_rsp_t *rsp = NULL;
- int32_t op_ret = 0;
- int32_t op_errno = 0;
- struct stat stbuf = {0, };
- inode_t *inode = NULL;
- client_local_t *local = NULL;
- int ret = 0;
-
- local = frame->local;
- frame->local = NULL;
- inode = local->loc.inode;
-
- rsp = gf_param (hdr);
-
- op_ret = ntoh32 (hdr->rsp.op_ret);
- op_errno = gf_error_to_errno (ntoh32 (hdr->rsp.op_errno));
-
- if (op_ret >= 0) {
- gf_stat_to_stat (&rsp->stat, &stbuf);
-
- ret = inode_ctx_put (inode, frame->this,
- stbuf.st_ino);
- if (ret < 0) {
- gf_log (frame->this->name, GF_LOG_DEBUG,
- "SYMLINK %"PRId64"/%s (%s): failed to set "
- "remote inode number to inode ctx",
- local->loc.parent->ino, local->loc.name,
- local->loc.path);
- }
- }
-
- STACK_UNWIND (frame, op_ret, op_errno, inode, &stbuf);
-
- client_local_wipe (local);
-
- return 0;
-}
-
-/*
- * client_link_cbk - link callback for client protocol
- * @frame: call frame
- * @args: argument dictionary
- *
- * not for external reference
- */
-
-int
-client_link_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen,
- struct iobuf *iobuf)
-{
- gf_fop_link_rsp_t *rsp = NULL;
- int32_t op_ret = 0;
- int32_t op_errno = 0;
- struct stat stbuf = {0, };
- inode_t *inode = NULL;
- client_local_t *local = NULL;
-
- local = frame->local;
- frame->local = NULL;
- inode = local->loc.inode;
-
- rsp = gf_param (hdr);
-
- op_ret = ntoh32 (hdr->rsp.op_ret);
- op_errno = gf_error_to_errno (ntoh32 (hdr->rsp.op_errno));
-
- if (op_ret >= 0) {
- gf_stat_to_stat (&rsp->stat, &stbuf);
- }
-
- STACK_UNWIND (frame, op_ret, op_errno, inode, &stbuf);
-
- client_local_wipe (local);
-
- return 0;
-}
-
-/*
- * client_truncate_cbk - truncate callback for client protocol
- * @frame: call frame
- * @args: argument dictionary
- *
- * not for external reference
- */
-
-int
-client_truncate_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen,
- struct iobuf *iobuf)
-{
- struct stat stbuf = {0, };
- gf_fop_truncate_rsp_t *rsp = NULL;
- int32_t op_ret = 0;
- int32_t op_errno = 0;
-
- rsp = gf_param (hdr);
-
- op_ret = ntoh32 (hdr->rsp.op_ret);
- op_errno = gf_error_to_errno (ntoh32 (hdr->rsp.op_errno));
-
- if (op_ret == 0) {
- gf_stat_to_stat (&rsp->stat, &stbuf);
- }
-
- STACK_UNWIND (frame, op_ret, op_errno, &stbuf);
-
- return 0;
-}
-
-/* client_fstat_cbk - fstat callback for client protocol
- * @frame: call frame
- * @args: argument dictionary
- *
- * not for external reference
- */
-
-int
-client_fstat_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen,
- struct iobuf *iobuf)
-{
- struct stat stbuf = {0, };
- gf_fop_fstat_rsp_t *rsp = NULL;
- int32_t op_ret = 0;
- int32_t op_errno = 0;
-
- rsp = gf_param (hdr);
-
- op_ret = ntoh32 (hdr->rsp.op_ret);
- op_errno = gf_error_to_errno (ntoh32 (hdr->rsp.op_errno));
-
- if (op_ret == 0) {
- gf_stat_to_stat (&rsp->stat, &stbuf);
- }
-
- STACK_UNWIND (frame, op_ret, op_errno, &stbuf);
-
- return 0;
-}
-
-/*
- * client_ftruncate_cbk - ftruncate callback for client protocol
- * @frame: call frame
- * @args: argument dictionary
- *
- * not for external reference
- */
-int
-client_ftruncate_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen,
- struct iobuf *iobuf)
-{
- struct stat stbuf = {0, };
- gf_fop_ftruncate_rsp_t *rsp = NULL;
- int32_t op_ret = 0;
- int32_t op_errno = 0;
-
- rsp = gf_param (hdr);
-
- op_ret = ntoh32 (hdr->rsp.op_ret);
- op_errno = gf_error_to_errno (ntoh32 (hdr->rsp.op_errno));
-
- if (op_ret == 0) {
- gf_stat_to_stat (&rsp->stat, &stbuf);
- }
-
- STACK_UNWIND (frame, op_ret, op_errno, &stbuf);
-
- return 0;
-}
-
-
-/* client_readv_cbk - readv callback for client protocol
- * @frame: call frame
- * @args: argument dictionary
- *
- * not for external referece
- */
-
-int
-client_readv_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen,
- struct iobuf *iobuf)
-{
- gf_fop_read_rsp_t *rsp = NULL;
- int32_t op_ret = 0;
- int32_t op_errno = 0;
- struct iovec vector = {0, };
- struct stat stbuf = {0, };
- struct iobref *iobref = NULL;
-
- rsp = gf_param (hdr);
-
- op_ret = ntoh32 (hdr->rsp.op_ret);
- op_errno = gf_error_to_errno (ntoh32 (hdr->rsp.op_errno));
-
- if (op_ret != -1) {
- iobref = iobref_new ();
- gf_stat_to_stat (&rsp->stat, &stbuf);
- vector.iov_len = op_ret;
-
- if (op_ret > 0) {
- vector.iov_base = iobuf->ptr;
- iobref_add (iobref, iobuf);
- }
- }
-
- STACK_UNWIND (frame, op_ret, op_errno, &vector, 1, &stbuf, iobref);
-
- if (iobref)
- iobref_unref (iobref);
-
- if (iobuf)
- iobuf_unref (iobuf);
-
- return 0;
-}
-
-/*
- * client_write_cbk - write callback for client protocol
- * @frame: cal frame
- * @args: argument dictionary
- *
- * not for external reference
- */
-
-int
-client_write_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen,
- struct iobuf *iobuf)
-{
- gf_fop_write_rsp_t *rsp = NULL;
- int32_t op_ret = 0;
- int32_t op_errno = 0;
- struct stat stbuf = {0, };
-
- rsp = gf_param (hdr);
-
- op_ret = ntoh32 (hdr->rsp.op_ret);
- op_errno = gf_error_to_errno (ntoh32 (hdr->rsp.op_errno));
-
- if (op_ret >= 0)
- gf_stat_to_stat (&rsp->stat, &stbuf);
-
- STACK_UNWIND (frame, op_ret, op_errno, &stbuf);
-
- return 0;
-}
-
-
-int
-client_readdir_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen,
- struct iobuf *iobuf)
-{
- gf_fop_readdir_rsp_t *rsp = NULL;
- int32_t op_ret = 0;
- int32_t op_errno = 0;
- uint32_t buf_size = 0;
- gf_dirent_t entries;
-
- rsp = gf_param (hdr);
-
- op_ret = ntoh32 (hdr->rsp.op_ret);
- op_errno = ntoh32 (hdr->rsp.op_errno);
-
- INIT_LIST_HEAD (&entries.list);
- if (op_ret > 0) {
- buf_size = ntoh32 (rsp->size);
- gf_dirent_unserialize (&entries, rsp->buf, buf_size);
- }
-
- STACK_UNWIND (frame, op_ret, op_errno, &entries);
-
- gf_dirent_free (&entries);
-
- return 0;
-}
-
-/*
- * client_fsync_cbk - fsync callback for client protocol
- *
- * @frame: call frame
- * @args: argument dictionary
- *
- * not for external reference
- */
-
-int
-client_fsync_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen,
- struct iobuf *iobuf)
-{
- struct stat stbuf = {0, };
- gf_fop_fsync_rsp_t *rsp = NULL;
- int32_t op_ret = 0;
- int32_t op_errno = 0;
-
- rsp = gf_param (hdr);
-
- op_ret = ntoh32 (hdr->rsp.op_ret);
- op_errno = gf_error_to_errno (ntoh32 (hdr->rsp.op_errno));
-
- STACK_UNWIND (frame, op_ret, op_errno, &stbuf);
-
- return 0;
-}
-
-/*
- * client_unlink_cbk - unlink callback for client protocol
- * @frame: call frame
- * @args: argument dictionary
- *
- * not for external reference
- */
-
-int
-client_unlink_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen,
- struct iobuf *iobuf)
-{
- gf_fop_unlink_rsp_t *rsp = NULL;
- int32_t op_ret = 0;
- int32_t op_errno = 0;
-
- rsp = gf_param (hdr);
-
- op_ret = ntoh32 (hdr->rsp.op_ret);
- op_errno = gf_error_to_errno (ntoh32 (hdr->rsp.op_errno));
-
- STACK_UNWIND (frame, op_ret, op_errno);
-
- return 0;
-}
-
-/*
- * client_rename_cbk - rename callback for client protocol
- * @frame: call frame
- * @args: argument dictionary
- *
- * not for external reference
- */
-
-int
-client_rename_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen,
- struct iobuf *iobuf)
-{
- struct stat stbuf = {0, };
- gf_fop_rename_rsp_t *rsp = NULL;
- int32_t op_ret = 0;
- int32_t op_errno = 0;
-
- rsp = gf_param (hdr);
-
- op_ret = ntoh32 (hdr->rsp.op_ret);
- op_errno = gf_error_to_errno (ntoh32 (hdr->rsp.op_errno));
-
- if (op_ret == 0) {
- gf_stat_to_stat (&rsp->stat, &stbuf);
- }
-
- STACK_UNWIND (frame, op_ret, op_errno, &stbuf);
-
- return 0;
-}
-
-
-/*
- * client_readlink_cbk - readlink callback for client protocol
- *
- * @frame: call frame
- * @args: argument dictionary
- *
- * not for external reference
- */
-int
-client_readlink_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen,
- struct iobuf *iobuf)
-{
- gf_fop_readlink_rsp_t *rsp = NULL;
- int32_t op_ret = 0;
- int32_t op_errno = 0;
- char *link = NULL;
-
- rsp = gf_param (hdr);
-
- op_ret = ntoh32 (hdr->rsp.op_ret);
- op_errno = gf_error_to_errno (ntoh32 (hdr->rsp.op_errno));
-
- if (op_ret > 0) {
- link = rsp->path;
- }
-
- STACK_UNWIND (frame, op_ret, op_errno, link);
- return 0;
-}
-
-/*
- * client_mkdir_cbk - mkdir callback for client protocol
- * @frame: call frame
- * @args: argument dictionary
- *
- * not for external reference
- */
-
-int
-client_mkdir_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen,
- struct iobuf *iobuf)
-{
- gf_fop_mkdir_rsp_t *rsp = NULL;
- int32_t op_ret = 0;
- int32_t op_errno = 0;
- struct stat stbuf = {0, };
- inode_t *inode = NULL;
- client_local_t *local = NULL;
- int ret = 0;
-
- local = frame->local;
- inode = local->loc.inode;
- frame->local = NULL;
-
- rsp = gf_param (hdr);
-
- op_ret = ntoh32 (hdr->rsp.op_ret);
- op_errno = gf_error_to_errno (ntoh32 (hdr->rsp.op_errno));
-
- if (op_ret >= 0) {
- gf_stat_to_stat (&rsp->stat, &stbuf);
-
- ret = inode_ctx_put (inode, frame->this, stbuf.st_ino);
- if (ret < 0) {
- gf_log (frame->this->name, GF_LOG_DEBUG,
- "MKDIR %"PRId64"/%s (%s): failed to set "
- "remote inode number to inode ctx",
- local->loc.parent->ino, local->loc.name,
- local->loc.path);
- }
- }
-
- STACK_UNWIND (frame, op_ret, op_errno, inode, &stbuf);
-
- client_local_wipe (local);
-
- return 0;
-}
-
-/*
- * client_flush_cbk - flush callback for client protocol
- *
- * @frame: call frame
- * @args: argument dictionary
- *
- * not for external reference
- */
-
-int
-client_flush_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen,
- struct iobuf *iobuf)
-{
- int32_t op_ret = 0;
- int32_t op_errno = 0;
-
- op_ret = ntoh32 (hdr->rsp.op_ret);
- op_errno = gf_error_to_errno (ntoh32 (hdr->rsp.op_errno));
-
- STACK_UNWIND (frame, op_ret, op_errno);
-
- return 0;
-}
-
-/*
- * client_opendir_cbk - opendir callback for client protocol
- * @frame: call frame
- * @args: argument dictionary
- *
- * not for external reference
- */
-
-int
-client_opendir_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen,
- struct iobuf *iobuf)
-{
- int32_t op_ret = -1;
- int32_t op_errno = ENOTCONN;
- fd_t *fd = NULL;
- int64_t remote_fd = 0;
- gf_fop_opendir_rsp_t *rsp = NULL;
- char key[32] = {0,};
- int32_t ret = -1;
- client_local_t *local = NULL;
- client_conf_t *conf = NULL;
-
-
- local = frame->local; frame->local = NULL;
- conf = frame->this->private;
- fd = local->fd;
-
- rsp = gf_param (hdr);
-
- op_ret = ntoh32 (hdr->rsp.op_ret);
- op_errno = ntoh32 (hdr->rsp.op_errno);
-
- if (op_ret >= 0) {
- remote_fd = ntoh64 (rsp->fd);
- }
-
- if (op_ret >= 0) {
- this_fd_set (fd, frame->this, &local->loc, remote_fd);
-
- sprintf (key, "%p", fd);
-
- pthread_mutex_lock (&conf->mutex);
- {
- ret = dict_set_str (conf->saved_fds, key, "");
- }
- pthread_mutex_unlock (&conf->mutex);
-
- if (ret < 0) {
- free (key);
- gf_log (frame->this->name, GF_LOG_DEBUG,
- "%s (%"PRId64"): failed to save remote fd",
- local->loc.path, local->loc.inode->ino);
- }
- }
-
- STACK_UNWIND (frame, op_ret, op_errno, fd);
-
- client_local_wipe (local);
-
- return 0;
-}
-
-/*
- * client_rmdir_cbk - rmdir callback for client protocol
- * @frame: call frame
- * @args: argument dictionary
- *
- * not for external reference
- */
-
-int
-client_rmdir_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen,
- struct iobuf *iobuf)
-{
- gf_fop_rmdir_rsp_t *rsp = NULL;
- int32_t op_ret = 0;
- int32_t op_errno = 0;
-
- rsp = gf_param (hdr);
-
- op_ret = ntoh32 (hdr->rsp.op_ret);
- op_errno = gf_error_to_errno (ntoh32 (hdr->rsp.op_errno));
-
- STACK_UNWIND (frame, op_ret, op_errno);
-
- return 0;
-}
-
-/*
- * client_access_cbk - access callback for client protocol
- * @frame: call frame
- * @args: argument dictionary
- *
- * not for external reference
- */
-
-int
-client_access_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen,
- struct iobuf *iobuf)
-{
- gf_fop_access_rsp_t *rsp = NULL;
- int32_t op_ret = 0;
- int32_t op_errno = 0;
-
- rsp = gf_param (hdr);
-
- op_ret = ntoh32 (hdr->rsp.op_ret);
- op_errno = gf_error_to_errno (ntoh32 (hdr->rsp.op_errno));
-
- STACK_UNWIND (frame, op_ret, op_errno);
-
- return 0;
-}
-
-/*
- * client_lookup_cbk - lookup callback for client protocol
- *
- * @frame: call frame
- * @args: arguments dictionary
- *
- * not for external reference
- */
-
-int
-client_lookup_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen,
- struct iobuf *iobuf)
-{
- struct stat stbuf = {0, };
- inode_t *inode = NULL;
- dict_t *xattr = NULL;
- gf_fop_lookup_rsp_t *rsp = NULL;
- int32_t op_ret = 0;
- int32_t op_errno = 0;
- size_t dict_len = 0;
- char *dictbuf = NULL;
- int32_t ret = -1;
- int32_t gf_errno = 0;
- client_local_t *local = NULL;
- ino_t oldino = 0;
-
- local = frame->local;
- inode = local->loc.inode;
- frame->local = NULL;
-
- rsp = gf_param (hdr);
-
- op_ret = ntoh32 (hdr->rsp.op_ret);
-
- if (op_ret == 0) {
- op_ret = -1;
- gf_stat_to_stat (&rsp->stat, &stbuf);
-
- ret = inode_ctx_get (inode, frame->this, &oldino);
- if (oldino != stbuf.st_ino) {
- if (oldino)
- gf_log (frame->this->name, GF_LOG_DEBUG,
- "LOOKUP %"PRId64"/%s (%s): "
- "inode number changed from "
- "%"PRId64" to %"PRId64,
- local->loc.parent->ino,
- local->loc.name,
- local->loc.path,
- oldino, stbuf.st_ino);
-
- ret = inode_ctx_put (inode, frame->this,
- stbuf.st_ino);
- if (ret < 0) {
- gf_log (frame->this->name, GF_LOG_DEBUG,
- "LOOKUP %"PRId64"/%s (%s) : "
- "failed to set remote inode "
- "number to inode ctx",
- local->loc.parent->ino,
- local->loc.name,
- local->loc.path);
- }
- }
-
- dict_len = ntoh32 (rsp->dict_len);
-
- if (dict_len > 0) {
- dictbuf = memdup (rsp->dict, dict_len);
- GF_VALIDATE_OR_GOTO(frame->this->name, dictbuf, fail);
-
- xattr = dict_new();
- GF_VALIDATE_OR_GOTO(frame->this->name, xattr, fail);
-
- ret = dict_unserialize (dictbuf, dict_len, &xattr);
- if (ret < 0) {
- gf_log (frame->this->name, GF_LOG_DEBUG,
- "%s (%"PRId64"): failed to "
- "unserialize dictionary",
- local->loc.path, inode->ino);
- goto fail;
- } else {
- xattr->extra_free = dictbuf;
- dictbuf = NULL;
- }
- }
- op_ret = 0;
- }
- gf_errno = ntoh32 (hdr->rsp.op_errno);
- op_errno = gf_error_to_errno (gf_errno);
-
-fail:
- STACK_UNWIND (frame, op_ret, op_errno, inode, &stbuf, xattr);
-
- client_local_wipe (local);
-
- if (dictbuf)
- free (dictbuf);
-
- if (xattr)
- dict_unref (xattr);
-
- return 0;
-}
-
-static dir_entry_t *
-gf_bin_to_direntry (char *buf, size_t count)
-{
- int idx = 0;
- int bread = 0;
- size_t rcount = 0;
- char *ender = NULL;
- char *buffer = NULL;
- char tmp_buf[512] = {0,};
- dir_entry_t *trav = NULL;
- dir_entry_t *prev = NULL;
- dir_entry_t *thead = NULL;
- dir_entry_t *head = NULL;
-
- thead = CALLOC (1, sizeof (dir_entry_t));
- GF_VALIDATE_OR_GOTO("client-protocol", thead, fail);
-
- buffer = buf;
- prev = thead;
-
- for (idx = 0; idx < count ; idx++) {
- bread = 0;
- trav = CALLOC (1, sizeof (dir_entry_t));
- GF_VALIDATE_OR_GOTO("client-protocol", trav, fail);
-
- ender = strchr (buffer, '/');
- if (!ender)
- break;
- rcount = ender - buffer;
- trav->name = CALLOC (1, rcount + 2);
- GF_VALIDATE_OR_GOTO("client-protocol", trav->name, fail);
-
- strncpy (trav->name, buffer, rcount);
- bread = rcount + 1;
- buffer += bread;
-
- ender = strchr (buffer, '\n');
- if (!ender)
- break;
- rcount = ender - buffer;
- strncpy (tmp_buf, buffer, rcount);
- bread = rcount + 1;
- buffer += bread;
-
- gf_string_to_stat (tmp_buf, &trav->buf);
-
- ender = strchr (buffer, '\n');
- if (!ender)
- break;
- rcount = ender - buffer;
- *ender = '\0';
- if (S_ISLNK (trav->buf.st_mode))
- trav->link = strdup (buffer);
- else
- trav->link = "";
-
- bread = rcount + 1;
- buffer += bread;
-
- prev->next = trav;
- prev = trav;
- }
-
- head = thead;
-fail:
- return head;
-}
-
-
-int
-gf_free_direntry (dir_entry_t *head)
-{
- dir_entry_t *prev = NULL;
- dir_entry_t *trav = NULL;
-
- prev = head;
- GF_VALIDATE_OR_GOTO("client-protocol", prev, fail);
-
- trav = head->next;
- 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 (head);
-fail:
- return 0;
-}
-
-/*
- * client_getdents_cbk - readdir callback for client protocol
- * @frame: call frame
- * @args: argument dictionary
- *
- * not for external reference
- */
-
-int
-client_getdents_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen,
- struct iobuf *iobuf)
-{
- gf_fop_getdents_rsp_t *rsp = NULL;
- int32_t op_ret = 0;
- int32_t op_errno = 0;
- int32_t gf_errno = 0;
- int32_t nr_count = 0;
- dir_entry_t *entry = NULL;
-
- rsp = gf_param (hdr);
-
- op_ret = ntoh32 (hdr->rsp.op_ret);
- gf_errno = ntoh32 (hdr->rsp.op_errno);
- op_errno = gf_error_to_errno (gf_errno);
-
- if (op_ret >= 0) {
- nr_count = ntoh32 (rsp->count);
- entry = gf_bin_to_direntry(iobuf->ptr, nr_count);
- if (entry == NULL) {
- op_ret = -1;
- op_errno = EINVAL;
- }
- }
-
- STACK_UNWIND (frame, op_ret, op_errno, entry, nr_count);
-
- if (iobuf)
- iobuf_unref (iobuf);
- if (entry)
- gf_free_direntry(entry);
-
- return 0;
-}
-
-/*
- * client_statfs_cbk - statfs callback for client protocol
- * @frame: call frame
- * @args: argument dictionary
- *
- * not for external reference
- */
-
-int
-client_statfs_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen,
- struct iobuf *iobuf)
-{
- struct statvfs stbuf = {0, };
- gf_fop_statfs_rsp_t *rsp = NULL;
- int32_t op_ret = 0;
- int32_t op_errno = 0;
-
- rsp = gf_param (hdr);
-
- op_ret = ntoh32 (hdr->rsp.op_ret);
- op_errno = gf_error_to_errno (ntoh32 (hdr->rsp.op_errno));
-
- if (op_ret == 0) {
- gf_statfs_to_statfs (&rsp->statfs, &stbuf);
- }
-
- STACK_UNWIND (frame, op_ret, op_errno, &stbuf);
-
- return 0;
-}
-
-/*
- * client_fsyncdir_cbk - fsyncdir callback for client protocol
- * @frame: call frame
- * @args: argument dictionary
- *
- * not for external reference
- */
-
-int
-client_fsyncdir_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen,
- struct iobuf *iobuf)
-{
- int32_t op_ret = 0;
- int32_t op_errno = 0;
-
- op_ret = ntoh32 (hdr->rsp.op_ret);
- op_errno = gf_error_to_errno (ntoh32 (hdr->rsp.op_errno));
-
- STACK_UNWIND (frame, op_ret, op_errno);
-
- return 0;
-}
-
-/*
- * client_setxattr_cbk - setxattr callback for client protocol
- * @frame: call frame
- * @args: argument dictionary
- *
- * not for external reference
- */
-
-int
-client_setxattr_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen,
- struct iobuf *iobuf)
-{
- gf_fop_setxattr_rsp_t *rsp = NULL;
- int32_t op_ret = 0;
- int32_t op_errno = 0;
-
- rsp = gf_param (hdr);
-
- op_ret = ntoh32 (hdr->rsp.op_ret);
- op_errno = gf_error_to_errno (ntoh32 (hdr->rsp.op_errno));
-
- STACK_UNWIND (frame, op_ret, op_errno);
-
- return 0;
-}
-
-/*
- * client_getxattr_cbk - getxattr callback for client protocol
- * @frame: call frame
- * @args: argument dictionary
- *
- * not for external reference
- */
-
-int
-client_getxattr_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen,
- struct iobuf *iobuf)
-{
- gf_fop_getxattr_rsp_t *rsp = NULL;
- int32_t op_ret = 0;
- int32_t gf_errno = 0;
- int32_t op_errno = 0;
- int32_t dict_len = 0;
- dict_t *dict = NULL;
- int32_t ret = -1;
- char *dictbuf = NULL;
- client_local_t *local = NULL;
-
- local = frame->local;
- frame->local = NULL;
-
- rsp = gf_param (hdr);
- GF_VALIDATE_OR_GOTO(frame->this->name, rsp, fail);
-
- op_ret = ntoh32 (hdr->rsp.op_ret);
-
- if (op_ret >= 0) {
- op_ret = -1;
- dict_len = ntoh32 (rsp->dict_len);
-
- if (dict_len > 0) {
- dictbuf = memdup (rsp->dict, dict_len);
- GF_VALIDATE_OR_GOTO(frame->this->name, dictbuf, fail);
-
- dict = dict_new();
- GF_VALIDATE_OR_GOTO(frame->this->name, dict, fail);
-
- ret = dict_unserialize (dictbuf, dict_len, &dict);
- if (ret < 0) {
- gf_log (frame->this->name, GF_LOG_DEBUG,
- "%s (%"PRId64"): failed to "
- "unserialize xattr dictionary",
- local->loc.path,
- local->loc.inode->ino);
- goto fail;
- } else {
- dict->extra_free = dictbuf;
- dictbuf = NULL;
- }
- }
- op_ret = 0;
- }
- gf_errno = ntoh32 (hdr->rsp.op_errno);
- op_errno = gf_error_to_errno (gf_errno);
-fail:
- STACK_UNWIND (frame, op_ret, op_errno, dict);
-
- client_local_wipe (local);
-
- if (dictbuf)
- free (dictbuf);
-
- if (dict)
- dict_unref (dict);
-
- return 0;
-}
-
-/*
- * client_removexattr_cbk - removexattr callback for client protocol
- * @frame: call frame
- * @args: argument dictionary
- *
- * not for external reference
- */
-
-int
-client_removexattr_cbk (call_frame_t *frame, gf_hdr_common_t *hdr,
- size_t hdrlen, struct iobuf *iobuf)
-{
- int32_t op_ret = 0;
- int32_t op_errno = 0;
-
- op_ret = ntoh32 (hdr->rsp.op_ret);
- op_errno = gf_error_to_errno (ntoh32 (hdr->rsp.op_errno));
-
- STACK_UNWIND (frame, op_ret, op_errno);
-
- return 0;
-}
-
-/*
- * client_lk_cbk - lk callback for client protocol
- * @frame: call frame
- * @args: argument dictionary
- *
- * not for external reference
- */
-
-int
-client_lk_common_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen,
- struct iobuf *iobuf)
-{
- struct flock lock = {0,};
- gf_fop_lk_rsp_t *rsp = NULL;
- int32_t op_ret = 0;
- int32_t op_errno = 0;
-
- rsp = gf_param (hdr);
-
- op_ret = ntoh32 (hdr->rsp.op_ret);
- op_errno = gf_error_to_errno (ntoh32 (hdr->rsp.op_errno));
-
- if (op_ret >= 0) {
- gf_flock_to_flock (&rsp->flock, &lock);
- }
-
- STACK_UNWIND (frame, op_ret, op_errno, &lock);
- return 0;
-}
-
-/*
- * client_gf_file_lk_cbk - gf_file_lk callback for client protocol
- * @frame: call frame
- * @args: argument dictionary
- *
- * not for external reference
- */
-
-int
-client_inodelk_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen,
- struct iobuf *iobuf)
-{
- gf_fop_inodelk_rsp_t *rsp = NULL;
- int32_t op_ret = 0;
- int32_t op_errno = 0;
-
- rsp = gf_param (hdr);
-
- op_ret = ntoh32 (hdr->rsp.op_ret);
- op_errno = gf_error_to_errno (ntoh32 (hdr->rsp.op_errno));
-
- STACK_UNWIND (frame, op_ret, op_errno);
- return 0;
-}
-
-
-int
-client_finodelk_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen,
- struct iobuf *iobuf)
-{
- gf_fop_finodelk_rsp_t *rsp = NULL;
- int32_t op_ret = 0;
- int32_t op_errno = 0;
-
- rsp = gf_param (hdr);
-
- op_ret = ntoh32 (hdr->rsp.op_ret);
- op_errno = gf_error_to_errno (ntoh32 (hdr->rsp.op_errno));
-
- STACK_UNWIND (frame, op_ret, op_errno);
- return 0;
-}
-
-/*
- * client_entrylk_cbk - entrylk callback for client protocol
- * @frame: call frame
- * @args: argument dictionary
- *
- * not for external reference
- */
-
-int
-client_entrylk_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen,
- struct iobuf *iobuf)
-{
- gf_fop_entrylk_rsp_t *rsp = NULL;
- int32_t op_ret = 0;
- int32_t op_errno = 0;
-
- rsp = gf_param (hdr);
-
- op_ret = ntoh32 (hdr->rsp.op_ret);
- op_errno = gf_error_to_errno (ntoh32 (hdr->rsp.op_errno));
-
- STACK_UNWIND (frame, op_ret, op_errno);
- return 0;
-}
-
-int
-client_fentrylk_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen,
- struct iobuf *iobuf)
-{
- gf_fop_fentrylk_rsp_t *rsp = NULL;
- int32_t op_ret = 0;
- int32_t op_errno = 0;
-
- rsp = gf_param (hdr);
-
- op_ret = ntoh32 (hdr->rsp.op_ret);
- op_errno = gf_error_to_errno (ntoh32 (hdr->rsp.op_errno));
-
- STACK_UNWIND (frame, op_ret, op_errno);
- return 0;
-}
-
-/**
- * client_writedir_cbk -
- *
- * @frame:
- * @args:
- *
- * not for external reference
- */
-
-int
-client_setdents_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen,
- struct iobuf *iobuf)
-{
- int32_t op_ret = 0;
- int32_t op_errno = 0;
-
- op_ret = ntoh32 (hdr->rsp.op_ret);
- op_errno = gf_error_to_errno (ntoh32 (hdr->rsp.op_errno));
-
- STACK_UNWIND (frame, op_ret, op_errno);
-
- return 0;
-}
-
-/*
- * client_stats_cbk - stats callback for client protocol
- *
- * @frame: call frame
- * @args: argument dictionary
- *
- * not for external reference
- */
-
-int
-client_stats_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen,
- struct iobuf *iobuf)
-{
- struct xlator_stats stats = {0,};
- gf_mop_stats_rsp_t *rsp = NULL;
- char *buffer = NULL;
- int32_t op_ret = 0;
- int32_t op_errno = 0;
-
- rsp = gf_param (hdr);
-
- op_ret = ntoh32 (hdr->rsp.op_ret);
- op_errno = gf_error_to_errno (ntoh32 (hdr->rsp.op_errno));
-
- if (op_ret >= 0)
- {
- buffer = rsp->buf;
-
- sscanf (buffer, "%"SCNx64",%"SCNx64",%"SCNx64",%"SCNx64
- ",%"SCNx64",%"SCNx64",%"SCNx64",%"SCNx64"\n",
- &stats.nr_files, &stats.disk_usage, &stats.free_disk,
- &stats.total_disk_size, &stats.read_usage,
- &stats.write_usage, &stats.disk_speed,
- &stats.nr_clients);
- }
-
- STACK_UNWIND (frame, op_ret, op_errno, &stats);
- return 0;
-}
-
-/*
- * client_getspec - getspec function for client protocol
- * @frame: call frame
- * @this: client protocol xlator structure
- * @flag:
- *
- * external reference through client_protocol_xlator->fops->getspec
- */
-
-int
-client_getspec (call_frame_t *frame, xlator_t *this, const char *key,
- int32_t flag)
-{
- gf_hdr_common_t *hdr = NULL;
- gf_mop_getspec_req_t *req = NULL;
- size_t hdrlen = -1;
- int keylen = 0;
- int ret = -1;
-
- if (key)
- keylen = STRLEN_0(key);
-
- hdrlen = gf_hdr_len (req, keylen);
- hdr = gf_hdr_new (req, keylen);
- GF_VALIDATE_OR_GOTO(this->name, hdr, unwind);
-
- req = gf_param (hdr);
- req->flags = hton32 (flag);
- req->keylen = hton32 (keylen);
- if (keylen)
- strcpy (req->key, key);
-
- ret = protocol_client_xfer (frame, this,
- CLIENT_CHANNEL (this, CHANNEL_BULK),
- GF_OP_TYPE_MOP_REQUEST, GF_MOP_GETSPEC,
- hdr, hdrlen, NULL, 0, NULL);
-
- return ret;
-unwind:
- if (hdr)
- free (hdr);
- STACK_UNWIND(frame, -1, EINVAL, NULL);
- return 0;
-}
-
-/*
- * client_getspec_cbk - getspec callback for client protocol
- *
- * @frame: call frame
- * @args: argument dictionary
- *
- * not for external reference
- */
-
-int
-client_getspec_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen,
- struct iobuf *iobuf)
-{
- gf_mop_getspec_rsp_t *rsp = NULL;
- char *spec_data = NULL;
- int32_t op_ret = 0;
- int32_t op_errno = 0;
- int32_t gf_errno = 0;
-
- op_ret = ntoh32 (hdr->rsp.op_ret);
- gf_errno = ntoh32 (hdr->rsp.op_errno);
- op_errno = gf_error_to_errno (gf_errno);
- rsp = gf_param (hdr);
-
- if (op_ret >= 0) {
- spec_data = rsp->spec;
- }
-
- STACK_UNWIND (frame, op_ret, op_errno, spec_data);
- return 0;
-}
-
-
-int
-client_checksum (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flag)
-{
- gf_hdr_common_t *hdr = NULL;
- gf_fop_checksum_req_t *req = NULL;
- size_t hdrlen = -1;
- int ret = -1;
- ino_t ino = 0;
-
- hdrlen = gf_hdr_len (req, strlen (loc->path) + 1);
- hdr = gf_hdr_new (req, strlen (loc->path) + 1);
- req = gf_param (hdr);
-
- ret = inode_ctx_get (loc->inode, this, &ino);
- if (loc->inode->ino && ret < 0) {
- gf_log (this->name, GF_LOG_DEBUG,
- "CHECKSUM %"PRId64" (%s): "
- "failed to get remote inode number",
- loc->inode->ino, loc->path);
- }
-
- req->ino = hton64 (ino);
- req->flag = hton32 (flag);
- strcpy (req->path, loc->path);
-
- ret = protocol_client_xfer (frame, this,
- CLIENT_CHANNEL (this, CHANNEL_BULK),
- GF_OP_TYPE_FOP_REQUEST, GF_FOP_CHECKSUM,
- hdr, hdrlen, NULL, 0, NULL);
-
- return ret;
-}
-
-
-int
-client_checksum_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen,
- struct iobuf *iobuf)
-{
- gf_fop_checksum_rsp_t *rsp = NULL;
- int32_t op_ret = 0;
- int32_t op_errno = 0;
- int32_t gf_errno = 0;
- unsigned char *fchecksum = NULL;
- unsigned char *dchecksum = NULL;
-
- rsp = gf_param (hdr);
-
- op_ret = ntoh32 (hdr->rsp.op_ret);
- gf_errno = ntoh32 (hdr->rsp.op_errno);
- op_errno = gf_error_to_errno (gf_errno);
-
- if (op_ret >= 0) {
- fchecksum = rsp->fchecksum;
- dchecksum = rsp->dchecksum + ZR_FILENAME_MAX;
- }
-
- STACK_UNWIND (frame, op_ret, op_errno, fchecksum, dchecksum);
- return 0;
-}
-
-/*
- * client_setspec_cbk - setspec callback for client protocol
- * @frame: call frame
- * @args: argument dictionary
- *
- * not for external reference
- */
-
-int
-client_setspec_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen,
- struct iobuf *iobuf)
-{
- int32_t op_ret = 0;
- int32_t op_errno = 0;
-
- op_ret = ntoh32 (hdr->rsp.op_ret);
- op_errno = gf_error_to_errno (ntoh32 (hdr->rsp.op_errno));
-
- STACK_UNWIND (frame, op_ret, op_errno);
-
- return 0;
-}
-
-/*
- * client_setvolume_cbk - setvolume callback for client protocol
- * @frame: call frame
- * @args: argument dictionary
- *
- * not for external reference
- */
-
-int
-client_setvolume_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen,
- struct iobuf *iobuf)
-{
- gf_mop_setvolume_rsp_t *rsp = NULL;
- client_connection_t *conn = NULL;
- glusterfs_ctx_t *ctx = NULL;
- xlator_t *this = NULL;
- xlator_list_t *parent = NULL;
- transport_t *trans = NULL;
- dict_t *reply = NULL;
- char *remote_subvol = NULL;
- char *remote_error = NULL;
- char *process_uuid = NULL;
- int32_t ret = -1;
- int32_t op_ret = -1;
- int32_t op_errno = EINVAL;
- int32_t dict_len = 0;
- transport_t *peer_trans = NULL;
- uint64_t peer_trans_int = 0;
-
-
- trans = frame->local; frame->local = NULL;
- this = frame->this;
- conn = trans->xl_private;
-
- rsp = gf_param (hdr);
-
- op_ret = ntoh32 (hdr->rsp.op_ret);
- op_errno = gf_error_to_errno (ntoh32 (hdr->rsp.op_errno));
-
- if ((op_ret < 0) && (op_errno == ENOTCONN)) {
- gf_log (this->name, GF_LOG_DEBUG,
- "setvolume failed (%s)",
- strerror (op_errno));
- goto out;
- }
-
- reply = dict_new ();
- GF_VALIDATE_OR_GOTO(this->name, reply, out);
-
- dict_len = ntoh32 (rsp->dict_len);
- ret = dict_unserialize (rsp->buf, dict_len, &reply);
- if (ret < 0) {
- gf_log (frame->this->name, GF_LOG_DEBUG,
- "failed to unserialize buffer(%p) to dictionary",
- rsp->buf);
- goto out;
- }
-
- ret = dict_get_str (reply, "ERROR", &remote_error);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_DEBUG,
- "failed to get ERROR string from reply dictionary");
- }
-
- ret = dict_get_str (reply, "process-uuid", &process_uuid);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_DEBUG,
- "failed to get 'process-uuid' from reply dictionary");
- }
-
- if (op_ret < 0) {
- gf_log (trans->xl->name, GF_LOG_DEBUG,
- "SETVOLUME on remote-host failed: %s",
- remote_error ? remote_error : strerror (op_errno));
- errno = op_errno;
- if (op_errno == ESTALE) {
- parent = trans->xl->parents;
- while (parent) {
- xlator_notify (parent->xlator,
- GF_EVENT_VOLFILE_MODIFIED,
- trans->xl);
- parent = parent->next;
- }
- }
-
- } else {
- ret = dict_get_str (this->options, "remote-subvolume",
- &remote_subvol);
- if (!remote_subvol)
- goto out;
-
- ctx = get_global_ctx_ptr ();
-
- if (process_uuid && !strcmp (ctx->process_uuid,process_uuid)) {
- ret = dict_get_uint64 (reply, "transport-ptr",
- &peer_trans_int);
-
- peer_trans = (void *) (long) (peer_trans_int);
-
- gf_log (this->name, GF_LOG_WARNING,
- "attaching to the local volume '%s'",
- remote_subvol);
-
- transport_setpeer (trans, peer_trans);
-
- }
-
- gf_log (trans->xl->name, GF_LOG_NORMAL,
- "Connected to %s, attached "
- "to remote volume '%s'.",
- trans->peerinfo.identifier, remote_subvol);
-
- pthread_mutex_lock (&(conn->lock));
- {
- conn->connected = 1;
- }
- pthread_mutex_unlock (&(conn->lock));
-
- parent = trans->xl->parents;
- while (parent) {
- xlator_notify (parent->xlator, GF_EVENT_CHILD_UP,
- trans->xl);
- parent = parent->next;
- }
- }
-
-out:
- if (-1 == op_ret) {
- /* Let the connection/re-connection happen in
- * background, for now, don't hang here,
- * tell the parents that i am all ok..
- */
- parent = trans->xl->parents;
- while (parent) {
- xlator_notify (parent->xlator,
- GF_EVENT_CHILD_CONNECTING, trans->xl);
- parent = parent->next;
- }
- }
-
- STACK_DESTROY (frame->root);
-
- if (reply)
- dict_unref (reply);
-
- return op_ret;
-}
-
-/*
- * client_enosys_cbk -
- * @frame: call frame
- *
- * not for external reference
- */
-
-int
-client_enosys_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen,
- struct iobuf *iobuf)
-{
- STACK_DESTROY (frame->root);
- return 0;
-}
-
-
-void
-client_protocol_reconnect (void *trans_ptr)
-{
- transport_t *trans = NULL;
- client_connection_t *conn = NULL;
- struct timeval tv = {0, 0};
- int32_t ret = 0;
-
- trans = trans_ptr;
- conn = trans->xl_private;
- pthread_mutex_lock (&conn->lock);
- {
- if (conn->reconnect)
- gf_timer_call_cancel (trans->xl->ctx,
- conn->reconnect);
- conn->reconnect = 0;
-
- if (conn->connected == 0) {
- tv.tv_sec = 10;
-
- gf_log (trans->xl->name, GF_LOG_TRACE,
- "attempting reconnect");
- ret = transport_connect (trans);
-
- conn->reconnect =
- gf_timer_call_after (trans->xl->ctx, tv,
- client_protocol_reconnect,
- trans);
- } else {
- gf_log (trans->xl->name, GF_LOG_TRACE,
- "breaking reconnect chain");
- }
- }
- pthread_mutex_unlock (&conn->lock);
-
- if (ret == -1 && errno != EINPROGRESS) {
- default_notify (trans->xl, GF_EVENT_CHILD_DOWN, NULL);
- }
-}
-
-int
-protocol_client_mark_fd_bad (xlator_t *this)
-{
- client_conf_t *conf = NULL;
- data_pair_t *trav = NULL;
- fd_t *fd_tmp = NULL;
-
- conf = this->private;
-
- trav = conf->saved_fds->members_list;
-
- while (trav) {
- fd_tmp = (fd_t *)(long) strtoul (trav->key, NULL, 0);
- fd_ctx_del (fd_tmp, this, NULL);
- trav = trav->next;
- }
-
- pthread_mutex_lock (&conf->mutex);
- {
- dict_destroy (conf->saved_fds);
-
- conf->saved_fds = get_new_dict_full (64);
- }
- pthread_mutex_unlock (&conf->mutex);
-
- return 0;
-}
-
-/*
- * client_protocol_cleanup - cleanup function
- * @trans: transport object
- *
- */
-
-int
-protocol_client_cleanup (transport_t *trans)
-{
- client_connection_t *conn = NULL;
- struct saved_frames *saved_frames = NULL;
-
- conn = trans->xl_private;
-
- gf_log (trans->xl->name, GF_LOG_TRACE,
- "cleaning up state in transport object %p", trans);
-
- pthread_mutex_lock (&conn->lock);
- {
- saved_frames = conn->saved_frames;
- conn->saved_frames = saved_frames_new ();
-
- /* bailout logic cleanup */
- if (conn->timer) {
- gf_timer_call_cancel (trans->xl->ctx, conn->timer);
- conn->timer = NULL;
- }
-
- if (conn->reconnect == NULL) {
- /* :O This part is empty.. any thing missing? */
- }
- }
- pthread_mutex_unlock (&conn->lock);
-
- saved_frames_destroy (trans->xl, saved_frames,
- gf_fops, gf_mops, gf_cbks);
-
- return 0;
-}
-
-
-/* cbk callbacks */
-int
-client_releasedir_cbk (call_frame_t *frame, gf_hdr_common_t *hdr,
- size_t hdrlen, struct iobuf *iobuf)
-{
- STACK_DESTROY (frame->root);
- return 0;
-}
-
-
-int
-client_release_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen,
- struct iobuf *iobuf)
-{
- STACK_DESTROY (frame->root);
- return 0;
-}
-
-
-int
-client_forget_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen,
- struct iobuf *iobuf)
-{
- client_conf_t *conf = NULL;
- client_forget_t forget = {0, };
- uint8_t send_forget = 0;
- int32_t ret = -1;
-
-
- conf = frame->this->private;
- LOCK (&conf->forget.lock);
- {
- conf->forget.frames_in_transit--;
-
- ret = client_get_forgets (frame->this, &forget);
- if (ret <= 0)
- send_forget = 0;
- else
- send_forget = 1;
- }
- UNLOCK (&conf->forget.lock);
-
- if (send_forget) {
- ret = protocol_client_xfer (forget.frame, frame->this,
- CLIENT_CHANNEL (frame->this,
- CHANNEL_BULK),
- GF_OP_TYPE_CBK_REQUEST,
- GF_CBK_FORGET,
- forget.hdr, forget.hdrlen,
- NULL, 0, NULL);
- }
-
- STACK_DESTROY (frame->root);
- return 0;
-}
-
-
-static gf_op_t gf_fops[] = {
- [GF_FOP_STAT] = client_stat_cbk,
- [GF_FOP_READLINK] = client_readlink_cbk,
- [GF_FOP_MKNOD] = client_mknod_cbk,
- [GF_FOP_MKDIR] = client_mkdir_cbk,
- [GF_FOP_UNLINK] = client_unlink_cbk,
- [GF_FOP_RMDIR] = client_rmdir_cbk,
- [GF_FOP_SYMLINK] = client_symlink_cbk,
- [GF_FOP_RENAME] = client_rename_cbk,
- [GF_FOP_LINK] = client_link_cbk,
- [GF_FOP_CHMOD] = client_chmod_cbk,
- [GF_FOP_CHOWN] = client_chown_cbk,
- [GF_FOP_TRUNCATE] = client_truncate_cbk,
- [GF_FOP_OPEN] = client_open_cbk,
- [GF_FOP_READ] = client_readv_cbk,
- [GF_FOP_WRITE] = client_write_cbk,
- [GF_FOP_STATFS] = client_statfs_cbk,
- [GF_FOP_FLUSH] = client_flush_cbk,
- [GF_FOP_FSYNC] = client_fsync_cbk,
- [GF_FOP_SETXATTR] = client_setxattr_cbk,
- [GF_FOP_GETXATTR] = client_getxattr_cbk,
- [GF_FOP_REMOVEXATTR] = client_removexattr_cbk,
- [GF_FOP_OPENDIR] = client_opendir_cbk,
- [GF_FOP_GETDENTS] = client_getdents_cbk,
- [GF_FOP_FSYNCDIR] = client_fsyncdir_cbk,
- [GF_FOP_ACCESS] = client_access_cbk,
- [GF_FOP_CREATE] = client_create_cbk,
- [GF_FOP_FTRUNCATE] = client_ftruncate_cbk,
- [GF_FOP_FSTAT] = client_fstat_cbk,
- [GF_FOP_LK] = client_lk_common_cbk,
- [GF_FOP_UTIMENS] = client_utimens_cbk,
- [GF_FOP_FCHMOD] = client_fchmod_cbk,
- [GF_FOP_FCHOWN] = client_fchown_cbk,
- [GF_FOP_LOOKUP] = client_lookup_cbk,
- [GF_FOP_SETDENTS] = client_setdents_cbk,
- [GF_FOP_READDIR] = client_readdir_cbk,
- [GF_FOP_INODELK] = client_inodelk_cbk,
- [GF_FOP_FINODELK] = client_finodelk_cbk,
- [GF_FOP_ENTRYLK] = client_entrylk_cbk,
- [GF_FOP_FENTRYLK] = client_fentrylk_cbk,
- [GF_FOP_CHECKSUM] = client_checksum_cbk,
- [GF_FOP_XATTROP] = client_xattrop_cbk,
- [GF_FOP_FXATTROP] = client_fxattrop_cbk,
-};
-
-static gf_op_t gf_mops[] = {
- [GF_MOP_SETVOLUME] = client_setvolume_cbk,
- [GF_MOP_GETVOLUME] = client_enosys_cbk,
- [GF_MOP_STATS] = client_stats_cbk,
- [GF_MOP_SETSPEC] = client_setspec_cbk,
- [GF_MOP_GETSPEC] = client_getspec_cbk,
- [GF_MOP_PING] = client_ping_cbk,
-};
-
-static gf_op_t gf_cbks[] = {
- [GF_CBK_FORGET] = client_forget_cbk,
- [GF_CBK_RELEASE] = client_release_cbk,
- [GF_CBK_RELEASEDIR] = client_releasedir_cbk
-};
-
-/*
- * client_protocol_interpret - protocol interpreter
- * @trans: transport object
- * @blk: data block
- *
- */
-int
-protocol_client_interpret (xlator_t *this, transport_t *trans,
- char *hdr_p, size_t hdrlen, struct iobuf *iobuf)
-{
- int ret = -1;
- call_frame_t *frame = NULL;
- gf_hdr_common_t *hdr = NULL;
- uint64_t callid = 0;
- int type = -1;
- int op = -1;
- client_connection_t *conn = NULL;
-
- conn = trans->xl_private;
-
- hdr = (gf_hdr_common_t *)hdr_p;
-
- type = ntoh32 (hdr->type);
- op = ntoh32 (hdr->op);
- callid = ntoh64 (hdr->callid);
-
- frame = lookup_frame (trans, op, type, callid);
- if (frame == NULL) {
- gf_log (this->name, GF_LOG_WARNING,
- "no frame for callid=%"PRId64" type=%d op=%d",
- callid, type, op);
- return 0;
- }
-
- switch (type) {
- case GF_OP_TYPE_FOP_REPLY:
- if ((op > GF_FOP_MAXVALUE) ||
- (op < 0)) {
- gf_log (trans->xl->name, GF_LOG_WARNING,
- "invalid fop '%d'", op);
- } else {
- ret = gf_fops[op] (frame, hdr, hdrlen, iobuf);
- }
- break;
- case GF_OP_TYPE_MOP_REPLY:
- if ((op > GF_MOP_MAXVALUE) ||
- (op < 0)) {
- gf_log (trans->xl->name, GF_LOG_WARNING,
- "invalid fop '%d'", op);
- } else {
- ret = gf_mops[op] (frame, hdr, hdrlen, iobuf);
- }
- break;
- case GF_OP_TYPE_CBK_REPLY:
- if ((op > GF_CBK_MAXVALUE) ||
- (op < 0)) {
- gf_log (trans->xl->name, GF_LOG_WARNING,
- "invalid cbk '%d'", op);
- } else {
- ret = gf_cbks[op] (frame, hdr, hdrlen, iobuf);
- }
- break;
- default:
- gf_log (trans->xl->name, GF_LOG_DEBUG,
- "invalid packet type: %d", type);
- break;
- }
-
- return ret;
-}
-
-/*
- * init - initiliazation function. called during loading of client protocol
- * @this:
- *
- */
-
-int
-init (xlator_t *this)
-{
- transport_t *trans = NULL;
- client_conf_t *conf = NULL;
- client_connection_t *conn = NULL;
- int32_t frame_timeout = 0;
- int32_t ping_timeout = 0;
- data_t *remote_subvolume = NULL;
- int32_t ret = -1;
- int i = 0;
-
- if (this->children) {
- gf_log (this->name, GF_LOG_ERROR,
- "FATAL: client protocol translator cannot have any "
- "subvolumes");
- goto out;
- }
-
- if (!this->parents) {
- gf_log (this->name, GF_LOG_WARNING,
- "Volume is dangling. ");
- }
-
- remote_subvolume = dict_get (this->options, "remote-subvolume");
- if (remote_subvolume == NULL) {
- gf_log (this->name, GF_LOG_ERROR,
- "Option 'remote-subvolume' is not specified.");
- goto out;
- }
-
- ret = dict_get_int32 (this->options, "frame-timeout",
- &frame_timeout);
- if (ret >= 0) {
- gf_log (this->name, GF_LOG_DEBUG,
- "setting frame-timeout to %d", frame_timeout);
- } else {
- gf_log (this->name, GF_LOG_DEBUG,
- "defaulting frame-timeout to 30mins");
- frame_timeout = 1800;
- }
-
- ret = dict_get_int32 (this->options, "ping-timeout",
- &ping_timeout);
- if (ret >= 0) {
- gf_log (this->name, GF_LOG_DEBUG,
- "setting ping-timeout to %d", ping_timeout);
- } else {
- gf_log (this->name, GF_LOG_DEBUG,
- "defaulting ping-timeout to 10");
- ping_timeout = 10;
- }
-
- conf = CALLOC (1, sizeof (client_conf_t));
-
- LOCK_INIT (&conf->forget.lock);
- pthread_mutex_init (&conf->mutex, NULL);
- conf->saved_fds = get_new_dict_full (64);
-
- this->private = conf;
-
- for (i = 0; i < CHANNEL_MAX; i++) {
- trans = transport_load (this->options, this);
- if (trans == NULL) {
- gf_log (this->name, GF_LOG_DEBUG,
- "Failed to load transport");
- ret = -1;
- goto out;
- }
-
- conn = CALLOC (1, sizeof (*conn));
-
- conn->saved_frames = saved_frames_new ();
-
- conn->callid = 1;
-
- conn->frame_timeout = frame_timeout;
- conn->ping_timeout = ping_timeout;
-
- pthread_mutex_init (&conn->lock, NULL);
-
- trans->xl_private = conn;
- conf->transport[i] = transport_ref (trans);
- }
-
-#ifndef GF_DARWIN_HOST_OS
- {
- struct rlimit lim;
-
- lim.rlim_cur = 1048576;
- lim.rlim_max = 1048576;
-
- ret = setrlimit (RLIMIT_NOFILE, &lim);
- if (ret == -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;
-
- ret = setrlimit (RLIMIT_NOFILE, &lim);
- if (ret == -1) {
- gf_log (this->name, GF_LOG_DEBUG,
- "Failed to set max open fd to 64k: %s",
- strerror(errno));
- } else {
- gf_log (this->name, GF_LOG_DEBUG,
- "max open fd set to 64k");
- }
-
- }
- }
-#endif
- ret = 0;
-out:
- return ret;
-}
-
-/*
- * fini - finish function called during unloading of client protocol
- * @this:
- *
- */
-void
-fini (xlator_t *this)
-{
- /* TODO: Check if its enough.. how to call transport's fini () */
- client_conf_t *conf = NULL;
-
- conf = this->private;
- this->private = NULL;
-
- if (conf) {
- LOCK_DESTROY (&conf->forget.lock);
- FREE (conf);
- }
- return;
-}
-
-
-int
-protocol_client_handshake (xlator_t *this, transport_t *trans)
-{
- gf_hdr_common_t *hdr = NULL;
- gf_mop_setvolume_req_t *req = NULL;
- dict_t *options = NULL;
- int32_t ret = -1;
- int hdrlen = 0;
- int dict_len = 0;
- call_frame_t *fr = NULL;
- char *process_uuid_xl;
-
- options = this->options;
- ret = dict_set_str (options, "version", PACKAGE_VERSION);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_DEBUG,
- "failed to set version(%s) in options dictionary",
- PACKAGE_VERSION);
- }
-
- asprintf (&process_uuid_xl, "%s-%s", this->ctx->process_uuid,
- this->name);
- ret = dict_set_dynstr (options, "process-uuid",
- process_uuid_xl);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_DEBUG,
- "failed to set process-uuid(%s) in options dictionary",
- PACKAGE_VERSION);
- }
-
- if (this->ctx->cmd_args.volfile_server) {
- if (this->ctx->cmd_args.volfile_id)
- ret = dict_set_str (options, "volfile-key",
- this->ctx->cmd_args.volfile_id);
- ret = dict_set_uint32 (options, "volfile-checksum",
- this->ctx->volfile_checksum);
- }
-
- dict_len = dict_serialized_length (options);
- if (dict_len < 0) {
- gf_log (this->name, GF_LOG_DEBUG,
- "failed to get serialized length of dict(%p)",
- options);
- ret = dict_len;
- goto fail;
- }
-
- hdrlen = gf_hdr_len (req, dict_len);
- hdr = gf_hdr_new (req, dict_len);
- GF_VALIDATE_OR_GOTO(this->name, hdr, fail);
-
- req = gf_param (hdr);
-
- ret = dict_serialize (options, req->buf);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_DEBUG,
- "failed to serialize dictionary(%p)",
- options);
- goto fail;
- }
-
- req->dict_len = hton32 (dict_len);
- fr = create_frame (this, this->ctx->pool);
- GF_VALIDATE_OR_GOTO(this->name, fr, fail);
-
- fr->local = trans;
- ret = protocol_client_xfer (fr, this, trans,
- GF_OP_TYPE_MOP_REQUEST, GF_MOP_SETVOLUME,
- hdr, hdrlen, NULL, 0, NULL);
- return ret;
-fail:
- if (hdr)
- free (hdr);
- return ret;
-}
-
-
-int
-protocol_client_pollout (xlator_t *this, transport_t *trans)
-{
- client_conf_t *conf = NULL;
-
- conf = trans->xl->private;
-
- pthread_mutex_lock (&conf->mutex);
- {
- gettimeofday (&conf->last_sent, NULL);
- }
- pthread_mutex_unlock (&conf->mutex);
-
- return 0;
-}
-
-
-int
-protocol_client_pollin (xlator_t *this, transport_t *trans)
-{
- client_conf_t *conf = NULL;
- int ret = -1;
- struct iobuf *iobuf = NULL;
- char *hdr = NULL;
- size_t hdrlen = 0;
-
- conf = trans->xl->private;
-
- pthread_mutex_lock (&conf->mutex);
- {
- gettimeofday (&conf->last_received, NULL);
- }
- pthread_mutex_unlock (&conf->mutex);
-
- ret = transport_receive (trans, &hdr, &hdrlen, &iobuf);
-
- if (ret == 0)
- {
- ret = protocol_client_interpret (this, trans, hdr, hdrlen,
- iobuf);
- }
-
- /* TODO: use mem-pool */
- FREE (hdr);
-
- return ret;
-}
-
-
-/*
- * client_protocol_notify - notify function for client protocol
- * @this:
- * @trans: transport object
- * @event
- *
- */
-
-int
-notify (xlator_t *this, int32_t event, void *data, ...)
-{
- int i = 0;
- int ret = -1;
- int child_down = 1;
- int was_not_down = 0;
- transport_t *trans = NULL;
- client_connection_t *conn = NULL;
- client_conf_t *conf = NULL;
- xlator_list_t *parent = NULL;
-
-
- conf = this->private;
- trans = data;
-
- switch (event) {
- case GF_EVENT_POLLOUT:
- {
- ret = protocol_client_pollout (this, trans);
-
- break;
- }
- case GF_EVENT_POLLIN:
- {
- ret = protocol_client_pollin (this, trans);
-
- break;
- }
- /* no break for ret check to happen below */
- case GF_EVENT_POLLERR:
- {
- ret = -1;
- protocol_client_cleanup (trans);
-
- was_not_down = 0;
- for (i = 0; i < CHANNEL_MAX; i++) {
- conn = conf->transport[i]->xl_private;
- if (conn->connected == 1)
- was_not_down = 1;
- }
-
- conn = trans->xl_private;
- if (conn->connected) {
- conn->connected = 0;
- if (conn->reconnect == 0)
- client_protocol_reconnect (trans);
- }
-
- child_down = 1;
- for (i = 0; i < CHANNEL_MAX; i++) {
- trans = conf->transport[i];
- conn = trans->xl_private;
- if (conn->connected == 1)
- child_down = 0;
- }
-
- if (child_down && was_not_down) {
- gf_log (this->name, GF_LOG_INFO, "disconnected");
-
- protocol_client_mark_fd_bad (this);
-
- parent = this->parents;
- while (parent) {
- xlator_notify (parent->xlator,
- GF_EVENT_CHILD_DOWN, this);
- parent = parent->next;
- }
- }
- }
- break;
-
- case GF_EVENT_PARENT_UP:
- {
- client_conf_t *conf = NULL;
- int i = 0;
- transport_t *trans = NULL;
-
- conf = this->private;
- for (i = 0; i < CHANNEL_MAX; i++) {
- trans = conf->transport[i];
- if (!trans) {
- gf_log (this->name, GF_LOG_DEBUG,
- "transport init failed");
- return -1;
- }
-
- conn = trans->xl_private;
-
- gf_log (this->name, GF_LOG_DEBUG,
- "got GF_EVENT_PARENT_UP, attempting connect "
- "on transport");
-
- client_protocol_reconnect (trans);
- }
- }
- break;
-
- case GF_EVENT_CHILD_UP:
- {
- char *handshake = NULL;
-
- ret = dict_get_str (this->options, "disable-handshake",
- &handshake);
- gf_log (this->name, GF_LOG_DEBUG,
- "got GF_EVENT_CHILD_UP");
- if ((ret < 0) ||
- (strcasecmp (handshake, "on"))) {
- ret = protocol_client_handshake (this, trans);
- } else {
- conn = trans->xl_private;
- conn->connected = 1;
- ret = default_notify (this, event, trans);
- }
-
- if (ret)
- transport_disconnect (trans);
-
- }
- break;
-
- default:
- gf_log (this->name, GF_LOG_DEBUG,
- "got %d, calling default_notify ()", event);
-
- default_notify (this, event, data);
- break;
- }
-
- return ret;
-}
-
-
-struct xlator_fops fops = {
- .stat = client_stat,
- .readlink = client_readlink,
- .mknod = client_mknod,
- .mkdir = client_mkdir,
- .unlink = client_unlink,
- .rmdir = client_rmdir,
- .symlink = client_symlink,
- .rename = client_rename,
- .link = client_link,
- .chmod = client_chmod,
- .chown = client_chown,
- .truncate = client_truncate,
- .utimens = client_utimens,
- .open = client_open,
- .readv = client_readv,
- .writev = client_writev,
- .statfs = client_statfs,
- .flush = client_flush,
- .fsync = client_fsync,
- .setxattr = client_setxattr,
- .getxattr = client_getxattr,
- .fsetxattr = client_fsetxattr,
- .fgetxattr = client_fgetxattr,
- .removexattr = client_removexattr,
- .opendir = client_opendir,
- .readdir = client_readdir,
- .fsyncdir = client_fsyncdir,
- .access = client_access,
- .ftruncate = client_ftruncate,
- .fstat = client_fstat,
- .create = client_create,
- .lk = client_lk,
- .inodelk = client_inodelk,
- .finodelk = client_finodelk,
- .entrylk = client_entrylk,
- .fentrylk = client_fentrylk,
- .lookup = client_lookup,
- .fchmod = client_fchmod,
- .fchown = client_fchown,
- .setdents = client_setdents,
- .getdents = client_getdents,
- .checksum = client_checksum,
- .xattrop = client_xattrop,
- .fxattrop = client_fxattrop,
-};
-
-struct xlator_mops mops = {
- .stats = client_stats,
- .getspec = client_getspec,
-};
-
-struct xlator_cbks cbks = {
- .forget = client_forget,
- .release = client_release,
- .releasedir = client_releasedir
-};
-
-
-struct volume_options options[] = {
- { .key = {"username"},
- .type = GF_OPTION_TYPE_ANY
- },
- { .key = {"password"},
- .type = GF_OPTION_TYPE_ANY
- },
- { .key = {"transport-type"},
- .value = {"tcp", "socket", "ib-verbs", "unix", "ib-sdp",
- "tcp/client", "ib-verbs/client"},
- .type = GF_OPTION_TYPE_STR
- },
- { .key = {"remote-host"},
- .type = GF_OPTION_TYPE_INTERNET_ADDRESS
- },
- { .key = {"remote-subvolume"},
- .type = GF_OPTION_TYPE_ANY
- },
- { .key = {"frame-timeout"},
- .type = GF_OPTION_TYPE_TIME,
- .min = 5,
- .max = 1013,
- },
- { .key = {"ping-timeout"},
- .type = GF_OPTION_TYPE_TIME,
- .min = 5,
- .max = 1013,
- },
- { .key = {NULL} },
-};
diff --git a/xlators/protocol/client/src/client-protocol.h b/xlators/protocol/client/src/client-protocol.h
deleted file mode 100644
index 1cbb22ef1..000000000
--- a/xlators/protocol/client/src/client-protocol.h
+++ /dev/null
@@ -1,173 +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 _CLIENT_PROTOCOL_H
-#define _CLIENT_PROTOCOL_H
-
-#ifndef _CONFIG_H
-#define _CONFIG_H
-#include "config.h"
-#endif
-
-#include <stdio.h>
-#include <arpa/inet.h>
-#include "inode.h"
-#include "timer.h"
-#include "byte-order.h"
-
-#define CLIENT_PROTO_FORGET_LIMIT 128
-#define CLIENT_PORT_CIELING 1023
-
-#define GF_CLIENT_INODE_SELF 0
-#define GF_CLIENT_INODE_PARENT 1
-
-#define CLIENT_CONF(this) ((client_conf_t *)(this->private))
-
-#define RECEIVE_TIMEOUT(_cprivate,_current) \
- ((_cprivate->last_received.tv_sec + \
- _cprivate->frame_timeout) < \
- _current.tv_sec)
-
-#define SEND_TIMEOUT(_cprivate,_current) \
- ((_cprivate->last_sent.tv_sec + \
- _cprivate->frame_timeout) < \
- _current.tv_sec)
-
-enum {
- CHANNEL_BULK = 0,
- CHANNEL_LOWLAT = 1,
- CHANNEL_MAX
-};
-
-#define CLIENT_CHANNEL client_channel
-
-struct client_connection;
-typedef struct client_connection client_connection_t;
-
-#include "stack.h"
-#include "xlator.h"
-#include "transport.h"
-#include "protocol.h"
-
-struct _client_conf {
- transport_t *transport[CHANNEL_MAX];
-
- /* enhancement for 'forget', a must required where lot
- of stats happening */
- struct {
- uint64_t ino_array[CLIENT_PROTO_FORGET_LIMIT + 4];
- uint32_t count;
- uint32_t frames_in_transit;
- gf_lock_t lock;
- } forget;
- dict_t *saved_fds;
- struct timeval last_sent;
- struct timeval last_received;
- pthread_mutex_t mutex;
-};
-typedef struct _client_conf client_conf_t;
-
-/* This will be stored in transport_t->xl_private */
-struct client_connection {
- pthread_mutex_t lock;
- uint64_t callid;
- struct saved_frames *saved_frames;
- int32_t frame_timeout;
- int32_t ping_started;
- int32_t ping_timeout;
- int32_t transport_activity;
- gf_timer_t *reconnect;
- char connected;
- uint64_t max_block_size;
- gf_timer_t *timer;
- gf_timer_t *ping_timer;
-};
-
-typedef struct {
- loc_t loc;
- loc_t loc2;
- fd_t *fd;
-} client_local_t;
-
-typedef struct {
- gf_hdr_common_t *hdr;
- size_t hdrlen;
- call_frame_t *frame;
-} client_forget_t;
-
-static inline void
-gf_string_to_stat(char *string, struct stat *stbuf)
-{
- uint64_t dev = 0;
- uint64_t ino = 0;
- uint32_t mode = 0;
- uint32_t nlink = 0;
- uint32_t uid = 0;
- uint32_t gid = 0;
- uint64_t rdev = 0;
- uint64_t size = 0;
- uint32_t blksize = 0;
- uint64_t blocks = 0;
- uint32_t atime = 0;
- uint32_t atime_nsec = 0;
- uint32_t mtime = 0;
- uint32_t mtime_nsec = 0;
- uint32_t ctime = 0;
- uint32_t ctime_nsec = 0;
-
- sscanf (string, GF_STAT_PRINT_FMT_STR,
- &dev,
- &ino,
- &mode,
- &nlink,
- &uid,
- &gid,
- &rdev,
- &size,
- &blksize,
- &blocks,
- &atime,
- &atime_nsec,
- &mtime,
- &mtime_nsec,
- &ctime,
- &ctime_nsec);
-
- stbuf->st_dev = dev;
- stbuf->st_ino = ino;
- stbuf->st_mode = mode;
- stbuf->st_nlink = nlink;
- stbuf->st_uid = uid;
- stbuf->st_gid = gid;
- stbuf->st_rdev = rdev;
- stbuf->st_size = size;
- stbuf->st_blksize = blksize;
- stbuf->st_blocks = blocks;
-
- stbuf->st_atime = atime;
- stbuf->st_mtime = mtime;
- stbuf->st_ctime = ctime;
-
- ST_ATIM_NSEC_SET(stbuf, atime_nsec);
- ST_MTIM_NSEC_SET(stbuf, mtime_nsec);
- ST_CTIM_NSEC_SET(stbuf, ctime_nsec);
-
-}
-
-#endif
diff --git a/xlators/protocol/client/src/client-rpc-fops.c b/xlators/protocol/client/src/client-rpc-fops.c
new file mode 100644
index 000000000..6355450c3
--- /dev/null
+++ b/xlators/protocol/client/src/client-rpc-fops.c
@@ -0,0 +1,6203 @@
+/*
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
+ This file is part of GlusterFS.
+
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
+*/
+
+#ifndef _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+#include "client.h"
+#include "glusterfs3-xdr.h"
+#include "glusterfs3.h"
+#include "compat-errno.h"
+
+int32_t client3_getspec (call_frame_t *frame, xlator_t *this, void *data);
+void client_start_ping (void *data);
+rpc_clnt_prog_t clnt3_3_fop_prog;
+
+
+int
+client_submit_vec_request (xlator_t *this, void *req, call_frame_t *frame,
+ rpc_clnt_prog_t *prog, int procnum,
+ fop_cbk_fn_t cbkfn,
+ struct iovec *payload, int payloadcnt,
+ struct iobref *iobref, xdrproc_t xdrproc)
+{
+ int ret = 0;
+ clnt_conf_t *conf = NULL;
+ struct iovec iov = {0, };
+ struct iobuf *iobuf = NULL;
+ int count = 0;
+ int start_ping = 0;
+ struct iobref *new_iobref = NULL;
+ ssize_t xdr_size = 0;
+ struct rpc_req rpcreq = {0, };
+
+ start_ping = 0;
+
+ conf = this->private;
+
+ if (req && xdrproc) {
+ xdr_size = xdr_sizeof (xdrproc, req);
+ iobuf = iobuf_get2 (this->ctx->iobuf_pool, xdr_size);
+ if (!iobuf) {
+ goto unwind;
+ };
+
+ new_iobref = iobref_new ();
+ if (!new_iobref) {
+ goto unwind;
+ }
+
+ if (iobref != NULL) {
+ ret = iobref_merge (new_iobref, iobref);
+ if (ret != 0) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "cannot merge iobref passed from caller "
+ "into new_iobref");
+ }
+ }
+
+ ret = iobref_add (new_iobref, iobuf);
+ if (ret != 0) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "cannot add iobuf into iobref");
+ goto unwind;
+ }
+
+ iov.iov_base = iobuf->ptr;
+ iov.iov_len = iobuf_size (iobuf);
+
+ /* Create the xdr payload */
+ ret = xdr_serialize_generic (iov, req, xdrproc);
+ if (ret == -1) {
+ gf_log_callingfn ("", GF_LOG_WARNING,
+ "XDR function failed");
+ goto unwind;
+ }
+
+ iov.iov_len = ret;
+ count = 1;
+ }
+
+ /* Send the msg */
+ ret = rpc_clnt_submit (conf->rpc, prog, procnum, cbkfn, &iov, count,
+ payload, payloadcnt, new_iobref, frame, NULL, 0,
+ NULL, 0, NULL);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_DEBUG, "rpc_clnt_submit failed");
+ }
+
+ if (ret == 0) {
+ pthread_mutex_lock (&conf->rpc->conn.lock);
+ {
+ if (!conf->rpc->conn.ping_started) {
+ start_ping = 1;
+ }
+ }
+ pthread_mutex_unlock (&conf->rpc->conn.lock);
+ }
+
+ if (start_ping)
+ client_start_ping ((void *) this);
+
+ if (new_iobref)
+ iobref_unref (new_iobref);
+
+ if (iobuf)
+ iobuf_unref (iobuf);
+
+ return ret;
+
+unwind:
+ rpcreq.rpc_status = -1;
+ cbkfn (&rpcreq, NULL, 0, frame);
+
+ if (new_iobref)
+ iobref_unref (new_iobref);
+
+ if (iobuf)
+ iobuf_unref (iobuf);
+
+ return ret;
+}
+
+/* CBK */
+
+int
+client3_3_symlink_cbk (struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ call_frame_t *frame = NULL;
+ gfs3_symlink_rsp rsp = {0,};
+ struct iatt stbuf = {0,};
+ struct iatt preparent = {0,};
+ struct iatt postparent = {0,};
+ int ret = 0;
+ clnt_local_t *local = NULL;
+ inode_t *inode = NULL;
+ xlator_t *this = NULL;
+ dict_t *xdata = NULL;
+
+ this = THIS;
+
+ frame = myframe;
+
+ local = frame->local;
+ inode = local->loc.inode;
+
+ if (-1 == req->rpc_status) {
+ rsp.op_ret = -1;
+ rsp.op_errno = ENOTCONN;
+ goto out;
+ }
+ ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gfs3_symlink_rsp);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "XDR decoding failed");
+ rsp.op_ret = -1;
+ rsp.op_errno = EINVAL;
+ goto out;
+ }
+
+ if (-1 != rsp.op_ret) {
+ gf_stat_to_iatt (&rsp.stat, &stbuf);
+
+ gf_stat_to_iatt (&rsp.preparent, &preparent);
+ gf_stat_to_iatt (&rsp.postparent, &postparent);
+ }
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (this, xdata, (rsp.xdata.xdata_val),
+ (rsp.xdata.xdata_len), ret,
+ rsp.op_errno, out);
+
+out:
+ if (rsp.op_ret == -1) {
+ /* no need to print the gfid, because it will be null, since
+ * symlink operation failed.
+ */
+ gf_log (this->name, GF_LOG_WARNING,
+ "remote operation failed: %s. Path: (%s to %s)",
+ strerror (gf_error_to_errno (rsp.op_errno)),
+ local->loc.path, local->loc2.path);
+ }
+
+ CLIENT_STACK_UNWIND (symlink, frame, rsp.op_ret,
+ gf_error_to_errno (rsp.op_errno), inode, &stbuf,
+ &preparent, &postparent, xdata);
+
+ free (rsp.xdata.xdata_val);
+
+ if (xdata)
+ dict_unref (xdata);
+
+ return 0;
+}
+
+
+int
+client3_3_mknod_cbk (struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ call_frame_t *frame = NULL;
+ gfs3_mknod_rsp rsp = {0,};
+ struct iatt stbuf = {0,};
+ struct iatt preparent = {0,};
+ struct iatt postparent = {0,};
+ int ret = 0;
+ clnt_local_t *local = NULL;
+ inode_t *inode = NULL;
+ xlator_t *this = NULL;
+ dict_t *xdata = NULL;
+
+ this = THIS;
+
+ frame = myframe;
+
+ local = frame->local;
+
+ inode = local->loc.inode;
+
+ if (-1 == req->rpc_status) {
+ rsp.op_ret = -1;
+ rsp.op_errno = ENOTCONN;
+ goto out;
+ }
+ ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gfs3_mknod_rsp);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "XDR decoding failed");
+ rsp.op_ret = -1;
+ rsp.op_errno = EINVAL;
+ goto out;
+ }
+
+ if (-1 != rsp.op_ret) {
+ gf_stat_to_iatt (&rsp.stat, &stbuf);
+
+ gf_stat_to_iatt (&rsp.preparent, &preparent);
+ gf_stat_to_iatt (&rsp.postparent, &postparent);
+ }
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (this, xdata, (rsp.xdata.xdata_val),
+ (rsp.xdata.xdata_len), ret,
+ rsp.op_errno, out);
+
+out:
+ if (rsp.op_ret == -1) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "remote operation failed: %s. Path: %s",
+ strerror (gf_error_to_errno (rsp.op_errno)),
+ local->loc.path);
+ }
+
+ CLIENT_STACK_UNWIND (mknod, frame, rsp.op_ret,
+ gf_error_to_errno (rsp.op_errno), inode,
+ &stbuf, &preparent, &postparent, xdata);
+
+ free (rsp.xdata.xdata_val);
+
+ if (xdata)
+ dict_unref (xdata);
+
+ return 0;
+}
+
+int
+client3_3_mkdir_cbk (struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ call_frame_t *frame = NULL;
+ gfs3_mkdir_rsp rsp = {0,};
+ struct iatt stbuf = {0,};
+ struct iatt preparent = {0,};
+ struct iatt postparent = {0,};
+ int ret = 0;
+ clnt_local_t *local = NULL;
+ inode_t *inode = NULL;
+ xlator_t *this = NULL;
+ dict_t *xdata = NULL;
+
+ this = THIS;
+
+ frame = myframe;
+
+ local = frame->local;
+ inode = local->loc.inode;
+
+ if (-1 == req->rpc_status) {
+ rsp.op_ret = -1;
+ rsp.op_errno = ENOTCONN;
+ goto out;
+ }
+ ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gfs3_mkdir_rsp);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "XDR decoding failed");
+ rsp.op_ret = -1;
+ rsp.op_errno = EINVAL;
+ goto out;
+ }
+
+ if (-1 != rsp.op_ret) {
+ gf_stat_to_iatt (&rsp.stat, &stbuf);
+
+ gf_stat_to_iatt (&rsp.preparent, &preparent);
+ gf_stat_to_iatt (&rsp.postparent, &postparent);
+ }
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (this, xdata, (rsp.xdata.xdata_val),
+ (rsp.xdata.xdata_len), ret,
+ rsp.op_errno, out);
+
+out:
+ if (rsp.op_ret == -1) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "remote operation failed: %s. Path: %s",
+ strerror (gf_error_to_errno (rsp.op_errno)),
+ local->loc.path);
+ }
+
+ CLIENT_STACK_UNWIND (mkdir, frame, rsp.op_ret,
+ gf_error_to_errno (rsp.op_errno), inode,
+ &stbuf, &preparent, &postparent, xdata);
+
+ free (rsp.xdata.xdata_val);
+
+ if (xdata)
+ dict_unref (xdata);
+
+ return 0;
+}
+
+int
+_copy_gfid_from_inode_holders (uuid_t gfid, loc_t *loc, fd_t *fd)
+{
+ int ret = 0;
+
+ if (fd && fd->inode && !uuid_is_null (fd->inode->gfid)) {
+ uuid_copy (gfid, fd->inode->gfid);
+ goto out;
+ }
+
+ if (!loc) {
+ GF_ASSERT (0);
+ ret = -1;
+ goto out;
+ }
+
+ if (loc->inode && !uuid_is_null (loc->inode->gfid)) {
+ uuid_copy (gfid, loc->inode->gfid);
+ } else if (!uuid_is_null (loc->gfid)) {
+ uuid_copy (gfid, loc->gfid);
+ } else {
+ GF_ASSERT (0);
+ ret = -1;
+ }
+out:
+ return ret;
+}
+
+int
+client_add_fd_to_saved_fds (xlator_t *this, fd_t *fd, loc_t *loc, int32_t flags,
+ int64_t remote_fd, int is_dir)
+{
+ int ret = 0;
+ uuid_t gfid = {0};
+ clnt_conf_t *conf = NULL;
+ clnt_fd_ctx_t *fdctx = NULL;
+
+ conf = this->private;
+ ret = _copy_gfid_from_inode_holders (gfid, loc, fd);
+ if (ret) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ fdctx = GF_CALLOC (1, sizeof (*fdctx),
+ gf_client_mt_clnt_fdctx_t);
+ if (!fdctx) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ uuid_copy (fdctx->gfid, gfid);
+ fdctx->is_dir = is_dir;
+ fdctx->remote_fd = remote_fd;
+ fdctx->flags = flags;
+ fdctx->lk_ctx = fd_lk_ctx_ref (fd->lk_ctx);
+ fdctx->lk_heal_state = GF_LK_HEAL_DONE;
+ fdctx->reopen_done = client_default_reopen_done;
+
+ INIT_LIST_HEAD (&fdctx->sfd_pos);
+ INIT_LIST_HEAD (&fdctx->lock_list);
+
+ this_fd_set_ctx (fd, this, loc, fdctx);
+
+ pthread_mutex_lock (&conf->lock);
+ {
+ list_add_tail (&fdctx->sfd_pos, &conf->saved_fds);
+ }
+ pthread_mutex_unlock (&conf->lock);
+out:
+ return ret;
+}
+
+int
+client3_3_open_cbk (struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ clnt_local_t *local = NULL;
+ clnt_conf_t *conf = NULL;
+ call_frame_t *frame = NULL;
+ fd_t *fd = NULL;
+ int ret = 0;
+ gfs3_open_rsp rsp = {0,};
+ xlator_t *this = NULL;
+ dict_t *xdata = NULL;
+
+
+ this = THIS;
+
+ frame = myframe;
+ local = frame->local;
+
+ conf = frame->this->private;
+ fd = local->fd;
+
+ if (-1 == req->rpc_status) {
+ rsp.op_ret = -1;
+ rsp.op_errno = ENOTCONN;
+ goto out;
+ }
+ ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gfs3_open_rsp);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "XDR decoding failed");
+ rsp.op_ret = -1;
+ rsp.op_errno = EINVAL;
+ goto out;
+ }
+
+ if (-1 != rsp.op_ret) {
+ ret = client_add_fd_to_saved_fds (frame->this, fd, &local->loc,
+ local->flags, rsp.fd, 0);
+ if (ret) {
+ rsp.op_ret = -1;
+ rsp.op_errno = -ret;
+ goto out;
+ }
+ }
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (this, xdata, (rsp.xdata.xdata_val),
+ (rsp.xdata.xdata_len), ret,
+ rsp.op_errno, out);
+
+out:
+ if (rsp.op_ret == -1) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "remote operation failed: %s. Path: %s (%s)",
+ strerror (gf_error_to_errno (rsp.op_errno)),
+ local->loc.path, loc_gfid_utoa (&local->loc));
+ }
+
+ CLIENT_STACK_UNWIND (open, frame, rsp.op_ret,
+ gf_error_to_errno (rsp.op_errno), fd, xdata);
+
+ free (rsp.xdata.xdata_val);
+
+ if (xdata)
+ dict_unref (xdata);
+
+ return 0;
+}
+
+
+int
+client3_3_stat_cbk (struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ gfs3_stat_rsp rsp = {0,};
+ call_frame_t *frame = NULL;
+ struct iatt iatt = {0,};
+ int ret = 0;
+ xlator_t *this = NULL;
+ dict_t *xdata = NULL;
+
+
+ this = THIS;
+
+ frame = myframe;
+
+ if (-1 == req->rpc_status) {
+ rsp.op_ret = -1;
+ rsp.op_errno = ENOTCONN;
+ goto out;
+ }
+ ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gfs3_stat_rsp);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "XDR decoding failed");
+ rsp.op_ret = -1;
+ rsp.op_errno = EINVAL;
+ goto out;
+ }
+
+ if (-1 != rsp.op_ret) {
+ gf_stat_to_iatt (&rsp.stat, &iatt);
+ }
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (this, xdata, (rsp.xdata.xdata_val),
+ (rsp.xdata.xdata_len), ret,
+ rsp.op_errno, out);
+
+out:
+ if (rsp.op_ret == -1) {
+ gf_log (this->name, GF_LOG_WARNING, "remote operation failed: %s",
+ strerror (gf_error_to_errno (rsp.op_errno)));
+ }
+
+ CLIENT_STACK_UNWIND (stat, frame, rsp.op_ret,
+ gf_error_to_errno (rsp.op_errno), &iatt, xdata);
+
+ free (rsp.xdata.xdata_val);
+
+ if (xdata)
+ dict_unref (xdata);
+
+ return 0;
+}
+
+int
+client3_3_readlink_cbk (struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ gfs3_readlink_rsp rsp = {0,};
+ call_frame_t *frame = NULL;
+ struct iatt iatt = {0,};
+ int ret = 0;
+ xlator_t *this = NULL;
+ dict_t *xdata = NULL;
+
+
+ this = THIS;
+
+ frame = myframe;
+
+ if (-1 == req->rpc_status) {
+ rsp.op_ret = -1;
+ rsp.op_errno = ENOTCONN;
+ goto out;
+ }
+ ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gfs3_readlink_rsp);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "XDR decoding failed");
+ rsp.op_ret = -1;
+ rsp.op_errno = EINVAL;
+ goto out;
+ }
+
+ if (-1 != rsp.op_ret) {
+ gf_stat_to_iatt (&rsp.buf, &iatt);
+ }
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (this, xdata, (rsp.xdata.xdata_val),
+ (rsp.xdata.xdata_len), ret,
+ rsp.op_errno, out);
+
+out:
+ if (rsp.op_ret == -1) {
+ gf_log (this->name, (gf_error_to_errno(rsp.op_errno) == ENOENT)?
+ GF_LOG_DEBUG:GF_LOG_WARNING, "remote operation failed:"
+ " %s", strerror (gf_error_to_errno (rsp.op_errno)));
+ }
+
+ CLIENT_STACK_UNWIND (readlink, frame, rsp.op_ret,
+ gf_error_to_errno (rsp.op_errno), rsp.path,
+ &iatt, xdata);
+
+ /* This is allocated by the libc while decoding RPC msg */
+ /* Hence no 'GF_FREE', but just 'free' */
+ free (rsp.path);
+
+ free (rsp.xdata.xdata_val);
+
+ if (xdata)
+ dict_unref (xdata);
+
+ return 0;
+}
+
+int
+client3_3_unlink_cbk (struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ call_frame_t *frame = NULL;
+ gfs3_unlink_rsp rsp = {0,};
+ struct iatt preparent = {0,};
+ struct iatt postparent = {0,};
+ int ret = 0;
+ xlator_t *this = NULL;
+ dict_t *xdata = NULL;
+
+
+ this = THIS;
+
+ frame = myframe;
+
+ if (-1 == req->rpc_status) {
+ rsp.op_ret = -1;
+ rsp.op_errno = ENOTCONN;
+ goto out;
+ }
+ ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gfs3_unlink_rsp);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "XDR decoding failed");
+ rsp.op_ret = -1;
+ rsp.op_errno = EINVAL;
+ goto out;
+ }
+
+ if (-1 != rsp.op_ret) {
+ gf_stat_to_iatt (&rsp.preparent, &preparent);
+ gf_stat_to_iatt (&rsp.postparent, &postparent);
+ }
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (this, xdata, (rsp.xdata.xdata_val),
+ (rsp.xdata.xdata_len), ret,
+ rsp.op_errno, out);
+
+out:
+ if (rsp.op_ret == -1) {
+ gf_log (this->name,
+ ((gf_error_to_errno (rsp.op_errno) == ENOENT)
+ ? GF_LOG_DEBUG : GF_LOG_WARNING),
+ "remote operation failed: %s",
+ strerror (gf_error_to_errno (rsp.op_errno)));
+ }
+
+ CLIENT_STACK_UNWIND (unlink, frame, rsp.op_ret,
+ gf_error_to_errno (rsp.op_errno), &preparent,
+ &postparent, xdata);
+
+ free (rsp.xdata.xdata_val);
+
+ if (xdata)
+ dict_unref (xdata);
+
+ return 0;
+}
+
+int
+client3_3_rmdir_cbk (struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ gfs3_rmdir_rsp rsp = {0,};
+ call_frame_t *frame = NULL;
+ struct iatt preparent = {0,};
+ struct iatt postparent = {0,};
+ int ret = 0;
+ xlator_t *this = NULL;
+ dict_t *xdata = NULL;
+
+
+ this = THIS;
+
+ frame = myframe;
+
+ if (-1 == req->rpc_status) {
+ rsp.op_ret = -1;
+ rsp.op_errno = ENOTCONN;
+ goto out;
+ }
+ ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gfs3_rmdir_rsp);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "XDR decoding failed");
+ rsp.op_ret = -1;
+ rsp.op_errno = EINVAL;
+ goto out;
+ }
+
+ if (-1 != rsp.op_ret) {
+ gf_stat_to_iatt (&rsp.preparent, &preparent);
+ gf_stat_to_iatt (&rsp.postparent, &postparent);
+ }
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (this, xdata, (rsp.xdata.xdata_val),
+ (rsp.xdata.xdata_len), ret,
+ rsp.op_errno, out);
+
+out:
+ if (rsp.op_ret == -1) {
+ gf_log (this->name, GF_LOG_WARNING, "remote operation failed: %s",
+ strerror (gf_error_to_errno (rsp.op_errno)));
+ }
+ CLIENT_STACK_UNWIND (rmdir, frame, rsp.op_ret,
+ gf_error_to_errno (rsp.op_errno), &preparent,
+ &postparent, xdata);
+
+ free (rsp.xdata.xdata_val);
+
+ if (xdata)
+ dict_unref (xdata);
+
+ return 0;
+}
+
+
+int
+client3_3_truncate_cbk (struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ gfs3_truncate_rsp rsp = {0,};
+ call_frame_t *frame = NULL;
+ struct iatt prestat = {0,};
+ struct iatt poststat = {0,};
+ int ret = 0;
+ xlator_t *this = NULL;
+ dict_t *xdata = NULL;
+
+
+ this = THIS;
+
+ frame = myframe;
+
+ if (-1 == req->rpc_status) {
+ rsp.op_ret = -1;
+ rsp.op_errno = ENOTCONN;
+ goto out;
+ }
+ ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gfs3_truncate_rsp);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "XDR decoding failed");
+ rsp.op_ret = -1;
+ rsp.op_errno = EINVAL;
+ goto out;
+ }
+
+ if (-1 != rsp.op_ret) {
+ gf_stat_to_iatt (&rsp.prestat, &prestat);
+ gf_stat_to_iatt (&rsp.poststat, &poststat);
+ }
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (this, xdata, (rsp.xdata.xdata_val),
+ (rsp.xdata.xdata_len), ret,
+ rsp.op_errno, out);
+
+out:
+ if (rsp.op_ret == -1) {
+ gf_log (this->name, GF_LOG_WARNING, "remote operation failed: %s",
+ strerror (gf_error_to_errno (rsp.op_errno)));
+ }
+ CLIENT_STACK_UNWIND (truncate, frame, rsp.op_ret,
+ gf_error_to_errno (rsp.op_errno), &prestat,
+ &poststat, xdata);
+
+ free (rsp.xdata.xdata_val);
+
+ if (xdata)
+ dict_unref (xdata);
+
+ return 0;
+}
+
+
+int
+client3_3_statfs_cbk (struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ gfs3_statfs_rsp rsp = {0,};
+ call_frame_t *frame = NULL;
+ struct statvfs statfs = {0,};
+ int ret = 0;
+ xlator_t *this = NULL;
+ dict_t *xdata = NULL;
+
+
+ this = THIS;
+
+ frame = myframe;
+
+ if (-1 == req->rpc_status) {
+ rsp.op_ret = -1;
+ rsp.op_errno = ENOTCONN;
+ goto out;
+ }
+ ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gfs3_statfs_rsp);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "XDR decoding failed");
+ rsp.op_ret = -1;
+ rsp.op_errno = EINVAL;
+ goto out;
+ }
+
+ if (-1 != rsp.op_ret) {
+ gf_statfs_to_statfs (&rsp.statfs, &statfs);
+ }
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (this, xdata, (rsp.xdata.xdata_val),
+ (rsp.xdata.xdata_len), ret,
+ rsp.op_errno, out);
+
+out:
+ if (rsp.op_ret == -1) {
+ gf_log (this->name, GF_LOG_WARNING, "remote operation failed: %s",
+ strerror (gf_error_to_errno (rsp.op_errno)));
+ }
+ CLIENT_STACK_UNWIND (statfs, frame, rsp.op_ret,
+ gf_error_to_errno (rsp.op_errno), &statfs, xdata);
+
+ free (rsp.xdata.xdata_val);
+
+ if (xdata)
+ dict_unref (xdata);
+
+ return 0;
+}
+
+
+int
+client3_3_writev_cbk (struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ gfs3_write_rsp rsp = {0,};
+ call_frame_t *frame = NULL;
+ struct iatt prestat = {0,};
+ struct iatt poststat = {0,};
+ int ret = 0;
+ xlator_t *this = NULL;
+ dict_t *xdata = NULL;
+ clnt_local_t *local = NULL;
+
+
+ this = THIS;
+
+ frame = myframe;
+ local = frame->local;
+
+ if (-1 == req->rpc_status) {
+ rsp.op_ret = -1;
+ rsp.op_errno = ENOTCONN;
+ goto out;
+ }
+
+ ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gfs3_truncate_rsp);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "XDR decoding failed");
+ rsp.op_ret = -1;
+ rsp.op_errno = EINVAL;
+ goto out;
+ }
+
+ if (-1 != rsp.op_ret) {
+ gf_stat_to_iatt (&rsp.prestat, &prestat);
+ gf_stat_to_iatt (&rsp.poststat, &poststat);
+ }
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (this, xdata, (rsp.xdata.xdata_val),
+ (rsp.xdata.xdata_len), ret,
+ rsp.op_errno, out);
+
+out:
+ if (rsp.op_ret == -1) {
+ gf_log (this->name, GF_LOG_WARNING, "remote operation failed: %s",
+ strerror (gf_error_to_errno (rsp.op_errno)));
+ } else if (rsp.op_ret >= 0) {
+ if (local->attempt_reopen)
+ client_attempt_reopen (local->fd, this);
+ }
+ CLIENT_STACK_UNWIND (writev, frame, rsp.op_ret,
+ gf_error_to_errno (rsp.op_errno), &prestat,
+ &poststat, xdata);
+
+ free (rsp.xdata.xdata_val);
+
+ if (xdata)
+ dict_unref (xdata);
+
+ return 0;
+}
+
+int
+client3_3_flush_cbk (struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ call_frame_t *frame = NULL;
+ clnt_local_t *local = NULL;
+ xlator_t *this = NULL;
+ dict_t *xdata = NULL;
+
+ gf_common_rsp rsp = {0,};
+ int ret = 0;
+
+ frame = myframe;
+ this = THIS;
+ local = frame->local;
+
+ if (-1 == req->rpc_status) {
+ rsp.op_ret = -1;
+ rsp.op_errno = ENOTCONN;
+ goto out;
+ }
+ ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_common_rsp);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "XDR decoding failed");
+ rsp.op_ret = -1;
+ rsp.op_errno = EINVAL;
+ goto out;
+ }
+
+ if (rsp.op_ret >= 0 && !fd_is_anonymous (local->fd)) {
+ /* Delete all saved locks of the owner issuing flush */
+ ret = delete_granted_locks_owner (local->fd, &local->owner);
+ gf_log (this->name, GF_LOG_TRACE,
+ "deleting locks of owner (%s) returned %d",
+ lkowner_utoa (&local->owner), ret);
+ }
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (this, xdata, (rsp.xdata.xdata_val),
+ (rsp.xdata.xdata_len), ret,
+ rsp.op_errno, out);
+
+out:
+ if (rsp.op_ret == -1) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "remote operation failed: %s",
+ strerror (gf_error_to_errno (rsp.op_errno)));
+ }
+ CLIENT_STACK_UNWIND (flush, frame, rsp.op_ret,
+ gf_error_to_errno (rsp.op_errno), xdata);
+
+ free (rsp.xdata.xdata_val);
+
+ if (xdata)
+ dict_unref (xdata);
+
+ return 0;
+}
+
+int
+client3_3_fsync_cbk (struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ gfs3_fsync_rsp rsp = {0,};
+ call_frame_t *frame = NULL;
+ struct iatt prestat = {0,};
+ struct iatt poststat = {0,};
+ int ret = 0;
+ xlator_t *this = NULL;
+ dict_t *xdata = NULL;
+
+
+ this = THIS;
+
+ frame = myframe;
+
+ if (-1 == req->rpc_status) {
+ rsp.op_ret = -1;
+ rsp.op_errno = ENOTCONN;
+ goto out;
+ }
+
+ ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gfs3_truncate_rsp);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "XDR decoding failed");
+ rsp.op_ret = -1;
+ rsp.op_errno = EINVAL;
+ goto out;
+ }
+
+ if (-1 != rsp.op_ret) {
+ gf_stat_to_iatt (&rsp.prestat, &prestat);
+ gf_stat_to_iatt (&rsp.poststat, &poststat);
+ }
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (this, xdata, (rsp.xdata.xdata_val),
+ (rsp.xdata.xdata_len), ret,
+ rsp.op_errno, out);
+
+out:
+ if (rsp.op_ret == -1) {
+ gf_log (this->name, GF_LOG_WARNING, "remote operation failed: %s",
+ strerror (gf_error_to_errno (rsp.op_errno)));
+ }
+ CLIENT_STACK_UNWIND (fsync, frame, rsp.op_ret,
+ gf_error_to_errno (rsp.op_errno), &prestat,
+ &poststat, xdata);
+
+ free (rsp.xdata.xdata_val);
+
+ if (xdata)
+ dict_unref (xdata);
+
+ return 0;
+}
+
+int
+client3_3_setxattr_cbk (struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ call_frame_t *frame = NULL;
+ gf_common_rsp rsp = {0,};
+ int ret = 0;
+ xlator_t *this = NULL;
+ dict_t *xdata = NULL;
+ int op_errno = EINVAL;
+
+ this = THIS;
+
+ frame = myframe;
+
+ if (-1 == req->rpc_status) {
+ rsp.op_ret = -1;
+ rsp.op_errno = ENOTCONN;
+ goto out;
+ }
+
+ ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_common_rsp);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "XDR decoding failed");
+ rsp.op_ret = -1;
+ rsp.op_errno = EINVAL;
+ goto out;
+ }
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (this, xdata, (rsp.xdata.xdata_val),
+ (rsp.xdata.xdata_len), ret,
+ rsp.op_errno, out);
+
+out:
+ op_errno = gf_error_to_errno (rsp.op_errno);
+ if (rsp.op_ret == -1) {
+ gf_log (this->name, ((op_errno == ENOTSUP) ?
+ GF_LOG_DEBUG : GF_LOG_WARNING),
+ "remote operation failed: %s",
+ strerror (op_errno));
+ }
+ CLIENT_STACK_UNWIND (setxattr, frame, rsp.op_ret, op_errno, xdata);
+
+ free (rsp.xdata.xdata_val);
+
+ if (xdata)
+ dict_unref (xdata);
+
+ return 0;
+}
+
+int
+client3_3_getxattr_cbk (struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ call_frame_t *frame = NULL;
+ dict_t *dict = NULL;
+ int op_errno = EINVAL;
+ gfs3_getxattr_rsp rsp = {0,};
+ int ret = 0;
+ clnt_local_t *local = NULL;
+ xlator_t *this = NULL;
+ dict_t *xdata = NULL;
+
+
+ this = THIS;
+
+ frame = myframe;
+ local = frame->local;
+
+ if (-1 == req->rpc_status) {
+ rsp.op_ret = -1;
+ op_errno = ENOTCONN;
+ goto out;
+ }
+
+ ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gfs3_getxattr_rsp);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "XDR decoding failed");
+ rsp.op_ret = -1;
+ op_errno = EINVAL;
+ goto out;
+ }
+
+ op_errno = gf_error_to_errno (rsp.op_errno);
+ if (-1 != rsp.op_ret) {
+ GF_PROTOCOL_DICT_UNSERIALIZE (frame->this, dict,
+ (rsp.dict.dict_val),
+ (rsp.dict.dict_len), rsp.op_ret,
+ op_errno, out);
+ }
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (this, xdata, (rsp.xdata.xdata_val),
+ (rsp.xdata.xdata_len), ret,
+ op_errno, out);
+
+out:
+ if (rsp.op_ret == -1) {
+ gf_log (this->name, (((op_errno == ENOTSUP) ||
+ (op_errno == ENODATA) ||
+ (op_errno == ENOENT)) ?
+ GF_LOG_DEBUG : GF_LOG_WARNING),
+ "remote operation failed: %s. Path: %s (%s). Key: %s",
+ strerror (op_errno),
+ local->loc.path, loc_gfid_utoa (&local->loc),
+ (local->name) ? local->name : "(null)");
+ }
+
+ CLIENT_STACK_UNWIND (getxattr, frame, rsp.op_ret, op_errno, dict, xdata);
+
+ /* don't use GF_FREE, this memory was allocated by libc */
+ free (rsp.dict.dict_val);
+
+ free (rsp.xdata.xdata_val);
+
+ if (xdata)
+ dict_unref (xdata);
+
+ if (dict)
+ dict_unref (dict);
+
+ return 0;
+}
+
+int
+client3_3_fgetxattr_cbk (struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ call_frame_t *frame = NULL;
+ dict_t *dict = NULL;
+ gfs3_fgetxattr_rsp rsp = {0,};
+ int ret = 0;
+ int op_errno = EINVAL;
+ clnt_local_t *local = NULL;
+ xlator_t *this = NULL;
+ dict_t *xdata = NULL;
+
+
+ this = THIS;
+
+ frame = myframe;
+ local = frame->local;
+
+ if (-1 == req->rpc_status) {
+ rsp.op_ret = -1;
+ op_errno = ENOTCONN;
+ goto out;
+ }
+ ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gfs3_fgetxattr_rsp);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "XDR decoding failed");
+ rsp.op_ret = -1;
+ op_errno = EINVAL;
+ goto out;
+ }
+
+ op_errno = gf_error_to_errno (rsp.op_errno);
+ if (-1 != rsp.op_ret) {
+ GF_PROTOCOL_DICT_UNSERIALIZE (frame->this, dict,
+ (rsp.dict.dict_val),
+ (rsp.dict.dict_len), rsp.op_ret,
+ op_errno, out);
+ }
+ GF_PROTOCOL_DICT_UNSERIALIZE (this, xdata, (rsp.xdata.xdata_val),
+ (rsp.xdata.xdata_len), ret,
+ op_errno, out);
+
+out:
+ if (rsp.op_ret == -1) {
+ gf_log (this->name, ((op_errno == ENOTSUP) ?
+ GF_LOG_DEBUG : GF_LOG_WARNING),
+ "remote operation failed: %s",
+ strerror (op_errno));
+ }
+
+ CLIENT_STACK_UNWIND (fgetxattr, frame, rsp.op_ret, op_errno, dict, xdata);
+
+ free (rsp.dict.dict_val);
+
+ free (rsp.xdata.xdata_val);
+
+ if (xdata)
+ dict_unref (xdata);
+
+ if (dict)
+ dict_unref (dict);
+
+ return 0;
+}
+
+int
+client3_3_removexattr_cbk (struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ call_frame_t *frame = NULL;
+ gf_common_rsp rsp = {0,};
+ int ret = 0;
+ xlator_t *this = NULL;
+ dict_t *xdata = NULL;
+
+ this = THIS;
+
+ frame = myframe;
+
+ if (-1 == req->rpc_status) {
+ rsp.op_ret = -1;
+ rsp.op_errno = ENOTCONN;
+ goto out;
+ }
+
+ ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_common_rsp);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "XDR decoding failed");
+ rsp.op_ret = -1;
+ rsp.op_errno = EINVAL;
+ goto out;
+ }
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (this, xdata, (rsp.xdata.xdata_val),
+ (rsp.xdata.xdata_len), ret,
+ rsp.op_errno, out);
+
+out:
+ if (rsp.op_ret == -1) {
+ gf_log (this->name, GF_LOG_WARNING, "remote operation failed: %s",
+ strerror (gf_error_to_errno (rsp.op_errno)));
+ }
+
+ CLIENT_STACK_UNWIND (removexattr, frame, rsp.op_ret,
+ gf_error_to_errno (rsp.op_errno), xdata);
+
+ free (rsp.xdata.xdata_val);
+
+ if (xdata)
+ dict_unref (xdata);
+
+ return 0;
+}
+
+int
+client3_3_fremovexattr_cbk (struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ call_frame_t *frame = NULL;
+ gf_common_rsp rsp = {0,};
+ int ret = 0;
+ xlator_t *this = NULL;
+ dict_t *xdata = NULL;
+
+
+ this = THIS;
+
+ frame = myframe;
+
+ if (-1 == req->rpc_status) {
+ rsp.op_ret = -1;
+ rsp.op_errno = ENOTCONN;
+ goto out;
+ }
+
+ ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_common_rsp);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "XDR decoding failed");
+ rsp.op_ret = -1;
+ rsp.op_errno = EINVAL;
+ goto out;
+ }
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (this, xdata, (rsp.xdata.xdata_val),
+ (rsp.xdata.xdata_len), ret,
+ rsp.op_errno, out);
+
+out:
+ if (rsp.op_ret == -1) {
+ gf_log (this->name, GF_LOG_WARNING, "remote operation failed: %s",
+ strerror (gf_error_to_errno (rsp.op_errno)));
+ }
+ CLIENT_STACK_UNWIND (fremovexattr, frame, rsp.op_ret,
+ gf_error_to_errno (rsp.op_errno), xdata);
+
+ free (rsp.xdata.xdata_val);
+
+ if (xdata)
+ dict_unref (xdata);
+
+ return 0;
+}
+
+int
+client3_3_fsyncdir_cbk (struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ call_frame_t *frame = NULL;
+ gf_common_rsp rsp = {0,};
+ int ret = 0;
+ xlator_t *this = NULL;
+ dict_t *xdata = NULL;
+
+
+ this = THIS;
+
+ frame = myframe;
+
+ if (-1 == req->rpc_status) {
+ rsp.op_ret = -1;
+ rsp.op_errno = ENOTCONN;
+ goto out;
+ }
+ ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_common_rsp);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "XDR decoding failed");
+ rsp.op_ret = -1;
+ rsp.op_errno = EINVAL;
+ goto out;
+ }
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (this, xdata, (rsp.xdata.xdata_val),
+ (rsp.xdata.xdata_len), ret,
+ rsp.op_errno, out);
+
+out:
+ if (rsp.op_ret == -1) {
+ gf_log (this->name, GF_LOG_WARNING, "remote operation failed: %s",
+ strerror (gf_error_to_errno (rsp.op_errno)));
+ }
+ CLIENT_STACK_UNWIND (fsyncdir, frame, rsp.op_ret,
+ gf_error_to_errno (rsp.op_errno), xdata);
+
+ free (rsp.xdata.xdata_val);
+
+ if (xdata)
+ dict_unref (xdata);
+
+ return 0;
+}
+
+int
+client3_3_access_cbk (struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ call_frame_t *frame = NULL;
+ gf_common_rsp rsp = {0,};
+ int ret = 0;
+ xlator_t *this = NULL;
+ dict_t *xdata = NULL;
+
+
+ this = THIS;
+
+ frame = myframe;
+
+ if (-1 == req->rpc_status) {
+ rsp.op_ret = -1;
+ rsp.op_errno = ENOTCONN;
+ goto out;
+ }
+ ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_common_rsp);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "XDR decoding failed");
+ rsp.op_ret = -1;
+ rsp.op_errno = EINVAL;
+ goto out;
+ }
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (this, xdata, (rsp.xdata.xdata_val),
+ (rsp.xdata.xdata_len), ret,
+ rsp.op_errno, out);
+
+out:
+ if (rsp.op_ret == -1) {
+ gf_log (this->name, GF_LOG_WARNING, "remote operation failed: %s",
+ strerror (gf_error_to_errno (rsp.op_errno)));
+ }
+ CLIENT_STACK_UNWIND (access, frame, rsp.op_ret,
+ gf_error_to_errno (rsp.op_errno), xdata);
+
+ free (rsp.xdata.xdata_val);
+
+ if (xdata)
+ dict_unref (xdata);
+
+ return 0;
+}
+
+
+int
+client3_3_ftruncate_cbk (struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ gfs3_ftruncate_rsp rsp = {0,};
+ call_frame_t *frame = NULL;
+ struct iatt prestat = {0,};
+ struct iatt poststat = {0,};
+ int ret = 0;
+ xlator_t *this = NULL;
+ dict_t *xdata = NULL;
+
+
+ this = THIS;
+
+ frame = myframe;
+
+ if (-1 == req->rpc_status) {
+ rsp.op_ret = -1;
+ rsp.op_errno = ENOTCONN;
+ goto out;
+ }
+ ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gfs3_ftruncate_rsp);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "XDR decoding failed");
+ rsp.op_ret = -1;
+ rsp.op_errno = EINVAL;
+ goto out;
+ }
+
+ if (-1 != rsp.op_ret) {
+ gf_stat_to_iatt (&rsp.prestat, &prestat);
+ gf_stat_to_iatt (&rsp.poststat, &poststat);
+ }
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (this, xdata, (rsp.xdata.xdata_val),
+ (rsp.xdata.xdata_len), ret,
+ rsp.op_errno, out);
+
+out:
+ if (rsp.op_ret == -1) {
+ gf_log (this->name, GF_LOG_WARNING, "remote operation failed: %s",
+ strerror (gf_error_to_errno (rsp.op_errno)));
+ }
+ CLIENT_STACK_UNWIND (ftruncate, frame, rsp.op_ret,
+ gf_error_to_errno (rsp.op_errno), &prestat,
+ &poststat, xdata);
+
+ free (rsp.xdata.xdata_val);
+
+ if (xdata)
+ dict_unref (xdata);
+
+ return 0;
+}
+
+int
+client3_3_fstat_cbk (struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ gfs3_fstat_rsp rsp = {0,};
+ call_frame_t *frame = NULL;
+ struct iatt stat = {0,};
+ int ret = 0;
+ xlator_t *this = NULL;
+ dict_t *xdata = NULL;
+
+
+ this = THIS;
+
+ frame = myframe;
+
+ if (-1 == req->rpc_status) {
+ rsp.op_ret = -1;
+ rsp.op_errno = ENOTCONN;
+ goto out;
+ }
+ ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gfs3_fstat_rsp);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "XDR decoding failed");
+ rsp.op_ret = -1;
+ rsp.op_errno = EINVAL;
+ goto out;
+ }
+
+ if (-1 != rsp.op_ret) {
+ gf_stat_to_iatt (&rsp.stat, &stat);
+ }
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (this, xdata, (rsp.xdata.xdata_val),
+ (rsp.xdata.xdata_len), ret,
+ rsp.op_errno, out);
+
+out:
+ if (rsp.op_ret == -1) {
+ gf_log (this->name, GF_LOG_WARNING, "remote operation failed: %s",
+ strerror (gf_error_to_errno (rsp.op_errno)));
+ }
+ CLIENT_STACK_UNWIND (fstat, frame, rsp.op_ret,
+ gf_error_to_errno (rsp.op_errno), &stat, xdata);
+
+ free (rsp.xdata.xdata_val);
+
+ if (xdata)
+ dict_unref (xdata);
+
+ return 0;
+}
+
+
+int
+client3_3_inodelk_cbk (struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ call_frame_t *frame = NULL;
+ gf_common_rsp rsp = {0,};
+ int ret = 0;
+ xlator_t *this = NULL;
+ dict_t *xdata = NULL;
+
+
+ this = THIS;
+
+ frame = myframe;
+
+ if (-1 == req->rpc_status) {
+ rsp.op_ret = -1;
+ rsp.op_errno = ENOTCONN;
+ goto out;
+ }
+ ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_common_rsp);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "XDR decoding failed");
+ rsp.op_ret = -1;
+ rsp.op_errno = EINVAL;
+ goto out;
+ }
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (this, xdata, (rsp.xdata.xdata_val),
+ (rsp.xdata.xdata_len), ret,
+ rsp.op_errno, out);
+
+out:
+ if ((rsp.op_ret == -1) &&
+ (EAGAIN != gf_error_to_errno (rsp.op_errno))) {
+ gf_log (this->name, GF_LOG_WARNING, "remote operation failed: %s",
+ strerror (gf_error_to_errno (rsp.op_errno)));
+ }
+ CLIENT_STACK_UNWIND (inodelk, frame, rsp.op_ret,
+ gf_error_to_errno (rsp.op_errno), xdata);
+
+ free (rsp.xdata.xdata_val);
+
+ if (xdata)
+ dict_unref (xdata);
+
+ return 0;
+}
+
+int
+client3_3_finodelk_cbk (struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ call_frame_t *frame = NULL;
+ gf_common_rsp rsp = {0,};
+ int ret = 0;
+ xlator_t *this = NULL;
+ dict_t *xdata = NULL;
+ clnt_local_t *local = NULL;
+
+
+ frame = myframe;
+ this = frame->this;
+ local = frame->local;
+
+ if (-1 == req->rpc_status) {
+ rsp.op_ret = -1;
+ rsp.op_errno = ENOTCONN;
+ goto out;
+ }
+ ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_common_rsp);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "XDR decoding failed");
+ rsp.op_ret = -1;
+ rsp.op_errno = EINVAL;
+ goto out;
+ }
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (this, xdata, (rsp.xdata.xdata_val),
+ (rsp.xdata.xdata_len), ret,
+ rsp.op_errno, out);
+
+out:
+ if ((rsp.op_ret == -1) &&
+ (EAGAIN != gf_error_to_errno (rsp.op_errno))) {
+ gf_log (this->name, GF_LOG_WARNING, "remote operation failed: %s",
+ strerror (gf_error_to_errno (rsp.op_errno)));
+ } else if (rsp.op_ret == 0) {
+ if (local->attempt_reopen)
+ client_attempt_reopen (local->fd, this);
+ }
+ CLIENT_STACK_UNWIND (finodelk, frame, rsp.op_ret,
+ gf_error_to_errno (rsp.op_errno), xdata);
+
+ free (rsp.xdata.xdata_val);
+
+ if (xdata)
+ dict_unref (xdata);
+
+ return 0;
+}
+
+int
+client3_3_entrylk_cbk (struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ call_frame_t *frame = NULL;
+ gf_common_rsp rsp = {0,};
+ int ret = 0;
+ xlator_t *this = NULL;
+ dict_t *xdata = NULL;
+
+
+ this = THIS;
+
+ frame = myframe;
+
+ if (-1 == req->rpc_status) {
+ rsp.op_ret = -1;
+ rsp.op_errno = ENOTCONN;
+ goto out;
+ }
+ ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_common_rsp);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "XDR decoding failed");
+ rsp.op_ret = -1;
+ rsp.op_errno = EINVAL;
+ goto out;
+ }
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (this, xdata, (rsp.xdata.xdata_val),
+ (rsp.xdata.xdata_len), ret,
+ rsp.op_errno, out);
+
+out:
+ if ((rsp.op_ret == -1) &&
+ (EAGAIN != gf_error_to_errno (rsp.op_errno))) {
+ gf_log (this->name, GF_LOG_WARNING, "remote operation failed: %s",
+ strerror (gf_error_to_errno (rsp.op_errno)));
+ }
+
+ CLIENT_STACK_UNWIND (entrylk, frame, rsp.op_ret,
+ gf_error_to_errno (rsp.op_errno), xdata);
+
+ free (rsp.xdata.xdata_val);
+
+ if (xdata)
+ dict_unref (xdata);
+
+ return 0;
+}
+
+int
+client3_3_fentrylk_cbk (struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ call_frame_t *frame = NULL;
+ gf_common_rsp rsp = {0,};
+ int ret = 0;
+ xlator_t *this = NULL;
+ dict_t *xdata = NULL;
+
+
+ this = THIS;
+
+ frame = myframe;
+
+ if (-1 == req->rpc_status) {
+ rsp.op_ret = -1;
+ rsp.op_errno = ENOTCONN;
+ goto out;
+ }
+ ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_common_rsp);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "XDR decoding failed");
+ rsp.op_ret = -1;
+ rsp.op_errno = EINVAL;
+ goto out;
+ }
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (this, xdata, (rsp.xdata.xdata_val),
+ (rsp.xdata.xdata_len), ret,
+ rsp.op_errno, out);
+
+out:
+ if ((rsp.op_ret == -1) &&
+ (EAGAIN != gf_error_to_errno (rsp.op_errno))) {
+ gf_log (this->name, GF_LOG_WARNING, "remote operation failed: %s",
+ strerror (gf_error_to_errno (rsp.op_errno)));
+ }
+
+ CLIENT_STACK_UNWIND (fentrylk, frame, rsp.op_ret,
+ gf_error_to_errno (rsp.op_errno), xdata);
+
+ free (rsp.xdata.xdata_val);
+
+ if (xdata)
+ dict_unref (xdata);
+
+ return 0;
+}
+
+int
+client3_3_xattrop_cbk (struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ call_frame_t *frame = NULL;
+ dict_t *dict = NULL;
+ gfs3_xattrop_rsp rsp = {0,};
+ int ret = 0;
+ int op_errno = EINVAL;
+ clnt_local_t *local = NULL;
+ xlator_t *this = NULL;
+ dict_t *xdata = NULL;
+
+
+ this = THIS;
+
+ frame = myframe;
+ local = frame->local;
+
+ if (-1 == req->rpc_status) {
+ rsp.op_ret = -1;
+ op_errno = ENOTCONN;
+ goto out;
+ }
+ ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gfs3_xattrop_rsp);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "XDR decoding failed");
+ rsp.op_ret = -1;
+ op_errno = EINVAL;
+ goto out;
+ }
+
+ op_errno = rsp.op_errno;
+ if (-1 != rsp.op_ret) {
+ GF_PROTOCOL_DICT_UNSERIALIZE (frame->this, dict,
+ (rsp.dict.dict_val),
+ (rsp.dict.dict_len), rsp.op_ret,
+ op_errno, out);
+ }
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (this, xdata, (rsp.xdata.xdata_val),
+ (rsp.xdata.xdata_len), ret,
+ op_errno, out);
+
+out:
+ if (rsp.op_ret == -1) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "remote operation failed: %s. Path: %s (%s)",
+ strerror (gf_error_to_errno (rsp.op_errno)),
+ local->loc.path, loc_gfid_utoa (&local->loc));
+ }
+
+ CLIENT_STACK_UNWIND (xattrop, frame, rsp.op_ret,
+ gf_error_to_errno (op_errno), dict, xdata);
+
+ free (rsp.dict.dict_val);
+
+ free (rsp.xdata.xdata_val);
+
+ if (xdata)
+ dict_unref (xdata);
+
+ if (dict)
+ dict_unref (dict);
+
+ return 0;
+}
+
+int
+client3_3_fxattrop_cbk (struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ call_frame_t *frame = NULL;
+ dict_t *dict = NULL;
+ dict_t *xdata = NULL;
+ gfs3_fxattrop_rsp rsp = {0,};
+ int ret = 0;
+ int op_errno = 0;
+ clnt_local_t *local = NULL;
+ xlator_t *this = NULL;
+
+ this = THIS;
+
+ frame = myframe;
+ local = frame->local;
+
+ if (-1 == req->rpc_status) {
+ rsp.op_ret = -1;
+ op_errno = ENOTCONN;
+ goto out;
+ }
+
+ ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gfs3_fxattrop_rsp);
+ if (ret < 0) {
+ rsp.op_ret = -1;
+ op_errno = EINVAL;
+ gf_log (this->name, GF_LOG_ERROR, "XDR decoding failed");
+ goto out;
+ }
+ op_errno = rsp.op_errno;
+ if (-1 != rsp.op_ret) {
+ GF_PROTOCOL_DICT_UNSERIALIZE (frame->this, dict,
+ (rsp.dict.dict_val),
+ (rsp.dict.dict_len), rsp.op_ret,
+ op_errno, out);
+ }
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (frame->this, xdata,
+ (rsp.xdata.xdata_val),
+ (rsp.xdata.xdata_len), rsp.op_ret,
+ op_errno, out);
+out:
+
+ if (rsp.op_ret == -1) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "remote operation failed: %s",
+ strerror (gf_error_to_errno (op_errno)));
+ } else if (rsp.op_ret == 0) {
+ if (local->attempt_reopen)
+ client_attempt_reopen (local->fd, this);
+ }
+ CLIENT_STACK_UNWIND (fxattrop, frame, rsp.op_ret,
+ gf_error_to_errno (op_errno), dict, xdata);
+
+ free (rsp.dict.dict_val);
+
+ free (rsp.xdata.xdata_val);
+
+ if (xdata)
+ dict_unref (xdata);
+
+ if (dict)
+ dict_unref (dict);
+
+ return 0;
+}
+
+int
+client3_3_fsetxattr_cbk (struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ call_frame_t *frame = NULL;
+ gf_common_rsp rsp = {0,};
+ int ret = 0;
+ xlator_t *this = NULL;
+ dict_t *xdata = NULL;
+ int op_errno = EINVAL;
+
+ this = THIS;
+
+ frame = myframe;
+
+ if (-1 == req->rpc_status) {
+ rsp.op_ret = -1;
+ rsp.op_errno = ENOTCONN;
+ goto out;
+ }
+ ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_common_rsp);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "XDR decoding failed");
+ rsp.op_ret = -1;
+ rsp.op_errno = EINVAL;
+ goto out;
+ }
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (this, xdata, (rsp.xdata.xdata_val),
+ (rsp.xdata.xdata_len), ret,
+ rsp.op_errno, out);
+
+out:
+ op_errno = gf_error_to_errno (rsp.op_errno);
+ if (rsp.op_ret == -1) {
+ gf_log (this->name, ((op_errno == ENOTSUP) ?
+ GF_LOG_DEBUG : GF_LOG_WARNING),
+ "remote operation failed: %s",
+ strerror (op_errno));
+ }
+
+ CLIENT_STACK_UNWIND (fsetxattr, frame, rsp.op_ret, op_errno, xdata);
+
+ free (rsp.xdata.xdata_val);
+
+ if (xdata)
+ dict_unref (xdata);
+
+ return 0;
+}
+
+int
+client3_3_fsetattr_cbk (struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ call_frame_t *frame = NULL;
+ gfs3_fsetattr_rsp rsp = {0,};
+ struct iatt prestat = {0,};
+ struct iatt poststat = {0,};
+ int ret = 0;
+ xlator_t *this = NULL;
+ dict_t *xdata = NULL;
+
+
+ this = THIS;
+
+ frame = myframe;
+
+ if (-1 == req->rpc_status) {
+ rsp.op_ret = -1;
+ rsp.op_errno = ENOTCONN;
+ goto out;
+ }
+ ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gfs3_fsetattr_rsp);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "XDR decoding failed");
+ rsp.op_ret = -1;
+ rsp.op_errno = EINVAL;
+ goto out;
+ }
+
+ if (-1 != rsp.op_ret) {
+ gf_stat_to_iatt (&rsp.statpre, &prestat);
+ gf_stat_to_iatt (&rsp.statpost, &poststat);
+ }
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (this, xdata, (rsp.xdata.xdata_val),
+ (rsp.xdata.xdata_len), ret,
+ rsp.op_errno, out);
+
+out:
+ if (rsp.op_ret == -1) {
+ gf_log (this->name, GF_LOG_WARNING, "remote operation failed: %s",
+ strerror (gf_error_to_errno (rsp.op_errno)));
+ }
+ CLIENT_STACK_UNWIND (fsetattr, frame, rsp.op_ret,
+ gf_error_to_errno (rsp.op_errno), &prestat,
+ &poststat, xdata);
+
+ free (rsp.xdata.xdata_val);
+
+ if (xdata)
+ dict_unref (xdata);
+
+ return 0;
+}
+
+int
+client3_3_fallocate_cbk (struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ call_frame_t *frame = NULL;
+ gfs3_fallocate_rsp rsp = {0,};
+ struct iatt prestat = {0,};
+ struct iatt poststat = {0,};
+ int ret = 0;
+ xlator_t *this = NULL;
+ dict_t *xdata = NULL;
+
+
+ this = THIS;
+
+ frame = myframe;
+
+ if (-1 == req->rpc_status) {
+ rsp.op_ret = -1;
+ rsp.op_errno = ENOTCONN;
+ goto out;
+ }
+ ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gfs3_fallocate_rsp);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "XDR decoding failed");
+ rsp.op_ret = -1;
+ rsp.op_errno = EINVAL;
+ goto out;
+ }
+
+ if (-1 != rsp.op_ret) {
+ gf_stat_to_iatt (&rsp.statpre, &prestat);
+ gf_stat_to_iatt (&rsp.statpost, &poststat);
+ }
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (this, xdata, (rsp.xdata.xdata_val),
+ (rsp.xdata.xdata_len), ret,
+ rsp.op_errno, out);
+
+out:
+ if (rsp.op_ret == -1) {
+ gf_log (this->name, GF_LOG_WARNING, "remote operation failed: %s",
+ strerror (gf_error_to_errno (rsp.op_errno)));
+ }
+ CLIENT_STACK_UNWIND (fallocate, frame, rsp.op_ret,
+ gf_error_to_errno (rsp.op_errno), &prestat,
+ &poststat, xdata);
+
+ free (rsp.xdata.xdata_val);
+
+ if (xdata)
+ dict_unref (xdata);
+
+ return 0;
+}
+
+int
+client3_3_discard_cbk(struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ call_frame_t *frame = NULL;
+ gfs3_discard_rsp rsp = {0,};
+ struct iatt prestat = {0,};
+ struct iatt poststat = {0,};
+ int ret = 0;
+ xlator_t *this = NULL;
+ dict_t *xdata = NULL;
+
+ this = THIS;
+
+ frame = myframe;
+
+ if (-1 == req->rpc_status) {
+ rsp.op_ret = -1;
+ rsp.op_errno = ENOTCONN;
+ goto out;
+ }
+ ret = xdr_to_generic(*iov, &rsp, (xdrproc_t) xdr_gfs3_discard_rsp);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "XDR decoding failed");
+ rsp.op_ret = -1;
+ rsp.op_errno = EINVAL;
+ goto out;
+ }
+
+ if (-1 != rsp.op_ret) {
+ gf_stat_to_iatt (&rsp.statpre, &prestat);
+ gf_stat_to_iatt (&rsp.statpost, &poststat);
+ }
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (this, xdata, (rsp.xdata.xdata_val),
+ (rsp.xdata.xdata_len), ret,
+ rsp.op_errno, out);
+
+out:
+ if (rsp.op_ret == -1) {
+ gf_log (this->name, GF_LOG_WARNING, "remote operation failed: %s",
+ strerror (gf_error_to_errno (rsp.op_errno)));
+ }
+ CLIENT_STACK_UNWIND (discard, frame, rsp.op_ret,
+ gf_error_to_errno (rsp.op_errno), &prestat,
+ &poststat, xdata);
+
+ free (rsp.xdata.xdata_val);
+
+ if (xdata)
+ dict_unref (xdata);
+
+ return 0;
+}
+
+int
+client3_3_zerofill_cbk(struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ call_frame_t *frame = NULL;
+ gfs3_zerofill_rsp rsp = {0,};
+ struct iatt prestat = {0,};
+ struct iatt poststat = {0,};
+ int ret = 0;
+ xlator_t *this = NULL;
+ dict_t *xdata = NULL;
+
+ this = THIS;
+
+ frame = myframe;
+
+ if (-1 == req->rpc_status) {
+ rsp.op_ret = -1;
+ rsp.op_errno = ENOTCONN;
+ goto out;
+ }
+ ret = xdr_to_generic(*iov, &rsp, (xdrproc_t) xdr_gfs3_zerofill_rsp);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "XDR decoding failed");
+ rsp.op_ret = -1;
+ rsp.op_errno = EINVAL;
+ goto out;
+ }
+
+ if (-1 != rsp.op_ret) {
+ gf_stat_to_iatt (&rsp.statpre, &prestat);
+ gf_stat_to_iatt (&rsp.statpost, &poststat);
+ }
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (this, xdata, (rsp.xdata.xdata_val),
+ (rsp.xdata.xdata_len), ret,
+ rsp.op_errno, out);
+
+out:
+ if (rsp.op_ret == -1) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "remote operation failed: %s",
+ strerror (gf_error_to_errno (rsp.op_errno)));
+ }
+ CLIENT_STACK_UNWIND (zerofill, frame, rsp.op_ret,
+ gf_error_to_errno (rsp.op_errno), &prestat,
+ &poststat, xdata);
+
+ free (rsp.xdata.xdata_val);
+
+ if (xdata)
+ dict_unref (xdata);
+
+ return 0;
+}
+
+int
+client3_3_setattr_cbk (struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ call_frame_t *frame = NULL;
+ gfs3_setattr_rsp rsp = {0,};
+ struct iatt prestat = {0,};
+ struct iatt poststat = {0,};
+ int ret = 0;
+ xlator_t *this = NULL;
+ dict_t *xdata = NULL;
+
+
+ this = THIS;
+
+ frame = myframe;
+
+ if (-1 == req->rpc_status) {
+ rsp.op_ret = -1;
+ rsp.op_errno = ENOTCONN;
+ goto out;
+ }
+
+ ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gfs3_setattr_rsp);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "XDR decoding failed");
+ rsp.op_ret = -1;
+ rsp.op_errno = EINVAL;
+ goto out;
+ }
+
+ if (-1 != rsp.op_ret) {
+ gf_stat_to_iatt (&rsp.statpre, &prestat);
+ gf_stat_to_iatt (&rsp.statpost, &poststat);
+ }
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (this, xdata, (rsp.xdata.xdata_val),
+ (rsp.xdata.xdata_len), ret,
+ rsp.op_errno, out);
+
+out:
+ if (rsp.op_ret == -1) {
+ gf_log (this->name, GF_LOG_WARNING, "remote operation failed: %s",
+ strerror (gf_error_to_errno (rsp.op_errno)));
+ }
+ CLIENT_STACK_UNWIND (setattr, frame, rsp.op_ret,
+ gf_error_to_errno (rsp.op_errno), &prestat,
+ &poststat, xdata);
+
+ free (rsp.xdata.xdata_val);
+
+ if (xdata)
+ dict_unref (xdata);
+
+ return 0;
+}
+
+int
+client3_3_create_cbk (struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ call_frame_t *frame = NULL;
+ fd_t *fd = NULL;
+ inode_t *inode = NULL;
+ struct iatt stbuf = {0, };
+ struct iatt preparent = {0, };
+ struct iatt postparent = {0, };
+ int32_t ret = -1;
+ clnt_local_t *local = NULL;
+ gfs3_create_rsp rsp = {0,};
+ xlator_t *this = NULL;
+ dict_t *xdata = NULL;
+
+ this = THIS;
+
+ frame = myframe;
+ local = frame->local;
+ fd = local->fd;
+ inode = local->loc.inode;
+
+ if (-1 == req->rpc_status) {
+ rsp.op_ret = -1;
+ rsp.op_errno = ENOTCONN;
+ goto out;
+ }
+
+ ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gfs3_create_rsp);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "XDR decoding failed");
+ rsp.op_ret = -1;
+ rsp.op_errno = EINVAL;
+ goto out;
+ }
+
+ if (-1 != rsp.op_ret) {
+ gf_stat_to_iatt (&rsp.stat, &stbuf);
+
+ gf_stat_to_iatt (&rsp.preparent, &preparent);
+ gf_stat_to_iatt (&rsp.postparent, &postparent);
+ uuid_copy (local->loc.gfid, stbuf.ia_gfid);
+ ret = client_add_fd_to_saved_fds (frame->this, fd, &local->loc,
+ local->flags, rsp.fd, 0);
+ if (ret) {
+ rsp.op_ret = -1;
+ rsp.op_errno = -ret;
+ goto out;
+ }
+ }
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (this, xdata, (rsp.xdata.xdata_val),
+ (rsp.xdata.xdata_len), ret,
+ rsp.op_errno, out);
+
+out:
+ if (rsp.op_ret == -1) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "remote operation failed: %s. Path: %s",
+ strerror (gf_error_to_errno (rsp.op_errno)),
+ local->loc.path);
+ }
+
+ CLIENT_STACK_UNWIND (create, frame, rsp.op_ret,
+ gf_error_to_errno (rsp.op_errno), fd, inode,
+ &stbuf, &preparent, &postparent, xdata);
+
+ free (rsp.xdata.xdata_val);
+
+ if (xdata)
+ dict_unref (xdata);
+
+ return 0;
+}
+
+
+int
+client3_3_rchecksum_cbk (struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ call_frame_t *frame = NULL;
+ gfs3_rchecksum_rsp rsp = {0,};
+ int ret = 0;
+ xlator_t *this = NULL;
+ dict_t *xdata = NULL;
+
+
+ this = THIS;
+
+ frame = myframe;
+
+ if (-1 == req->rpc_status) {
+ rsp.op_ret = -1;
+ rsp.op_errno = ENOTCONN;
+ goto out;
+ }
+
+ ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gfs3_rchecksum_rsp);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "XDR decoding failed");
+ rsp.op_ret = -1;
+ rsp.op_errno = EINVAL;
+ goto out;
+ }
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (this, xdata, (rsp.xdata.xdata_val),
+ (rsp.xdata.xdata_len), ret,
+ rsp.op_errno, out);
+
+out:
+ if (rsp.op_ret == -1) {
+ gf_log (this->name, GF_LOG_WARNING, "remote operation failed: %s",
+ strerror (gf_error_to_errno (rsp.op_errno)));
+ }
+ CLIENT_STACK_UNWIND (rchecksum, frame, rsp.op_ret,
+ gf_error_to_errno (rsp.op_errno),
+ rsp.weak_checksum,
+ (uint8_t *)rsp.strong_checksum.strong_checksum_val,
+ xdata);
+
+ if (rsp.strong_checksum.strong_checksum_val) {
+ /* This is allocated by the libc while decoding RPC msg */
+ /* Hence no 'GF_FREE', but just 'free' */
+ free (rsp.strong_checksum.strong_checksum_val);
+ }
+
+ free (rsp.xdata.xdata_val);
+
+ if (xdata)
+ dict_unref (xdata);
+
+ return 0;
+}
+
+int
+client3_3_lk_cbk (struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ call_frame_t *frame = NULL;
+ clnt_local_t *local = NULL;
+ struct gf_flock lock = {0,};
+ gfs3_lk_rsp rsp = {0,};
+ int ret = 0;
+ xlator_t *this = NULL;
+ dict_t *xdata = NULL;
+
+ this = THIS;
+
+ frame = myframe;
+ local = frame->local;
+
+ if (-1 == req->rpc_status) {
+ rsp.op_ret = -1;
+ rsp.op_errno = ENOTCONN;
+ goto out;
+ }
+
+ ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gfs3_lk_rsp);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "XDR decoding failed");
+ rsp.op_ret = -1;
+ rsp.op_errno = EINVAL;
+ goto out;
+ }
+
+ if (rsp.op_ret >= 0) {
+ gf_proto_flock_to_flock (&rsp.flock, &lock);
+ }
+
+ /* Save the lock to the client lock cache to be able
+ to recover in the case of server reboot.*/
+ /*
+ temporarily
+ if (local->cmd == F_SETLK || local->cmd == F_SETLKW) {
+ ret = client_add_lock_for_recovery (local->fd, &lock,
+ local->owner, local->cmd);
+ if (ret < 0) {
+ rsp.op_ret = -1;
+ rsp.op_errno = -ret;
+ }
+ }
+ */
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (this, xdata, (rsp.xdata.xdata_val),
+ (rsp.xdata.xdata_len), ret,
+ rsp.op_errno, out);
+
+out:
+ if ((rsp.op_ret == -1) &&
+ (EAGAIN != gf_error_to_errno (rsp.op_errno))) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "remote operation failed: %s",
+ strerror (gf_error_to_errno (rsp.op_errno)));
+ }
+
+ CLIENT_STACK_UNWIND (lk, frame, rsp.op_ret,
+ gf_error_to_errno (rsp.op_errno), &lock, xdata);
+
+ free (rsp.xdata.xdata_val);
+
+ free (rsp.flock.lk_owner.lk_owner_val);
+
+ if (xdata)
+ dict_unref (xdata);
+
+ return 0;
+}
+
+int
+client3_3_readdir_cbk (struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ call_frame_t *frame = NULL;
+ gfs3_readdir_rsp rsp = {0,};
+ int32_t ret = 0;
+ clnt_local_t *local = NULL;
+ gf_dirent_t entries;
+ xlator_t *this = NULL;
+ dict_t *xdata = NULL;
+
+ this = THIS;
+
+ frame = myframe;
+ local = frame->local;
+
+ if (-1 == req->rpc_status) {
+ rsp.op_ret = -1;
+ rsp.op_errno = ENOTCONN;
+ goto out;
+ }
+
+ ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gfs3_readdir_rsp);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "XDR decoding failed");
+ rsp.op_ret = -1;
+ rsp.op_errno = EINVAL;
+ goto out;
+ }
+
+ INIT_LIST_HEAD (&entries.list);
+ if (rsp.op_ret > 0) {
+ unserialize_rsp_dirent (&rsp, &entries);
+ }
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (frame->this, xdata,
+ (rsp.xdata.xdata_val),
+ (rsp.xdata.xdata_len), rsp.op_ret,
+ rsp.op_errno, out);
+
+out:
+ if (rsp.op_ret == -1) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "remote operation failed: %s remote_fd = %d",
+ strerror (gf_error_to_errno (rsp.op_errno)),
+ local->cmd);
+ }
+ CLIENT_STACK_UNWIND (readdir, frame, rsp.op_ret,
+ gf_error_to_errno (rsp.op_errno), &entries, xdata);
+
+ if (rsp.op_ret != -1) {
+ gf_dirent_free (&entries);
+ }
+
+ free (rsp.xdata.xdata_val);
+
+ if (xdata)
+ dict_unref (xdata);
+
+ clnt_readdir_rsp_cleanup (&rsp);
+
+ return 0;
+}
+
+
+int
+client3_3_readdirp_cbk (struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ call_frame_t *frame = NULL;
+ gfs3_readdirp_rsp rsp = {0,};
+ int32_t ret = 0;
+ clnt_local_t *local = NULL;
+ gf_dirent_t entries;
+ xlator_t *this = NULL;
+ dict_t *xdata = NULL;
+
+ this = THIS;
+
+ frame = myframe;
+ local = frame->local;
+
+ if (-1 == req->rpc_status) {
+ rsp.op_ret = -1;
+ rsp.op_errno = ENOTCONN;
+ goto out;
+ }
+
+ ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gfs3_readdirp_rsp);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "XDR decoding failed");
+ rsp.op_ret = -1;
+ rsp.op_errno = EINVAL;
+ goto out;
+ }
+
+ INIT_LIST_HEAD (&entries.list);
+ if (rsp.op_ret > 0) {
+ unserialize_rsp_direntp (this, local->fd, &rsp, &entries);
+ }
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (this, xdata, (rsp.xdata.xdata_val),
+ (rsp.xdata.xdata_len), ret,
+ rsp.op_errno, out);
+
+out:
+ if (rsp.op_ret == -1) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "remote operation failed: %s",
+ strerror (gf_error_to_errno (rsp.op_errno)));
+ }
+ CLIENT_STACK_UNWIND (readdirp, frame, rsp.op_ret,
+ gf_error_to_errno (rsp.op_errno), &entries, xdata);
+
+ if (rsp.op_ret != -1) {
+ gf_dirent_free (&entries);
+ }
+ free (rsp.xdata.xdata_val);
+
+ if (xdata)
+ dict_unref (xdata);
+
+ clnt_readdirp_rsp_cleanup (&rsp);
+
+ return 0;
+}
+
+
+int
+client3_3_rename_cbk (struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ call_frame_t *frame = NULL;
+ gfs3_rename_rsp rsp = {0,};
+ struct iatt stbuf = {0,};
+ struct iatt preoldparent = {0,};
+ struct iatt postoldparent = {0,};
+ struct iatt prenewparent = {0,};
+ struct iatt postnewparent = {0,};
+ int ret = 0;
+ xlator_t *this = NULL;
+ dict_t *xdata = NULL;
+
+ this = THIS;
+
+ frame = myframe;
+
+ if (-1 == req->rpc_status) {
+ rsp.op_ret = -1;
+ rsp.op_errno = ENOTCONN;
+ goto out;
+ }
+
+ ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gfs3_rename_rsp);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "XDR decoding failed");
+ rsp.op_ret = -1;
+ rsp.op_errno = EINVAL;
+ goto out;
+ }
+
+ if (-1 != rsp.op_ret) {
+ gf_stat_to_iatt (&rsp.stat, &stbuf);
+
+ gf_stat_to_iatt (&rsp.preoldparent, &preoldparent);
+ gf_stat_to_iatt (&rsp.postoldparent, &postoldparent);
+
+ gf_stat_to_iatt (&rsp.prenewparent, &prenewparent);
+ gf_stat_to_iatt (&rsp.postnewparent, &postnewparent);
+ }
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (this, xdata, (rsp.xdata.xdata_val),
+ (rsp.xdata.xdata_len), ret,
+ rsp.op_errno, out);
+
+out:
+ if (rsp.op_ret == -1) {
+ gf_log (this->name, GF_LOG_WARNING, "remote operation failed: %s",
+ strerror (gf_error_to_errno (rsp.op_errno)));
+ }
+ CLIENT_STACK_UNWIND (rename, frame, rsp.op_ret,
+ gf_error_to_errno (rsp.op_errno),
+ &stbuf, &preoldparent, &postoldparent,
+ &prenewparent, &postnewparent, xdata);
+
+ free (rsp.xdata.xdata_val);
+
+ if (xdata)
+ dict_unref (xdata);
+
+ return 0;
+}
+
+int
+client3_3_link_cbk (struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ call_frame_t *frame = NULL;
+ gfs3_link_rsp rsp = {0,};
+ struct iatt stbuf = {0,};
+ struct iatt preparent = {0,};
+ struct iatt postparent = {0,};
+ int ret = 0;
+ clnt_local_t *local = NULL;
+ inode_t *inode = NULL;
+ xlator_t *this = NULL;
+ dict_t *xdata = NULL;
+
+
+ this = THIS;
+
+ frame = myframe;
+
+ local = frame->local;
+ inode = local->loc.inode;
+
+ if (-1 == req->rpc_status) {
+ rsp.op_ret = -1;
+ rsp.op_errno = ENOTCONN;
+ goto out;
+ }
+
+ ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gfs3_link_rsp);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "XDR decoding failed");
+ rsp.op_ret = -1;
+ rsp.op_errno = EINVAL;
+ goto out;
+ }
+
+ if (-1 != rsp.op_ret) {
+ gf_stat_to_iatt (&rsp.stat, &stbuf);
+
+ gf_stat_to_iatt (&rsp.preparent, &preparent);
+ gf_stat_to_iatt (&rsp.postparent, &postparent);
+ }
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (this, xdata, (rsp.xdata.xdata_val),
+ (rsp.xdata.xdata_len), ret,
+ rsp.op_errno, out);
+
+out:
+ if (rsp.op_ret == -1) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "remote operation failed: %s (%s -> %s)",
+ strerror (gf_error_to_errno (rsp.op_errno)),
+ local->loc.path, local->loc2.path);
+ }
+
+ CLIENT_STACK_UNWIND (link, frame, rsp.op_ret,
+ gf_error_to_errno (rsp.op_errno), inode,
+ &stbuf, &preparent, &postparent, xdata);
+
+ free (rsp.xdata.xdata_val);
+
+ if (xdata)
+ dict_unref (xdata);
+
+ return 0;
+}
+
+
+int
+client3_3_opendir_cbk (struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ clnt_local_t *local = NULL;
+ clnt_conf_t *conf = NULL;
+ call_frame_t *frame = NULL;
+ fd_t *fd = NULL;
+ int ret = 0;
+ gfs3_opendir_rsp rsp = {0,};
+ xlator_t *this = NULL;
+ dict_t *xdata = NULL;
+
+ this = THIS;
+
+ frame = myframe;
+ local = frame->local;
+
+ conf = frame->this->private;
+ fd = local->fd;
+
+ if (-1 == req->rpc_status) {
+ rsp.op_ret = -1;
+ rsp.op_errno = ENOTCONN;
+ goto out;
+ }
+
+ ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gfs3_opendir_rsp);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "XDR decoding failed");
+ rsp.op_ret = -1;
+ rsp.op_errno = EINVAL;
+ goto out;
+ }
+
+ if (-1 != rsp.op_ret) {
+ ret = client_add_fd_to_saved_fds (frame->this, fd, &local->loc,
+ 0, rsp.fd, 1);
+ if (ret) {
+ rsp.op_ret = -1;
+ rsp.op_errno = -ret;
+ goto out;
+ }
+ }
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (this, xdata, (rsp.xdata.xdata_val),
+ (rsp.xdata.xdata_len), ret,
+ rsp.op_errno, out);
+
+out:
+ if (rsp.op_ret == -1) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "remote operation failed: %s. Path: %s (%s)",
+ strerror (gf_error_to_errno (rsp.op_errno)),
+ local->loc.path, loc_gfid_utoa (&local->loc));
+ }
+ CLIENT_STACK_UNWIND (opendir, frame, rsp.op_ret,
+ gf_error_to_errno (rsp.op_errno), fd, xdata);
+
+ free (rsp.xdata.xdata_val);
+
+ if (xdata)
+ dict_unref (xdata);
+
+ return 0;
+}
+
+
+int
+client3_3_lookup_cbk (struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ clnt_local_t *local = NULL;
+ call_frame_t *frame = NULL;
+ int ret = 0;
+ gfs3_lookup_rsp rsp = {0,};
+ struct iatt stbuf = {0,};
+ struct iatt postparent = {0,};
+ int op_errno = EINVAL;
+ dict_t *xdata = NULL;
+ inode_t *inode = NULL;
+ xlator_t *this = NULL;
+
+ this = THIS;
+
+ frame = myframe;
+ local = frame->local;
+ inode = local->loc.inode;
+
+ if (-1 == req->rpc_status) {
+ rsp.op_ret = -1;
+ op_errno = ENOTCONN;
+ goto out;
+ }
+
+ ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gfs3_lookup_rsp);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "XDR decoding failed");
+ rsp.op_ret = -1;
+ op_errno = EINVAL;
+ goto out;
+ }
+
+ op_errno = gf_error_to_errno (rsp.op_errno);
+ gf_stat_to_iatt (&rsp.postparent, &postparent);
+
+ if (rsp.op_ret == -1)
+ goto out;
+
+ rsp.op_ret = -1;
+ gf_stat_to_iatt (&rsp.stat, &stbuf);
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (frame->this, xdata, (rsp.xdata.xdata_val),
+ (rsp.xdata.xdata_len), rsp.op_ret,
+ op_errno, out);
+
+ if ((!uuid_is_null (inode->gfid))
+ && (uuid_compare (stbuf.ia_gfid, inode->gfid) != 0)) {
+ gf_log (frame->this->name, GF_LOG_DEBUG,
+ "gfid changed for %s", local->loc.path);
+ rsp.op_ret = -1;
+ op_errno = ESTALE;
+ goto out;
+ }
+
+ rsp.op_ret = 0;
+
+out:
+ rsp.op_errno = op_errno;
+ if (rsp.op_ret == -1) {
+ /* any error other than ENOENT */
+ if (rsp.op_errno != ENOENT)
+ gf_log (this->name, GF_LOG_WARNING,
+ "remote operation failed: %s. Path: %s (%s)",
+ strerror (rsp.op_errno), local->loc.path,
+ loc_gfid_utoa (&local->loc));
+ else
+ gf_log (this->name, GF_LOG_TRACE, "not found on remote node");
+
+ }
+
+ CLIENT_STACK_UNWIND (lookup, frame, rsp.op_ret, rsp.op_errno, inode,
+ &stbuf, xdata, &postparent);
+
+ if (xdata)
+ dict_unref (xdata);
+
+ free (rsp.xdata.xdata_val);
+
+ return 0;
+}
+
+int
+client3_3_readv_cbk (struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ call_frame_t *frame = NULL;
+ struct iobref *iobref = NULL;
+ struct iovec vector[MAX_IOVEC] = {{0}, };
+ struct iatt stat = {0,};
+ gfs3_read_rsp rsp = {0,};
+ int ret = 0, rspcount = 0;
+ clnt_local_t *local = NULL;
+ xlator_t *this = NULL;
+ dict_t *xdata = NULL;
+
+ this = THIS;
+
+ memset (vector, 0, sizeof (vector));
+
+ frame = myframe;
+ local = frame->local;
+
+ if (-1 == req->rpc_status) {
+ rsp.op_ret = -1;
+ rsp.op_errno = ENOTCONN;
+ goto out;
+ }
+
+ ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gfs3_read_rsp);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "XDR decoding failed");
+ rsp.op_ret = -1;
+ rsp.op_errno = EINVAL;
+ goto out;
+ }
+
+ if (rsp.op_ret != -1) {
+ iobref = req->rsp_iobref;
+ gf_stat_to_iatt (&rsp.stat, &stat);
+
+ vector[0].iov_len = rsp.op_ret;
+ if (rsp.op_ret > 0)
+ vector[0].iov_base = req->rsp[1].iov_base;
+ rspcount = 1;
+ }
+ GF_PROTOCOL_DICT_UNSERIALIZE (this, xdata, (rsp.xdata.xdata_val),
+ (rsp.xdata.xdata_len), ret,
+ rsp.op_errno, out);
+
+#ifdef GF_TESTING_IO_XDATA
+ dict_dump (xdata);
+#endif
+
+out:
+ if (rsp.op_ret == -1) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "remote operation failed: %s",
+ strerror (gf_error_to_errno (rsp.op_errno)));
+ } else if (rsp.op_ret >= 0) {
+ if (local->attempt_reopen)
+ client_attempt_reopen (local->fd, this);
+ }
+ CLIENT_STACK_UNWIND (readv, frame, rsp.op_ret,
+ gf_error_to_errno (rsp.op_errno), vector, rspcount,
+ &stat, iobref, xdata);
+
+ free (rsp.xdata.xdata_val);
+
+ if (xdata)
+ dict_unref (xdata);
+
+ return 0;
+}
+
+int
+client3_3_release_cbk (struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ call_frame_t *frame = NULL;
+
+ frame = myframe;
+ STACK_DESTROY (frame->root);
+ return 0;
+}
+int
+client3_3_releasedir_cbk (struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ call_frame_t *frame = NULL;
+
+ frame = myframe;
+ STACK_DESTROY (frame->root);
+ return 0;
+}
+
+int
+client_fdctx_destroy (xlator_t *this, clnt_fd_ctx_t *fdctx)
+{
+ clnt_conf_t *conf = NULL;
+ call_frame_t *fr = NULL;
+ int32_t ret = -1;
+ char parent_down = 0;
+ fd_lk_ctx_t *lk_ctx = NULL;
+
+ GF_VALIDATE_OR_GOTO ("client", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, fdctx, out);
+
+ conf = (clnt_conf_t *) this->private;
+
+ if (fdctx->remote_fd == -1) {
+ gf_log (this->name, GF_LOG_DEBUG, "not a valid fd");
+ goto out;
+ }
+
+ pthread_mutex_lock (&conf->lock);
+ {
+ parent_down = conf->parent_down;
+ lk_ctx = fdctx->lk_ctx;
+ fdctx->lk_ctx = NULL;
+ }
+ pthread_mutex_unlock (&conf->lock);
+
+ if (lk_ctx)
+ fd_lk_ctx_unref (lk_ctx);
+
+ if (!parent_down)
+ rpc_clnt_ref (conf->rpc);
+ else
+ goto out;
+
+ fr = create_frame (this, this->ctx->pool);
+ if (fr == NULL) {
+ goto out;
+ }
+
+ ret = 0;
+
+ if (fdctx->is_dir) {
+ gfs3_releasedir_req req = {{0,},};
+ req.fd = fdctx->remote_fd;
+ gf_log (this->name, GF_LOG_TRACE, "sending releasedir on fd");
+ client_submit_request (this, &req, fr, &clnt3_3_fop_prog,
+ GFS3_OP_RELEASEDIR,
+ client3_3_releasedir_cbk,
+ NULL, NULL, 0, NULL, 0, NULL,
+ (xdrproc_t)xdr_gfs3_releasedir_req);
+ } else {
+ gfs3_release_req req = {{0,},};
+ req.fd = fdctx->remote_fd;
+ gf_log (this->name, GF_LOG_TRACE, "sending release on fd");
+ client_submit_request (this, &req, fr, &clnt3_3_fop_prog,
+ GFS3_OP_RELEASE,
+ client3_3_release_cbk, NULL,
+ NULL, 0, NULL, 0, NULL,
+ (xdrproc_t)xdr_gfs3_release_req);
+ }
+
+ rpc_clnt_unref (conf->rpc);
+out:
+ if (fdctx) {
+ fdctx->remote_fd = -1;
+ GF_FREE (fdctx);
+ }
+
+ if (ret && fr)
+ STACK_DESTROY (fr->root);
+
+ return ret;
+}
+
+int32_t
+client3_3_releasedir (call_frame_t *frame, xlator_t *this,
+ void *data)
+{
+ clnt_conf_t *conf = NULL;
+ clnt_fd_ctx_t *fdctx = NULL;
+ clnt_args_t *args = NULL;
+ int64_t remote_fd = -1;
+
+ if (!this || !data)
+ goto out;
+
+ args = data;
+ conf = this->private;
+
+ pthread_mutex_lock (&conf->lock);
+ {
+ fdctx = this_fd_del_ctx (args->fd, this);
+ if (fdctx != NULL) {
+ remote_fd = fdctx->remote_fd;
+
+ /* fdctx->remote_fd == -1 indicates a reopen attempt
+ in progress. Just mark ->released = 1 and let
+ reopen_cbk handle releasing
+ */
+
+ if (remote_fd != -1)
+ list_del_init (&fdctx->sfd_pos);
+
+ fdctx->released = 1;
+ }
+ }
+ pthread_mutex_unlock (&conf->lock);
+
+ if (remote_fd != -1)
+ client_fdctx_destroy (this, fdctx);
+out:
+
+ return 0;
+}
+
+int32_t
+client3_3_release (call_frame_t *frame, xlator_t *this,
+ void *data)
+{
+ int64_t remote_fd = -1;
+ clnt_conf_t *conf = NULL;
+ clnt_fd_ctx_t *fdctx = NULL;
+ clnt_args_t *args = NULL;
+ lk_heal_state_t lk_heal_state = GF_LK_HEAL_DONE;
+
+ if (!this || !data)
+ goto out;
+
+ args = data;
+ conf = this->private;
+
+ pthread_mutex_lock (&conf->lock);
+ {
+ fdctx = this_fd_del_ctx (args->fd, this);
+ if (fdctx != NULL) {
+ remote_fd = fdctx->remote_fd;
+ lk_heal_state = fdctx->lk_heal_state;
+
+ /* fdctx->remote_fd == -1 indicates a reopen attempt
+ in progress. Just mark ->released = 1 and let
+ reopen_cbk handle releasing
+ */
+
+ if (remote_fd != -1 &&
+ lk_heal_state == GF_LK_HEAL_DONE)
+ list_del_init (&fdctx->sfd_pos);
+
+ fdctx->released = 1;
+ }
+ }
+ pthread_mutex_unlock (&conf->lock);
+
+ if (remote_fd != -1 && lk_heal_state == GF_LK_HEAL_DONE)
+ client_fdctx_destroy (this, fdctx);
+out:
+ return 0;
+}
+
+
+int32_t
+client3_3_lookup (call_frame_t *frame, xlator_t *this,
+ void *data)
+{
+ clnt_conf_t *conf = NULL;
+ clnt_local_t *local = NULL;
+ clnt_args_t *args = NULL;
+ gfs3_lookup_req req = {{0,},};
+ int ret = 0;
+ int op_errno = ESTALE;
+ data_t *content = NULL;
+ struct iovec vector[MAX_IOVEC] = {{0}, };
+ int count = 0;
+ struct iobref *rsp_iobref = NULL;
+ struct iobuf *rsp_iobuf = NULL;
+ struct iovec *rsphdr = NULL;
+
+ if (!frame || !this || !data)
+ goto unwind;
+
+ memset (vector, 0, sizeof (vector));
+
+ conf = this->private;
+ args = data;
+ local = mem_get0 (this->local_pool);
+ if (!local) {
+ op_errno = ENOMEM;
+ goto unwind;
+ }
+
+ if (!(args->loc && args->loc->inode))
+ goto unwind;
+
+ loc_copy (&local->loc, args->loc);
+ loc_path (&local->loc, NULL);
+ frame->local = local;
+
+ if (args->loc->parent) {
+ if (!uuid_is_null (args->loc->parent->gfid))
+ memcpy (req.pargfid, args->loc->parent->gfid, 16);
+ else
+ memcpy (req.pargfid, args->loc->pargfid, 16);
+ } else {
+ if (!uuid_is_null (args->loc->inode->gfid))
+ memcpy (req.gfid, args->loc->inode->gfid, 16);
+ else
+ memcpy (req.gfid, args->loc->gfid, 16);
+ }
+
+ if (args->xdata) {
+ content = dict_get (args->xdata, GF_CONTENT_KEY);
+ if (content != NULL) {
+ rsp_iobref = iobref_new ();
+ if (rsp_iobref == NULL) {
+ goto unwind;
+ }
+
+ /* TODO: what is the size we should send ? */
+ /* This change very much depends on quick-read
+ changes */
+ rsp_iobuf = iobuf_get (this->ctx->iobuf_pool);
+ if (rsp_iobuf == NULL) {
+ goto unwind;
+ }
+
+ iobref_add (rsp_iobref, rsp_iobuf);
+ iobuf_unref (rsp_iobuf);
+ rsphdr = &vector[0];
+ rsphdr->iov_base = iobuf_ptr (rsp_iobuf);
+ rsphdr->iov_len = iobuf_pagesize (rsp_iobuf);
+ count = 1;
+ local->iobref = rsp_iobref;
+ rsp_iobuf = NULL;
+ rsp_iobref = NULL;
+ }
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, args->xdata,
+ (&req.xdata.xdata_val),
+ req.xdata.xdata_len,
+ op_errno, unwind);
+ }
+
+ if (args->loc->name)
+ req.bname = (char *)args->loc->name;
+ else
+ req.bname = "";
+
+ ret = client_submit_request (this, &req, frame, conf->fops,
+ GFS3_OP_LOOKUP, client3_3_lookup_cbk,
+ NULL, rsphdr, count,
+ NULL, 0, local->iobref,
+ (xdrproc_t)xdr_gfs3_lookup_req);
+
+ if (ret) {
+ gf_log (this->name, GF_LOG_WARNING, "failed to send the fop");
+ }
+
+ GF_FREE (req.xdata.xdata_val);
+
+ if (rsp_iobref)
+ iobref_unref (rsp_iobref);
+
+ if (rsp_iobuf)
+ iobuf_unref (rsp_iobuf);
+
+ return 0;
+
+unwind:
+ CLIENT_STACK_UNWIND (lookup, frame, -1, op_errno, NULL, NULL, NULL,
+ NULL);
+
+ GF_FREE (req.xdata.xdata_val);
+
+ if (rsp_iobref)
+ iobref_unref (rsp_iobref);
+
+ if (rsp_iobuf)
+ iobuf_unref (rsp_iobuf);
+
+ return 0;
+}
+
+int32_t
+client3_3_stat (call_frame_t *frame, xlator_t *this,
+ void *data)
+{
+ clnt_conf_t *conf = NULL;
+ clnt_args_t *args = NULL;
+ gfs3_stat_req req = {{0,},};
+ int ret = 0;
+ int op_errno = ESTALE;
+
+ if (!frame || !this || !data)
+ goto unwind;
+
+ args = data;
+ if (!(args->loc && args->loc->inode))
+ goto unwind;
+
+ if (!uuid_is_null (args->loc->inode->gfid))
+ memcpy (req.gfid, args->loc->inode->gfid, 16);
+ else
+ memcpy (req.gfid, args->loc->gfid, 16);
+
+ GF_ASSERT_AND_GOTO_WITH_ERROR (this->name,
+ !uuid_is_null (*((uuid_t*)req.gfid)),
+ unwind, op_errno, EINVAL);
+ conf = this->private;
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, args->xdata, (&req.xdata.xdata_val),
+ req.xdata.xdata_len, op_errno, unwind);
+
+ ret = client_submit_request (this, &req, frame, conf->fops,
+ GFS3_OP_STAT, client3_3_stat_cbk, NULL,
+ NULL, 0, NULL, 0, NULL,
+ (xdrproc_t)xdr_gfs3_stat_req);
+ if (ret) {
+ gf_log (this->name, GF_LOG_WARNING, "failed to send the fop");
+ }
+
+ GF_FREE (req.xdata.xdata_val);
+
+ return 0;
+unwind:
+ CLIENT_STACK_UNWIND (stat, frame, -1, op_errno, NULL, NULL);
+
+ GF_FREE (req.xdata.xdata_val);
+
+ return 0;
+}
+
+
+int32_t
+client3_3_truncate (call_frame_t *frame, xlator_t *this,
+ void *data)
+{
+ clnt_conf_t *conf = NULL;
+ clnt_args_t *args = NULL;
+ gfs3_truncate_req req = {{0,},};
+ int ret = 0;
+ int op_errno = ESTALE;
+
+ if (!frame || !this || !data)
+ goto unwind;
+
+ args = data;
+
+ if (!(args->loc && args->loc->inode))
+ goto unwind;
+
+ if (!uuid_is_null (args->loc->inode->gfid))
+ memcpy (req.gfid, args->loc->inode->gfid, 16);
+ else
+ memcpy (req.gfid, args->loc->gfid, 16);
+
+ GF_ASSERT_AND_GOTO_WITH_ERROR (this->name,
+ !uuid_is_null (*((uuid_t*)req.gfid)),
+ unwind, op_errno, EINVAL);
+ req.offset = args->offset;
+
+ conf = this->private;
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, args->xdata, (&req.xdata.xdata_val),
+ req.xdata.xdata_len, op_errno, unwind);
+
+ ret = client_submit_request (this, &req, frame, conf->fops,
+ GFS3_OP_TRUNCATE,
+ client3_3_truncate_cbk, NULL,
+ NULL, 0, NULL, 0,
+ NULL, (xdrproc_t)xdr_gfs3_truncate_req);
+ if (ret) {
+ gf_log (this->name, GF_LOG_WARNING, "failed to send the fop");
+ }
+
+ GF_FREE (req.xdata.xdata_val);
+
+ return 0;
+unwind:
+ CLIENT_STACK_UNWIND (truncate, frame, -1, op_errno, NULL, NULL, NULL);
+ GF_FREE (req.xdata.xdata_val);
+
+ return 0;
+}
+
+
+int32_t
+client3_3_ftruncate (call_frame_t *frame, xlator_t *this,
+ void *data)
+{
+ clnt_args_t *args = NULL;
+ int64_t remote_fd = -1;
+ clnt_conf_t *conf = NULL;
+ gfs3_ftruncate_req req = {{0,},};
+ int op_errno = EINVAL;
+ int ret = 0;
+
+ if (!frame || !this || !data)
+ goto unwind;
+
+ args = data;
+
+ conf = this->private;
+
+ CLIENT_GET_REMOTE_FD (this, args->fd, DEFAULT_REMOTE_FD,
+ remote_fd, op_errno, unwind);
+
+ req.offset = args->offset;
+ req.fd = remote_fd;
+ memcpy (req.gfid, args->fd->inode->gfid, 16);
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, args->xdata, (&req.xdata.xdata_val),
+ req.xdata.xdata_len, op_errno, unwind);
+
+ ret = client_submit_request (this, &req, frame, conf->fops,
+ GFS3_OP_FTRUNCATE,
+ client3_3_ftruncate_cbk, NULL,
+ NULL, 0, NULL, 0,
+ NULL, (xdrproc_t)xdr_gfs3_ftruncate_req);
+ if (ret) {
+ gf_log (this->name, GF_LOG_WARNING, "failed to send the fop");
+ }
+
+ GF_FREE (req.xdata.xdata_val);
+
+ return 0;
+unwind:
+ CLIENT_STACK_UNWIND (ftruncate, frame, -1, op_errno, NULL, NULL, NULL);
+ GF_FREE (req.xdata.xdata_val);
+
+ return 0;
+}
+
+
+
+int32_t
+client3_3_access (call_frame_t *frame, xlator_t *this,
+ void *data)
+{
+ clnt_conf_t *conf = NULL;
+ clnt_args_t *args = NULL;
+ gfs3_access_req req = {{0,},};
+ int ret = 0;
+ int op_errno = ESTALE;
+
+ if (!frame || !this || !data)
+ goto unwind;
+
+ args = data;
+
+ if (!(args->loc && args->loc->inode))
+ goto unwind;
+
+ if (!uuid_is_null (args->loc->inode->gfid))
+ memcpy (req.gfid, args->loc->inode->gfid, 16);
+ else
+ memcpy (req.gfid, args->loc->gfid, 16);
+
+ GF_ASSERT_AND_GOTO_WITH_ERROR (this->name,
+ !uuid_is_null (*((uuid_t*)req.gfid)),
+ unwind, op_errno, EINVAL);
+ req.mask = args->mask;
+
+ conf = this->private;
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, args->xdata, (&req.xdata.xdata_val),
+ req.xdata.xdata_len, op_errno, unwind);
+
+ ret = client_submit_request (this, &req, frame, conf->fops,
+ GFS3_OP_ACCESS,
+ client3_3_access_cbk, NULL,
+ NULL, 0, NULL, 0,
+ NULL, (xdrproc_t)xdr_gfs3_access_req);
+ if (ret) {
+ gf_log (this->name, GF_LOG_WARNING, "failed to send the fop");
+ }
+
+ GF_FREE (req.xdata.xdata_val);
+
+ return 0;
+unwind:
+ CLIENT_STACK_UNWIND (access, frame, -1, op_errno, NULL);
+ GF_FREE (req.xdata.xdata_val);
+
+ return 0;
+}
+
+int32_t
+client3_3_readlink (call_frame_t *frame, xlator_t *this,
+ void *data)
+{
+ clnt_conf_t *conf = NULL;
+ clnt_args_t *args = NULL;
+ gfs3_readlink_req req = {{0,},};
+ int ret = 0;
+ int op_errno = ESTALE;
+ clnt_local_t *local = NULL;
+ struct iobuf *rsp_iobuf = NULL;
+ struct iobref *rsp_iobref = NULL;
+ struct iovec *rsphdr = NULL;
+ int count = 0;
+ struct iovec vector[MAX_IOVEC] = {{0}, };
+
+ if (!frame || !this || !data)
+ goto unwind;
+
+ args = data;
+
+ if (!(args->loc && args->loc->inode))
+ goto unwind;
+
+ if (!uuid_is_null (args->loc->inode->gfid))
+ memcpy (req.gfid, args->loc->inode->gfid, 16);
+ else
+ memcpy (req.gfid, args->loc->gfid, 16);
+
+ GF_ASSERT_AND_GOTO_WITH_ERROR (this->name,
+ !uuid_is_null (*((uuid_t*)req.gfid)),
+ unwind, op_errno, EINVAL);
+ req.size = args->size;
+ conf = this->private;
+
+ local = mem_get0 (this->local_pool);
+ if (!local) {
+ op_errno = ENOMEM;
+ goto unwind;
+ }
+
+ frame->local = local;
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, args->xdata, (&req.xdata.xdata_val),
+ req.xdata.xdata_len, op_errno, unwind);
+
+ rsp_iobref = iobref_new ();
+ if (rsp_iobref == NULL) {
+ goto unwind;
+ }
+
+ rsp_iobuf = iobuf_get (this->ctx->iobuf_pool);
+ if (rsp_iobuf == NULL) {
+ goto unwind;
+ }
+
+ iobref_add (rsp_iobref, rsp_iobuf);
+ iobuf_unref (rsp_iobuf);
+ rsphdr = &vector[0];
+ rsphdr->iov_base = iobuf_ptr (rsp_iobuf);
+ rsphdr->iov_len = iobuf_pagesize (rsp_iobuf);
+ count = 1;
+ local->iobref = rsp_iobref;
+ rsp_iobuf = NULL;
+ rsp_iobref = NULL;
+
+ ret = client_submit_request (this, &req, frame, conf->fops,
+ GFS3_OP_READLINK,
+ client3_3_readlink_cbk, NULL,
+ rsphdr, count, NULL, 0,
+ local->iobref,
+ (xdrproc_t)xdr_gfs3_readlink_req);
+ if (ret) {
+ gf_log (this->name, GF_LOG_WARNING, "failed to send the fop");
+ }
+
+ GF_FREE (req.xdata.xdata_val);
+
+ return 0;
+unwind:
+ if (rsp_iobref != NULL) {
+ iobref_unref (rsp_iobref);
+ }
+
+ CLIENT_STACK_UNWIND (readlink, frame, -1, op_errno, NULL, NULL, NULL);
+ GF_FREE (req.xdata.xdata_val);
+
+ return 0;
+}
+
+
+
+
+int32_t
+client3_3_unlink (call_frame_t *frame, xlator_t *this,
+ void *data)
+{
+ clnt_conf_t *conf = NULL;
+ clnt_args_t *args = NULL;
+ gfs3_unlink_req req = {{0,},};
+ int ret = 0;
+ int op_errno = 0;
+
+ if (!frame || !this || !data)
+ goto unwind;
+
+ args = data;
+
+ if (!(args->loc && args->loc->parent))
+ goto unwind;
+
+ if (!uuid_is_null (args->loc->parent->gfid))
+ memcpy (req.pargfid, args->loc->parent->gfid, 16);
+ else
+ memcpy (req.pargfid, args->loc->pargfid, 16);
+
+ GF_ASSERT_AND_GOTO_WITH_ERROR (this->name,
+ !uuid_is_null (*((uuid_t*)req.pargfid)),
+ unwind, op_errno, EINVAL);
+ req.bname = (char *)args->loc->name;
+ conf = this->private;
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, args->xdata, (&req.xdata.xdata_val),
+ req.xdata.xdata_len, op_errno, unwind);
+
+ ret = client_submit_request (this, &req, frame, conf->fops,
+ GFS3_OP_UNLINK,
+ client3_3_unlink_cbk, NULL,
+ NULL, 0, NULL, 0,
+ NULL, (xdrproc_t)xdr_gfs3_unlink_req);
+ if (ret) {
+ gf_log (this->name, GF_LOG_WARNING, "failed to send the fop");
+ }
+
+ GF_FREE (req.xdata.xdata_val);
+
+ return 0;
+unwind:
+ CLIENT_STACK_UNWIND (unlink, frame, -1, op_errno, NULL, NULL, NULL);
+ GF_FREE (req.xdata.xdata_val);
+
+ return 0;
+}
+
+
+
+int32_t
+client3_3_rmdir (call_frame_t *frame, xlator_t *this,
+ void *data)
+{
+ clnt_conf_t *conf = NULL;
+ clnt_args_t *args = NULL;
+ gfs3_rmdir_req req = {{0,},};
+ int ret = 0;
+ int op_errno = ESTALE;
+
+ if (!frame || !this || !data)
+ goto unwind;
+
+ args = data;
+
+ if (!(args->loc && args->loc->parent))
+ goto unwind;
+
+ if (!uuid_is_null (args->loc->parent->gfid))
+ memcpy (req.pargfid, args->loc->parent->gfid, 16);
+ else
+ memcpy (req.pargfid, args->loc->pargfid, 16);
+
+ GF_ASSERT_AND_GOTO_WITH_ERROR (this->name,
+ !uuid_is_null (*((uuid_t*)req.pargfid)),
+ unwind, op_errno, EINVAL);
+ req.bname = (char *)args->loc->name;
+ req.xflags = args->flags;
+ conf = this->private;
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, args->xdata, (&req.xdata.xdata_val),
+ req.xdata.xdata_len, op_errno, unwind);
+
+ ret = client_submit_request (this, &req, frame, conf->fops,
+ GFS3_OP_RMDIR, client3_3_rmdir_cbk, NULL,
+ NULL, 0, NULL, 0,
+ NULL, (xdrproc_t)xdr_gfs3_rmdir_req);
+ if (ret) {
+ gf_log (this->name, GF_LOG_WARNING, "failed to send the fop");
+ }
+ GF_FREE (req.xdata.xdata_val);
+
+ return 0;
+unwind:
+ CLIENT_STACK_UNWIND (rmdir, frame, -1, op_errno, NULL, NULL, NULL);
+ GF_FREE (req.xdata.xdata_val);
+
+ return 0;
+}
+
+
+
+int32_t
+client3_3_symlink (call_frame_t *frame, xlator_t *this,
+ void *data)
+{
+ clnt_local_t *local = NULL;
+ clnt_conf_t *conf = NULL;
+ clnt_args_t *args = NULL;
+ gfs3_symlink_req req = {{0,},};
+ int ret = 0;
+ int op_errno = ESTALE;
+
+ if (!frame || !this || !data)
+ goto unwind;
+
+ args = data;
+ local = mem_get0 (this->local_pool);
+ if (!local) {
+ op_errno = ENOMEM;
+ goto unwind;
+ }
+
+ frame->local = local;
+
+ if (!(args->loc && args->loc->parent))
+ goto unwind;
+
+ loc_copy (&local->loc, args->loc);
+ loc_path (&local->loc, NULL);
+
+ if (!uuid_is_null (args->loc->parent->gfid))
+ memcpy (req.pargfid, args->loc->parent->gfid, 16);
+ else
+ memcpy (req.pargfid, args->loc->pargfid, 16);
+
+ GF_ASSERT_AND_GOTO_WITH_ERROR (this->name,
+ !uuid_is_null (*((uuid_t*)req.pargfid)),
+ unwind, op_errno, EINVAL);
+ req.linkname = (char *)args->linkname;
+ req.bname = (char *)args->loc->name;
+ req.umask = args->umask;
+ local->loc2.path = gf_strdup (req.linkname);
+
+ conf = this->private;
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, args->xdata, (&req.xdata.xdata_val),
+ req.xdata.xdata_len, op_errno, unwind);
+
+ ret = client_submit_request (this, &req, frame, conf->fops,
+ GFS3_OP_SYMLINK, client3_3_symlink_cbk,
+ NULL, NULL, 0, NULL,
+ 0, NULL, (xdrproc_t)xdr_gfs3_symlink_req);
+ if (ret) {
+ gf_log (this->name, GF_LOG_WARNING, "failed to send the fop");
+ }
+
+ GF_FREE (req.xdata.xdata_val);
+
+ return 0;
+unwind:
+
+ CLIENT_STACK_UNWIND (symlink, frame, -1, op_errno, NULL, NULL, NULL,
+ NULL, NULL);
+
+ GF_FREE (req.xdata.xdata_val);
+
+ return 0;
+}
+
+
+
+int32_t
+client3_3_rename (call_frame_t *frame, xlator_t *this,
+ void *data)
+{
+ clnt_conf_t *conf = NULL;
+ clnt_args_t *args = NULL;
+ gfs3_rename_req req = {{0,},};
+ int ret = 0;
+ int op_errno = ESTALE;
+
+ if (!frame || !this || !data)
+ goto unwind;
+
+ args = data;
+
+ if (!(args->oldloc && args->newloc && args->oldloc->parent &&
+ args->newloc->parent))
+ goto unwind;
+
+ if (!uuid_is_null (args->oldloc->parent->gfid))
+ memcpy (req.oldgfid, args->oldloc->parent->gfid, 16);
+ else
+ memcpy (req.oldgfid, args->oldloc->pargfid, 16);
+
+ if (!uuid_is_null (args->newloc->parent->gfid))
+ memcpy (req.newgfid, args->newloc->parent->gfid, 16);
+ else
+ memcpy (req.newgfid, args->newloc->pargfid, 16);
+
+ GF_ASSERT_AND_GOTO_WITH_ERROR (this->name,
+ !uuid_is_null (*((uuid_t*)req.oldgfid)),
+ unwind, op_errno, EINVAL);
+ GF_ASSERT_AND_GOTO_WITH_ERROR (this->name,
+ !uuid_is_null (*((uuid_t*)req.newgfid)),
+ unwind, op_errno, EINVAL);
+ req.oldbname = (char *)args->oldloc->name;
+ req.newbname = (char *)args->newloc->name;
+ conf = this->private;
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, args->xdata, (&req.xdata.xdata_val),
+ req.xdata.xdata_len, op_errno, unwind);
+
+ ret = client_submit_request (this, &req, frame, conf->fops,
+ GFS3_OP_RENAME, client3_3_rename_cbk, NULL,
+ NULL, 0, NULL, 0,
+ NULL, (xdrproc_t)xdr_gfs3_rename_req);
+ if (ret) {
+ gf_log (this->name, GF_LOG_WARNING, "failed to send the fop");
+ }
+
+ GF_FREE (req.xdata.xdata_val);
+
+ return 0;
+unwind:
+ CLIENT_STACK_UNWIND (rename, frame, -1, op_errno, NULL, NULL, NULL,
+ NULL, NULL, NULL);
+
+ GF_FREE (req.xdata.xdata_val);
+
+ return 0;
+}
+
+
+
+int32_t
+client3_3_link (call_frame_t *frame, xlator_t *this,
+ void *data)
+{
+ clnt_local_t *local = NULL;
+ clnt_conf_t *conf = NULL;
+ clnt_args_t *args = NULL;
+ gfs3_link_req req = {{0,},};
+ int ret = 0;
+ int op_errno = ESTALE;
+
+ if (!frame || !this || !data)
+ goto unwind;
+
+ args = data;
+
+ if (!(args->oldloc && args->oldloc->inode && args->newloc &&
+ args->newloc->parent))
+ goto unwind;
+
+ if (!uuid_is_null (args->oldloc->inode->gfid))
+ memcpy (req.oldgfid, args->oldloc->inode->gfid, 16);
+ else
+ memcpy (req.oldgfid, args->oldloc->gfid, 16);
+
+ if (!uuid_is_null (args->newloc->parent->gfid))
+ memcpy (req.newgfid, args->newloc->parent->gfid, 16);
+ else
+ memcpy (req.newgfid, args->newloc->pargfid, 16);
+
+ GF_ASSERT_AND_GOTO_WITH_ERROR (this->name,
+ !uuid_is_null (*((uuid_t*)req.oldgfid)),
+ unwind, op_errno, EINVAL);
+ GF_ASSERT_AND_GOTO_WITH_ERROR (this->name,
+ !uuid_is_null (*((uuid_t*)req.newgfid)),
+ unwind, op_errno, EINVAL);
+ local = mem_get0 (this->local_pool);
+ if (!local) {
+ op_errno = ENOMEM;
+ goto unwind;
+ }
+
+ loc_copy (&local->loc, args->oldloc);
+ loc_path (&local->loc, NULL);
+ loc_copy (&local->loc2, args->newloc);
+ loc_path (&local->loc2, NULL);
+ frame->local = local;
+
+ req.newbname = (char *)args->newloc->name;
+ conf = this->private;
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, args->xdata, (&req.xdata.xdata_val),
+ req.xdata.xdata_len, op_errno, unwind);
+
+ ret = client_submit_request (this, &req, frame, conf->fops,
+ GFS3_OP_LINK, client3_3_link_cbk, NULL,
+ NULL, 0, NULL, 0, NULL,
+ (xdrproc_t)xdr_gfs3_link_req);
+ if (ret) {
+ gf_log (this->name, GF_LOG_WARNING, "failed to send the fop");
+ }
+
+ GF_FREE (req.xdata.xdata_val);
+
+ return 0;
+unwind:
+ CLIENT_STACK_UNWIND (link, frame, -1, op_errno, NULL, NULL, NULL, NULL, NULL);
+ GF_FREE (req.xdata.xdata_val);
+
+ return 0;
+}
+
+
+
+int32_t
+client3_3_mknod (call_frame_t *frame, xlator_t *this,
+ void *data)
+{
+ clnt_local_t *local = NULL;
+ clnt_conf_t *conf = NULL;
+ clnt_args_t *args = NULL;
+ gfs3_mknod_req req = {{0,},};
+ int ret = 0;
+ int op_errno = ESTALE;
+
+ if (!frame || !this || !data)
+ goto unwind;
+
+ args = data;
+
+ local = mem_get0 (this->local_pool);
+ if (!local) {
+ op_errno = ENOMEM;
+ goto unwind;
+ }
+
+ if (!(args->loc && args->loc->parent))
+ goto unwind;
+
+ loc_copy (&local->loc, args->loc);
+ loc_path (&local->loc, NULL);
+ frame->local = local;
+
+ if (!uuid_is_null (args->loc->parent->gfid))
+ memcpy (req.pargfid, args->loc->parent->gfid, 16);
+ else
+ memcpy (req.pargfid, args->loc->pargfid, 16);
+
+ GF_ASSERT_AND_GOTO_WITH_ERROR (this->name,
+ !uuid_is_null (*((uuid_t*)req.pargfid)),
+ unwind, op_errno, EINVAL);
+ req.bname = (char *)args->loc->name;
+ req.mode = args->mode;
+ req.dev = args->rdev;
+ req.umask = args->umask;
+
+ conf = this->private;
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, args->xdata, (&req.xdata.xdata_val),
+ req.xdata.xdata_len, op_errno, unwind);
+
+ ret = client_submit_request (this, &req, frame, conf->fops,
+ GFS3_OP_MKNOD, client3_3_mknod_cbk, NULL,
+ NULL, 0, NULL, 0,
+ NULL, (xdrproc_t)xdr_gfs3_mknod_req);
+ if (ret) {
+ gf_log (this->name, GF_LOG_WARNING, "failed to send the fop");
+ }
+ GF_FREE (req.xdata.xdata_val);
+
+ return 0;
+unwind:
+ CLIENT_STACK_UNWIND (mknod, frame, -1, op_errno, NULL, NULL, NULL,
+ NULL, NULL);
+
+ GF_FREE (req.xdata.xdata_val);
+
+ return 0;
+}
+
+
+
+int32_t
+client3_3_mkdir (call_frame_t *frame, xlator_t *this,
+ void *data)
+{
+ clnt_local_t *local = NULL;
+ clnt_conf_t *conf = NULL;
+ clnt_args_t *args = NULL;
+ gfs3_mkdir_req req = {{0,},};
+ int ret = 0;
+ int op_errno = ESTALE;
+
+ if (!frame || !this || !data)
+ goto unwind;
+
+ args = data;
+
+ local = mem_get0 (this->local_pool);
+ if (!local) {
+ op_errno = ENOMEM;
+ goto unwind;
+ }
+
+ if (!(args->loc && args->loc->parent))
+ goto unwind;
+
+ loc_copy (&local->loc, args->loc);
+ loc_path (&local->loc, NULL);
+ frame->local = local;
+
+ if (!uuid_is_null (args->loc->parent->gfid))
+ memcpy (req.pargfid, args->loc->parent->gfid, 16);
+ else
+ memcpy (req.pargfid, args->loc->pargfid, 16);
+
+ GF_ASSERT_AND_GOTO_WITH_ERROR (this->name,
+ !uuid_is_null (*((uuid_t*)req.pargfid)),
+ unwind, op_errno, EINVAL);
+
+ req.bname = (char *)args->loc->name;
+ req.mode = args->mode;
+ req.umask = args->umask;
+
+ conf = this->private;
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, args->xdata, (&req.xdata.xdata_val),
+ req.xdata.xdata_len, op_errno, unwind);
+
+ ret = client_submit_request (this, &req, frame, conf->fops,
+ GFS3_OP_MKDIR, client3_3_mkdir_cbk, NULL,
+ NULL, 0, NULL, 0,
+ NULL, (xdrproc_t)xdr_gfs3_mkdir_req);
+ if (ret) {
+ gf_log (this->name, GF_LOG_WARNING, "failed to send the fop");
+ }
+ GF_FREE (req.xdata.xdata_val);
+
+ return 0;
+unwind:
+ CLIENT_STACK_UNWIND (mkdir, frame, -1, op_errno, NULL, NULL, NULL,
+ NULL, NULL);
+
+ GF_FREE (req.xdata.xdata_val);
+
+ return 0;
+}
+
+
+int32_t
+client3_3_create (call_frame_t *frame, xlator_t *this,
+ void *data)
+{
+ clnt_local_t *local = NULL;
+ clnt_conf_t *conf = NULL;
+ clnt_args_t *args = NULL;
+ gfs3_create_req req = {{0,},};
+ int ret = 0;
+ int op_errno = ESTALE;
+
+ if (!frame || !this || !data)
+ goto unwind;
+
+ args = data;
+
+ local = mem_get0 (this->local_pool);
+ if (!local) {
+ op_errno = ENOMEM;
+ goto unwind;
+ }
+ if (!(args->loc && args->loc->parent))
+ goto unwind;
+
+ local->fd = fd_ref (args->fd);
+ local->flags = args->flags;
+
+ loc_copy (&local->loc, args->loc);
+ loc_path (&local->loc, NULL);
+ frame->local = local;
+
+ if (!uuid_is_null (args->loc->parent->gfid))
+ memcpy (req.pargfid, args->loc->parent->gfid, 16);
+ else
+ memcpy (req.pargfid, args->loc->pargfid, 16);
+
+ GF_ASSERT_AND_GOTO_WITH_ERROR (this->name,
+ !uuid_is_null (*((uuid_t*)req.pargfid)),
+ unwind, op_errno, EINVAL);
+ req.bname = (char *)args->loc->name;
+ req.mode = args->mode;
+ req.flags = gf_flags_from_flags (args->flags);
+ req.umask = args->umask;
+
+ conf = this->private;
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, args->xdata, (&req.xdata.xdata_val),
+ req.xdata.xdata_len, op_errno, unwind);
+
+ ret = client_submit_request (this, &req, frame, conf->fops,
+ GFS3_OP_CREATE, client3_3_create_cbk, NULL,
+ NULL, 0, NULL, 0,
+ NULL, (xdrproc_t)xdr_gfs3_create_req);
+ if (ret) {
+ gf_log (this->name, GF_LOG_WARNING, "failed to send the fop");
+ }
+
+ GF_FREE (req.xdata.xdata_val);
+
+ return 0;
+unwind:
+ CLIENT_STACK_UNWIND (create, frame, -1, op_errno, NULL, NULL, NULL,
+ NULL, NULL, NULL);
+
+ GF_FREE (req.xdata.xdata_val);
+
+ return 0;
+}
+
+
+
+int32_t
+client3_3_open (call_frame_t *frame, xlator_t *this,
+ void *data)
+{
+ clnt_local_t *local = NULL;
+ clnt_conf_t *conf = NULL;
+ clnt_args_t *args = NULL;
+ gfs3_open_req req = {{0,},};
+ int ret = 0;
+ int op_errno = ESTALE;
+
+ if (!frame || !this || !data)
+ goto unwind;
+
+ args = data;
+
+ local = mem_get0 (this->local_pool);
+ if (!local) {
+ op_errno = ENOMEM;
+ goto unwind;
+ }
+ if (!(args->loc && args->loc->inode))
+ goto unwind;
+
+ local->fd = fd_ref (args->fd);
+ local->flags = args->flags;
+ loc_copy (&local->loc, args->loc);
+ loc_path (&local->loc, NULL);
+ frame->local = local;
+
+ if (!uuid_is_null (args->loc->inode->gfid))
+ memcpy (req.gfid, args->loc->inode->gfid, 16);
+ else
+ memcpy (req.gfid, args->loc->gfid, 16);
+
+ GF_ASSERT_AND_GOTO_WITH_ERROR (this->name,
+ !uuid_is_null (*((uuid_t*)req.gfid)),
+ unwind, op_errno, EINVAL);
+ req.flags = gf_flags_from_flags (args->flags);
+
+ conf = this->private;
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, args->xdata, (&req.xdata.xdata_val),
+ req.xdata.xdata_len, op_errno, unwind);
+
+ ret = client_submit_request (this, &req, frame, conf->fops,
+ GFS3_OP_OPEN, client3_3_open_cbk, NULL,
+ NULL, 0, NULL, 0, NULL,
+ (xdrproc_t)xdr_gfs3_open_req);
+ if (ret) {
+ gf_log (this->name, GF_LOG_WARNING, "failed to send the fop");
+ }
+
+ GF_FREE (req.xdata.xdata_val);
+
+ return 0;
+unwind:
+ CLIENT_STACK_UNWIND (open, frame, -1, op_errno, NULL, NULL);
+
+ GF_FREE (req.xdata.xdata_val);
+
+ return 0;
+}
+
+
+
+int32_t
+client3_3_readv (call_frame_t *frame, xlator_t *this,
+ void *data)
+{
+ clnt_args_t *args = NULL;
+ int64_t remote_fd = -1;
+ clnt_conf_t *conf = NULL;
+ clnt_local_t *local = NULL;
+ int op_errno = ESTALE;
+ gfs3_read_req req = {{0,},};
+ int ret = 0;
+ struct iovec rsp_vec = {0, };
+ struct iobuf *rsp_iobuf = NULL;
+ struct iobref *rsp_iobref = NULL;
+
+ if (!frame || !this || !data)
+ goto unwind;
+
+ args = data;
+ conf = this->private;
+
+ CLIENT_GET_REMOTE_FD (this, args->fd, FALLBACK_TO_ANON_FD,
+ remote_fd, op_errno, unwind);
+ ret = client_fd_fop_prepare_local (frame, args->fd, remote_fd);
+ if (ret) {
+ op_errno = -ret;
+ goto unwind;
+ }
+ local = frame->local;
+
+ req.size = args->size;
+ req.offset = args->offset;
+ req.fd = remote_fd;
+ req.flag = args->flags;
+
+ memcpy (req.gfid, args->fd->inode->gfid, 16);
+
+ rsp_iobuf = iobuf_get2 (this->ctx->iobuf_pool, args->size);
+ if (rsp_iobuf == NULL) {
+ op_errno = ENOMEM;
+ goto unwind;
+ }
+
+ rsp_iobref = iobref_new ();
+ if (rsp_iobref == NULL) {
+ op_errno = ENOMEM;
+ goto unwind;
+ }
+
+ iobref_add (rsp_iobref, rsp_iobuf);
+ iobuf_unref (rsp_iobuf);
+
+ rsp_vec.iov_base = iobuf_ptr (rsp_iobuf);
+ rsp_vec.iov_len = iobuf_pagesize (rsp_iobuf);
+
+ rsp_iobuf = NULL;
+
+ if (args->size > rsp_vec.iov_len) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "read-size (%lu) is bigger than iobuf size (%lu)",
+ (unsigned long)args->size,
+ (unsigned long)rsp_vec.iov_len);
+ op_errno = EINVAL;
+ goto unwind;
+ }
+
+ local->iobref = rsp_iobref;
+ rsp_iobref = NULL;
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, args->xdata, (&req.xdata.xdata_val),
+ req.xdata.xdata_len, op_errno, unwind);
+
+ ret = client_submit_request (this, &req, frame, conf->fops,
+ GFS3_OP_READ, client3_3_readv_cbk, NULL,
+ NULL, 0, &rsp_vec, 1,
+ local->iobref,
+ (xdrproc_t)xdr_gfs3_read_req);
+ if (ret) {
+ //unwind is done in the cbk
+ gf_log (this->name, GF_LOG_WARNING, "failed to send the fop");
+ }
+
+ GF_FREE (req.xdata.xdata_val);
+
+ return 0;
+unwind:
+ if (rsp_iobuf)
+ iobuf_unref (rsp_iobuf);
+
+ if (rsp_iobref)
+ iobref_unref (rsp_iobref);
+
+ CLIENT_STACK_UNWIND (readv, frame, -1, op_errno, NULL, 0, NULL, NULL, NULL);
+ GF_FREE (req.xdata.xdata_val);
+
+ return 0;
+}
+
+
+int32_t
+client3_3_writev (call_frame_t *frame, xlator_t *this, void *data)
+{
+ clnt_args_t *args = NULL;
+ int64_t remote_fd = -1;
+ clnt_conf_t *conf = NULL;
+ gfs3_write_req req = {{0,},};
+ int op_errno = ESTALE;
+ int ret = 0;
+
+ if (!frame || !this || !data)
+ goto unwind;
+
+ args = data;
+ conf = this->private;
+
+ CLIENT_GET_REMOTE_FD (this, args->fd, FALLBACK_TO_ANON_FD,
+ remote_fd, op_errno, unwind);
+ ret = client_fd_fop_prepare_local (frame, args->fd, remote_fd);
+ if (ret) {
+ op_errno = -ret;
+ goto unwind;
+ }
+
+ req.size = args->size;
+ req.offset = args->offset;
+ req.fd = remote_fd;
+ req.flag = args->flags;
+
+ memcpy (req.gfid, args->fd->inode->gfid, 16);
+
+#ifdef GF_TESTING_IO_XDATA
+ if (!args->xdata)
+ args->xdata = dict_new ();
+
+ ret = dict_set_str (args->xdata, "testing-the-xdata-key",
+ "testing-the-xdata-value");
+#endif
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, args->xdata, (&req.xdata.xdata_val),
+ req.xdata.xdata_len, op_errno, unwind);
+
+ ret = client_submit_vec_request (this, &req, frame, conf->fops,
+ GFS3_OP_WRITE, client3_3_writev_cbk,
+ args->vector, args->count,
+ args->iobref,
+ (xdrproc_t)xdr_gfs3_write_req);
+ if (ret) {
+ /*
+ * If the lower layers fail to submit a request, they'll also
+ * do the unwind for us (see rpc_clnt_submit), so don't unwind
+ * here in such cases.
+ */
+ gf_log (this->name, GF_LOG_WARNING, "failed to send the fop");
+ }
+
+ GF_FREE (req.xdata.xdata_val);
+
+ return 0;
+
+unwind:
+ CLIENT_STACK_UNWIND (writev, frame, -1, op_errno, NULL, NULL, NULL);
+ GF_FREE (req.xdata.xdata_val);
+
+ return 0;
+}
+
+
+int32_t
+client3_3_flush (call_frame_t *frame, xlator_t *this,
+ void *data)
+{
+ clnt_args_t *args = NULL;
+ gfs3_flush_req req = {{0,},};
+ int64_t remote_fd = -1;
+ clnt_conf_t *conf = NULL;
+ clnt_local_t *local = NULL;
+ int op_errno = ESTALE;
+ int ret = 0;
+
+ if (!frame || !this || !data)
+ goto unwind;
+
+ args = data;
+ conf = this->private;
+
+ CLIENT_GET_REMOTE_FD (this, args->fd, DEFAULT_REMOTE_FD,
+ remote_fd, op_errno, unwind);
+
+ conf = this->private;
+
+ local = mem_get0 (this->local_pool);
+ if (!local) {
+ op_errno = ENOMEM;
+ goto unwind;
+ }
+
+ local->fd = fd_ref (args->fd);
+ local->owner = frame->root->lk_owner;
+ frame->local = local;
+
+ req.fd = remote_fd;
+ memcpy (req.gfid, args->fd->inode->gfid, 16);
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, args->xdata, (&req.xdata.xdata_val),
+ req.xdata.xdata_len, op_errno, unwind);
+
+ ret = client_submit_request (this, &req, frame, conf->fops,
+ GFS3_OP_FLUSH, client3_3_flush_cbk, NULL,
+ NULL, 0, NULL, 0,
+ NULL, (xdrproc_t)xdr_gfs3_flush_req);
+ if (ret) {
+ gf_log (this->name, GF_LOG_WARNING, "failed to send the fop");
+ }
+
+ GF_FREE (req.xdata.xdata_val);
+
+
+ return 0;
+
+unwind:
+ CLIENT_STACK_UNWIND (flush, frame, -1, op_errno, NULL);
+ GF_FREE (req.xdata.xdata_val);
+
+ return 0;
+}
+
+
+
+int32_t
+client3_3_fsync (call_frame_t *frame, xlator_t *this,
+ void *data)
+{
+ clnt_args_t *args = NULL;
+ gfs3_fsync_req req = {{0,},};
+ int64_t remote_fd = -1;
+ clnt_conf_t *conf = NULL;
+ int op_errno = 0;
+ int ret = 0;
+
+ if (!frame || !this || !data)
+ goto unwind;
+
+ args = data;
+ conf = this->private;
+
+ CLIENT_GET_REMOTE_FD (this, args->fd, DEFAULT_REMOTE_FD,
+ remote_fd, op_errno, unwind);
+
+ req.fd = remote_fd;
+ req.data = args->flags;
+ memcpy (req.gfid, args->fd->inode->gfid, 16);
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, args->xdata, (&req.xdata.xdata_val),
+ req.xdata.xdata_len, op_errno, unwind);
+
+ ret = client_submit_request (this, &req, frame, conf->fops,
+ GFS3_OP_FSYNC, client3_3_fsync_cbk, NULL,
+ NULL, 0, NULL, 0,
+ NULL, (xdrproc_t)xdr_gfs3_fsync_req);
+ if (ret) {
+ gf_log (this->name, GF_LOG_WARNING, "failed to send the fop");
+
+ }
+
+ GF_FREE (req.xdata.xdata_val);
+
+ return 0;
+
+unwind:
+ CLIENT_STACK_UNWIND (fsync, frame, -1, op_errno, NULL, NULL, NULL);
+ GF_FREE (req.xdata.xdata_val);
+
+ return 0;
+}
+
+
+
+int32_t
+client3_3_fstat (call_frame_t *frame, xlator_t *this,
+ void *data)
+{
+ clnt_args_t *args = NULL;
+ gfs3_fstat_req req = {{0,},};
+ int64_t remote_fd = -1;
+ clnt_conf_t *conf = NULL;
+ int op_errno = ESTALE;
+ int ret = 0;
+
+ if (!frame || !this || !data)
+ goto unwind;
+
+ args = data;
+ conf = this->private;
+
+ CLIENT_GET_REMOTE_FD (this, args->fd, DEFAULT_REMOTE_FD,
+ remote_fd, op_errno, unwind);
+
+ req.fd = remote_fd;
+ memcpy (req.gfid, args->fd->inode->gfid, 16);
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, args->xdata, (&req.xdata.xdata_val),
+ req.xdata.xdata_len, op_errno, unwind);
+
+ ret = client_submit_request (this, &req, frame, conf->fops,
+ GFS3_OP_FSTAT, client3_3_fstat_cbk, NULL,
+ NULL, 0, NULL, 0,
+ NULL, (xdrproc_t)xdr_gfs3_fstat_req);
+ if (ret) {
+ gf_log (this->name, GF_LOG_WARNING, "failed to send the fop");
+ }
+
+ GF_FREE (req.xdata.xdata_val);
+
+ return 0;
+
+unwind:
+ CLIENT_STACK_UNWIND (fstat, frame, -1, op_errno, NULL, NULL);
+ GF_FREE (req.xdata.xdata_val);
+
+ return 0;
+}
+
+
+
+int32_t
+client3_3_opendir (call_frame_t *frame, xlator_t *this,
+ void *data)
+{
+ clnt_local_t *local = NULL;
+ clnt_conf_t *conf = NULL;
+ clnt_args_t *args = NULL;
+ gfs3_opendir_req req = {{0,},};
+ int ret = 0;
+ int op_errno = ESTALE;
+
+ if (!frame || !this || !data)
+ goto unwind;
+
+ args = data;
+
+ local = mem_get0 (this->local_pool);
+ if (!local) {
+ op_errno = ENOMEM;
+ goto unwind;
+ }
+ if (!(args->loc && args->loc->inode))
+ goto unwind;
+
+ local->fd = fd_ref (args->fd);
+ loc_copy (&local->loc, args->loc);
+ loc_path (&local->loc, NULL);
+ frame->local = local;
+
+ if (!uuid_is_null (args->loc->inode->gfid))
+ memcpy (req.gfid, args->loc->inode->gfid, 16);
+ else
+ memcpy (req.gfid, args->loc->gfid, 16);
+
+ GF_ASSERT_AND_GOTO_WITH_ERROR (this->name,
+ !uuid_is_null (*((uuid_t*)req.gfid)),
+ unwind, op_errno, EINVAL);
+
+ conf = this->private;
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, args->xdata, (&req.xdata.xdata_val),
+ req.xdata.xdata_len, op_errno, unwind);
+
+ ret = client_submit_request (this, &req, frame, conf->fops,
+ GFS3_OP_OPENDIR, client3_3_opendir_cbk,
+ NULL, NULL, 0, NULL, 0, NULL,
+ (xdrproc_t)xdr_gfs3_opendir_req);
+ if (ret) {
+ gf_log (this->name, GF_LOG_WARNING, "failed to send the fop");
+ }
+
+ GF_FREE (req.xdata.xdata_val);
+
+ return 0;
+
+unwind:
+ CLIENT_STACK_UNWIND (opendir, frame, -1, op_errno, NULL, NULL);
+
+ GF_FREE (req.xdata.xdata_val);
+
+ return 0;
+}
+
+
+
+int32_t
+client3_3_fsyncdir (call_frame_t *frame, xlator_t *this, void *data)
+{
+ clnt_args_t *args = NULL;
+ int64_t remote_fd = -1;
+ clnt_conf_t *conf = NULL;
+ gfs3_fsyncdir_req req = {{0,},};
+ int ret = 0;
+ int32_t op_errno = ESTALE;
+
+ if (!frame || !this || !data)
+ goto unwind;
+
+ args = data;
+ conf = this->private;
+
+ CLIENT_GET_REMOTE_FD (this, args->fd, DEFAULT_REMOTE_FD,
+ remote_fd, op_errno, unwind);
+
+ req.fd = remote_fd;
+ req.data = args->flags;
+ memcpy (req.gfid, args->fd->inode->gfid, 16);
+
+ conf = this->private;
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, args->xdata, (&req.xdata.xdata_val),
+ req.xdata.xdata_len, op_errno, unwind);
+
+ ret = client_submit_request (this, &req, frame, conf->fops,
+ GFS3_OP_FSYNCDIR, client3_3_fsyncdir_cbk,
+ NULL, NULL, 0,
+ NULL, 0, NULL,
+ (xdrproc_t)xdr_gfs3_fsyncdir_req);
+ if (ret) {
+ gf_log (this->name, GF_LOG_WARNING, "failed to send the fop");
+ }
+
+ GF_FREE (req.xdata.xdata_val);
+
+ return 0;
+
+unwind:
+ CLIENT_STACK_UNWIND (fsyncdir, frame, -1, op_errno, NULL);
+ GF_FREE (req.xdata.xdata_val);
+
+ return 0;
+}
+
+
+
+int32_t
+client3_3_statfs (call_frame_t *frame, xlator_t *this,
+ void *data)
+{
+ clnt_conf_t *conf = NULL;
+ clnt_args_t *args = NULL;
+ gfs3_statfs_req req = {{0,},};
+ int ret = 0;
+ int op_errno = ESTALE;
+
+ if (!frame || !this || !data)
+ goto unwind;
+
+ args = data;
+
+ if (!args->loc)
+ goto unwind;
+
+ if (args->loc->inode) {
+ if (!uuid_is_null (args->loc->inode->gfid))
+ memcpy (req.gfid, args->loc->inode->gfid, 16);
+ else
+ memcpy (req.gfid, args->loc->gfid, 16);
+ } else
+ req.gfid[15] = 1;
+
+ GF_ASSERT_AND_GOTO_WITH_ERROR (this->name,
+ !uuid_is_null (*((uuid_t*)req.gfid)),
+ unwind, op_errno, EINVAL);
+
+ conf = this->private;
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, args->xdata, (&req.xdata.xdata_val),
+ req.xdata.xdata_len, op_errno, unwind);
+
+ ret = client_submit_request (this, &req, frame, conf->fops,
+ GFS3_OP_STATFS, client3_3_statfs_cbk, NULL,
+ NULL, 0, NULL, 0,
+ NULL, (xdrproc_t)xdr_gfs3_statfs_req);
+ if (ret) {
+ gf_log (this->name, GF_LOG_WARNING, "failed to send the fop");
+ }
+
+ GF_FREE (req.xdata.xdata_val);
+
+ return 0;
+
+unwind:
+ CLIENT_STACK_UNWIND (statfs, frame, -1, op_errno, NULL, NULL);
+ GF_FREE (req.xdata.xdata_val);
+
+ return 0;
+}
+
+
+
+int32_t
+client3_3_setxattr (call_frame_t *frame, xlator_t *this,
+ void *data)
+{
+ clnt_conf_t *conf = NULL;
+ clnt_args_t *args = NULL;
+ gfs3_setxattr_req req = {{0,},};
+ int ret = 0;
+ int op_errno = ESTALE;
+
+ if (!frame || !this || !data)
+ goto unwind;
+
+ args = data;
+
+ if (!(args->loc && args->loc->inode))
+ goto unwind;
+
+ if (!uuid_is_null (args->loc->inode->gfid))
+ memcpy (req.gfid, args->loc->inode->gfid, 16);
+ else
+ memcpy (req.gfid, args->loc->gfid, 16);
+
+ GF_ASSERT_AND_GOTO_WITH_ERROR (this->name,
+ !uuid_is_null (*((uuid_t*)req.gfid)),
+ unwind, op_errno, EINVAL);
+ if (args->xattr) {
+ GF_PROTOCOL_DICT_SERIALIZE (this, args->xattr,
+ (&req.dict.dict_val),
+ req.dict.dict_len,
+ op_errno, unwind);
+ }
+
+ req.flags = args->flags;
+
+ conf = this->private;
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, args->xdata, (&req.xdata.xdata_val),
+ req.xdata.xdata_len, op_errno, unwind);
+
+ ret = client_submit_request (this, &req, frame, conf->fops,
+ GFS3_OP_SETXATTR, client3_3_setxattr_cbk,
+ NULL, NULL, 0, NULL, 0, NULL,
+ (xdrproc_t)xdr_gfs3_setxattr_req);
+ if (ret) {
+ gf_log (this->name, GF_LOG_WARNING, "failed to send the fop");
+ }
+ GF_FREE (req.dict.dict_val);
+
+ GF_FREE (req.xdata.xdata_val);
+
+ return 0;
+unwind:
+ CLIENT_STACK_UNWIND (setxattr, frame, -1, op_errno, NULL);
+ GF_FREE (req.dict.dict_val);
+
+ GF_FREE (req.xdata.xdata_val);
+
+ return 0;
+}
+
+
+
+int32_t
+client3_3_fsetxattr (call_frame_t *frame, xlator_t *this,
+ void *data)
+{
+ clnt_args_t *args = NULL;
+ int64_t remote_fd = -1;
+ clnt_conf_t *conf = NULL;
+ gfs3_fsetxattr_req req = {{0,},};
+ int op_errno = ESTALE;
+ int ret = 0;
+
+ if (!frame || !this || !data)
+ goto unwind;
+
+ args = data;
+ conf = this->private;
+
+ CLIENT_GET_REMOTE_FD (this, args->fd, DEFAULT_REMOTE_FD,
+ remote_fd, op_errno, unwind);
+
+ req.fd = remote_fd;
+ req.flags = args->flags;
+ memcpy (req.gfid, args->fd->inode->gfid, 16);
+
+ if (args->xattr) {
+ GF_PROTOCOL_DICT_SERIALIZE (this, args->xattr,
+ (&req.dict.dict_val),
+ req.dict.dict_len,
+ op_errno, unwind);
+ }
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, args->xdata, (&req.xdata.xdata_val),
+ req.xdata.xdata_len, op_errno, unwind);
+
+ ret = client_submit_request (this, &req, frame, conf->fops,
+ GFS3_OP_FSETXATTR, client3_3_fsetxattr_cbk,
+ NULL, NULL, 0, NULL, 0, NULL,
+ (xdrproc_t)xdr_gfs3_fsetxattr_req);
+ if (ret) {
+ gf_log (this->name, GF_LOG_WARNING, "failed to send the fop");
+ }
+
+ GF_FREE (req.dict.dict_val);
+
+ GF_FREE (req.xdata.xdata_val);
+
+ return 0;
+unwind:
+ CLIENT_STACK_UNWIND (fsetxattr, frame, -1, op_errno, NULL);
+ GF_FREE (req.dict.dict_val);
+
+ GF_FREE (req.xdata.xdata_val);
+
+ return 0;
+}
+
+
+
+
+int32_t
+client3_3_fgetxattr (call_frame_t *frame, xlator_t *this,
+ void *data)
+{
+ clnt_args_t *args = NULL;
+ int64_t remote_fd = -1;
+ clnt_conf_t *conf = NULL;
+ gfs3_fgetxattr_req req = {{0,},};
+ int op_errno = ESTALE;
+ int ret = 0;
+ int count = 0;
+ clnt_local_t *local = NULL;
+ struct iobref *rsp_iobref = NULL;
+ struct iobuf *rsp_iobuf = NULL;
+ struct iovec *rsphdr = NULL;
+ struct iovec vector[MAX_IOVEC] = {{0}, };
+
+ if (!frame || !this || !data)
+ goto unwind;
+
+ args = data;
+ conf = this->private;
+
+ CLIENT_GET_REMOTE_FD (this, args->fd, DEFAULT_REMOTE_FD,
+ remote_fd, op_errno, unwind);
+
+ local = mem_get0 (this->local_pool);
+ if (!local) {
+ op_errno = ENOMEM;
+ goto unwind;
+ }
+ frame->local = local;
+
+ rsp_iobref = iobref_new ();
+ if (rsp_iobref == NULL) {
+ op_errno = ENOMEM;
+ goto unwind;
+ }
+
+ /* TODO: what is the size we should send ? */
+ rsp_iobuf = iobuf_get2 (this->ctx->iobuf_pool, 8 * GF_UNIT_KB);
+ if (rsp_iobuf == NULL) {
+ op_errno = ENOMEM;
+ goto unwind;
+ }
+
+ iobref_add (rsp_iobref, rsp_iobuf);
+ iobuf_unref (rsp_iobuf);
+
+ rsphdr = &vector[0];
+ rsphdr->iov_base = iobuf_ptr (rsp_iobuf);
+ rsphdr->iov_len = iobuf_pagesize (rsp_iobuf);;
+ count = 1;
+ local->iobref = rsp_iobref;
+ rsp_iobuf = NULL;
+ rsp_iobref = NULL;
+
+ req.namelen = 1; /* Use it as a flag */
+ req.fd = remote_fd;
+ req.name = (char *)args->name;
+ if (!req.name) {
+ req.name = "";
+ req.namelen = 0;
+ }
+ memcpy (req.gfid, args->fd->inode->gfid, 16);
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, args->xdata, (&req.xdata.xdata_val),
+ req.xdata.xdata_len, op_errno, unwind);
+
+ ret = client_submit_request (this, &req, frame, conf->fops,
+ GFS3_OP_FGETXATTR,
+ client3_3_fgetxattr_cbk, NULL,
+ rsphdr, count,
+ NULL, 0, local->iobref,
+ (xdrproc_t)xdr_gfs3_fgetxattr_req);
+ if (ret) {
+ gf_log (this->name, GF_LOG_WARNING, "failed to send the fop");
+ }
+
+ GF_FREE (req.xdata.xdata_val);
+
+ if (rsp_iobuf)
+ iobuf_unref (rsp_iobuf);
+
+ if (rsp_iobref)
+ iobref_unref (rsp_iobref);
+
+ return 0;
+unwind:
+ CLIENT_STACK_UNWIND (fgetxattr, frame, -1, op_errno, NULL, NULL);
+
+ if (rsp_iobuf)
+ iobuf_unref (rsp_iobuf);
+
+ if (rsp_iobref)
+ iobref_unref (rsp_iobref);
+
+ GF_FREE (req.xdata.xdata_val);
+
+ return 0;
+}
+
+
+
+int32_t
+client3_3_getxattr (call_frame_t *frame, xlator_t *this,
+ void *data)
+{
+ clnt_conf_t *conf = NULL;
+ clnt_args_t *args = NULL;
+ gfs3_getxattr_req req = {{0,},};
+ dict_t *dict = NULL;
+ int ret = 0;
+ int32_t op_ret = -1;
+ int op_errno = ESTALE;
+ int count = 0;
+ clnt_local_t *local = NULL;
+ struct iobref *rsp_iobref = NULL;
+ struct iobuf *rsp_iobuf = NULL;
+ struct iovec *rsphdr = NULL;
+ struct iovec vector[MAX_IOVEC] = {{0}, };
+
+ if (!frame || !this || !data) {
+ op_errno = 0;
+ goto unwind;
+ }
+ args = data;
+
+ if (!args->loc) {
+ op_errno = EINVAL;
+ goto unwind;
+ }
+
+ local = mem_get0 (this->local_pool);
+ if (!local) {
+ op_errno = ENOMEM;
+ goto unwind;
+ }
+
+ loc_copy (&local->loc, args->loc);
+ loc_path (&local->loc, NULL);
+ if (args->name)
+ local->name = gf_strdup (args->name);
+
+ frame->local = local;
+
+ rsp_iobref = iobref_new ();
+ if (rsp_iobref == NULL) {
+ op_errno = ENOMEM;
+ goto unwind;
+ }
+
+ /* TODO: what is the size we should send ? */
+ rsp_iobuf = iobuf_get2 (this->ctx->iobuf_pool, 8 * GF_UNIT_KB);
+ if (rsp_iobuf == NULL) {
+ op_errno = ENOMEM;
+ goto unwind;
+ }
+
+ iobref_add (rsp_iobref, rsp_iobuf);
+ iobuf_unref (rsp_iobuf);
+
+ rsphdr = &vector[0];
+ rsphdr->iov_base = iobuf_ptr (rsp_iobuf);
+ rsphdr->iov_len = iobuf_pagesize (rsp_iobuf);
+ count = 1;
+ local->iobref = rsp_iobref;
+ rsp_iobuf = NULL;
+ rsp_iobref = NULL;
+
+ if (args->loc->inode && !uuid_is_null (args->loc->inode->gfid))
+ memcpy (req.gfid, args->loc->inode->gfid, 16);
+ else
+ memcpy (req.gfid, args->loc->gfid, 16);
+
+ GF_ASSERT_AND_GOTO_WITH_ERROR (this->name,
+ !uuid_is_null (*((uuid_t*)req.gfid)),
+ unwind, op_errno, EINVAL);
+ req.namelen = 1; /* Use it as a flag */
+
+ req.name = (char *)args->name;
+ if (!req.name) {
+ req.name = "";
+ req.namelen = 0;
+ }
+
+ conf = this->private;
+
+ if (args && args->name) {
+ if (is_client_dump_locks_cmd ((char *)args->name)) {
+ dict = dict_new ();
+ ret = client_dump_locks ((char *)args->name,
+ args->loc->inode,
+ dict);
+ if (ret) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "Client dump locks failed");
+ op_errno = EINVAL;
+ }
+
+ GF_ASSERT (dict);
+ op_ret = 0;
+ op_errno = 0;
+ goto unwind;
+ }
+ }
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, args->xdata, (&req.xdata.xdata_val),
+ req.xdata.xdata_len, op_errno, unwind);
+
+ ret = client_submit_request (this, &req, frame, conf->fops,
+ GFS3_OP_GETXATTR,
+ client3_3_getxattr_cbk, NULL,
+ rsphdr, count,
+ NULL, 0, local->iobref,
+ (xdrproc_t)xdr_gfs3_getxattr_req);
+ if (ret) {
+ gf_log (this->name, GF_LOG_WARNING, "failed to send the fop");
+ }
+
+ GF_FREE (req.xdata.xdata_val);
+
+ if (rsp_iobuf)
+ iobuf_unref (rsp_iobuf);
+
+ if (rsp_iobref)
+ iobref_unref (rsp_iobref);
+
+ return 0;
+unwind:
+ if (rsp_iobuf)
+ iobuf_unref (rsp_iobuf);
+
+ if (rsp_iobref)
+ iobref_unref (rsp_iobref);
+
+ CLIENT_STACK_UNWIND (getxattr, frame, op_ret, op_errno, dict, NULL);
+
+ GF_FREE (req.xdata.xdata_val);
+
+ return 0;
+}
+
+
+
+int32_t
+client3_3_xattrop (call_frame_t *frame, xlator_t *this,
+ void *data)
+{
+ clnt_conf_t *conf = NULL;
+ clnt_args_t *args = NULL;
+ gfs3_xattrop_req req = {{0,},};
+ int ret = 0;
+ int op_errno = ESTALE;
+ int count = 0;
+ clnt_local_t *local = NULL;
+ struct iobref *rsp_iobref = NULL;
+ struct iobuf *rsp_iobuf = NULL;
+ struct iovec *rsphdr = NULL;
+ struct iovec vector[MAX_IOVEC] = {{0}, };
+
+ if (!frame || !this || !data)
+ goto unwind;
+
+ args = data;
+
+ if (!(args->loc && args->loc->inode))
+ goto unwind;
+
+ local = mem_get0 (this->local_pool);
+ if (!local) {
+ op_errno = ENOMEM;
+ goto unwind;
+ }
+ frame->local = local;
+
+ rsp_iobref = iobref_new ();
+ if (rsp_iobref == NULL) {
+ op_errno = ENOMEM;
+ goto unwind;
+ }
+
+ /* TODO: what is the size we should send ? */
+ rsp_iobuf = iobuf_get2 (this->ctx->iobuf_pool, 8 * GF_UNIT_KB);
+ if (rsp_iobuf == NULL) {
+ op_errno = ENOMEM;
+ goto unwind;
+ }
+
+ iobref_add (rsp_iobref, rsp_iobuf);
+ iobuf_unref (rsp_iobuf);
+
+ rsphdr = &vector[0];
+ rsphdr->iov_base = iobuf_ptr (rsp_iobuf);
+ rsphdr->iov_len = iobuf_pagesize (rsp_iobuf);
+ count = 1;
+ local->iobref = rsp_iobref;
+ rsp_iobuf = NULL;
+ rsp_iobref = NULL;
+
+ if (!uuid_is_null (args->loc->inode->gfid))
+ memcpy (req.gfid, args->loc->inode->gfid, 16);
+ else
+ memcpy (req.gfid, args->loc->gfid, 16);
+
+ loc_copy (&local->loc, args->loc);
+ loc_path (&local->loc, NULL);
+ GF_ASSERT_AND_GOTO_WITH_ERROR (this->name,
+ !uuid_is_null (*((uuid_t*)req.gfid)),
+ unwind, op_errno, EINVAL);
+ if (args->xattr) {
+ GF_PROTOCOL_DICT_SERIALIZE (this, args->xattr,
+ (&req.dict.dict_val),
+ req.dict.dict_len,
+ op_errno, unwind);
+ }
+
+ req.flags = args->flags;
+
+ conf = this->private;
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, args->xdata, (&req.xdata.xdata_val),
+ req.xdata.xdata_len, op_errno, unwind);
+
+ ret = client_submit_request (this, &req, frame, conf->fops,
+ GFS3_OP_XATTROP,
+ client3_3_xattrop_cbk, NULL,
+ rsphdr, count,
+ NULL, 0, local->iobref,
+ (xdrproc_t)xdr_gfs3_xattrop_req);
+ if (ret) {
+ gf_log (this->name, GF_LOG_WARNING, "failed to send the fop");
+ }
+
+ GF_FREE (req.dict.dict_val);
+
+ GF_FREE (req.xdata.xdata_val);
+
+ if (rsp_iobuf)
+ iobuf_unref (rsp_iobuf);
+
+ if (rsp_iobref)
+ iobref_unref (rsp_iobref);
+
+ return 0;
+unwind:
+ CLIENT_STACK_UNWIND (xattrop, frame, -1, op_errno, NULL, NULL);
+
+ GF_FREE (req.dict.dict_val);
+
+ if (rsp_iobuf)
+ iobuf_unref (rsp_iobuf);
+
+ if (rsp_iobref)
+ iobref_unref (rsp_iobref);
+
+ GF_FREE (req.xdata.xdata_val);
+
+ return 0;
+}
+
+
+
+int32_t
+client3_3_fxattrop (call_frame_t *frame, xlator_t *this,
+ void *data)
+{
+ clnt_args_t *args = NULL;
+ int64_t remote_fd = -1;
+ clnt_conf_t *conf = NULL;
+ clnt_local_t *local = NULL;
+ gfs3_fxattrop_req req = {{0,},};
+ int op_errno = ESTALE;
+ int ret = 0;
+ int count = 0;
+ struct iobref *rsp_iobref = NULL;
+ struct iobuf *rsp_iobuf = NULL;
+ struct iovec *rsphdr = NULL;
+ struct iovec vector[MAX_IOVEC] = {{0}, };
+
+ if (!frame || !this || !data)
+ goto unwind;
+
+ args = data;
+ conf = this->private;
+
+ CLIENT_GET_REMOTE_FD (this, args->fd, FALLBACK_TO_ANON_FD,
+ remote_fd, op_errno, unwind);
+ ret = client_fd_fop_prepare_local (frame, args->fd, remote_fd);
+ if (ret) {
+ op_errno = -ret;
+ goto unwind;
+ }
+
+ local = frame->local;
+
+ req.fd = remote_fd;
+ req.flags = args->flags;
+ memcpy (req.gfid, args->fd->inode->gfid, 16);
+
+ rsp_iobref = iobref_new ();
+ if (rsp_iobref == NULL) {
+ op_errno = ENOMEM;
+ goto unwind;
+ }
+
+ /* TODO: what is the size we should send ? */
+ rsp_iobuf = iobuf_get2 (this->ctx->iobuf_pool, 8 * GF_UNIT_KB);
+ if (rsp_iobuf == NULL) {
+ op_errno = ENOMEM;
+ goto unwind;
+ }
+
+ iobref_add (rsp_iobref, rsp_iobuf);
+ iobuf_unref (rsp_iobuf);
+ rsphdr = &vector[0];
+ rsphdr->iov_base = iobuf_ptr (rsp_iobuf);
+ rsphdr->iov_len = iobuf_pagesize (rsp_iobuf);
+ count = 1;
+ local->iobref = rsp_iobref;
+ rsp_iobuf = NULL;
+ rsp_iobref = NULL;
+
+ if (args->xattr) {
+ GF_PROTOCOL_DICT_SERIALIZE (this, args->xattr,
+ (&req.dict.dict_val),
+ req.dict.dict_len,
+ op_errno, unwind);
+ }
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, args->xdata, (&req.xdata.xdata_val),
+ req.xdata.xdata_len, op_errno, unwind);
+
+ ret = client_submit_request (this, &req, frame, conf->fops,
+ GFS3_OP_FXATTROP,
+ client3_3_fxattrop_cbk, NULL,
+ rsphdr, count,
+ NULL, 0, local->iobref,
+ (xdrproc_t)xdr_gfs3_fxattrop_req);
+ if (ret) {
+ gf_log (this->name, GF_LOG_WARNING, "failed to send the fop");
+ }
+
+ GF_FREE (req.dict.dict_val);
+
+ GF_FREE (req.xdata.xdata_val);
+
+ return 0;
+unwind:
+ CLIENT_STACK_UNWIND (fxattrop, frame, -1, op_errno, NULL, NULL);
+
+ GF_FREE (req.dict.dict_val);
+
+ if (rsp_iobref)
+ iobref_unref (rsp_iobref);
+
+ if (rsp_iobuf)
+ iobuf_unref (rsp_iobuf);
+
+ GF_FREE (req.xdata.xdata_val);
+
+ return 0;
+}
+
+
+int32_t
+client3_3_removexattr (call_frame_t *frame, xlator_t *this,
+ void *data)
+{
+ clnt_conf_t *conf = NULL;
+ clnt_args_t *args = NULL;
+ gfs3_removexattr_req req = {{0,},};
+ int ret = 0;
+ int op_errno = ESTALE;
+
+ if (!frame || !this || !data)
+ goto unwind;
+
+ args = data;
+
+ if (!(args->loc && args->loc->inode))
+ goto unwind;
+
+ if (!uuid_is_null (args->loc->inode->gfid))
+ memcpy (req.gfid, args->loc->inode->gfid, 16);
+ else
+ memcpy (req.gfid, args->loc->gfid, 16);
+
+ GF_ASSERT_AND_GOTO_WITH_ERROR (this->name,
+ !uuid_is_null (*((uuid_t*)req.gfid)),
+ unwind, op_errno, EINVAL);
+ req.name = (char *)args->name;
+
+ conf = this->private;
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, args->xdata, (&req.xdata.xdata_val),
+ req.xdata.xdata_len, op_errno, unwind);
+
+ ret = client_submit_request (this, &req, frame, conf->fops,
+ GFS3_OP_REMOVEXATTR,
+ client3_3_removexattr_cbk, NULL,
+ NULL, 0, NULL, 0, NULL,
+ (xdrproc_t)xdr_gfs3_removexattr_req);
+ if (ret) {
+ gf_log (this->name, GF_LOG_WARNING, "failed to send the fop");
+ }
+
+ GF_FREE (req.xdata.xdata_val);
+
+ return 0;
+unwind:
+ CLIENT_STACK_UNWIND (removexattr, frame, -1, op_errno, NULL);
+ GF_FREE (req.xdata.xdata_val);
+
+ return 0;
+}
+
+int32_t
+client3_3_fremovexattr (call_frame_t *frame, xlator_t *this,
+ void *data)
+{
+ clnt_conf_t *conf = NULL;
+ clnt_args_t *args = NULL;
+ gfs3_fremovexattr_req req = {{0,},};
+ int ret = 0;
+ int64_t remote_fd = -1;
+ int op_errno = ESTALE;
+
+ if (!frame || !this || !data)
+ goto unwind;
+
+ args = data;
+
+ if (!(args->fd && args->fd->inode))
+ goto unwind;
+
+ conf = this->private;
+
+ CLIENT_GET_REMOTE_FD (this, args->fd, DEFAULT_REMOTE_FD,
+ remote_fd, op_errno, unwind);
+
+ memcpy (req.gfid, args->fd->inode->gfid, 16);
+ req.name = (char *)args->name;
+ req.fd = remote_fd;
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, args->xdata, (&req.xdata.xdata_val),
+ req.xdata.xdata_len, op_errno, unwind);
+
+ ret = client_submit_request (this, &req, frame, conf->fops,
+ GFS3_OP_FREMOVEXATTR,
+ client3_3_fremovexattr_cbk, NULL,
+ NULL, 0, NULL, 0, NULL,
+ (xdrproc_t)xdr_gfs3_fremovexattr_req);
+ if (ret) {
+ gf_log (this->name, GF_LOG_WARNING, "failed to send the fop");
+ }
+
+ GF_FREE (req.xdata.xdata_val);
+
+ return 0;
+unwind:
+ CLIENT_STACK_UNWIND (fremovexattr, frame, -1, op_errno, NULL);
+ GF_FREE (req.xdata.xdata_val);
+
+ return 0;
+}
+
+int32_t
+client3_3_lk (call_frame_t *frame, xlator_t *this,
+ void *data)
+{
+ clnt_args_t *args = NULL;
+ gfs3_lk_req req = {{0,},};
+ int32_t gf_cmd = 0;
+ int32_t gf_type = 0;
+ int64_t remote_fd = -1;
+ clnt_local_t *local = NULL;
+ clnt_conf_t *conf = NULL;
+ int op_errno = ESTALE;
+ int ret = 0;
+
+ if (!frame || !this || !data)
+ goto unwind;
+
+ args = data;
+ conf = this->private;
+ local = mem_get0 (this->local_pool);
+ if (!local) {
+ op_errno = ENOMEM;
+ goto unwind;
+ }
+
+ CLIENT_GET_REMOTE_FD (this, args->fd, DEFAULT_REMOTE_FD,
+ remote_fd, op_errno, unwind);
+
+ ret = client_cmd_to_gf_cmd (args->cmd, &gf_cmd);
+ if (ret) {
+ op_errno = EINVAL;
+ gf_log (this->name, GF_LOG_WARNING,
+ "Unknown cmd (%d)!", gf_cmd);
+ goto unwind;
+ }
+
+ switch (args->flock->l_type) {
+ case F_RDLCK:
+ gf_type = GF_LK_F_RDLCK;
+ break;
+ case F_WRLCK:
+ gf_type = GF_LK_F_WRLCK;
+ break;
+ case F_UNLCK:
+ gf_type = GF_LK_F_UNLCK;
+ break;
+ }
+
+ local->owner = frame->root->lk_owner;
+ local->cmd = args->cmd;
+ local->fd = fd_ref (args->fd);
+ frame->local = local;
+
+ req.fd = remote_fd;
+ req.cmd = gf_cmd;
+ req.type = gf_type;
+ gf_proto_flock_from_flock (&req.flock, args->flock);
+
+ memcpy (req.gfid, args->fd->inode->gfid, 16);
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, args->xdata, (&req.xdata.xdata_val),
+ req.xdata.xdata_len, op_errno, unwind);
+
+ ret = client_submit_request (this, &req, frame, conf->fops, GFS3_OP_LK,
+ client3_3_lk_cbk, NULL,
+ NULL, 0, NULL, 0, NULL,
+ (xdrproc_t)xdr_gfs3_lk_req);
+ if (ret) {
+ gf_log (this->name, GF_LOG_WARNING, "failed to send the fop");
+ }
+
+ GF_FREE (req.xdata.xdata_val);
+
+ return 0;
+unwind:
+ CLIENT_STACK_UNWIND (lk, frame, -1, op_errno, NULL, NULL);
+ GF_FREE (req.xdata.xdata_val);
+
+ return 0;
+}
+
+
+int32_t
+client3_3_inodelk (call_frame_t *frame, xlator_t *this,
+ void *data)
+{
+ clnt_conf_t *conf = NULL;
+ clnt_args_t *args = NULL;
+ gfs3_inodelk_req req = {{0,},};
+ int ret = 0;
+ int32_t gf_cmd = 0;
+ int32_t gf_type = 0;
+ int op_errno = ESTALE;
+
+ if (!frame || !this || !data)
+ goto unwind;
+
+ args = data;
+ if (!(args->loc && args->loc->inode))
+ goto unwind;
+
+ if (!uuid_is_null (args->loc->inode->gfid))
+ memcpy (req.gfid, args->loc->inode->gfid, 16);
+ else
+ memcpy (req.gfid, args->loc->gfid, 16);
+
+ GF_ASSERT_AND_GOTO_WITH_ERROR (this->name,
+ !uuid_is_null (*((uuid_t*)req.gfid)),
+ unwind, op_errno, EINVAL);
+ if (args->cmd == F_GETLK || args->cmd == F_GETLK64)
+ gf_cmd = GF_LK_GETLK;
+ else if (args->cmd == F_SETLK || args->cmd == F_SETLK64)
+ gf_cmd = GF_LK_SETLK;
+ else if (args->cmd == F_SETLKW || args->cmd == F_SETLKW64)
+ gf_cmd = GF_LK_SETLKW;
+ else {
+ gf_log (this->name, GF_LOG_WARNING,
+ "Unknown cmd (%d)!", gf_cmd);
+ op_errno = EINVAL;
+ goto unwind;
+ }
+
+ switch (args->flock->l_type) {
+ case F_RDLCK:
+ gf_type = GF_LK_F_RDLCK;
+ break;
+ case F_WRLCK:
+ gf_type = GF_LK_F_WRLCK;
+ break;
+ case F_UNLCK:
+ gf_type = GF_LK_F_UNLCK;
+ break;
+ }
+
+ req.volume = (char *)args->volume;
+ req.cmd = gf_cmd;
+ req.type = gf_type;
+ gf_proto_flock_from_flock (&req.flock, args->flock);
+
+ conf = this->private;
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, args->xdata, (&req.xdata.xdata_val),
+ req.xdata.xdata_len, op_errno, unwind);
+
+ ret = client_submit_request (this, &req, frame, conf->fops,
+ GFS3_OP_INODELK,
+ client3_3_inodelk_cbk, NULL,
+ NULL, 0, NULL, 0,
+ NULL, (xdrproc_t)xdr_gfs3_inodelk_req);
+ if (ret) {
+ gf_log (this->name, GF_LOG_WARNING, "failed to send the fop");
+ }
+
+ GF_FREE (req.xdata.xdata_val);
+
+ return 0;
+unwind:
+ CLIENT_STACK_UNWIND (inodelk, frame, -1, op_errno, NULL);
+ GF_FREE (req.xdata.xdata_val);
+
+ return 0;
+}
+
+
+
+int32_t
+client3_3_finodelk (call_frame_t *frame, xlator_t *this,
+ void *data)
+{
+ clnt_args_t *args = NULL;
+ gfs3_finodelk_req req = {{0,},};
+ int32_t gf_cmd = 0;
+ int32_t gf_type = 0;
+ int64_t remote_fd = -1;
+ clnt_conf_t *conf = NULL;
+ int op_errno = ESTALE;
+ int ret = 0;
+
+ if (!frame || !this || !data)
+ goto unwind;
+
+ args = data;
+ conf = this->private;
+ CLIENT_GET_REMOTE_FD (this, args->fd, FALLBACK_TO_ANON_FD,
+ remote_fd, op_errno, unwind);
+ ret = client_fd_fop_prepare_local (frame, args->fd, remote_fd);
+ if (ret) {
+ op_errno = -ret;
+ goto unwind;
+ }
+
+ if (args->cmd == F_GETLK || args->cmd == F_GETLK64)
+ gf_cmd = GF_LK_GETLK;
+ else if (args->cmd == F_SETLK || args->cmd == F_SETLK64)
+ gf_cmd = GF_LK_SETLK;
+ else if (args->cmd == F_SETLKW || args->cmd == F_SETLKW64)
+ gf_cmd = GF_LK_SETLKW;
+ else {
+ gf_log (this->name, GF_LOG_WARNING,
+ "Unknown cmd (%d)!", gf_cmd);
+ goto unwind;
+ }
+
+ switch (args->flock->l_type) {
+ case F_RDLCK:
+ gf_type = GF_LK_F_RDLCK;
+ break;
+ case F_WRLCK:
+ gf_type = GF_LK_F_WRLCK;
+ break;
+ case F_UNLCK:
+ gf_type = GF_LK_F_UNLCK;
+ break;
+ }
+
+ req.volume = (char *)args->volume;
+ req.fd = remote_fd;
+ req.cmd = gf_cmd;
+ req.type = gf_type;
+ gf_proto_flock_from_flock (&req.flock, args->flock);
+ memcpy (req.gfid, args->fd->inode->gfid, 16);
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, args->xdata, (&req.xdata.xdata_val),
+ req.xdata.xdata_len, op_errno, unwind);
+
+ ret = client_submit_request (this, &req, frame, conf->fops,
+ GFS3_OP_FINODELK,
+ client3_3_finodelk_cbk, NULL,
+ NULL, 0, NULL, 0,
+ NULL, (xdrproc_t)xdr_gfs3_finodelk_req);
+ if (ret) {
+ gf_log (this->name, GF_LOG_WARNING, "failed to send the fop");
+ }
+
+ GF_FREE (req.xdata.xdata_val);
+ return 0;
+unwind:
+ CLIENT_STACK_UNWIND (finodelk, frame, -1, op_errno, NULL);
+ GF_FREE (req.xdata.xdata_val);
+
+ return 0;
+}
+
+
+int32_t
+client3_3_entrylk (call_frame_t *frame, xlator_t *this,
+ void *data)
+{
+ clnt_conf_t *conf = NULL;
+ clnt_args_t *args = NULL;
+ gfs3_entrylk_req req = {{0,},};
+ int ret = 0;
+ int op_errno = ESTALE;
+
+ if (!frame || !this || !data)
+ goto unwind;
+
+ args = data;
+
+ if (!(args->loc && args->loc->inode))
+ goto unwind;
+
+ if (!uuid_is_null (args->loc->inode->gfid))
+ memcpy (req.gfid, args->loc->inode->gfid, 16);
+ else
+ memcpy (req.gfid, args->loc->gfid, 16);
+
+ GF_ASSERT_AND_GOTO_WITH_ERROR (this->name,
+ !uuid_is_null (*((uuid_t*)req.gfid)),
+ unwind, op_errno, EINVAL);
+ req.cmd = args->cmd_entrylk;
+ req.type = args->type;
+ req.volume = (char *)args->volume;
+ req.name = "";
+ if (args->basename) {
+ req.name = (char *)args->basename;
+ req.namelen = 1;
+ }
+
+ conf = this->private;
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, args->xdata, (&req.xdata.xdata_val),
+ req.xdata.xdata_len, op_errno, unwind);
+
+ ret = client_submit_request (this, &req, frame, conf->fops,
+ GFS3_OP_ENTRYLK,
+ client3_3_entrylk_cbk, NULL,
+ NULL, 0, NULL, 0,
+ NULL, (xdrproc_t)xdr_gfs3_entrylk_req);
+ if (ret) {
+ gf_log (this->name, GF_LOG_WARNING, "failed to send the fop");
+ }
+
+ GF_FREE (req.xdata.xdata_val);
+
+ return 0;
+unwind:
+ CLIENT_STACK_UNWIND (entrylk, frame, -1, op_errno, NULL);
+ GF_FREE (req.xdata.xdata_val);
+
+ return 0;
+}
+
+
+
+int32_t
+client3_3_fentrylk (call_frame_t *frame, xlator_t *this,
+ void *data)
+{
+ clnt_args_t *args = NULL;
+ gfs3_fentrylk_req req = {{0,},};
+ int64_t remote_fd = -1;
+ clnt_conf_t *conf = NULL;
+ int op_errno = ESTALE;
+ int ret = 0;
+
+ if (!frame || !this || !data)
+ goto unwind;
+
+ args = data;
+ conf = this->private;
+
+ CLIENT_GET_REMOTE_FD (this, args->fd, DEFAULT_REMOTE_FD,
+ remote_fd, op_errno, unwind);
+
+ req.fd = remote_fd;
+ req.cmd = args->cmd_entrylk;
+ req.type = args->type;
+ req.volume = (char *)args->volume;
+ req.name = "";
+ if (args->basename) {
+ req.name = (char *)args->basename;
+ req.namelen = 1;
+ }
+ memcpy (req.gfid, args->fd->inode->gfid, 16);
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, args->xdata, (&req.xdata.xdata_val),
+ req.xdata.xdata_len, op_errno, unwind);
+
+ ret = client_submit_request (this, &req, frame, conf->fops,
+ GFS3_OP_FENTRYLK,
+ client3_3_fentrylk_cbk, NULL,
+ NULL, 0, NULL, 0,
+ NULL, (xdrproc_t)xdr_gfs3_fentrylk_req);
+ if (ret) {
+ gf_log (this->name, GF_LOG_WARNING, "failed to send the fop");
+ }
+
+ GF_FREE (req.xdata.xdata_val);
+
+ return 0;
+unwind:
+ CLIENT_STACK_UNWIND (fentrylk, frame, -1, op_errno, NULL);
+ GF_FREE (req.xdata.xdata_val);
+
+ return 0;
+}
+
+
+int32_t
+client3_3_rchecksum (call_frame_t *frame, xlator_t *this,
+ void *data)
+{
+ clnt_args_t *args = NULL;
+ int64_t remote_fd = -1;
+ clnt_conf_t *conf = NULL;
+ gfs3_rchecksum_req req = {0,};
+ int op_errno = ESTALE;
+ int ret = 0;
+
+ if (!frame || !this || !data)
+ goto unwind;
+
+ args = data;
+ conf = this->private;
+
+ CLIENT_GET_REMOTE_FD (this, args->fd, DEFAULT_REMOTE_FD,
+ remote_fd, op_errno, unwind);
+
+ req.len = args->len;
+ req.offset = args->offset;
+ req.fd = remote_fd;
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, args->xdata, (&req.xdata.xdata_val),
+ req.xdata.xdata_len, op_errno, unwind);
+
+ ret = client_submit_request (this, &req, frame, conf->fops,
+ GFS3_OP_RCHECKSUM,
+ client3_3_rchecksum_cbk, NULL,
+ NULL, 0, NULL,
+ 0, NULL,
+ (xdrproc_t)xdr_gfs3_rchecksum_req);
+ if (ret) {
+ gf_log (this->name, GF_LOG_WARNING, "failed to send the fop");
+ }
+
+ GF_FREE (req.xdata.xdata_val);
+
+ return 0;
+unwind:
+ CLIENT_STACK_UNWIND (rchecksum, frame, -1, op_errno, 0, NULL, NULL);
+ GF_FREE (req.xdata.xdata_val);
+
+ return 0;
+}
+
+
+
+int32_t
+client3_3_readdir (call_frame_t *frame, xlator_t *this,
+ void *data)
+{
+ clnt_args_t *args = NULL;
+ int64_t remote_fd = -1;
+ clnt_conf_t *conf = NULL;
+ gfs3_readdir_req req = {{0,},};
+ gfs3_readdir_rsp rsp = {0, };
+ clnt_local_t *local = NULL;
+ int op_errno = ESTALE;
+ int ret = 0;
+ int count = 0;
+ struct iobref *rsp_iobref = NULL;
+ struct iobuf *rsp_iobuf = NULL;
+ struct iovec *rsphdr = NULL;
+ struct iovec vector[MAX_IOVEC] = {{0}, };
+ int readdir_rsp_size = 0;
+
+ if (!frame || !this || !data)
+ goto unwind;
+
+ args = data;
+ conf = this->private;
+
+ CLIENT_GET_REMOTE_FD (this, args->fd, DEFAULT_REMOTE_FD,
+ remote_fd, op_errno, unwind);
+
+ readdir_rsp_size = xdr_sizeof ((xdrproc_t) xdr_gfs3_readdir_rsp, &rsp)
+ + args->size;
+
+ if ((readdir_rsp_size + GLUSTERFS_RPC_REPLY_SIZE + GLUSTERFS_RDMA_MAX_HEADER_SIZE)
+ > (GLUSTERFS_RDMA_INLINE_THRESHOLD)) {
+ local = mem_get0 (this->local_pool);
+ if (!local) {
+ op_errno = ENOMEM;
+ goto unwind;
+ }
+ frame->local = local;
+
+ rsp_iobref = iobref_new ();
+ if (rsp_iobref == NULL) {
+ goto unwind;
+ }
+
+ /* TODO: what is the size we should send ? */
+ /* This iobuf will live for only receiving the response,
+ so not harmful */
+ rsp_iobuf = iobuf_get (this->ctx->iobuf_pool);
+ if (rsp_iobuf == NULL) {
+ goto unwind;
+ }
+
+ iobref_add (rsp_iobref, rsp_iobuf);
+ iobuf_unref (rsp_iobuf);
+
+ rsphdr = &vector[0];
+ rsphdr->iov_base = iobuf_ptr (rsp_iobuf);
+ rsphdr->iov_len = iobuf_pagesize (rsp_iobuf);
+ count = 1;
+ local->iobref = rsp_iobref;
+ rsp_iobuf = NULL;
+ rsp_iobref = NULL;
+ }
+
+ req.size = args->size;
+ req.offset = args->offset;
+ req.fd = remote_fd;
+
+ local->cmd = remote_fd;
+
+ memcpy (req.gfid, args->fd->inode->gfid, 16);
+ GF_PROTOCOL_DICT_SERIALIZE (this, args->xdata, (&req.xdata.xdata_val),
+ req.xdata.xdata_len, op_errno, unwind);
+
+ ret = client_submit_request (this, &req, frame, conf->fops,
+ GFS3_OP_READDIR,
+ client3_3_readdir_cbk, NULL,
+ rsphdr, count,
+ NULL, 0, rsp_iobref,
+ (xdrproc_t)xdr_gfs3_readdir_req);
+
+ if (ret) {
+ gf_log (this->name, GF_LOG_WARNING, "failed to send the fop");
+ }
+
+ GF_FREE (req.xdata.xdata_val);
+
+ if (rsp_iobuf)
+ iobuf_unref (rsp_iobuf);
+
+ if (rsp_iobref)
+ iobref_unref (rsp_iobref);
+
+ return 0;
+
+unwind:
+ if (rsp_iobref)
+ iobref_unref (rsp_iobref);
+
+ if (rsp_iobuf)
+ iobuf_unref (rsp_iobuf);
+
+ CLIENT_STACK_UNWIND (readdir, frame, -1, op_errno, NULL, NULL);
+ GF_FREE (req.xdata.xdata_val);
+
+ return 0;
+}
+
+
+int32_t
+client3_3_readdirp (call_frame_t *frame, xlator_t *this,
+ void *data)
+{
+ clnt_args_t *args = NULL;
+ gfs3_readdirp_req req = {{0,},};
+ gfs3_readdirp_rsp rsp = {0,};
+ int64_t remote_fd = -1;
+ clnt_conf_t *conf = NULL;
+ int op_errno = ESTALE;
+ int ret = 0;
+ int count = 0;
+ int readdirp_rsp_size = 0;
+ struct iobref *rsp_iobref = NULL;
+ struct iobuf *rsp_iobuf = NULL;
+ struct iovec *rsphdr = NULL;
+ struct iovec vector[MAX_IOVEC] = {{0}, };
+ clnt_local_t *local = NULL;
+
+ if (!frame || !this || !data)
+ goto unwind;
+
+ args = data;
+ conf = this->private;
+
+ CLIENT_GET_REMOTE_FD (this, args->fd, DEFAULT_REMOTE_FD,
+ remote_fd, op_errno, unwind);
+
+ readdirp_rsp_size = xdr_sizeof ((xdrproc_t) xdr_gfs3_readdirp_rsp, &rsp)
+ + args->size;
+
+ local = mem_get0 (this->local_pool);
+ if (!local) {
+ op_errno = ENOMEM;
+ goto unwind;
+ }
+ frame->local = local;
+
+ if ((readdirp_rsp_size + GLUSTERFS_RPC_REPLY_SIZE
+ + GLUSTERFS_RDMA_MAX_HEADER_SIZE)
+ > (GLUSTERFS_RDMA_INLINE_THRESHOLD)) {
+ rsp_iobref = iobref_new ();
+ if (rsp_iobref == NULL) {
+ goto unwind;
+ }
+
+ /* TODO: what is the size we should send ? */
+ /* This iobuf will live for only receiving the response,
+ so not harmful */
+ rsp_iobuf = iobuf_get (this->ctx->iobuf_pool);
+ if (rsp_iobuf == NULL) {
+ goto unwind;
+ }
+
+ iobref_add (rsp_iobref, rsp_iobuf);
+ iobuf_unref (rsp_iobuf);
+
+ rsphdr = &vector[0];
+ rsphdr->iov_base = iobuf_ptr (rsp_iobuf);
+ rsphdr->iov_len = iobuf_pagesize (rsp_iobuf);
+ count = 1;
+ local->iobref = rsp_iobref;
+ rsp_iobuf = NULL;
+ rsp_iobref = NULL;
+ }
+
+ local->fd = fd_ref (args->fd);
+
+ req.size = args->size;
+ req.offset = args->offset;
+ req.fd = remote_fd;
+ memcpy (req.gfid, args->fd->inode->gfid, 16);
+
+ /* dict itself is 'xdata' here */
+ GF_PROTOCOL_DICT_SERIALIZE (this, args->xdata, (&req.dict.dict_val),
+ req.dict.dict_len, op_errno, unwind);
+
+ ret = client_submit_request (this, &req, frame, conf->fops,
+ GFS3_OP_READDIRP,
+ client3_3_readdirp_cbk, NULL,
+ rsphdr, count, NULL,
+ 0, rsp_iobref,
+ (xdrproc_t)xdr_gfs3_readdirp_req);
+ if (ret) {
+ gf_log (this->name, GF_LOG_WARNING, "failed to send the fop");
+ }
+
+ GF_FREE (req.dict.dict_val);
+
+ if (rsp_iobuf)
+ iobuf_unref (rsp_iobuf);
+
+ if (rsp_iobref)
+ iobref_unref (rsp_iobref);
+
+ return 0;
+unwind:
+ if (rsp_iobref)
+ iobref_unref (rsp_iobref);
+
+ if (rsp_iobuf)
+ iobuf_unref (rsp_iobuf);
+
+ GF_FREE (req.dict.dict_val);
+
+ CLIENT_STACK_UNWIND (readdirp, frame, -1, op_errno, NULL, NULL);
+ return 0;
+}
+
+
+int32_t
+client3_3_setattr (call_frame_t *frame, xlator_t *this,
+ void *data)
+{
+ clnt_conf_t *conf = NULL;
+ clnt_args_t *args = NULL;
+ gfs3_setattr_req req = {{0,},};
+ int ret = 0;
+ int op_errno = ESTALE;
+
+ if (!frame || !this || !data)
+ goto unwind;
+
+ args = data;
+
+ if (!(args->loc && args->loc->inode))
+ goto unwind;
+
+ if (!uuid_is_null (args->loc->inode->gfid))
+ memcpy (req.gfid, args->loc->inode->gfid, 16);
+ else
+ memcpy (req.gfid, args->loc->gfid, 16);
+
+ GF_ASSERT_AND_GOTO_WITH_ERROR (this->name,
+ !uuid_is_null (*((uuid_t*)req.gfid)),
+ unwind, op_errno, EINVAL);
+ req.valid = args->valid;
+ gf_stat_from_iatt (&req.stbuf, args->stbuf);
+
+ conf = this->private;
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, args->xdata, (&req.xdata.xdata_val),
+ req.xdata.xdata_len, op_errno, unwind);
+
+ ret = client_submit_request (this, &req, frame, conf->fops,
+ GFS3_OP_SETATTR,
+ client3_3_setattr_cbk, NULL,
+ NULL, 0, NULL, 0,
+ NULL, (xdrproc_t)xdr_gfs3_setattr_req);
+ if (ret) {
+ gf_log (this->name, GF_LOG_WARNING, "failed to send the fop");
+ }
+
+ GF_FREE (req.xdata.xdata_val);
+
+ return 0;
+unwind:
+ CLIENT_STACK_UNWIND (setattr, frame, -1, op_errno, NULL, NULL, NULL);
+ GF_FREE (req.xdata.xdata_val);
+
+ return 0;
+}
+
+int32_t
+client3_3_fsetattr (call_frame_t *frame, xlator_t *this, void *data)
+{
+ clnt_args_t *args = NULL;
+ int64_t remote_fd = -1;
+ clnt_conf_t *conf = NULL;
+ gfs3_fsetattr_req req = {0,};
+ int op_errno = ESTALE;
+ int ret = 0;
+
+ if (!frame || !this || !data)
+ goto unwind;
+
+ args = data;
+ conf = this->private;
+
+ CLIENT_GET_REMOTE_FD (this, args->fd, DEFAULT_REMOTE_FD,
+ remote_fd, op_errno, unwind);
+
+ req.fd = remote_fd;
+ req.valid = args->valid;
+ gf_stat_from_iatt (&req.stbuf, args->stbuf);
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, args->xdata, (&req.xdata.xdata_val),
+ req.xdata.xdata_len, op_errno, unwind);
+
+ ret = client_submit_request (this, &req, frame, conf->fops,
+ GFS3_OP_FSETATTR,
+ client3_3_fsetattr_cbk, NULL,
+ NULL, 0, NULL, 0,
+ NULL, (xdrproc_t)xdr_gfs3_fsetattr_req);
+ if (ret) {
+ gf_log (this->name, GF_LOG_WARNING, "failed to send the fop");
+ }
+
+ GF_FREE (req.xdata.xdata_val);
+
+ return 0;
+unwind:
+ CLIENT_STACK_UNWIND (fsetattr, frame, -1, op_errno, NULL, NULL, NULL);
+ GF_FREE (req.xdata.xdata_val);
+
+ return 0;
+}
+
+int32_t
+client3_3_fallocate(call_frame_t *frame, xlator_t *this, void *data)
+{
+ clnt_args_t *args = NULL;
+ int64_t remote_fd = -1;
+ clnt_conf_t *conf = NULL;
+ gfs3_fallocate_req req = {{0},};
+ int op_errno = ESTALE;
+ int ret = 0;
+
+ if (!frame || !this || !data)
+ goto unwind;
+
+ args = data;
+ conf = this->private;
+
+ CLIENT_GET_REMOTE_FD (this, args->fd, DEFAULT_REMOTE_FD,
+ remote_fd, op_errno, unwind);
+
+ req.fd = remote_fd;
+ req.flags = args->flags;
+ req.offset = args->offset;
+ req.size = args->size;
+ memcpy(req.gfid, args->fd->inode->gfid, 16);
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, args->xdata, (&req.xdata.xdata_val),
+ req.xdata.xdata_len, op_errno, unwind);
+
+ ret = client_submit_request (this, &req, frame, conf->fops,
+ GFS3_OP_FALLOCATE,
+ client3_3_fallocate_cbk, NULL,
+ NULL, 0, NULL, 0,
+ NULL, (xdrproc_t)xdr_gfs3_fallocate_req);
+ if (ret) {
+ gf_log (this->name, GF_LOG_WARNING, "failed to send the fop");
+ }
+
+ GF_FREE (req.xdata.xdata_val);
+
+ return 0;
+unwind:
+ CLIENT_STACK_UNWIND (fallocate, frame, -1, op_errno, NULL, NULL, NULL);
+ GF_FREE (req.xdata.xdata_val);
+
+ return 0;
+}
+
+int32_t
+client3_3_discard(call_frame_t *frame, xlator_t *this, void *data)
+{
+ clnt_args_t *args = NULL;
+ int64_t remote_fd = -1;
+ clnt_conf_t *conf = NULL;
+ gfs3_discard_req req = {{0},};
+ int op_errno = ESTALE;
+ int ret = 0;
+
+ if (!frame || !this || !data)
+ goto unwind;
+
+ args = data;
+ conf = this->private;
+
+ CLIENT_GET_REMOTE_FD (this, args->fd, DEFAULT_REMOTE_FD,
+ remote_fd, op_errno, unwind);
+
+ req.fd = remote_fd;
+ req.offset = args->offset;
+ req.size = args->size;
+ memcpy(req.gfid, args->fd->inode->gfid, 16);
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, args->xdata, (&req.xdata.xdata_val),
+ req.xdata.xdata_len, op_errno, unwind);
+
+ ret = client_submit_request(this, &req, frame, conf->fops,
+ GFS3_OP_DISCARD, client3_3_discard_cbk,
+ NULL, NULL, 0, NULL, 0, NULL,
+ (xdrproc_t) xdr_gfs3_discard_req);
+ if (ret)
+ gf_log (this->name, GF_LOG_WARNING, "failed to send the fop");
+
+ GF_FREE (req.xdata.xdata_val);
+
+ return 0;
+unwind:
+ CLIENT_STACK_UNWIND(discard, frame, -1, op_errno, NULL, NULL, NULL);
+ GF_FREE (req.xdata.xdata_val);
+
+ return 0;
+}
+
+int32_t
+client3_3_zerofill(call_frame_t *frame, xlator_t *this, void *data)
+{
+ clnt_args_t *args = NULL;
+ int64_t remote_fd = -1;
+ clnt_conf_t *conf = NULL;
+ gfs3_zerofill_req req = {{0},};
+ int op_errno = ESTALE;
+ int ret = 0;
+
+ if (!frame || !this || !data)
+ goto unwind;
+
+ args = data;
+ conf = this->private;
+
+ CLIENT_GET_REMOTE_FD (this, args->fd, DEFAULT_REMOTE_FD,
+ remote_fd, op_errno, unwind);
+
+ req.fd = remote_fd;
+ req.offset = args->offset;
+ req.size = args->size;
+ memcpy(req.gfid, args->fd->inode->gfid, 16);
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, args->xdata, (&req.xdata.xdata_val),
+ req.xdata.xdata_len, op_errno, unwind);
+
+ ret = client_submit_request(this, &req, frame, conf->fops,
+ GFS3_OP_ZEROFILL, client3_3_zerofill_cbk,
+ NULL, NULL, 0, NULL, 0, NULL,
+ (xdrproc_t) xdr_gfs3_zerofill_req);
+ if (ret)
+ gf_log (this->name, GF_LOG_WARNING, "failed to send the fop");
+
+ GF_FREE (req.xdata.xdata_val);
+
+ return 0;
+unwind:
+ CLIENT_STACK_UNWIND(zerofill, frame, -1, op_errno, NULL, NULL, NULL);
+ GF_FREE (req.xdata.xdata_val);
+
+ return 0;
+}
+
+/* Table Specific to FOPS */
+
+
+rpc_clnt_procedure_t clnt3_3_fop_actors[GF_FOP_MAXVALUE] = {
+ [GF_FOP_NULL] = { "NULL", NULL},
+ [GF_FOP_STAT] = { "STAT", client3_3_stat },
+ [GF_FOP_READLINK] = { "READLINK", client3_3_readlink },
+ [GF_FOP_MKNOD] = { "MKNOD", client3_3_mknod },
+ [GF_FOP_MKDIR] = { "MKDIR", client3_3_mkdir },
+ [GF_FOP_UNLINK] = { "UNLINK", client3_3_unlink },
+ [GF_FOP_RMDIR] = { "RMDIR", client3_3_rmdir },
+ [GF_FOP_SYMLINK] = { "SYMLINK", client3_3_symlink },
+ [GF_FOP_RENAME] = { "RENAME", client3_3_rename },
+ [GF_FOP_LINK] = { "LINK", client3_3_link },
+ [GF_FOP_TRUNCATE] = { "TRUNCATE", client3_3_truncate },
+ [GF_FOP_OPEN] = { "OPEN", client3_3_open },
+ [GF_FOP_READ] = { "READ", client3_3_readv },
+ [GF_FOP_WRITE] = { "WRITE", client3_3_writev },
+ [GF_FOP_STATFS] = { "STATFS", client3_3_statfs },
+ [GF_FOP_FLUSH] = { "FLUSH", client3_3_flush },
+ [GF_FOP_FSYNC] = { "FSYNC", client3_3_fsync },
+ [GF_FOP_SETXATTR] = { "SETXATTR", client3_3_setxattr },
+ [GF_FOP_GETXATTR] = { "GETXATTR", client3_3_getxattr },
+ [GF_FOP_REMOVEXATTR] = { "REMOVEXATTR", client3_3_removexattr },
+ [GF_FOP_OPENDIR] = { "OPENDIR", client3_3_opendir },
+ [GF_FOP_FSYNCDIR] = { "FSYNCDIR", client3_3_fsyncdir },
+ [GF_FOP_ACCESS] = { "ACCESS", client3_3_access },
+ [GF_FOP_CREATE] = { "CREATE", client3_3_create },
+ [GF_FOP_FTRUNCATE] = { "FTRUNCATE", client3_3_ftruncate },
+ [GF_FOP_FSTAT] = { "FSTAT", client3_3_fstat },
+ [GF_FOP_LK] = { "LK", client3_3_lk },
+ [GF_FOP_LOOKUP] = { "LOOKUP", client3_3_lookup },
+ [GF_FOP_READDIR] = { "READDIR", client3_3_readdir },
+ [GF_FOP_INODELK] = { "INODELK", client3_3_inodelk },
+ [GF_FOP_FINODELK] = { "FINODELK", client3_3_finodelk },
+ [GF_FOP_ENTRYLK] = { "ENTRYLK", client3_3_entrylk },
+ [GF_FOP_FENTRYLK] = { "FENTRYLK", client3_3_fentrylk },
+ [GF_FOP_XATTROP] = { "XATTROP", client3_3_xattrop },
+ [GF_FOP_FXATTROP] = { "FXATTROP", client3_3_fxattrop },
+ [GF_FOP_FGETXATTR] = { "FGETXATTR", client3_3_fgetxattr },
+ [GF_FOP_FSETXATTR] = { "FSETXATTR", client3_3_fsetxattr },
+ [GF_FOP_RCHECKSUM] = { "RCHECKSUM", client3_3_rchecksum },
+ [GF_FOP_SETATTR] = { "SETATTR", client3_3_setattr },
+ [GF_FOP_FSETATTR] = { "FSETATTR", client3_3_fsetattr },
+ [GF_FOP_READDIRP] = { "READDIRP", client3_3_readdirp },
+ [GF_FOP_FALLOCATE] = { "FALLOCATE", client3_3_fallocate },
+ [GF_FOP_DISCARD] = { "DISCARD", client3_3_discard },
+ [GF_FOP_ZEROFILL] = { "ZEROFILL", client3_3_zerofill},
+ [GF_FOP_RELEASE] = { "RELEASE", client3_3_release },
+ [GF_FOP_RELEASEDIR] = { "RELEASEDIR", client3_3_releasedir },
+ [GF_FOP_GETSPEC] = { "GETSPEC", client3_getspec },
+ [GF_FOP_FREMOVEXATTR] = { "FREMOVEXATTR", client3_3_fremovexattr },
+};
+
+/* Used From RPC-CLNT library to log proper name of procedure based on number */
+char *clnt3_3_fop_names[GFS3_OP_MAXVALUE] = {
+ [GFS3_OP_NULL] = "NULL",
+ [GFS3_OP_STAT] = "STAT",
+ [GFS3_OP_READLINK] = "READLINK",
+ [GFS3_OP_MKNOD] = "MKNOD",
+ [GFS3_OP_MKDIR] = "MKDIR",
+ [GFS3_OP_UNLINK] = "UNLINK",
+ [GFS3_OP_RMDIR] = "RMDIR",
+ [GFS3_OP_SYMLINK] = "SYMLINK",
+ [GFS3_OP_RENAME] = "RENAME",
+ [GFS3_OP_LINK] = "LINK",
+ [GFS3_OP_TRUNCATE] = "TRUNCATE",
+ [GFS3_OP_OPEN] = "OPEN",
+ [GFS3_OP_READ] = "READ",
+ [GFS3_OP_WRITE] = "WRITE",
+ [GFS3_OP_STATFS] = "STATFS",
+ [GFS3_OP_FLUSH] = "FLUSH",
+ [GFS3_OP_FSYNC] = "FSYNC",
+ [GFS3_OP_SETXATTR] = "SETXATTR",
+ [GFS3_OP_GETXATTR] = "GETXATTR",
+ [GFS3_OP_REMOVEXATTR] = "REMOVEXATTR",
+ [GFS3_OP_OPENDIR] = "OPENDIR",
+ [GFS3_OP_FSYNCDIR] = "FSYNCDIR",
+ [GFS3_OP_ACCESS] = "ACCESS",
+ [GFS3_OP_CREATE] = "CREATE",
+ [GFS3_OP_FTRUNCATE] = "FTRUNCATE",
+ [GFS3_OP_FSTAT] = "FSTAT",
+ [GFS3_OP_LK] = "LK",
+ [GFS3_OP_LOOKUP] = "LOOKUP",
+ [GFS3_OP_READDIR] = "READDIR",
+ [GFS3_OP_INODELK] = "INODELK",
+ [GFS3_OP_FINODELK] = "FINODELK",
+ [GFS3_OP_ENTRYLK] = "ENTRYLK",
+ [GFS3_OP_FENTRYLK] = "FENTRYLK",
+ [GFS3_OP_XATTROP] = "XATTROP",
+ [GFS3_OP_FXATTROP] = "FXATTROP",
+ [GFS3_OP_FGETXATTR] = "FGETXATTR",
+ [GFS3_OP_FSETXATTR] = "FSETXATTR",
+ [GFS3_OP_RCHECKSUM] = "RCHECKSUM",
+ [GFS3_OP_SETATTR] = "SETATTR",
+ [GFS3_OP_FSETATTR] = "FSETATTR",
+ [GFS3_OP_READDIRP] = "READDIRP",
+ [GFS3_OP_RELEASE] = "RELEASE",
+ [GFS3_OP_RELEASEDIR] = "RELEASEDIR",
+ [GFS3_OP_FREMOVEXATTR] = "FREMOVEXATTR",
+ [GFS3_OP_FALLOCATE] = "FALLOCATE",
+ [GFS3_OP_DISCARD] = "DISCARD",
+ [GFS3_OP_ZEROFILL] = "ZEROFILL",
+
+};
+
+rpc_clnt_prog_t clnt3_3_fop_prog = {
+ .progname = "GlusterFS 3.3",
+ .prognum = GLUSTER_FOP_PROGRAM,
+ .progver = GLUSTER_FOP_VERSION,
+ .numproc = GLUSTER_FOP_PROCCNT,
+ .proctable = clnt3_3_fop_actors,
+ .procnames = clnt3_3_fop_names,
+};
diff --git a/xlators/protocol/client/src/client.c b/xlators/protocol/client/src/client.c
new file mode 100644
index 000000000..1f7d13ea4
--- /dev/null
+++ b/xlators/protocol/client/src/client.c
@@ -0,0 +1,2867 @@
+/*
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
+ This file is part of GlusterFS.
+
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
+*/
+
+
+#ifndef _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+#include "client.h"
+#include "xlator.h"
+#include "defaults.h"
+#include "glusterfs.h"
+#include "statedump.h"
+#include "compat-errno.h"
+
+#include "glusterfs3.h"
+
+extern rpc_clnt_prog_t clnt_handshake_prog;
+extern rpc_clnt_prog_t clnt_dump_prog;
+extern struct rpcclnt_cb_program gluster_cbk_prog;
+
+int client_handshake (xlator_t *this, struct rpc_clnt *rpc);
+void client_start_ping (void *data);
+int client_init_rpc (xlator_t *this);
+int client_destroy_rpc (xlator_t *this);
+int client_mark_fd_bad (xlator_t *this);
+
+int32_t
+client_type_to_gf_type (short l_type)
+{
+ int32_t gf_type = GF_LK_EOL;
+
+ switch (l_type) {
+ case F_RDLCK:
+ gf_type = GF_LK_F_RDLCK;
+ break;
+ case F_WRLCK:
+ gf_type = GF_LK_F_WRLCK;
+ break;
+ case F_UNLCK:
+ gf_type = GF_LK_F_UNLCK;
+ break;
+ }
+
+ return gf_type;
+}
+
+uint32_t
+client_get_lk_ver (clnt_conf_t *conf)
+{
+ uint32_t lk_ver = 0;
+
+ GF_VALIDATE_OR_GOTO ("client", conf, out);
+
+ pthread_mutex_lock (&conf->lock);
+ {
+ lk_ver = conf->lk_version;
+ }
+ pthread_mutex_unlock (&conf->lock);
+out:
+ return lk_ver;
+}
+
+void
+client_grace_timeout (void *data)
+{
+ int ver = 0;
+ xlator_t *this = NULL;
+ struct clnt_conf *conf = NULL;
+ struct rpc_clnt *rpc = NULL;
+
+ GF_VALIDATE_OR_GOTO ("client", data, out);
+
+ this = THIS;
+
+ rpc = (struct rpc_clnt *) data;
+
+ conf = (struct clnt_conf *) this->private;
+
+ pthread_mutex_lock (&conf->lock);
+ {
+ ver = ++conf->lk_version;
+ /* ver == 0 is a special value used by server
+ to notify client that this is a fresh connect.*/
+ if (ver == 0)
+ ver = ++conf->lk_version;
+
+ gf_timer_call_cancel (this->ctx, conf->grace_timer);
+ conf->grace_timer = NULL;
+ }
+ pthread_mutex_unlock (&conf->lock);
+
+ gf_log (this->name, GF_LOG_WARNING,
+ "client grace timer expired, updating "
+ "the lk-version to %d", ver);
+
+ client_mark_fd_bad (this);
+out:
+ return;
+}
+
+int32_t
+client_register_grace_timer (xlator_t *this, clnt_conf_t *conf)
+{
+ int32_t ret = -1;
+
+ GF_VALIDATE_OR_GOTO ("client", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, conf, out);
+
+ pthread_mutex_lock (&conf->lock);
+ {
+ if (conf->grace_timer || !conf->grace_timer_needed) {
+ gf_log (this->name, GF_LOG_TRACE,
+ "Client grace timer is already set "
+ "or a grace-timer has already time out, "
+ "not registering a new timer");
+ } else {
+ gf_log (this->name, GF_LOG_INFO,
+ "Registering a grace timer");
+
+ conf->grace_timer_needed = _gf_false;
+
+ conf->grace_timer =
+ gf_timer_call_after (this->ctx,
+ conf->grace_ts,
+ client_grace_timeout,
+ conf->rpc);
+ }
+ }
+ pthread_mutex_unlock (&conf->lock);
+
+ ret = 0;
+out:
+ return ret;
+}
+
+int
+client_submit_request (xlator_t *this, void *req, call_frame_t *frame,
+ rpc_clnt_prog_t *prog, int procnum, fop_cbk_fn_t cbkfn,
+ struct iobref *iobref, struct iovec *rsphdr,
+ int rsphdr_count, struct iovec *rsp_payload,
+ int rsp_payload_count, struct iobref *rsp_iobref,
+ xdrproc_t xdrproc)
+{
+ int ret = -1;
+ clnt_conf_t *conf = NULL;
+ struct iovec iov = {0, };
+ struct iobuf *iobuf = NULL;
+ int count = 0;
+ char start_ping = 0;
+ struct iobref *new_iobref = NULL;
+ ssize_t xdr_size = 0;
+ struct rpc_req rpcreq = {0, };
+
+ GF_VALIDATE_OR_GOTO ("client", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, prog, out);
+ GF_VALIDATE_OR_GOTO (this->name, frame, out);
+
+ conf = this->private;
+
+ /* If 'setvolume' is not successful, we should not send frames to
+ server, mean time we should be able to send 'DUMP' and 'SETVOLUME'
+ call itself even if its not connected */
+ if (!(conf->connected ||
+ ((prog->prognum == GLUSTER_DUMP_PROGRAM) ||
+ (prog->prognum == GLUSTER_PMAP_PROGRAM) ||
+ ((prog->prognum == GLUSTER_HNDSK_PROGRAM) &&
+ (procnum == GF_HNDSK_SETVOLUME))))) {
+ /* This particular error captured/logged in
+ functions calling this */
+ gf_log (this->name, GF_LOG_DEBUG,
+ "connection in disconnected state");
+ goto out;
+ }
+
+ if (req && xdrproc) {
+ xdr_size = xdr_sizeof (xdrproc, req);
+ iobuf = iobuf_get2 (this->ctx->iobuf_pool, xdr_size);
+ if (!iobuf) {
+ goto out;
+ };
+
+ new_iobref = iobref_new ();
+ if (!new_iobref) {
+ goto out;
+ }
+
+ if (iobref != NULL) {
+ ret = iobref_merge (new_iobref, iobref);
+ if (ret != 0) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "cannot merge iobref passed from caller "
+ "into new_iobref");
+ }
+ }
+
+ ret = iobref_add (new_iobref, iobuf);
+ if (ret != 0) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "cannot add iobuf into iobref");
+ goto out;
+ }
+
+ iov.iov_base = iobuf->ptr;
+ iov.iov_len = iobuf_size (iobuf);
+
+ /* Create the xdr payload */
+ ret = xdr_serialize_generic (iov, req, xdrproc);
+ if (ret == -1) {
+ /* callingfn so that, we can get to know which xdr
+ function was called */
+ gf_log_callingfn (this->name, GF_LOG_WARNING,
+ "XDR payload creation failed");
+ goto out;
+ }
+ iov.iov_len = ret;
+ count = 1;
+ }
+
+ /* Send the msg */
+ ret = rpc_clnt_submit (conf->rpc, prog, procnum, cbkfn, &iov, count,
+ NULL, 0, new_iobref, frame, rsphdr, rsphdr_count,
+ rsp_payload, rsp_payload_count, rsp_iobref);
+
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_DEBUG, "rpc_clnt_submit failed");
+ }
+
+ if (ret == 0) {
+ pthread_mutex_lock (&conf->rpc->conn.lock);
+ {
+ if (!conf->rpc->conn.ping_started) {
+ start_ping = 1;
+ }
+ }
+ pthread_mutex_unlock (&conf->rpc->conn.lock);
+ }
+
+ if (start_ping)
+ client_start_ping ((void *) this);
+
+ ret = 0;
+
+ if (new_iobref)
+ iobref_unref (new_iobref);
+
+ if (iobuf)
+ iobuf_unref (iobuf);
+
+ return ret;
+
+out:
+ rpcreq.rpc_status = -1;
+
+ cbkfn (&rpcreq, NULL, 0, frame);
+
+ if (new_iobref)
+ iobref_unref (new_iobref);
+
+ if (iobuf)
+ iobuf_unref (iobuf);
+
+ return 0;
+}
+
+
+int32_t
+client_forget (xlator_t *this, inode_t *inode)
+{
+ /* Nothing here */
+ return 0;
+}
+
+int32_t
+client_releasedir (xlator_t *this, fd_t *fd)
+{
+ int ret = -1;
+ clnt_conf_t *conf = NULL;
+ rpc_clnt_procedure_t *proc = NULL;
+ clnt_args_t args = {0,};
+
+ conf = this->private;
+ if (!conf || !conf->fops)
+ goto out;
+
+ args.fd = fd;
+
+ proc = &conf->fops->proctable[GF_FOP_RELEASEDIR];
+ if (!proc) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "rpc procedure not found for %s",
+ gf_fop_list[GF_FOP_RELEASEDIR]);
+ goto out;
+ }
+ if (proc->fn) {
+ ret = proc->fn (NULL, this, &args);
+ }
+out:
+ if (ret)
+ gf_log (this->name, GF_LOG_WARNING,
+ "releasedir fop failed");
+ return 0;
+}
+
+int32_t
+client_release (xlator_t *this, fd_t *fd)
+{
+ int ret = -1;
+ clnt_conf_t *conf = NULL;
+ rpc_clnt_procedure_t *proc = NULL;
+ clnt_args_t args = {0,};
+
+ conf = this->private;
+ if (!conf || !conf->fops)
+ goto out;
+
+ args.fd = fd;
+ proc = &conf->fops->proctable[GF_FOP_RELEASE];
+ if (!proc) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "rpc procedure not found for %s",
+ gf_fop_list[GF_FOP_RELEASE]);
+ goto out;
+ }
+ if (proc->fn) {
+ ret = proc->fn (NULL, this, &args);
+ }
+out:
+ if (ret)
+ gf_log (this->name, GF_LOG_WARNING,
+ "release fop failed");
+ return 0;
+}
+
+
+int32_t
+client_lookup (call_frame_t *frame, xlator_t *this, loc_t *loc,
+ dict_t *xdata)
+{
+ int ret = -1;
+ clnt_conf_t *conf = NULL;
+ rpc_clnt_procedure_t *proc = NULL;
+ clnt_args_t args = {0,};
+
+ conf = this->private;
+ if (!conf || !conf->fops)
+ goto out;
+
+ args.loc = loc;
+ args.xdata = xdata;
+
+ proc = &conf->fops->proctable[GF_FOP_LOOKUP];
+ if (!proc) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "rpc procedure not found for %s",
+ gf_fop_list[GF_FOP_LOOKUP]);
+ goto out;
+ }
+ if (proc->fn)
+ ret = proc->fn (frame, this, &args);
+out:
+ /* think of avoiding a missing frame */
+ if (ret)
+ STACK_UNWIND_STRICT (lookup, frame, -1, ENOTCONN,
+ NULL, NULL, NULL, NULL);
+
+ return 0;
+}
+
+
+int32_t
+client_stat (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)
+{
+ int ret = -1;
+ clnt_conf_t *conf = NULL;
+ rpc_clnt_procedure_t *proc = NULL;
+ clnt_args_t args = {0,};
+
+ conf = this->private;
+ if (!conf || !conf->fops)
+ goto out;
+
+ args.loc = loc;
+ args.xdata = xdata;
+
+ proc = &conf->fops->proctable[GF_FOP_STAT];
+ if (!proc) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "rpc procedure not found for %s",
+ gf_fop_list[GF_FOP_STAT]);
+ goto out;
+ }
+ if (proc->fn)
+ ret = proc->fn (frame, this, &args);
+out:
+ if (ret)
+ STACK_UNWIND_STRICT (stat, frame, -1, ENOTCONN, NULL, NULL);
+
+ return 0;
+}
+
+
+int32_t
+client_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc,
+ off_t offset, dict_t *xdata)
+{
+ int ret = -1;
+ clnt_conf_t *conf = NULL;
+ rpc_clnt_procedure_t *proc = NULL;
+ clnt_args_t args = {0,};
+
+ conf = this->private;
+ if (!conf || !conf->fops)
+ goto out;
+
+ args.loc = loc;
+ args.offset = offset;
+ args.xdata = xdata;
+
+ proc = &conf->fops->proctable[GF_FOP_TRUNCATE];
+ if (!proc) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "rpc procedure not found for %s",
+ gf_fop_list[GF_FOP_TRUNCATE]);
+ goto out;
+ }
+ if (proc->fn)
+ ret = proc->fn (frame, this, &args);
+out:
+ if (ret)
+ STACK_UNWIND_STRICT (truncate, frame, -1, ENOTCONN, NULL, NULL, NULL);
+
+
+ return 0;
+}
+
+
+int32_t
+client_ftruncate (call_frame_t *frame, xlator_t *this, fd_t *fd,
+ off_t offset, dict_t *xdata)
+{
+ int ret = -1;
+ clnt_conf_t *conf = NULL;
+ rpc_clnt_procedure_t *proc = NULL;
+ clnt_args_t args = {0,};
+
+ conf = this->private;
+ if (!conf || !conf->fops)
+ goto out;
+
+ args.fd = fd;
+ args.offset = offset;
+ args.xdata = xdata;
+
+ proc = &conf->fops->proctable[GF_FOP_FTRUNCATE];
+ if (!proc) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "rpc procedure not found for %s",
+ gf_fop_list[GF_FOP_FTRUNCATE]);
+ goto out;
+ }
+ if (proc->fn)
+ ret = proc->fn (frame, this, &args);
+out:
+ if (ret)
+ STACK_UNWIND_STRICT (ftruncate, frame, -1, ENOTCONN, NULL, NULL, NULL);
+
+ return 0;
+}
+
+
+
+int32_t
+client_access (call_frame_t *frame, xlator_t *this, loc_t *loc,
+ int32_t mask, dict_t *xdata)
+{
+ int ret = -1;
+ clnt_conf_t *conf = NULL;
+ rpc_clnt_procedure_t *proc = NULL;
+ clnt_args_t args = {0,};
+
+ conf = this->private;
+ if (!conf || !conf->fops)
+ goto out;
+
+ args.loc = loc;
+ args.mask = mask;
+ args.xdata = xdata;
+
+ proc = &conf->fops->proctable[GF_FOP_ACCESS];
+ if (!proc) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "rpc procedure not found for %s",
+ gf_fop_list[GF_FOP_ACCESS]);
+ goto out;
+ }
+ if (proc->fn)
+ ret = proc->fn (frame, this, &args);
+out:
+ if (ret)
+ STACK_UNWIND_STRICT (access, frame, -1, ENOTCONN, NULL);
+
+ return 0;
+}
+
+
+
+
+int32_t
+client_readlink (call_frame_t *frame, xlator_t *this, loc_t *loc,
+ size_t size, dict_t *xdata)
+{
+ int ret = -1;
+ clnt_conf_t *conf = NULL;
+ rpc_clnt_procedure_t *proc = NULL;
+ clnt_args_t args = {0,};
+
+ conf = this->private;
+ if (!conf || !conf->fops)
+ goto out;
+
+ args.loc = loc;
+ args.size = size;
+ args.xdata = xdata;
+
+ proc = &conf->fops->proctable[GF_FOP_READLINK];
+ if (!proc) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "rpc procedure not found for %s",
+ gf_fop_list[GF_FOP_READLINK]);
+ goto out;
+ }
+ if (proc->fn)
+ ret = proc->fn (frame, this, &args);
+out:
+ if (ret)
+ STACK_UNWIND_STRICT (readlink, frame, -1, ENOTCONN, NULL, NULL, NULL);
+
+ return 0;
+}
+
+
+int
+client_mknod (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
+ dev_t rdev, mode_t umask, dict_t *xdata)
+{
+ int ret = -1;
+ clnt_conf_t *conf = NULL;
+ rpc_clnt_procedure_t *proc = NULL;
+ clnt_args_t args = {0,};
+
+ conf = this->private;
+ if (!conf || !conf->fops)
+ goto out;
+
+ args.loc = loc;
+ args.mode = mode;
+ args.rdev = rdev;
+ args.umask = umask;
+ args.xdata = xdata;
+
+ proc = &conf->fops->proctable[GF_FOP_MKNOD];
+ if (!proc) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "rpc procedure not found for %s",
+ gf_fop_list[GF_FOP_MKNOD]);
+ goto out;
+ }
+ if (proc->fn)
+ ret = proc->fn (frame, this, &args);
+out:
+ if (ret)
+ STACK_UNWIND_STRICT (mknod, frame, -1, ENOTCONN,
+ NULL, NULL, NULL, NULL, NULL);
+
+ return 0;
+}
+
+
+int
+client_mkdir (call_frame_t *frame, xlator_t *this, loc_t *loc,
+ mode_t mode, mode_t umask, dict_t *xdata)
+{
+ int ret = -1;
+ clnt_conf_t *conf = NULL;
+ rpc_clnt_procedure_t *proc = NULL;
+ clnt_args_t args = {0,};
+
+ conf = this->private;
+ if (!conf || !conf->fops)
+ goto out;
+
+ args.loc = loc;
+ args.mode = mode;
+ args.umask = umask;
+ args.xdata = xdata;
+
+ proc = &conf->fops->proctable[GF_FOP_MKDIR];
+ if (!proc) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "rpc procedure not found for %s",
+ gf_fop_list[GF_FOP_MKDIR]);
+ goto out;
+ }
+ if (proc->fn)
+ ret = proc->fn (frame, this, &args);
+out:
+ if (ret)
+ STACK_UNWIND_STRICT (mkdir, frame, -1, ENOTCONN,
+ NULL, NULL, NULL, NULL, NULL);
+
+ return 0;
+}
+
+
+
+int32_t
+client_unlink (call_frame_t *frame, xlator_t *this, loc_t *loc,
+ int xflag, dict_t *xdata)
+{
+ int ret = -1;
+ clnt_conf_t *conf = NULL;
+ rpc_clnt_procedure_t *proc = NULL;
+ clnt_args_t args = {0,};
+
+ conf = this->private;
+ if (!conf || !conf->fops)
+ goto out;
+
+ args.loc = loc;
+ args.xdata = xdata;
+ args.flags = xflag;
+
+ proc = &conf->fops->proctable[GF_FOP_UNLINK];
+ if (!proc) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "rpc procedure not found for %s",
+ gf_fop_list[GF_FOP_UNLINK]);
+ goto out;
+ }
+ if (proc->fn)
+ ret = proc->fn (frame, this, &args);
+out:
+ if (ret)
+ STACK_UNWIND_STRICT (unlink, frame, -1, ENOTCONN,
+ NULL, NULL, NULL);
+
+ return 0;
+}
+
+int32_t
+client_rmdir (call_frame_t *frame, xlator_t *this, loc_t *loc, int flags,
+ dict_t *xdata)
+{
+ int ret = -1;
+ clnt_conf_t *conf = NULL;
+ rpc_clnt_procedure_t *proc = NULL;
+ clnt_args_t args = {0,};
+
+ conf = this->private;
+ if (!conf || !conf->fops)
+ goto out;
+
+ args.loc = loc;
+ args.flags = flags;
+ args.xdata = xdata;
+
+ proc = &conf->fops->proctable[GF_FOP_RMDIR];
+ if (!proc) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "rpc procedure not found for %s",
+ gf_fop_list[GF_FOP_RMDIR]);
+ goto out;
+ }
+ if (proc->fn)
+ ret = proc->fn (frame, this, &args);
+out:
+ /* think of avoiding a missing frame */
+ if (ret)
+ STACK_UNWIND_STRICT (rmdir, frame, -1, ENOTCONN,
+ NULL, NULL, NULL);
+
+ return 0;
+}
+
+
+int
+client_symlink (call_frame_t *frame, xlator_t *this, const char *linkpath,
+ loc_t *loc, mode_t umask, dict_t *xdata)
+{
+ int ret = -1;
+ clnt_conf_t *conf = NULL;
+ rpc_clnt_procedure_t *proc = NULL;
+ clnt_args_t args = {0,};
+
+ conf = this->private;
+ if (!conf || !conf->fops)
+ goto out;
+
+ args.linkname = linkpath;
+ args.loc = loc;
+ args.umask = umask;
+ args.xdata = xdata;
+
+ proc = &conf->fops->proctable[GF_FOP_SYMLINK];
+ if (!proc) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "rpc procedure not found for %s",
+ gf_fop_list[GF_FOP_SYMLINK]);
+ goto out;
+ }
+ if (proc->fn)
+ ret = proc->fn (frame, this, &args);
+out:
+ if (ret)
+ STACK_UNWIND_STRICT (symlink, frame, -1, ENOTCONN,
+ NULL, NULL, NULL, NULL, NULL);
+
+ return 0;
+}
+
+
+
+int32_t
+client_rename (call_frame_t *frame, xlator_t *this, loc_t *oldloc,
+ loc_t *newloc, dict_t *xdata)
+{
+ int ret = -1;
+ clnt_conf_t *conf = NULL;
+ rpc_clnt_procedure_t *proc = NULL;
+ clnt_args_t args = {0,};
+
+ conf = this->private;
+ if (!conf || !conf->fops)
+ goto out;
+
+ args.oldloc = oldloc;
+ args.newloc = newloc;
+ args.xdata = xdata;
+
+ proc = &conf->fops->proctable[GF_FOP_RENAME];
+ if (!proc) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "rpc procedure not found for %s",
+ gf_fop_list[GF_FOP_RENAME]);
+ goto out;
+ }
+ if (proc->fn)
+ ret = proc->fn (frame, this, &args);
+out:
+ if (ret)
+ STACK_UNWIND_STRICT (rename, frame, -1, ENOTCONN,
+ NULL, NULL, NULL, NULL, NULL, NULL);
+
+ return 0;
+}
+
+
+
+int32_t
+client_link (call_frame_t *frame, xlator_t *this, loc_t *oldloc,
+ loc_t *newloc, dict_t *xdata)
+{
+ int ret = -1;
+ clnt_conf_t *conf = NULL;
+ rpc_clnt_procedure_t *proc = NULL;
+ clnt_args_t args = {0,};
+
+ conf = this->private;
+ if (!conf || !conf->fops)
+ goto out;
+
+ args.oldloc = oldloc;
+ args.newloc = newloc;
+ args.xdata = xdata;
+
+ proc = &conf->fops->proctable[GF_FOP_LINK];
+ if (!proc) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "rpc procedure not found for %s",
+ gf_fop_list[GF_FOP_LINK]);
+ goto out;
+ }
+ if (proc->fn)
+ ret = proc->fn (frame, this, &args);
+out:
+ if (ret)
+ STACK_UNWIND_STRICT (link, frame, -1, ENOTCONN,
+ NULL, NULL, NULL, NULL, NULL);
+
+ return 0;
+}
+
+
+
+int32_t
+client_create (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,
+ mode_t mode, mode_t umask, fd_t *fd, dict_t *xdata)
+{
+ int ret = -1;
+ clnt_conf_t *conf = NULL;
+ rpc_clnt_procedure_t *proc = NULL;
+ clnt_args_t args = {0,};
+
+ conf = this->private;
+ if (!conf || !conf->fops)
+ goto out;
+
+ args.loc = loc;
+ args.mode = mode;
+ args.fd = fd;
+ args.umask = umask;
+ args.xdata = xdata;
+
+ if (!conf->filter_o_direct)
+ args.flags = flags;
+ else
+ args.flags = (flags & ~O_DIRECT);
+
+ proc = &conf->fops->proctable[GF_FOP_CREATE];
+ if (!proc) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "rpc procedure not found for %s",
+ gf_fop_list[GF_FOP_CREATE]);
+ goto out;
+ }
+ if (proc->fn)
+ ret = proc->fn (frame, this, &args);
+out:
+ if (ret)
+ STACK_UNWIND_STRICT (create, frame, -1, ENOTCONN,
+ NULL, NULL, NULL, NULL, NULL, NULL);
+
+ return 0;
+}
+
+
+
+int32_t
+client_open (call_frame_t *frame, xlator_t *this, loc_t *loc,
+ int32_t flags, fd_t *fd, dict_t *xdata)
+{
+ int ret = -1;
+ clnt_conf_t *conf = NULL;
+ rpc_clnt_procedure_t *proc = NULL;
+ clnt_args_t args = {0,};
+
+ conf = this->private;
+ if (!conf || !conf->fops)
+ goto out;
+
+ args.loc = loc;
+ args.fd = fd;
+ args.xdata = xdata;
+
+ if (!conf->filter_o_direct)
+ args.flags = flags;
+ else
+ args.flags = (flags & ~O_DIRECT);
+
+ proc = &conf->fops->proctable[GF_FOP_OPEN];
+ if (!proc) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "rpc procedure not found for %s",
+ gf_fop_list[GF_FOP_OPEN]);
+ goto out;
+ }
+ if (proc->fn)
+ ret = proc->fn (frame, this, &args);
+
+out:
+ if (ret)
+ STACK_UNWIND_STRICT (open, frame, -1, ENOTCONN, NULL, NULL);
+
+ return 0;
+}
+
+
+
+int32_t
+client_readv (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
+ off_t offset, uint32_t flags, dict_t *xdata)
+{
+ int ret = -1;
+ clnt_conf_t *conf = NULL;
+ rpc_clnt_procedure_t *proc = NULL;
+ clnt_args_t args = {0,};
+
+ conf = this->private;
+ if (!conf || !conf->fops)
+ goto out;
+
+ args.fd = fd;
+ args.size = size;
+ args.offset = offset;
+ args.flags = flags;
+ args.xdata = xdata;
+
+ proc = &conf->fops->proctable[GF_FOP_READ];
+ if (!proc) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "rpc procedure not found for %s",
+ gf_fop_list[GF_FOP_READ]);
+ goto out;
+ }
+ if (proc->fn)
+ ret = proc->fn (frame, this, &args);
+
+out:
+ if (ret)
+ STACK_UNWIND_STRICT (readv, frame, -1, ENOTCONN,
+ NULL, 0, NULL, NULL, NULL);
+
+ return 0;
+}
+
+
+
+
+int32_t
+client_writev (call_frame_t *frame, xlator_t *this, fd_t *fd,
+ struct iovec *vector, int32_t count, off_t off,
+ uint32_t flags, struct iobref *iobref, dict_t *xdata)
+{
+ int ret = -1;
+ clnt_conf_t *conf = NULL;
+ rpc_clnt_procedure_t *proc = NULL;
+ clnt_args_t args = {0,};
+
+ conf = this->private;
+ if (!conf || !conf->fops)
+ goto out;
+
+ args.fd = fd;
+ args.vector = vector;
+ args.count = count;
+ args.offset = off;
+ args.flags = flags;
+ args.iobref = iobref;
+ args.xdata = xdata;
+
+ proc = &conf->fops->proctable[GF_FOP_WRITE];
+ if (!proc) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "rpc procedure not found for %s",
+ gf_fop_list[GF_FOP_WRITE]);
+ goto out;
+ }
+ if (proc->fn)
+ ret = proc->fn (frame, this, &args);
+out:
+ if (ret)
+ STACK_UNWIND_STRICT (writev, frame, -1, ENOTCONN, NULL, NULL, NULL);
+
+ return 0;
+}
+
+
+int32_t
+client_flush (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
+{
+ int ret = -1;
+ clnt_conf_t *conf = NULL;
+ rpc_clnt_procedure_t *proc = NULL;
+ clnt_args_t args = {0,};
+
+ conf = this->private;
+ if (!conf || !conf->fops)
+ goto out;
+
+ args.fd = fd;
+ args.xdata = xdata;
+
+ proc = &conf->fops->proctable[GF_FOP_FLUSH];
+ if (!proc) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "rpc procedure not found for %s",
+ gf_fop_list[GF_FOP_FLUSH]);
+ goto out;
+ }
+ if (proc->fn)
+ ret = proc->fn (frame, this, &args);
+out:
+ if (ret)
+ STACK_UNWIND_STRICT (flush, frame, -1, ENOTCONN, NULL);
+
+ return 0;
+}
+
+
+
+int32_t
+client_fsync (call_frame_t *frame, xlator_t *this, fd_t *fd,
+ int32_t flags, dict_t *xdata)
+{
+ int ret = -1;
+ clnt_conf_t *conf = NULL;
+ rpc_clnt_procedure_t *proc = NULL;
+ clnt_args_t args = {0,};
+
+ conf = this->private;
+ if (!conf || !conf->fops)
+ goto out;
+
+ args.fd = fd;
+ args.flags = flags;
+ args.xdata = xdata;
+
+ proc = &conf->fops->proctable[GF_FOP_FSYNC];
+ if (!proc) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "rpc procedure not found for %s",
+ gf_fop_list[GF_FOP_FSYNC]);
+ goto out;
+ }
+ if (proc->fn)
+ ret = proc->fn (frame, this, &args);
+out:
+ if (ret)
+ STACK_UNWIND_STRICT (fsync, frame, -1, ENOTCONN, NULL, NULL, NULL);
+
+ return 0;
+}
+
+
+
+int32_t
+client_fstat (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
+{
+ int ret = -1;
+ clnt_conf_t *conf = NULL;
+ rpc_clnt_procedure_t *proc = NULL;
+ clnt_args_t args = {0,};
+
+ conf = this->private;
+ if (!conf || !conf->fops)
+ goto out;
+
+ args.fd = fd;
+ args.xdata = xdata;
+
+ proc = &conf->fops->proctable[GF_FOP_FSTAT];
+ if (!proc) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "rpc procedure not found for %s",
+ gf_fop_list[GF_FOP_FSTAT]);
+ goto out;
+ }
+ if (proc->fn)
+ ret = proc->fn (frame, this, &args);
+out:
+ if (ret)
+ STACK_UNWIND_STRICT (fstat, frame, -1, ENOTCONN, NULL, NULL);
+
+ return 0;
+}
+
+
+
+int32_t
+client_opendir (call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd,
+ dict_t *xdata)
+{
+ int ret = -1;
+ clnt_conf_t *conf = NULL;
+ rpc_clnt_procedure_t *proc = NULL;
+ clnt_args_t args = {0,};
+
+ conf = this->private;
+ if (!conf || !conf->fops)
+ goto out;
+
+ args.loc = loc;
+ args.fd = fd;
+ args.xdata = xdata;
+
+ proc = &conf->fops->proctable[GF_FOP_OPENDIR];
+ if (!proc) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "rpc procedure not found for %s",
+ gf_fop_list[GF_FOP_OPENDIR]);
+ goto out;
+ }
+ if (proc->fn)
+ ret = proc->fn (frame, this, &args);
+out:
+ if (ret)
+ STACK_UNWIND_STRICT (opendir, frame, -1, ENOTCONN, NULL, NULL);
+
+ return 0;
+}
+
+
+
+int32_t
+client_fsyncdir (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t flags, dict_t *xdata)
+{
+ int ret = -1;
+ clnt_conf_t *conf = NULL;
+ rpc_clnt_procedure_t *proc = NULL;
+ clnt_args_t args = {0,};
+
+ conf = this->private;
+ if (!conf || !conf->fops)
+ goto out;
+
+ args.fd = fd;
+ args.flags = flags;
+ args.xdata = xdata;
+
+ proc = &conf->fops->proctable[GF_FOP_FSYNCDIR];
+ if (!proc) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "rpc procedure not found for %s",
+ gf_fop_list[GF_FOP_FSYNCDIR]);
+ goto out;
+ }
+ if (proc->fn)
+ ret = proc->fn (frame, this, &args);
+out:
+ if (ret)
+ STACK_UNWIND_STRICT (fsyncdir, frame, -1, ENOTCONN, NULL);
+
+ return 0;
+}
+
+
+
+int32_t
+client_statfs (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)
+{
+ int ret = -1;
+ clnt_conf_t *conf = NULL;
+ rpc_clnt_procedure_t *proc = NULL;
+ clnt_args_t args = {0,};
+
+ conf = this->private;
+ if (!conf || !conf->fops)
+ goto out;
+
+ args.loc = loc;
+ args.xdata = xdata;
+
+ proc = &conf->fops->proctable[GF_FOP_STATFS];
+ if (!proc) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "rpc procedure not found for %s",
+ gf_fop_list[GF_FOP_STATFS]);
+ goto out;
+ }
+ if (proc->fn)
+ ret = proc->fn (frame, this, &args);
+out:
+ if (ret)
+ STACK_UNWIND_STRICT (statfs, frame, -1, ENOTCONN, NULL, NULL);
+
+ return 0;
+}
+
+static gf_boolean_t
+is_client_rpc_init_command (dict_t *dict, xlator_t *this,
+ char **value)
+{
+ gf_boolean_t ret = _gf_false;
+ int dict_ret = -1;
+
+ if (!strstr (this->name, "replace-brick")) {
+ gf_log (this->name, GF_LOG_TRACE, "name is !replace-brick");
+ goto out;
+ }
+ dict_ret = dict_get_str (dict, CLIENT_CMD_CONNECT, value);
+ if (dict_ret) {
+ gf_log (this->name, GF_LOG_TRACE, "key %s not present",
+ CLIENT_CMD_CONNECT);
+ goto out;
+ }
+
+ ret = _gf_true;
+
+out:
+ return ret;
+
+}
+
+static gf_boolean_t
+is_client_rpc_destroy_command (dict_t *dict, xlator_t *this)
+{
+ gf_boolean_t ret = _gf_false;
+ int dict_ret = -1;
+ char *dummy = NULL;
+
+ if (strncmp (this->name, "replace-brick", 13)) {
+ gf_log (this->name, GF_LOG_TRACE, "name is !replace-brick");
+ goto out;
+ }
+
+ dict_ret = dict_get_str (dict, CLIENT_CMD_DISCONNECT, &dummy);
+ if (dict_ret) {
+ gf_log (this->name, GF_LOG_TRACE, "key %s not present",
+ CLIENT_CMD_DISCONNECT);
+ goto out;
+ }
+
+ ret = _gf_true;
+
+out:
+ return ret;
+
+}
+
+static gf_boolean_t
+client_set_remote_options (char *value, xlator_t *this)
+{
+ char *dup_value = NULL;
+ char *host = NULL;
+ char *subvol = NULL;
+ char *host_dup = NULL;
+ char *subvol_dup = NULL;
+ char *remote_port_str = NULL;
+ char *tmp = NULL;
+ int remote_port = 0;
+ gf_boolean_t ret = _gf_false;
+
+ dup_value = gf_strdup (value);
+ host = strtok_r (dup_value, ":", &tmp);
+ subvol = strtok_r (NULL, ":", &tmp);
+ remote_port_str = strtok_r (NULL, ":", &tmp);
+
+ if (!subvol) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "proper value not passed as subvolume");
+ goto out;
+ }
+
+ host_dup = gf_strdup (host);
+ if (!host_dup) {
+ goto out;
+ }
+
+ ret = dict_set_dynstr (this->options, "remote-host", host_dup);
+ if (ret) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "failed to set remote-host with %s", host);
+ goto out;
+ }
+
+ subvol_dup = gf_strdup (subvol);
+ if (!subvol_dup) {
+ goto out;
+ }
+
+ ret = dict_set_dynstr (this->options, "remote-subvolume", subvol_dup);
+ if (ret) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "failed to set remote-host with %s", host);
+ goto out;
+ }
+
+ remote_port = atoi (remote_port_str);
+ GF_ASSERT (remote_port);
+
+ ret = dict_set_int32 (this->options, "remote-port",
+ remote_port);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "failed to set remote-port to %d", remote_port);
+ goto out;
+ }
+
+ ret = _gf_true;
+out:
+ GF_FREE (dup_value);
+
+ return ret;
+}
+
+
+int32_t
+client_setxattr (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *dict,
+ int32_t flags, dict_t *xdata)
+{
+ int ret = -1;
+ int op_ret = -1;
+ int op_errno = ENOTCONN;
+ int need_unwind = 0;
+ clnt_conf_t *conf = NULL;
+ rpc_clnt_procedure_t *proc = NULL;
+ clnt_args_t args = {0,};
+ char *value = NULL;
+
+
+ if (is_client_rpc_init_command (dict, this, &value) == _gf_true) {
+ GF_ASSERT (value);
+ gf_log (this->name, GF_LOG_INFO, "client rpc init command");
+ ret = client_set_remote_options (value, this);
+ if (ret) {
+ (void) client_destroy_rpc (this);
+ ret = client_init_rpc (this);
+ }
+
+ if (!ret) {
+ op_ret = 0;
+ op_errno = 0;
+ }
+ need_unwind = 1;
+ goto out;
+ }
+
+ if (is_client_rpc_destroy_command (dict, this) == _gf_true) {
+ gf_log (this->name, GF_LOG_INFO, "client rpc destroy command");
+ ret = client_destroy_rpc (this);
+ if (ret) {
+ op_ret = 0;
+ op_errno = 0;
+ }
+ need_unwind = 1;
+ goto out;
+ }
+
+ conf = this->private;
+ if (!conf || !conf->fops) {
+ op_errno = ENOTCONN;
+ need_unwind = 1;
+ goto out;
+ }
+
+ args.loc = loc;
+ args.xattr = dict;
+ args.flags = flags;
+ args.xdata = xdata;
+
+ proc = &conf->fops->proctable[GF_FOP_SETXATTR];
+ if (!proc) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "rpc procedure not found for %s",
+ gf_fop_list[GF_FOP_SETXATTR]);
+ goto out;
+ }
+ if (proc->fn) {
+ ret = proc->fn (frame, this, &args);
+ if (ret) {
+ need_unwind = 1;
+ }
+ }
+out:
+ if (need_unwind)
+ STACK_UNWIND_STRICT (setxattr, frame, op_ret, op_errno, NULL);
+
+ return 0;
+}
+
+
+
+int32_t
+client_fsetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
+ dict_t *dict, int32_t flags, dict_t *xdata)
+{
+ int ret = -1;
+ clnt_conf_t *conf = NULL;
+ rpc_clnt_procedure_t *proc = NULL;
+ clnt_args_t args = {0,};
+
+ conf = this->private;
+ if (!conf || !conf->fops)
+ goto out;
+
+ args.fd = fd;
+ args.xattr = dict;
+ args.flags = flags;
+ args.xdata = xdata;
+
+ proc = &conf->fops->proctable[GF_FOP_FSETXATTR];
+ if (!proc) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "rpc procedure not found for %s",
+ gf_fop_list[GF_FOP_FSETXATTR]);
+ goto out;
+ }
+ if (proc->fn)
+ ret = proc->fn (frame, this, &args);
+out:
+ if (ret)
+ STACK_UNWIND_STRICT (fsetxattr, frame, -1, ENOTCONN, NULL);
+
+ return 0;
+}
+
+
+
+
+int32_t
+client_fgetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
+ const char *name, dict_t *xdata)
+{
+ int ret = -1;
+ clnt_conf_t *conf = NULL;
+ rpc_clnt_procedure_t *proc = NULL;
+ clnt_args_t args = {0,};
+
+ conf = this->private;
+ if (!conf || !conf->fops)
+ goto out;
+
+ args.fd = fd;
+ args.name = name;
+ args.xdata = xdata;
+
+ proc = &conf->fops->proctable[GF_FOP_FGETXATTR];
+ if (!proc) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "rpc procedure not found for %s",
+ gf_fop_list[GF_FOP_FGETXATTR]);
+ goto out;
+ }
+ if (proc->fn)
+ ret = proc->fn (frame, this, &args);
+out:
+ if (ret)
+ STACK_UNWIND_STRICT (fgetxattr, frame, -1, ENOTCONN, NULL, NULL);
+
+ return 0;
+}
+
+
+
+int32_t
+client_getxattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
+ const char *name, dict_t *xdata)
+{
+ int ret = -1;
+ clnt_conf_t *conf = NULL;
+ rpc_clnt_procedure_t *proc = NULL;
+ clnt_args_t args = {0,};
+
+ conf = this->private;
+ if (!conf || !conf->fops)
+ goto out;
+
+ args.name = name;
+ args.loc = loc;
+ args.xdata = xdata;
+
+ proc = &conf->fops->proctable[GF_FOP_GETXATTR];
+ if (!proc) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "rpc procedure not found for %s",
+ gf_fop_list[GF_FOP_GETXATTR]);
+ goto out;
+ }
+ if (proc->fn)
+ ret = proc->fn (frame, this, &args);
+out:
+ if (ret)
+ STACK_UNWIND_STRICT (getxattr, frame, -1, ENOTCONN, NULL, NULL);
+
+ return 0;
+}
+
+
+
+int32_t
+client_xattrop (call_frame_t *frame, xlator_t *this, loc_t *loc,
+ gf_xattrop_flags_t flags, dict_t *dict, dict_t *xdata)
+{
+ int ret = -1;
+ clnt_conf_t *conf = NULL;
+ rpc_clnt_procedure_t *proc = NULL;
+ clnt_args_t args = {0,};
+
+ conf = this->private;
+ if (!conf || !conf->fops)
+ goto out;
+
+ args.loc = loc;
+ args.flags = flags;
+ args.xattr = dict;
+ args.xdata = xdata;
+
+ proc = &conf->fops->proctable[GF_FOP_XATTROP];
+ if (!proc) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "rpc procedure not found for %s",
+ gf_fop_list[GF_FOP_XATTROP]);
+ goto out;
+ }
+ if (proc->fn)
+ ret = proc->fn (frame, this, &args);
+out:
+ if (ret)
+ STACK_UNWIND_STRICT (xattrop, frame, -1, ENOTCONN, NULL, NULL);
+
+ return 0;
+}
+
+
+
+int32_t
+client_fxattrop (call_frame_t *frame, xlator_t *this, fd_t *fd,
+ gf_xattrop_flags_t flags, dict_t *dict, dict_t *xdata)
+{
+ int ret = -1;
+ clnt_conf_t *conf = NULL;
+ rpc_clnt_procedure_t *proc = NULL;
+ clnt_args_t args = {0,};
+
+ conf = this->private;
+ if (!conf || !conf->fops)
+ goto out;
+
+ args.fd = fd;
+ args.flags = flags;
+ args.xattr = dict;
+ args.xdata = xdata;
+
+ proc = &conf->fops->proctable[GF_FOP_FXATTROP];
+ if (!proc) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "rpc procedure not found for %s",
+ gf_fop_list[GF_FOP_FXATTROP]);
+ goto out;
+ }
+ if (proc->fn)
+ ret = proc->fn (frame, this, &args);
+out:
+ if (ret)
+ STACK_UNWIND_STRICT (fxattrop, frame, -1, ENOTCONN, NULL, NULL);
+
+ return 0;
+}
+
+
+
+int32_t
+client_removexattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
+ const char *name, dict_t *xdata)
+{
+ int ret = -1;
+ clnt_conf_t *conf = NULL;
+ rpc_clnt_procedure_t *proc = NULL;
+ clnt_args_t args = {0,};
+
+ conf = this->private;
+ if (!conf || !conf->fops)
+ goto out;
+
+ args.name = name;
+ args.loc = loc;
+ args.xdata = xdata;
+
+ proc = &conf->fops->proctable[GF_FOP_REMOVEXATTR];
+ if (!proc) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "rpc procedure not found for %s",
+ gf_fop_list[GF_FOP_REMOVEXATTR]);
+ goto out;
+ }
+ if (proc->fn)
+ ret = proc->fn (frame, this, &args);
+out:
+ if (ret)
+ STACK_UNWIND_STRICT (removexattr, frame, -1, ENOTCONN, NULL);
+
+ return 0;
+}
+
+int32_t
+client_fremovexattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
+ const char *name, dict_t *xdata)
+{
+ int ret = -1;
+ clnt_conf_t *conf = NULL;
+ rpc_clnt_procedure_t *proc = NULL;
+ clnt_args_t args = {0,};
+
+ conf = this->private;
+ if (!conf || !conf->fops)
+ goto out;
+
+ args.name = name;
+ args.fd = fd;
+ args.xdata = xdata;
+
+ proc = &conf->fops->proctable[GF_FOP_FREMOVEXATTR];
+ if (!proc) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "rpc procedure not found for %s",
+ gf_fop_list[GF_FOP_FREMOVEXATTR]);
+ goto out;
+ }
+ if (proc->fn)
+ ret = proc->fn (frame, this, &args);
+out:
+ if (ret)
+ STACK_UNWIND_STRICT (fremovexattr, frame, -1, ENOTCONN, NULL);
+
+ return 0;
+}
+
+int32_t
+client_lk (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t cmd,
+ struct gf_flock *lock, dict_t *xdata)
+{
+ int ret = -1;
+ clnt_conf_t *conf = NULL;
+ rpc_clnt_procedure_t *proc = NULL;
+ clnt_args_t args = {0,};
+
+ conf = this->private;
+ if (!conf || !conf->fops)
+ goto out;
+
+ args.fd = fd;
+ args.cmd = cmd;
+ args.flock = lock;
+ args.xdata = xdata;
+
+ proc = &conf->fops->proctable[GF_FOP_LK];
+ if (!proc) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "rpc procedure not found for %s",
+ gf_fop_list[GF_FOP_LK]);
+ goto out;
+ }
+ if (proc->fn)
+ ret = proc->fn (frame, this, &args);
+out:
+ if (ret)
+ STACK_UNWIND_STRICT (lk, frame, -1, ENOTCONN, NULL, NULL);
+
+ return 0;
+}
+
+
+int32_t
+client_inodelk (call_frame_t *frame, xlator_t *this, const char *volume,
+ loc_t *loc, int32_t cmd, struct gf_flock *lock, dict_t *xdata)
+{
+ int ret = -1;
+ clnt_conf_t *conf = NULL;
+ rpc_clnt_procedure_t *proc = NULL;
+ clnt_args_t args = {0,};
+
+ conf = this->private;
+ if (!conf || !conf->fops)
+ goto out;
+
+ args.loc = loc;
+ args.cmd = cmd;
+ args.flock = lock;
+ args.volume = volume;
+ args.xdata = xdata;
+
+ proc = &conf->fops->proctable[GF_FOP_INODELK];
+ if (!proc) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "rpc procedure not found for %s",
+ gf_fop_list[GF_FOP_INODELK]);
+ goto out;
+ }
+ if (proc->fn)
+ ret = proc->fn (frame, this, &args);
+out:
+ if (ret)
+ STACK_UNWIND_STRICT (inodelk, frame, -1, ENOTCONN, NULL);
+
+ return 0;
+}
+
+
+
+int32_t
+client_finodelk (call_frame_t *frame, xlator_t *this, const char *volume,
+ fd_t *fd, int32_t cmd, struct gf_flock *lock, dict_t *xdata)
+{
+ int ret = -1;
+ clnt_conf_t *conf = NULL;
+ rpc_clnt_procedure_t *proc = NULL;
+ clnt_args_t args = {0,};
+
+ conf = this->private;
+ if (!conf || !conf->fops)
+ goto out;
+
+ args.fd = fd;
+ args.cmd = cmd;
+ args.flock = lock;
+ args.volume = volume;
+ args.xdata = xdata;
+
+ proc = &conf->fops->proctable[GF_FOP_FINODELK];
+ if (!proc) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "rpc procedure not found for %s",
+ gf_fop_list[GF_FOP_FINODELK]);
+ goto out;
+ }
+ if (proc->fn)
+ ret = proc->fn (frame, this, &args);
+out:
+ if (ret)
+ STACK_UNWIND_STRICT (finodelk, frame, -1, ENOTCONN, NULL);
+
+ return 0;
+}
+
+
+int32_t
+client_entrylk (call_frame_t *frame, xlator_t *this, const char *volume,
+ loc_t *loc, const char *basename, entrylk_cmd cmd,
+ entrylk_type type, dict_t *xdata)
+{
+ int ret = -1;
+ clnt_conf_t *conf = NULL;
+ rpc_clnt_procedure_t *proc = NULL;
+ clnt_args_t args = {0,};
+
+ conf = this->private;
+ if (!conf || !conf->fops)
+ goto out;
+
+ args.loc = loc;
+ args.basename = basename;
+ args.type = type;
+ args.volume = volume;
+ args.cmd_entrylk = cmd;
+ args.xdata = xdata;
+
+ proc = &conf->fops->proctable[GF_FOP_ENTRYLK];
+ if (!proc) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "rpc procedure not found for %s",
+ gf_fop_list[GF_FOP_ENTRYLK]);
+ goto out;
+ }
+ if (proc->fn)
+ ret = proc->fn (frame, this, &args);
+out:
+ if (ret)
+ STACK_UNWIND_STRICT (entrylk, frame, -1, ENOTCONN, NULL);
+
+ return 0;
+}
+
+
+
+int32_t
+client_fentrylk (call_frame_t *frame, xlator_t *this, const char *volume,
+ fd_t *fd, const char *basename, entrylk_cmd cmd,
+ entrylk_type type, dict_t *xdata)
+{
+ int ret = -1;
+ clnt_conf_t *conf = NULL;
+ rpc_clnt_procedure_t *proc = NULL;
+ clnt_args_t args = {0,};
+
+ conf = this->private;
+ if (!conf || !conf->fops)
+ goto out;
+
+ args.fd = fd;
+ args.basename = basename;
+ args.type = type;
+ args.volume = volume;
+ args.cmd_entrylk = cmd;
+ args.xdata = xdata;
+
+ proc = &conf->fops->proctable[GF_FOP_FENTRYLK];
+ if (!proc) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "rpc procedure not found for %s",
+ gf_fop_list[GF_FOP_FENTRYLK]);
+ goto out;
+ }
+ if (proc->fn)
+ ret = proc->fn (frame, this, &args);
+out:
+ if (ret)
+ STACK_UNWIND_STRICT (fentrylk, frame, -1, ENOTCONN, NULL);
+
+ return 0;
+}
+
+
+int32_t
+client_rchecksum (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
+ int32_t len, dict_t *xdata)
+{
+ int ret = -1;
+ clnt_conf_t *conf = NULL;
+ rpc_clnt_procedure_t *proc = NULL;
+ clnt_args_t args = {0,};
+
+ conf = this->private;
+ if (!conf || !conf->fops)
+ goto out;
+
+ args.fd = fd;
+ args.offset = offset;
+ args.len = len;
+ args.xdata = xdata;
+
+ proc = &conf->fops->proctable[GF_FOP_RCHECKSUM];
+ if (!proc) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "rpc procedure not found for %s",
+ gf_fop_list[GF_FOP_RCHECKSUM]);
+ goto out;
+ }
+ if (proc->fn)
+ ret = proc->fn (frame, this, &args);
+out:
+ if (ret)
+ STACK_UNWIND_STRICT (rchecksum, frame, -1, ENOTCONN, 0, NULL, NULL);
+
+ return 0;
+}
+
+int32_t
+client_readdir (call_frame_t *frame, xlator_t *this, fd_t *fd,
+ size_t size, off_t off, dict_t *xdata)
+{
+ int ret = -1;
+ clnt_conf_t *conf = NULL;
+ rpc_clnt_procedure_t *proc = NULL;
+ clnt_args_t args = {0,};
+
+ conf = this->private;
+ if (!conf || !conf->fops)
+ goto out;
+
+ args.fd = fd;
+ args.size = size;
+ args.offset = off;
+ args.xdata = xdata;
+
+ proc = &conf->fops->proctable[GF_FOP_READDIR];
+ if (!proc) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "rpc procedure not found for %s",
+ gf_fop_list[GF_FOP_READDIR]);
+ goto out;
+ }
+ if (proc->fn)
+ ret = proc->fn (frame, this, &args);
+out:
+ if (ret)
+ STACK_UNWIND_STRICT (readdir, frame, -1, ENOTCONN, NULL, NULL);
+
+ return 0;
+}
+
+
+int32_t
+client_readdirp (call_frame_t *frame, xlator_t *this, fd_t *fd,
+ size_t size, off_t off, dict_t *dict)
+{
+ int ret = -1;
+ clnt_conf_t *conf = NULL;
+ rpc_clnt_procedure_t *proc = NULL;
+ clnt_args_t args = {0,};
+
+ conf = this->private;
+ if (!conf || !conf->fops)
+ goto out;
+
+ args.fd = fd;
+ args.size = size;
+ args.offset = off;
+ args.xdata = dict;
+
+ proc = &conf->fops->proctable[GF_FOP_READDIRP];
+ if (!proc) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "rpc procedure not found for %s",
+ gf_fop_list[GF_FOP_READDIRP]);
+ goto out;
+ }
+ if (proc->fn)
+ ret = proc->fn (frame, this, &args);
+out:
+ if (ret)
+ STACK_UNWIND_STRICT (readdirp, frame, -1, ENOTCONN, NULL, NULL);
+
+ return 0;
+}
+
+
+int32_t
+client_setattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
+ struct iatt *stbuf, int32_t valid, dict_t *xdata)
+{
+ int ret = -1;
+ clnt_conf_t *conf = NULL;
+ rpc_clnt_procedure_t *proc = NULL;
+ clnt_args_t args = {0,};
+
+ conf = this->private;
+ if (!conf || !conf->fops)
+ goto out;
+
+ args.loc = loc;
+ args.stbuf = stbuf;
+ args.valid = valid;
+ args.xdata = xdata;
+
+ proc = &conf->fops->proctable[GF_FOP_SETATTR];
+ if (!proc) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "rpc procedure not found for %s",
+ gf_fop_list[GF_FOP_SETATTR]);
+ goto out;
+ }
+ if (proc->fn)
+ ret = proc->fn (frame, this, &args);
+out:
+ if (ret)
+ STACK_UNWIND_STRICT (setattr, frame, -1, ENOTCONN, NULL, NULL, NULL);
+
+ return 0;
+}
+
+int32_t
+client_fsetattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
+ struct iatt *stbuf, int32_t valid, dict_t *xdata)
+{
+ int ret = -1;
+ clnt_conf_t *conf = NULL;
+ rpc_clnt_procedure_t *proc = NULL;
+ clnt_args_t args = {0,};
+
+ conf = this->private;
+ if (!conf || !conf->fops)
+ goto out;
+
+ args.fd = fd;
+ args.stbuf = stbuf;
+ args.valid = valid;
+ args.xdata = xdata;
+
+ proc = &conf->fops->proctable[GF_FOP_FSETATTR];
+ if (!proc) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "rpc procedure not found for %s",
+ gf_fop_list[GF_FOP_FSETATTR]);
+ goto out;
+ }
+ if (proc->fn)
+ ret = proc->fn (frame, this, &args);
+out:
+ if (ret)
+ STACK_UNWIND_STRICT (fsetattr, frame, -1, ENOTCONN, NULL, NULL, NULL);
+
+ return 0;
+}
+
+int32_t
+client_fallocate(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t mode,
+ off_t offset, size_t len, dict_t *xdata)
+{
+ int ret = -1;
+ clnt_conf_t *conf = NULL;
+ rpc_clnt_procedure_t *proc = NULL;
+ clnt_args_t args = {0,};
+
+ conf = this->private;
+ if (!conf || !conf->fops)
+ goto out;
+
+ args.fd = fd;
+ args.flags = mode;
+ args.offset = offset;
+ args.size = len;
+ args.xdata = xdata;
+
+ proc = &conf->fops->proctable[GF_FOP_FALLOCATE];
+ if (!proc) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "rpc procedure not found for %s",
+ gf_fop_list[GF_FOP_FALLOCATE]);
+ goto out;
+ }
+ if (proc->fn)
+ ret = proc->fn (frame, this, &args);
+out:
+ if (ret)
+ STACK_UNWIND_STRICT (fallocate, frame, -1, ENOTCONN, NULL, NULL, NULL);
+
+ return 0;
+}
+
+int32_t
+client_discard(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
+ size_t len, dict_t *xdata)
+{
+ int ret = -1;
+ clnt_conf_t *conf = NULL;
+ rpc_clnt_procedure_t *proc = NULL;
+ clnt_args_t args = {0,};
+
+ conf = this->private;
+ if (!conf || !conf->fops)
+ goto out;
+
+ args.fd = fd;
+ args.offset = offset;
+ args.size = len;
+ args.xdata = xdata;
+
+ proc = &conf->fops->proctable[GF_FOP_DISCARD];
+ if (!proc) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "rpc procedure not found for %s",
+ gf_fop_list[GF_FOP_DISCARD]);
+ goto out;
+ }
+ if (proc->fn)
+ ret = proc->fn (frame, this, &args);
+out:
+ if (ret)
+ STACK_UNWIND_STRICT(discard, frame, -1, ENOTCONN, NULL, NULL, NULL);
+
+ return 0;
+}
+
+int32_t
+client_zerofill(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
+ size_t len, dict_t *xdata)
+{
+ int ret = -1;
+ clnt_conf_t *conf = NULL;
+ rpc_clnt_procedure_t *proc = NULL;
+ clnt_args_t args = {0,};
+
+ conf = this->private;
+ if (!conf || !conf->fops)
+ goto out;
+
+ args.fd = fd;
+ args.offset = offset;
+ args.size = len;
+ args.xdata = xdata;
+
+ proc = &conf->fops->proctable[GF_FOP_ZEROFILL];
+ if (!proc) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "rpc procedure not found for %s",
+ gf_fop_list[GF_FOP_ZEROFILL]);
+ goto out;
+ }
+ if (proc->fn)
+ ret = proc->fn (frame, this, &args);
+out:
+ if (ret)
+ STACK_UNWIND_STRICT(zerofill, frame, -1, ENOTCONN,
+ NULL, NULL, NULL);
+
+ return 0;
+}
+
+
+int32_t
+client_getspec (call_frame_t *frame, xlator_t *this, const char *key,
+ int32_t flags)
+{
+ int ret = -1;
+ clnt_conf_t *conf = NULL;
+ rpc_clnt_procedure_t *proc = NULL;
+ clnt_args_t args = {0,};
+
+ conf = this->private;
+ if (!conf || !conf->fops || !conf->handshake)
+ goto out;
+
+ args.name = key;
+ args.flags = flags;
+
+ /* For all other xlators, getspec is an fop, hence its in fops table */
+ proc = &conf->fops->proctable[GF_FOP_GETSPEC];
+ if (!proc) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "rpc procedure not found for %s",
+ gf_fop_list[GF_FOP_GETSPEC]);
+ goto out;
+ }
+ if (proc->fn) {
+ /* But at protocol level, this is handshake */
+ ret = proc->fn (frame, this, &args);
+ }
+out:
+ if (ret)
+ STACK_UNWIND_STRICT (getspec, frame, -1, EINVAL, NULL);
+
+ return 0;
+}
+
+
+int
+client_mark_fd_bad (xlator_t *this)
+{
+ clnt_conf_t *conf = NULL;
+ clnt_fd_ctx_t *tmp = NULL, *fdctx = NULL;
+
+ conf = this->private;
+
+ pthread_mutex_lock (&conf->lock);
+ {
+ list_for_each_entry_safe (fdctx, tmp, &conf->saved_fds,
+ sfd_pos) {
+ fdctx->remote_fd = -1;
+ }
+ }
+ pthread_mutex_unlock (&conf->lock);
+
+ return 0;
+}
+
+
+int
+client_rpc_notify (struct rpc_clnt *rpc, void *mydata, rpc_clnt_event_t event,
+ void *data)
+{
+ xlator_t *this = NULL;
+ char *handshake = NULL;
+ clnt_conf_t *conf = NULL;
+ int ret = 0;
+
+ this = mydata;
+ if (!this || !this->private) {
+ gf_log ("client", GF_LOG_ERROR,
+ (this != NULL) ?
+ "private structure of the xlator is NULL":
+ "xlator is NULL");
+ goto out;
+ }
+
+ conf = this->private;
+
+ switch (event) {
+ case RPC_CLNT_CONNECT:
+ {
+ conf->connected = 1;
+ // connect happened, send 'get_supported_versions' mop
+ ret = dict_get_str (this->options, "disable-handshake",
+ &handshake);
+
+ gf_log (this->name, GF_LOG_DEBUG, "got RPC_CLNT_CONNECT");
+
+ if ((ret < 0) || (strcasecmp (handshake, "on"))) {
+ ret = client_handshake (this, rpc);
+ if (ret)
+ gf_log (this->name, GF_LOG_WARNING,
+ "handshake msg returned %d", ret);
+ } else {
+ //conf->rpc->connected = 1;
+ if (conf->last_sent_event != GF_EVENT_CHILD_UP) {
+ ret = default_notify (this, GF_EVENT_CHILD_UP,
+ NULL);
+ if (ret)
+ gf_log (this->name, GF_LOG_INFO,
+ "CHILD_UP notify failed");
+ conf->last_sent_event = GF_EVENT_CHILD_UP;
+ }
+ }
+
+ /* Cancel grace timer if set */
+ pthread_mutex_lock (&conf->lock);
+ {
+ conf->grace_timer_needed = _gf_true;
+
+ if (conf->grace_timer) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "Cancelling the grace timer");
+
+ gf_timer_call_cancel (this->ctx,
+ conf->grace_timer);
+
+ conf->grace_timer = NULL;
+ }
+ }
+ pthread_mutex_unlock (&conf->lock);
+
+ break;
+ }
+ case RPC_CLNT_DISCONNECT:
+ if (!conf->lk_heal)
+ client_mark_fd_bad (this);
+ else
+ client_register_grace_timer (this, conf);
+
+ if (!conf->skip_notify) {
+ if (conf->connected) {
+ gf_log (this->name,
+ ((!conf->disconnect_err_logged)
+ ? GF_LOG_INFO : GF_LOG_DEBUG),
+ "disconnected from %s. Client process "
+ "will keep trying to connect to "
+ "glusterd until brick's port is "
+ "available",
+ conf->rpc->conn.trans->peerinfo.identifier);
+
+ if (conf->portmap_err_logged)
+ conf->disconnect_err_logged = 1;
+ }
+
+ /* If the CHILD_DOWN event goes to parent xlator
+ multiple times, the logic of parent xlator notify
+ may get screwed up.. (eg. CHILD_MODIFIED event in
+ replicate), hence make sure events which are passed
+ to parent are genuine */
+ if (conf->last_sent_event != GF_EVENT_CHILD_DOWN) {
+ ret = default_notify (this, GF_EVENT_CHILD_DOWN,
+ NULL);
+ if (ret)
+ gf_log (this->name, GF_LOG_INFO,
+ "CHILD_DOWN notify failed");
+ conf->last_sent_event = GF_EVENT_CHILD_DOWN;
+ }
+ } else {
+ if (conf->connected)
+ gf_log (this->name, GF_LOG_DEBUG,
+ "disconnected (skipped notify)");
+ }
+
+ conf->connected = 0;
+ conf->skip_notify = 0;
+
+ if (conf->quick_reconnect) {
+ conf->quick_reconnect = 0;
+ rpc_clnt_start (rpc);
+
+ } else {
+ rpc->conn.config.remote_port = 0;
+
+ }
+
+ break;
+
+ default:
+ gf_log (this->name, GF_LOG_TRACE,
+ "got some other RPC event %d", event);
+
+ break;
+ }
+
+out:
+ return 0;
+}
+
+
+int
+notify (xlator_t *this, int32_t event, void *data, ...)
+{
+ clnt_conf_t *conf = NULL;
+
+ conf = this->private;
+ if (!conf)
+ return 0;
+
+ switch (event) {
+ case GF_EVENT_PARENT_UP:
+ {
+ gf_log (this->name, GF_LOG_INFO,
+ "parent translators are ready, attempting connect "
+ "on transport");
+
+ rpc_clnt_start (conf->rpc);
+ break;
+ }
+
+ case GF_EVENT_PARENT_DOWN:
+ gf_log (this->name, GF_LOG_INFO,
+ "current graph is no longer active, destroying "
+ "rpc_client ");
+
+ pthread_mutex_lock (&conf->lock);
+ {
+ conf->parent_down = 1;
+ }
+ pthread_mutex_unlock (&conf->lock);
+
+ rpc_clnt_disable (conf->rpc);
+ break;
+
+ default:
+ gf_log (this->name, GF_LOG_DEBUG,
+ "got %d, calling default_notify ()", event);
+
+ default_notify (this, event, data);
+ conf->last_sent_event = event;
+ break;
+ }
+
+ return 0;
+}
+
+int
+build_client_config (xlator_t *this, clnt_conf_t *conf)
+{
+ int ret = -1;
+
+ if (!conf)
+ goto out;
+
+ GF_OPTION_INIT ("frame-timeout", conf->rpc_conf.rpc_timeout,
+ int32, out);
+
+ GF_OPTION_INIT ("remote-port", conf->rpc_conf.remote_port,
+ int32, out);
+
+ GF_OPTION_INIT ("ping-timeout", conf->opt.ping_timeout,
+ int32, out);
+
+ GF_OPTION_INIT ("remote-subvolume", conf->opt.remote_subvolume,
+ path, out);
+ if (!conf->opt.remote_subvolume)
+ gf_log (this->name, GF_LOG_WARNING,
+ "option 'remote-subvolume' not given");
+
+ GF_OPTION_INIT ("filter-O_DIRECT", conf->filter_o_direct,
+ bool, out);
+
+ ret = 0;
+out:
+ return ret;
+}
+
+
+int32_t
+mem_acct_init (xlator_t *this)
+{
+ int ret = -1;
+
+ if (!this)
+ return ret;
+
+ ret = xlator_mem_acct_init (this, gf_client_mt_end + 1);
+
+ if (ret != 0) {
+ gf_log (this->name, GF_LOG_ERROR, "Memory accounting init"
+ "failed");
+ return ret;
+ }
+
+ return ret;
+}
+
+int
+client_destroy_rpc (xlator_t *this)
+{
+ int ret = -1;
+ clnt_conf_t *conf = NULL;
+
+ conf = this->private;
+ if (!conf)
+ goto out;
+
+ if (conf->rpc) {
+ /* cleanup the saved-frames before last unref */
+ rpc_clnt_connection_cleanup (&conf->rpc->conn);
+
+ conf->rpc = rpc_clnt_unref (conf->rpc);
+ ret = 0;
+ gf_log (this->name, GF_LOG_DEBUG,
+ "Client rpc conn destroyed");
+ goto out;
+ }
+
+ gf_log (this->name, GF_LOG_WARNING,
+ "RPC destroy called on already destroyed "
+ "connection");
+
+out:
+ return ret;
+}
+
+int
+client_init_rpc (xlator_t *this)
+{
+ int ret = -1;
+ clnt_conf_t *conf = NULL;
+
+ conf = this->private;
+
+ if (conf->rpc) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "client rpc already init'ed");
+ ret = -1;
+ goto out;
+ }
+
+ conf->rpc = rpc_clnt_new (this->options, this->ctx, this->name, 0);
+ if (!conf->rpc) {
+ gf_log (this->name, GF_LOG_ERROR, "failed to initialize RPC");
+ goto out;
+ }
+
+ ret = rpc_clnt_register_notify (conf->rpc, client_rpc_notify, this);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR, "failed to register notify");
+ goto out;
+ }
+
+ conf->handshake = &clnt_handshake_prog;
+ conf->dump = &clnt_dump_prog;
+
+ ret = rpcclnt_cbk_program_register (conf->rpc, &gluster_cbk_prog,
+ this);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "failed to register callback program");
+ goto out;
+ }
+
+ ret = 0;
+
+ gf_log (this->name, GF_LOG_DEBUG, "client init successful");
+out:
+ return ret;
+}
+
+
+int
+client_init_grace_timer (xlator_t *this, dict_t *options,
+ clnt_conf_t *conf)
+{
+ char *lk_heal = NULL;
+ int32_t ret = -1;
+ int32_t grace_timeout = -1;
+
+ GF_VALIDATE_OR_GOTO ("client", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, options, out);
+ GF_VALIDATE_OR_GOTO (this->name, conf, out);
+
+ conf->lk_heal = _gf_false;
+
+ ret = dict_get_str (options, "lk-heal", &lk_heal);
+ if (!ret)
+ gf_string2boolean (lk_heal, &conf->lk_heal);
+
+ gf_log (this->name, GF_LOG_DEBUG, "lk-heal = %s",
+ (conf->lk_heal) ? "on" : "off");
+
+ ret = dict_get_int32 (options, "grace-timeout", &grace_timeout);
+ if (!ret)
+ conf->grace_ts.tv_sec = grace_timeout;
+ else
+ conf->grace_ts.tv_sec = 10;
+
+ conf->grace_ts.tv_nsec = 0;
+
+ gf_log (this->name, GF_LOG_DEBUG, "Client grace timeout "
+ "value = %"PRIu64, conf->grace_ts.tv_sec);
+
+ ret = 0;
+out:
+ return ret;
+}
+
+int
+reconfigure (xlator_t *this, dict_t *options)
+{
+ clnt_conf_t *conf = NULL;
+ int ret = -1;
+ int subvol_ret = 0;
+ char *old_remote_subvol = NULL;
+ char *new_remote_subvol = NULL;
+ char *old_remote_host = NULL;
+ char *new_remote_host = NULL;
+
+ conf = this->private;
+
+ GF_OPTION_RECONF ("frame-timeout", conf->rpc_conf.rpc_timeout,
+ options, int32, out);
+
+ GF_OPTION_RECONF ("ping-timeout", conf->opt.ping_timeout,
+ options, int32, out);
+
+ subvol_ret = dict_get_str (this->options, "remote-host",
+ &old_remote_host);
+
+ if (subvol_ret == 0) {
+ subvol_ret = dict_get_str (options, "remote-host",
+ &new_remote_host);
+ if (subvol_ret == 0) {
+ if (strcmp (old_remote_host, new_remote_host)) {
+ ret = 1;
+ goto out;
+ }
+ }
+ }
+
+ subvol_ret = dict_get_str (this->options, "remote-subvolume",
+ &old_remote_subvol);
+
+ if (subvol_ret == 0) {
+ subvol_ret = dict_get_str (options, "remote-subvolume",
+ &new_remote_subvol);
+ if (subvol_ret == 0) {
+ if (strcmp (old_remote_subvol, new_remote_subvol)) {
+ ret = 1;
+ goto out;
+ }
+ }
+ }
+
+ GF_OPTION_RECONF ("filter-O_DIRECT", conf->filter_o_direct,
+ options, bool, out);
+
+ ret = client_init_grace_timer (this, options, conf);
+ if (ret)
+ goto out;
+
+ ret = 0;
+out:
+ return ret;
+
+}
+
+
+int
+init (xlator_t *this)
+{
+ int ret = -1;
+ clnt_conf_t *conf = NULL;
+
+ if (this->children) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "FATAL: client protocol translator cannot have any "
+ "subvolumes");
+ goto out;
+ }
+
+ if (!this->parents) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "Volume is dangling. ");
+ }
+
+ conf = GF_CALLOC (1, sizeof (*conf), gf_client_mt_clnt_conf_t);
+ if (!conf)
+ goto out;
+
+ pthread_mutex_init (&conf->lock, NULL);
+ INIT_LIST_HEAD (&conf->saved_fds);
+
+ /* Initialize parameters for lock self healing*/
+ conf->lk_version = 1;
+ conf->grace_timer = NULL;
+ conf->grace_timer_needed = _gf_true;
+
+ ret = client_init_grace_timer (this, this->options, conf);
+ if (ret)
+ goto out;
+
+ LOCK_INIT (&conf->rec_lock);
+
+ conf->last_sent_event = -1; /* To start with we don't have any events */
+
+ this->private = conf;
+
+ /* If it returns -1, then its a failure, if it returns +1 we need
+ have to understand that 'this' is subvolume of a xlator which,
+ will set the remote host and remote subvolume in a setxattr
+ call.
+ */
+
+ ret = build_client_config (this, conf);
+ if (ret == -1)
+ goto out;
+
+ if (ret) {
+ ret = 0;
+ goto out;
+ }
+
+ this->local_pool = mem_pool_new (clnt_local_t, 64);
+ if (!this->local_pool) {
+ ret = -1;
+ gf_log (this->name, GF_LOG_ERROR,
+ "failed to create local_t's memory pool");
+ goto out;
+ }
+
+ ret = client_init_rpc (this);
+out:
+ if (ret)
+ this->fini (this);
+
+ return ret;
+}
+
+void
+fini (xlator_t *this)
+{
+ clnt_conf_t *conf = NULL;
+
+ conf = this->private;
+ this->private = NULL;
+
+ if (conf) {
+ if (conf->rpc) {
+ /* cleanup the saved-frames before last unref */
+ rpc_clnt_connection_cleanup (&conf->rpc->conn);
+
+ rpc_clnt_unref (conf->rpc);
+ }
+
+ /* Saved Fds */
+ /* TODO: */
+
+ pthread_mutex_destroy (&conf->lock);
+
+ GF_FREE (conf);
+ }
+ return;
+}
+
+static void
+client_fd_lk_ctx_dump (xlator_t *this, fd_lk_ctx_t *lk_ctx, int nth_fd)
+{
+ gf_boolean_t use_try_lock = _gf_true;
+ int ret = -1;
+ int lock_no = 0;
+ fd_lk_ctx_t *lk_ctx_ref = NULL;
+ fd_lk_ctx_node_t *plock = NULL;
+ char key[GF_DUMP_MAX_BUF_LEN] = {0,};
+
+ lk_ctx_ref = fd_lk_ctx_try_ref (lk_ctx);
+ if (!lk_ctx_ref)
+ return;
+
+ ret = client_fd_lk_list_empty (lk_ctx_ref, (use_try_lock = _gf_true));
+ if (ret != 0)
+ return;
+
+ ret = TRY_LOCK (&lk_ctx_ref->lock);
+ if (ret)
+ return;
+
+ gf_proc_dump_write ("------","------");
+
+ lock_no = 0;
+ list_for_each_entry (plock, &lk_ctx_ref->lk_list, next) {
+ snprintf (key, sizeof (key), "granted-posix-lock[%d]",
+ lock_no++);
+ gf_proc_dump_write (key, "owner = %s, cmd = %s "
+ "fl_type = %s, fl_start = %"
+ PRId64", fl_end = %"PRId64
+ ", user_flock: l_type = %s, "
+ "l_start = %"PRId64", l_len = %"PRId64,
+ lkowner_utoa (&plock->user_flock.l_owner),
+ get_lk_cmd (plock->cmd),
+ get_lk_type (plock->fl_type),
+ plock->fl_start, plock->fl_end,
+ get_lk_type (plock->user_flock.l_type),
+ plock->user_flock.l_start,
+ plock->user_flock.l_len);
+ }
+ gf_proc_dump_write ("------","------");
+
+ UNLOCK (&lk_ctx_ref->lock);
+ fd_lk_ctx_unref (lk_ctx_ref);
+
+}
+
+int
+client_priv_dump (xlator_t *this)
+{
+ clnt_conf_t *conf = NULL;
+ int ret = -1;
+ clnt_fd_ctx_t *tmp = NULL;
+ int i = 0;
+ char key[GF_DUMP_MAX_BUF_LEN];
+ char key_prefix[GF_DUMP_MAX_BUF_LEN];
+
+ if (!this)
+ return -1;
+
+ conf = this->private;
+ if (!conf)
+ return -1;
+
+ ret = pthread_mutex_trylock(&conf->lock);
+ if (ret)
+ return -1;
+
+ gf_proc_dump_build_key(key_prefix, "xlator.protocol.client",
+ "%s.priv", this->name);
+
+ gf_proc_dump_add_section(key_prefix);
+
+ list_for_each_entry(tmp, &conf->saved_fds, sfd_pos) {
+ sprintf (key, "fd.%d.remote_fd", i);
+ gf_proc_dump_write(key, "%d", tmp->remote_fd);
+ client_fd_lk_ctx_dump (this, tmp->lk_ctx, i);
+ i++;
+ }
+
+ gf_proc_dump_write("connecting", "%d", conf->connecting);
+
+ if (conf->rpc) {
+ gf_proc_dump_write("total_bytes_read", "%"PRIu64,
+ conf->rpc->conn.trans->total_bytes_read);
+
+ gf_proc_dump_write("total_bytes_written", "%"PRIu64,
+ conf->rpc->conn.trans->total_bytes_write);
+ }
+ pthread_mutex_unlock(&conf->lock);
+
+ return 0;
+
+}
+
+int32_t
+client_inodectx_dump (xlator_t *this, inode_t *inode)
+{
+ if (!inode)
+ return -1;
+
+ if (!this)
+ return -1;
+
+ /*TODO*/
+
+ return 0;
+}
+
+
+
+
+struct xlator_cbks cbks = {
+ .forget = client_forget,
+ .release = client_release,
+ .releasedir = client_releasedir
+};
+
+struct xlator_fops fops = {
+ .stat = client_stat,
+ .readlink = client_readlink,
+ .mknod = client_mknod,
+ .mkdir = client_mkdir,
+ .unlink = client_unlink,
+ .rmdir = client_rmdir,
+ .symlink = client_symlink,
+ .rename = client_rename,
+ .link = client_link,
+ .truncate = client_truncate,
+ .open = client_open,
+ .readv = client_readv,
+ .writev = client_writev,
+ .statfs = client_statfs,
+ .flush = client_flush,
+ .fsync = client_fsync,
+ .setxattr = client_setxattr,
+ .getxattr = client_getxattr,
+ .fsetxattr = client_fsetxattr,
+ .fgetxattr = client_fgetxattr,
+ .removexattr = client_removexattr,
+ .fremovexattr = client_fremovexattr,
+ .opendir = client_opendir,
+ .readdir = client_readdir,
+ .readdirp = client_readdirp,
+ .fsyncdir = client_fsyncdir,
+ .access = client_access,
+ .ftruncate = client_ftruncate,
+ .fstat = client_fstat,
+ .create = client_create,
+ .lk = client_lk,
+ .inodelk = client_inodelk,
+ .finodelk = client_finodelk,
+ .entrylk = client_entrylk,
+ .fentrylk = client_fentrylk,
+ .lookup = client_lookup,
+ .rchecksum = client_rchecksum,
+ .xattrop = client_xattrop,
+ .fxattrop = client_fxattrop,
+ .setattr = client_setattr,
+ .fsetattr = client_fsetattr,
+ .fallocate = client_fallocate,
+ .discard = client_discard,
+ .zerofill = client_zerofill,
+ .getspec = client_getspec,
+};
+
+
+struct xlator_dumpops dumpops = {
+ .priv = client_priv_dump,
+ .inodectx = client_inodectx_dump,
+};
+
+
+struct volume_options options[] = {
+ { .key = {"username"},
+ .type = GF_OPTION_TYPE_ANY
+ },
+ { .key = {"password"},
+ .type = GF_OPTION_TYPE_ANY
+ },
+ { .key = {"transport-type"},
+ .value = {"tcp", "socket", "ib-verbs", "unix", "ib-sdp",
+ "tcp/client", "ib-verbs/client", "rdma"},
+ .type = GF_OPTION_TYPE_STR
+ },
+ { .key = {"remote-host"},
+ .type = GF_OPTION_TYPE_INTERNET_ADDRESS
+ },
+ { .key = {"remote-port"},
+ .type = GF_OPTION_TYPE_INT,
+ },
+ { .key = {"remote-subvolume"},
+ .type = GF_OPTION_TYPE_ANY
+ },
+ { .key = {"frame-timeout",
+ "rpc-timeout" },
+ .type = GF_OPTION_TYPE_TIME,
+ .min = 0,
+ .max = 86400,
+ .default_value = "1800",
+ .description = "Time frame after which the (file) operation would be "
+ "declared as dead, if the server does not respond for "
+ "a particular (file) operation."
+ },
+ { .key = {"ping-timeout"},
+ .type = GF_OPTION_TYPE_TIME,
+ .min = 1,
+ .max = 1013,
+ .default_value = "42",
+ .description = "Time duration for which the client waits to "
+ "check if the server is responsive."
+ },
+ { .key = {"client-bind-insecure"},
+ .type = GF_OPTION_TYPE_BOOL
+ },
+ { .key = {"lk-heal"},
+ .type = GF_OPTION_TYPE_BOOL,
+ .default_value = "off",
+ .description = "Enables or disables the lock heal."
+ },
+ { .key = {"grace-timeout"},
+ .type = GF_OPTION_TYPE_INT,
+ .min = 10,
+ .max = 1800,
+ .description = "Sets the grace-timeout value. Valid range 10-1800."
+ },
+ {.key = {"tcp-window-size"},
+ .type = GF_OPTION_TYPE_SIZET,
+ .min = GF_MIN_SOCKET_WINDOW_SIZE,
+ .max = GF_MAX_SOCKET_WINDOW_SIZE,
+ .description = "Specifies the window size for tcp socket."
+ },
+ { .key = {"filter-O_DIRECT"},
+ .type = GF_OPTION_TYPE_BOOL,
+ .default_value = "disable",
+ .description = "If enabled, in open() and creat() calls, O_DIRECT "
+ "flag will be filtered at the client protocol level so server will "
+ "still continue to cache the file. This works similar to NFS's "
+ "behavior of O_DIRECT",
+ },
+ { .key = {NULL} },
+};
diff --git a/xlators/protocol/client/src/client.h b/xlators/protocol/client/src/client.h
new file mode 100644
index 000000000..afab2d74f
--- /dev/null
+++ b/xlators/protocol/client/src/client.h
@@ -0,0 +1,257 @@
+/*
+ Copyright (c) 2008-2012 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 _CLIENT_H
+#define _CLIENT_H
+
+#include <pthread.h>
+#include <stdint.h>
+
+#include "rpc-clnt.h"
+#include "list.h"
+#include "inode.h"
+#include "client-mem-types.h"
+#include "protocol-common.h"
+#include "glusterfs3.h"
+#include "fd-lk.h"
+
+/* FIXME: Needs to be defined in a common file */
+#define CLIENT_CMD_CONNECT "trusted.glusterfs.client-connect"
+#define CLIENT_CMD_DISCONNECT "trusted.glusterfs.client-disconnect"
+#define CLIENT_DUMP_LOCKS "trusted.glusterfs.clientlk-dump"
+#define GF_MAX_SOCKET_WINDOW_SIZE (1 * GF_UNIT_MB)
+#define GF_MIN_SOCKET_WINDOW_SIZE (0)
+
+typedef enum {
+ GF_LK_HEAL_IN_PROGRESS,
+ GF_LK_HEAL_DONE,
+} lk_heal_state_t;
+
+typedef enum {
+ DEFAULT_REMOTE_FD = 0,
+ FALLBACK_TO_ANON_FD = 1
+} clnt_remote_fd_flags_t;
+
+#define CLIENT_GET_REMOTE_FD(xl, fd, flags, remote_fd, op_errno, label) \
+ do { \
+ int _ret = 0; \
+ _ret = client_get_remote_fd (xl, fd, flags, &remote_fd);\
+ if (_ret < 0) { \
+ op_errno = errno; \
+ goto label; \
+ } \
+ if (remote_fd == -1) { \
+ gf_log (xl->name, GF_LOG_WARNING, " (%s) " \
+ "remote_fd is -1. EBADFD", \
+ uuid_utoa (fd->inode->gfid)); \
+ op_errno = EBADFD; \
+ goto label; \
+ } \
+ } while (0)
+
+#define CLIENT_STACK_UNWIND(op, frame, params ...) do { \
+ clnt_local_t *__local = frame->local; \
+ frame->local = NULL; \
+ STACK_UNWIND_STRICT (op, frame, params); \
+ client_local_wipe (__local); \
+ } while (0)
+
+
+struct clnt_options {
+ char *remote_subvolume;
+ int ping_timeout;
+};
+
+typedef struct clnt_conf {
+ struct rpc_clnt *rpc;
+ struct clnt_options opt;
+ struct rpc_clnt_config rpc_conf;
+ struct list_head saved_fds;
+ pthread_mutex_t lock;
+ int connecting;
+ int connected;
+
+ rpc_clnt_prog_t *fops;
+ rpc_clnt_prog_t *mgmt;
+ rpc_clnt_prog_t *handshake;
+ rpc_clnt_prog_t *dump;
+
+ uint64_t reopen_fd_count; /* Count of fds reopened after a
+ connection is established */
+ gf_lock_t rec_lock;
+ int skip_notify;
+
+ int last_sent_event; /* Flag used to make sure we are
+ not repeating the same event
+ which was sent earlier */
+ char portmap_err_logged; /* flag used to prevent
+ excessive logging */
+ char disconnect_err_logged; /* flag used to prevent
+ excessive disconnect
+ logging */
+
+ char need_different_port; /* flag used to change the
+ portmap path in case of
+ 'tcp,rdma' on server */
+ gf_boolean_t lk_heal;
+ uint16_t lk_version; /* this variable is used to distinguish
+ client-server transaction while
+ performing lock healing */
+ struct timespec grace_ts;
+ gf_timer_t *grace_timer;
+ gf_boolean_t grace_timer_needed; /* The state of this flag will
+ be used to decide whether
+ a new grace-timer must be
+ registered or not. False
+ means dont register, true
+ means register */
+ char parent_down;
+ gf_boolean_t quick_reconnect; /* When reconnecting after
+ portmap query, do not let
+ the reconnection happen after
+ the usual 3-second wait
+ */
+ gf_boolean_t filter_o_direct; /* if set, filter O_DIRECT from
+ the flags list of open() */
+} clnt_conf_t;
+
+typedef struct _client_fd_ctx {
+ struct list_head sfd_pos; /* Stores the reference to this
+ fd's position in the saved_fds list.
+ */
+ int64_t remote_fd;
+ char is_dir;
+ char released;
+ int32_t flags;
+ fd_lk_ctx_t *lk_ctx;
+ pthread_mutex_t mutex;
+ lk_heal_state_t lk_heal_state;
+ uuid_t gfid;
+ void (*reopen_done) (struct _client_fd_ctx*, xlator_t *);
+ struct list_head lock_list; /* List of all granted locks on this fd */
+ int32_t reopen_attempts;
+} clnt_fd_ctx_t;
+
+typedef struct _client_posix_lock {
+ fd_t *fd; /* The fd on which the lk operation was made */
+
+ struct gf_flock user_flock; /* the flock supplied by the user */
+ off_t fl_start;
+ off_t fl_end;
+ short fl_type;
+ int32_t cmd; /* the cmd for the lock call */
+ gf_lkowner_t owner; /* lock owner from fuse */
+ struct list_head list; /* reference used to add to the fdctx list of locks */
+} client_posix_lock_t;
+
+typedef struct client_local {
+ loc_t loc;
+ loc_t loc2;
+ fd_t *fd;
+ clnt_fd_ctx_t *fdctx;
+ uint32_t flags;
+ struct iobref *iobref;
+
+ client_posix_lock_t *client_lock;
+ gf_lkowner_t owner;
+ int32_t cmd;
+ struct list_head lock_list;
+ pthread_mutex_t mutex;
+ char *name;
+ gf_boolean_t attempt_reopen;
+} clnt_local_t;
+
+typedef struct client_args {
+ loc_t *loc;
+ fd_t *fd;
+ const char *linkname;
+ struct iobref *iobref;
+ struct iovec *vector;
+ dict_t *xattr;
+ struct iatt *stbuf;
+ loc_t *oldloc;
+ loc_t *newloc;
+ const char *name;
+ struct gf_flock *flock;
+ const char *volume;
+ const char *basename;
+ off_t offset;
+ int32_t mask;
+ int32_t cmd;
+ size_t size;
+ mode_t mode;
+ dev_t rdev;
+ int32_t flags;
+ int32_t count;
+ int32_t datasync;
+ entrylk_cmd cmd_entrylk;
+ entrylk_type type;
+ gf_xattrop_flags_t optype;
+ int32_t valid;
+ int32_t len;
+
+ mode_t umask;
+ dict_t *xdata;
+} clnt_args_t;
+
+typedef ssize_t (*gfs_serialize_t) (struct iovec outmsg, void *args);
+
+clnt_fd_ctx_t *this_fd_get_ctx (fd_t *file, xlator_t *this);
+clnt_fd_ctx_t *this_fd_del_ctx (fd_t *file, xlator_t *this);
+void this_fd_set_ctx (fd_t *file, xlator_t *this, loc_t *loc,
+ clnt_fd_ctx_t *ctx);
+
+int client_local_wipe (clnt_local_t *local);
+int client_submit_request (xlator_t *this, void *req,
+ call_frame_t *frame, rpc_clnt_prog_t *prog,
+ int procnum, fop_cbk_fn_t cbk,
+ struct iobref *iobref,
+ struct iovec *rsphdr, int rsphdr_count,
+ struct iovec *rsp_payload, int rsp_count,
+ struct iobref *rsp_iobref, xdrproc_t xdrproc);
+
+int unserialize_rsp_dirent (struct gfs3_readdir_rsp *rsp, gf_dirent_t *entries);
+int unserialize_rsp_direntp (xlator_t *this, fd_t *fd,
+ struct gfs3_readdirp_rsp *rsp, gf_dirent_t *entries);
+
+int clnt_readdir_rsp_cleanup (gfs3_readdir_rsp *rsp);
+int clnt_readdirp_rsp_cleanup (gfs3_readdirp_rsp *rsp);
+int client_attempt_lock_recovery (xlator_t *this, clnt_fd_ctx_t *fdctx);
+int32_t delete_granted_locks_owner (fd_t *fd, gf_lkowner_t *owner);
+int client_add_lock_for_recovery (fd_t *fd, struct gf_flock *flock,
+ gf_lkowner_t *owner, int32_t cmd);
+int32_t delete_granted_locks_fd (clnt_fd_ctx_t *fdctx);
+int32_t client_cmd_to_gf_cmd (int32_t cmd, int32_t *gf_cmd);
+void client_save_number_fds (clnt_conf_t *conf, int count);
+int dump_client_locks (inode_t *inode);
+int client_notify_parents_child_up (xlator_t *this);
+int32_t is_client_dump_locks_cmd (char *name);
+int32_t client_dump_locks (char *name, inode_t *inode,
+ dict_t *dict);
+int client_fdctx_destroy (xlator_t *this, clnt_fd_ctx_t *fdctx);
+
+uint32_t client_get_lk_ver (clnt_conf_t *conf);
+
+int32_t client_type_to_gf_type (short l_type);
+
+int client_mark_fd_bad (xlator_t *this);
+
+int client_set_lk_version (xlator_t *this);
+
+int client_fd_lk_list_empty (fd_lk_ctx_t *lk_ctx, gf_boolean_t use_try_lock);
+void client_default_reopen_done (clnt_fd_ctx_t *fdctx, xlator_t *this);
+void client_attempt_reopen (fd_t *fd, xlator_t *this);
+int client_get_remote_fd (xlator_t *this, fd_t *fd, int flags,
+ int64_t *remote_fd);
+int client_fd_fop_prepare_local (call_frame_t *frame, fd_t *fd,
+ int64_t remote_fd);
+gf_boolean_t
+__is_fd_reopen_in_progress (clnt_fd_ctx_t *fdctx);
+#endif /* !_CLIENT_H */
diff --git a/xlators/protocol/client/src/saved-frames.c b/xlators/protocol/client/src/saved-frames.c
deleted file mode 100644
index 501045fd1..000000000
--- a/xlators/protocol/client/src/saved-frames.c
+++ /dev/null
@@ -1,191 +0,0 @@
-/*
- Copyright (c) 2008-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/>.
-*/
-
-
-#include "saved-frames.h"
-#include "common-utils.h"
-#include "protocol.h"
-#include "xlator.h"
-
-
-
-struct saved_frames *
-saved_frames_new (void)
-{
- struct saved_frames *saved_frames = NULL;
-
- saved_frames = CALLOC (sizeof (*saved_frames), 1);
- if (!saved_frames) {
- return NULL;
- }
-
- INIT_LIST_HEAD (&saved_frames->fops.list);
- INIT_LIST_HEAD (&saved_frames->mops.list);
- INIT_LIST_HEAD (&saved_frames->cbks.list);
-
- return saved_frames;
-}
-
-
-struct saved_frame *
-get_head_frame_for_type (struct saved_frames *frames, int8_t type)
-{
- struct saved_frame *head_frame = NULL;
-
- switch (type) {
- case GF_OP_TYPE_FOP_REQUEST:
- case GF_OP_TYPE_FOP_REPLY:
- head_frame = &frames->fops;
- break;
- case GF_OP_TYPE_MOP_REQUEST:
- case GF_OP_TYPE_MOP_REPLY:
- head_frame = &frames->mops;
- break;
- case GF_OP_TYPE_CBK_REQUEST:
- case GF_OP_TYPE_CBK_REPLY:
- head_frame = &frames->cbks;
- break;
- }
-
- return head_frame;
-}
-
-
-int
-saved_frames_put (struct saved_frames *frames, call_frame_t *frame,
- int32_t op, int8_t type, int64_t callid)
-{
- struct saved_frame *saved_frame = NULL;
- struct saved_frame *head_frame = NULL;
-
- head_frame = get_head_frame_for_type (frames, type);
-
- saved_frame = CALLOC (sizeof (*saved_frame), 1);
- if (!saved_frame) {
- return -ENOMEM;
- }
-
- INIT_LIST_HEAD (&saved_frame->list);
- saved_frame->frame = frame;
- saved_frame->op = op;
- saved_frame->type = type;
- saved_frame->callid = callid;
-
- gettimeofday (&saved_frame->saved_at, NULL);
-
- list_add_tail (&saved_frame->list, &head_frame->list);
- frames->count++;
-
- return 0;
-}
-
-
-call_frame_t *
-saved_frames_get (struct saved_frames *frames, int32_t op,
- int8_t type, int64_t callid)
-{
- struct saved_frame *saved_frame = NULL;
- struct saved_frame *tmp = NULL;
- struct saved_frame *head_frame = NULL;
- call_frame_t *frame = NULL;
-
- head_frame = get_head_frame_for_type (frames, type);
-
- list_for_each_entry (tmp, &head_frame->list, list) {
- if (tmp->callid == callid) {
- list_del_init (&tmp->list);
- frames->count--;
- saved_frame = tmp;
- break;
- }
- }
-
- if (saved_frame)
- frame = saved_frame->frame;
-
- FREE (saved_frame);
-
- return frame;
-}
-
-struct saved_frame *
-saved_frames_get_timedout (struct saved_frames *frames, int8_t type,
- uint32_t timeout, struct timeval *current)
-{
- struct saved_frame *bailout_frame = NULL, *tmp = NULL;
- struct saved_frame *head_frame = NULL;
-
- head_frame = get_head_frame_for_type (frames, type);
-
- if (!list_empty(&head_frame->list)) {
- tmp = list_entry (head_frame->list.next, typeof (*tmp), list);
- if ((tmp->saved_at.tv_sec + timeout) < current->tv_sec) {
- bailout_frame = tmp;
- list_del_init (&bailout_frame->list);
- frames->count--;
- }
- }
-
- return bailout_frame;
-}
-
-void
-saved_frames_unwind (xlator_t *this, struct saved_frames *saved_frames,
- struct saved_frame *head,
- gf_op_t gf_ops[], char *gf_op_list[])
-{
- struct saved_frame *trav = NULL;
- struct saved_frame *tmp = NULL;
-
- gf_hdr_common_t hdr = {0, };
- call_frame_t *frame = NULL;
-
- hdr.rsp.op_ret = hton32 (-1);
- hdr.rsp.op_errno = hton32 (ENOTCONN);
-
- list_for_each_entry_safe (trav, tmp, &head->list, list) {
- gf_log (this->name, GF_LOG_ERROR,
- "forced unwinding frame type(%d) op(%s)",
- trav->type, gf_op_list[trav->op]);
-
- hdr.type = hton32 (trav->type);
- hdr.op = hton32 (trav->op);
-
- frame = trav->frame;
-
- saved_frames->count--;
-
- gf_ops[trav->op] (frame, &hdr, sizeof (hdr), NULL);
-
- list_del_init (&trav->list);
- FREE (trav);
- }
-}
-
-
-void
-saved_frames_destroy (xlator_t *this, struct saved_frames *frames,
- gf_op_t gf_fops[], gf_op_t gf_mops[], gf_op_t gf_cbks[])
-{
- saved_frames_unwind (this, frames, &frames->fops, gf_fops, gf_fop_list);
- saved_frames_unwind (this, frames, &frames->mops, gf_mops, gf_mop_list);
- saved_frames_unwind (this, frames, &frames->cbks, gf_cbks, gf_cbk_list);
-
- FREE (frames);
-}
diff --git a/xlators/protocol/client/src/saved-frames.h b/xlators/protocol/client/src/saved-frames.h
deleted file mode 100644
index cd628232b..000000000
--- a/xlators/protocol/client/src/saved-frames.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- Copyright (c) 2008-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 _SAVED_FRAMES_H
-#define _SAVED_FRAMES_H
-
-#ifndef _CONFIG_H
-#define _CONFIG_H
-#include "config.h"
-#endif
-
-#include <stdint.h>
-#include <sys/time.h>
-#include "stack.h"
-#include "list.h"
-#include "protocol.h"
-
-/* UGLY: have common typedef b/w saved-frames.c and protocol-client.c */
-typedef int32_t (*gf_op_t) (call_frame_t *frame,
- gf_hdr_common_t *hdr, size_t hdrlen,
- struct iobuf *iobuf);
-
-
-struct saved_frame {
- union {
- struct list_head list;
- struct {
- struct saved_frame *frame_next;
- struct saved_frame *frame_prev;
- };
- };
-
- struct timeval saved_at;
- call_frame_t *frame;
- int32_t op;
- int8_t type;
- uint64_t callid;
-};
-
-
-struct saved_frames {
- int64_t count;
- struct saved_frame fops;
- struct saved_frame mops;
- struct saved_frame cbks;
-};
-
-
-struct saved_frames *saved_frames_new ();
-int saved_frames_put (struct saved_frames *frames, call_frame_t *frame,
- int32_t op, int8_t type, int64_t callid);
-call_frame_t *saved_frames_get (struct saved_frames *frames, int32_t op,
- int8_t type, int64_t callid);
-
-struct saved_frame *
-saved_frames_get_timedout (struct saved_frames *frames, int8_t type,
- uint32_t timeout, struct timeval *current);
-
-void saved_frames_destroy (xlator_t *this, struct saved_frames *frames,
- gf_op_t gf_fops[], gf_op_t gf_mops[],
- gf_op_t gf_cbks[]);
-
-#endif /* _SAVED_FRAMES_H */