summaryrefslogtreecommitdiffstats
path: root/xlators/protocol/client/src/client.c
diff options
context:
space:
mode:
Diffstat (limited to 'xlators/protocol/client/src/client.c')
-rw-r--r--xlators/protocol/client/src/client.c1791
1 files changed, 1791 insertions, 0 deletions
diff --git a/xlators/protocol/client/src/client.c b/xlators/protocol/client/src/client.c
new file mode 100644
index 000000000..49e88bfde
--- /dev/null
+++ b/xlators/protocol/client/src/client.c
@@ -0,0 +1,1791 @@
+/*
+ Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
+ This file is part of GlusterFS.
+
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+
+#ifndef _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+#include "client.h"
+#include "xlator.h"
+#include "defaults.h"
+#include "glusterfs.h"
+#include "msg-xdr.h"
+#include "statedump.h"
+#include "compat-errno.h"
+
+extern rpc_clnt_prog_t clnt_handshake_prog;
+int
+client_handshake (xlator_t *this, struct rpc_clnt *rpc);
+
+void
+client_start_ping (void *data);
+
+int
+client_submit_request (xlator_t *this, void *req,
+ call_frame_t *frame, rpc_clnt_prog_t *prog, int procnum,
+ struct iobref *iobref, gfs_serialize_t sfunc)
+{
+ int ret = -1;
+ clnt_conf_t *conf = NULL;
+ struct iovec iov = {0, };
+ struct iobuf *iobuf = NULL;
+ int count = 0;
+ char new_iobref = 0, start_ping = 0;
+
+ conf = this->private;
+
+ iobuf = iobuf_get (this->ctx->iobuf_pool);
+ if (!iobuf) {
+ goto out;
+ };
+
+ if (!iobref) {
+ iobref = iobref_new ();
+ if (!iobref) {
+ goto out;
+ }
+
+ new_iobref = 1;
+ }
+
+ iobref_add (iobref, iobuf);
+
+ iov.iov_base = iobuf->ptr;
+ iov.iov_len = 128 * GF_UNIT_KB;
+
+ /* Create the xdr payload */
+ if (req && sfunc) {
+ ret = sfunc (iov, req);
+ if (ret == -1) {
+ goto out;
+ }
+ iov.iov_len = ret;
+ count = 1;
+ }
+ /* Send the msg */
+ ret = rpc_clnt_submit (conf->rpc, prog, procnum, &iov, count, NULL, 0,
+ iobref, frame);
+
+ 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;
+out:
+ if (new_iobref) {
+ iobref_unref (iobref);
+ }
+
+ iobuf_unref (iobuf);
+
+ return ret;
+}
+
+
+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,};
+ call_frame_t *frame = NULL;
+
+ conf = this->private;
+ if (!conf->fops)
+ goto out;
+
+ args.fd = fd;
+
+ proc = &conf->fops->actor[GF_FOP_RELEASEDIR];
+ if (proc->fn) {
+ frame = create_frame (this, this->ctx->pool);
+ if (!frame) {
+ goto out;
+ }
+ ret = proc->fn (frame, this, conf->fops, &args);
+ }
+out:
+ 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,};
+ call_frame_t *frame = NULL;
+
+ conf = this->private;
+ if (!conf->fops)
+ goto out;
+
+ args.fd = fd;
+ proc = &conf->fops->actor[GF_FOP_RELEASE];
+ if (proc->fn) {
+ frame = create_frame (this, this->ctx->pool);
+ if (!frame) {
+ goto out;
+ }
+ ret = proc->fn (frame, this, conf->fops, &args);
+ }
+out:
+ return 0;
+}
+
+
+int32_t
+client_lookup (call_frame_t *frame, xlator_t *this, loc_t *loc,
+ dict_t *xattr_req)
+{
+ int ret = -1;
+ clnt_conf_t *conf = NULL;
+ rpc_clnt_procedure_t *proc = NULL;
+ clnt_args_t args = {0,};
+
+ conf = this->private;
+ if (!conf->fops)
+ goto out;
+
+ args.loc = loc;
+ args.dict = xattr_req;
+
+ proc = &conf->fops->actor[GF_FOP_LOOKUP];
+ if (proc->fn)
+ ret = proc->fn (frame, this, conf->fops, &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)
+{
+ int ret = -1;
+ clnt_conf_t *conf = NULL;
+ rpc_clnt_procedure_t *proc = NULL;
+ clnt_args_t args = {0,};
+
+ conf = this->private;
+ if (!conf->fops)
+ goto out;
+
+ args.loc = loc;
+
+ proc = &conf->fops->actor[GF_FOP_STAT];
+ if (proc->fn)
+ ret = proc->fn (frame, this, conf->fops, &args);
+out:
+ if (ret)
+ STACK_UNWIND_STRICT (stat, frame, -1, ENOTCONN, NULL);
+
+
+ return 0;
+}
+
+
+int32_t
+client_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset)
+{
+ int ret = -1;
+ clnt_conf_t *conf = NULL;
+ rpc_clnt_procedure_t *proc = NULL;
+ clnt_args_t args = {0,};
+
+ conf = this->private;
+ if (!conf->fops)
+ goto out;
+
+ args.loc = loc;
+ args.offset = offset;
+
+ proc = &conf->fops->actor[GF_FOP_TRUNCATE];
+ if (proc->fn)
+ ret = proc->fn (frame, this, conf->fops, &args);
+out:
+ if (ret)
+ STACK_UNWIND_STRICT (truncate, frame, -1, ENOTCONN, NULL, NULL);
+
+
+ return 0;
+}
+
+
+int32_t
+client_ftruncate (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset)
+{
+ int ret = -1;
+ clnt_conf_t *conf = NULL;
+ rpc_clnt_procedure_t *proc = NULL;
+ clnt_args_t args = {0,};
+
+ conf = this->private;
+ if (!conf->fops)
+ goto out;
+
+ args.fd = fd;
+ args.offset = offset;
+
+ proc = &conf->fops->actor[GF_FOP_FTRUNCATE];
+ if (proc->fn)
+ ret = proc->fn (frame, this, conf->fops, &args);
+out:
+ if (ret)
+ STACK_UNWIND_STRICT (ftruncate, frame, -1, ENOTCONN, NULL, NULL);
+
+ return 0;
+}
+
+
+
+int32_t
+client_access (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t mask)
+{
+ int ret = -1;
+ clnt_conf_t *conf = NULL;
+ rpc_clnt_procedure_t *proc = NULL;
+ clnt_args_t args = {0,};
+
+ conf = this->private;
+ if (!conf->fops)
+ goto out;
+
+ args.loc = loc;
+ args.mask = mask;
+
+ proc = &conf->fops->actor[GF_FOP_ACCESS];
+ if (proc->fn)
+ ret = proc->fn (frame, this, conf->fops, &args);
+out:
+ if (ret)
+ STACK_UNWIND_STRICT (access, frame, -1, ENOTCONN);
+
+ return 0;
+}
+
+
+
+
+int32_t
+client_readlink (call_frame_t *frame, xlator_t *this, loc_t *loc, size_t size)
+{
+ int ret = -1;
+ clnt_conf_t *conf = NULL;
+ rpc_clnt_procedure_t *proc = NULL;
+ clnt_args_t args = {0,};
+
+ conf = this->private;
+ if (!conf->fops)
+ goto out;
+
+ args.loc = loc;
+ args.size = size;
+
+ proc = &conf->fops->actor[GF_FOP_READLINK];
+ if (proc->fn)
+ ret = proc->fn (frame, this, conf->fops, &args);
+out:
+ if (ret)
+ STACK_UNWIND_STRICT (readlink, frame, -1, ENOTCONN, NULL, NULL);
+
+ return 0;
+}
+
+
+
+int32_t
+client_mknod (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
+ dev_t rdev)
+{
+ int ret = -1;
+ clnt_conf_t *conf = NULL;
+ rpc_clnt_procedure_t *proc = NULL;
+ clnt_args_t args = {0,};
+
+ conf = this->private;
+ if (!conf->fops)
+ goto out;
+
+ args.loc = loc;
+ args.mode = mode;
+ args.rdev = rdev;
+
+ proc = &conf->fops->actor[GF_FOP_MKNOD];
+ if (proc->fn)
+ ret = proc->fn (frame, this, conf->fops, &args);
+out:
+ if (ret)
+ STACK_UNWIND_STRICT (mknod, frame, -1, ENOTCONN,
+ NULL, NULL, NULL, NULL);
+
+ return 0;
+}
+
+
+
+int32_t
+client_mkdir (call_frame_t *frame, xlator_t *this, loc_t *loc,
+ mode_t mode)
+{
+ int ret = -1;
+ clnt_conf_t *conf = NULL;
+ rpc_clnt_procedure_t *proc = NULL;
+ clnt_args_t args = {0,};
+
+ conf = this->private;
+ if (!conf->fops)
+ goto out;
+
+ args.loc = loc;
+ args.mode = mode;
+
+ proc = &conf->fops->actor[GF_FOP_MKDIR];
+ if (proc->fn)
+ ret = proc->fn (frame, this, conf->fops, &args);
+out:
+ if (ret)
+ STACK_UNWIND_STRICT (mkdir, frame, -1, ENOTCONN,
+ NULL, NULL, NULL, NULL);
+
+ return 0;
+}
+
+
+
+int32_t
+client_unlink (call_frame_t *frame, xlator_t *this, loc_t *loc)
+{
+ int ret = -1;
+ clnt_conf_t *conf = NULL;
+ rpc_clnt_procedure_t *proc = NULL;
+ clnt_args_t args = {0,};
+
+ conf = this->private;
+ if (!conf->fops)
+ goto out;
+
+ args.loc = loc;
+
+ proc = &conf->fops->actor[GF_FOP_UNLINK];
+ if (proc->fn)
+ ret = proc->fn (frame, this, conf->fops, &args);
+out:
+ if (ret)
+ STACK_UNWIND_STRICT (unlink, frame, -1, ENOTCONN,
+ NULL, NULL);
+
+ return 0;
+}
+
+int32_t
+client_rmdir (call_frame_t *frame, xlator_t *this, loc_t *loc)
+{
+ int ret = -1;
+ clnt_conf_t *conf = NULL;
+ rpc_clnt_procedure_t *proc = NULL;
+ clnt_args_t args = {0,};
+
+ conf = this->private;
+ if (!conf->fops)
+ goto out;
+
+ args.loc = loc;
+
+ proc = &conf->fops->actor[GF_FOP_RMDIR];
+ if (proc->fn)
+ ret = proc->fn (frame, this, conf->fops, &args);
+out:
+ /* think of avoiding a missing frame */
+ if (ret)
+ STACK_UNWIND_STRICT (rmdir, frame, -1, ENOTCONN,
+ NULL, NULL);
+
+ return 0;
+}
+
+
+
+int32_t
+client_symlink (call_frame_t *frame, xlator_t *this, const char *linkpath,
+ loc_t *loc)
+{
+ int ret = -1;
+ clnt_conf_t *conf = NULL;
+ rpc_clnt_procedure_t *proc = NULL;
+ clnt_args_t args = {0,};
+
+ conf = this->private;
+ if (!conf->fops)
+ goto out;
+
+ args.linkname = linkpath;
+ args.loc = loc;
+
+ proc = &conf->fops->actor[GF_FOP_SYMLINK];
+ if (proc->fn)
+ ret = proc->fn (frame, this, conf->fops, &args);
+out:
+ if (ret)
+ STACK_UNWIND_STRICT (symlink, frame, -1, ENOTCONN,
+ NULL, NULL, NULL, NULL);
+
+ return 0;
+}
+
+
+
+int32_t
+client_rename (call_frame_t *frame, xlator_t *this, loc_t *oldloc,
+ loc_t *newloc)
+{
+ int ret = -1;
+ clnt_conf_t *conf = NULL;
+ rpc_clnt_procedure_t *proc = NULL;
+ clnt_args_t args = {0,};
+
+ conf = this->private;
+ if (!conf->fops)
+ goto out;
+
+ args.oldloc = oldloc;
+ args.newloc = newloc;
+ proc = &conf->fops->actor[GF_FOP_RENAME];
+ if (proc->fn)
+ ret = proc->fn (frame, this, conf->fops, &args);
+out:
+ if (ret)
+ STACK_UNWIND_STRICT (rename, frame, -1, ENOTCONN,
+ NULL, NULL, NULL, NULL, NULL);
+
+ return 0;
+}
+
+
+
+int32_t
+client_link (call_frame_t *frame, xlator_t *this, loc_t *oldloc,
+ loc_t *newloc)
+{
+ int ret = -1;
+ clnt_conf_t *conf = NULL;
+ rpc_clnt_procedure_t *proc = NULL;
+ clnt_args_t args = {0,};
+
+ conf = this->private;
+ if (!conf->fops)
+ goto out;
+
+ args.oldloc = oldloc;
+ args.newloc = newloc;
+
+ proc = &conf->fops->actor[GF_FOP_LINK];
+ if (proc->fn)
+ ret = proc->fn (frame, this, conf->fops, &args);
+out:
+ if (ret)
+ STACK_UNWIND_STRICT (link, frame, -1, ENOTCONN,
+ 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, 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->fops)
+ goto out;
+
+ args.loc = loc;
+ args.flags = flags;
+ args.mode = mode;
+ args.fd = fd;
+
+ proc = &conf->fops->actor[GF_FOP_CREATE];
+ if (proc->fn)
+ ret = proc->fn (frame, this, conf->fops, &args);
+out:
+ if (ret)
+ STACK_UNWIND_STRICT (create, frame, -1, ENOTCONN,
+ 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, int32_t wbflags)
+{
+ int ret = -1;
+ clnt_conf_t *conf = NULL;
+ rpc_clnt_procedure_t *proc = NULL;
+ clnt_args_t args = {0,};
+
+ conf = this->private;
+ if (!conf->fops)
+ goto out;
+
+ args.loc = loc;
+ args.flags = flags;
+ args.fd = fd;
+ args.wbflags = wbflags;
+
+ proc = &conf->fops->actor[GF_FOP_OPEN];
+ if (proc->fn)
+ ret = proc->fn (frame, this, conf->fops, &args);
+
+out:
+ if (ret)
+ STACK_UNWIND_STRICT (open, frame, -1, ENOTCONN, NULL);
+
+ return 0;
+}
+
+
+
+int32_t
+client_readv (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
+ off_t offset)
+{
+ int ret = -1;
+ clnt_conf_t *conf = NULL;
+ rpc_clnt_procedure_t *proc = NULL;
+ clnt_args_t args = {0,};
+
+ conf = this->private;
+ if (!conf->fops)
+ goto out;
+
+ args.fd = fd;
+ args.size = size;
+ args.offset = offset;
+
+ proc = &conf->fops->actor[GF_FOP_READ];
+ if (proc->fn)
+ ret = proc->fn (frame, this, conf->fops, &args);
+
+out:
+ if (ret)
+ STACK_UNWIND_STRICT (readv, frame, -1, ENOTCONN,
+ NULL, 0, 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,
+ struct iobref *iobref)
+{
+ int ret = -1;
+ clnt_conf_t *conf = NULL;
+ rpc_clnt_procedure_t *proc = NULL;
+ clnt_args_t args = {0,};
+
+ conf = this->private;
+ if (!conf->fops)
+ goto out;
+
+ args.fd = fd;
+ args.vector = vector;
+ args.count = count;
+ args.offset = off;
+ args.iobref = iobref;
+
+ proc = &conf->fops->actor[GF_FOP_WRITE];
+ if (proc->fn)
+ ret = proc->fn (frame, this, conf->fops, &args);
+out:
+ if (ret)
+ STACK_UNWIND_STRICT (writev, frame, -1, ENOTCONN, NULL, NULL);
+
+ return 0;
+}
+
+
+
+int32_t
+client_flush (call_frame_t *frame, 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->fops)
+ goto out;
+
+ args.fd = fd;
+
+ proc = &conf->fops->actor[GF_FOP_FLUSH];
+ if (proc->fn)
+ ret = proc->fn (frame, this, conf->fops, &args);
+out:
+ if (ret)
+ STACK_UNWIND_STRICT (flush, frame, -1, ENOTCONN);
+
+ return 0;
+}
+
+
+
+int32_t
+client_fsync (call_frame_t *frame, xlator_t *this, fd_t *fd,
+ 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->fops)
+ goto out;
+
+ args.fd = fd;
+ args.flags = flags;
+
+ proc = &conf->fops->actor[GF_FOP_FSYNC];
+ if (proc->fn)
+ ret = proc->fn (frame, this, conf->fops, &args);
+out:
+ if (ret)
+ STACK_UNWIND_STRICT (fsync, frame, -1, ENOTCONN, NULL, NULL);
+
+ return 0;
+}
+
+
+
+int32_t
+client_fstat (call_frame_t *frame, 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->fops)
+ goto out;
+
+ args.fd = fd;
+
+ proc = &conf->fops->actor[GF_FOP_FSTAT];
+ if (proc->fn)
+ ret = proc->fn (frame, this, conf->fops, &args);
+out:
+ if (ret)
+ STACK_UNWIND_STRICT (fstat, frame, -1, ENOTCONN, NULL);
+
+ return 0;
+}
+
+
+
+int32_t
+client_opendir (call_frame_t *frame, xlator_t *this, loc_t *loc, 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->fops)
+ goto out;
+
+ args.loc = loc;
+ args.fd = fd;
+
+ proc = &conf->fops->actor[GF_FOP_OPENDIR];
+ if (proc->fn)
+ ret = proc->fn (frame, this, conf->fops, &args);
+out:
+ if (ret)
+ STACK_UNWIND_STRICT (opendir, frame, -1, ENOTCONN, NULL);
+
+ return 0;
+}
+
+
+
+int32_t
+client_fsyncdir (call_frame_t *frame, xlator_t *this, fd_t *fd, 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->fops)
+ goto out;
+
+ args.fd = fd;
+ args.flags = flags;
+
+ proc = &conf->fops->actor[GF_FOP_FSYNCDIR];
+ if (proc->fn)
+ ret = proc->fn (frame, this, conf->fops, &args);
+out:
+ if (ret)
+ STACK_UNWIND_STRICT (fsyncdir, frame, -1, ENOTCONN);
+
+ return 0;
+}
+
+
+
+int32_t
+client_statfs (call_frame_t *frame, xlator_t *this, loc_t *loc)
+{
+ int ret = -1;
+ clnt_conf_t *conf = NULL;
+ rpc_clnt_procedure_t *proc = NULL;
+ clnt_args_t args = {0,};
+
+ conf = this->private;
+ if (!conf->fops)
+ goto out;
+
+ args.loc = loc;
+
+ proc = &conf->fops->actor[GF_FOP_STATFS];
+ if (proc->fn)
+ ret = proc->fn (frame, this, conf->fops, &args);
+out:
+ if (ret)
+ STACK_UNWIND_STRICT (statfs, frame, -1, ENOTCONN, NULL);
+
+ return 0;
+}
+
+
+
+int32_t
+client_setxattr (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *dict,
+ 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->fops)
+ goto out;
+
+ args.loc = loc;
+ args.dict = dict;
+ args.flags = flags;
+
+ proc = &conf->fops->actor[GF_FOP_SETXATTR];
+ if (proc->fn)
+ ret = proc->fn (frame, this, conf->fops, &args);
+out:
+ if (ret)
+ STACK_UNWIND_STRICT (setxattr, frame, -1, ENOTCONN);
+
+ return 0;
+}
+
+
+
+int32_t
+client_fsetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
+ dict_t *dict, 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->fops)
+ goto out;
+
+ args.fd = fd;
+ args.dict = dict;
+ args.flags = flags;
+
+ proc = &conf->fops->actor[GF_FOP_FSETXATTR];
+ if (proc->fn)
+ ret = proc->fn (frame, this, conf->fops, &args);
+out:
+ if (ret)
+ STACK_UNWIND_STRICT (fsetxattr, frame, -1, ENOTCONN);
+
+ return 0;
+}
+
+
+
+
+int32_t
+client_fgetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
+ const char *name)
+{
+ int ret = -1;
+ clnt_conf_t *conf = NULL;
+ rpc_clnt_procedure_t *proc = NULL;
+ clnt_args_t args = {0,};
+
+ conf = this->private;
+ if (!conf->fops)
+ goto out;
+
+ args.fd = fd;
+ args.name = name;
+
+ proc = &conf->fops->actor[GF_FOP_FGETXATTR];
+ if (proc->fn)
+ ret = proc->fn (frame, this, conf->fops, &args);
+out:
+ if (ret)
+ STACK_UNWIND_STRICT (fgetxattr, frame, -1, ENOTCONN, NULL);
+
+ return 0;
+}
+
+
+
+int32_t
+client_getxattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
+ const char *name)
+{
+ int ret = -1;
+ clnt_conf_t *conf = NULL;
+ rpc_clnt_procedure_t *proc = NULL;
+ clnt_args_t args = {0,};
+
+ conf = this->private;
+ if (!conf->fops)
+ goto out;
+
+ args.name = name;
+ args.loc = loc;
+
+ proc = &conf->fops->actor[GF_FOP_GETXATTR];
+ if (proc->fn)
+ ret = proc->fn (frame, this, conf->fops, &args);
+out:
+ if (ret)
+ STACK_UNWIND_STRICT (getxattr, frame, -1, ENOTCONN, 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)
+{
+ int ret = -1;
+ clnt_conf_t *conf = NULL;
+ rpc_clnt_procedure_t *proc = NULL;
+ clnt_args_t args = {0,};
+
+ conf = this->private;
+ if (!conf->fops)
+ goto out;
+
+ args.loc = loc;
+ args.flags = flags;
+ args.dict = dict;
+
+ proc = &conf->fops->actor[GF_FOP_XATTROP];
+ if (proc->fn)
+ ret = proc->fn (frame, this, conf->fops, &args);
+out:
+ if (ret)
+ STACK_UNWIND_STRICT (xattrop, frame, -1, ENOTCONN, 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)
+{
+ int ret = -1;
+ clnt_conf_t *conf = NULL;
+ rpc_clnt_procedure_t *proc = NULL;
+ clnt_args_t args = {0,};
+
+ conf = this->private;
+ if (!conf->fops)
+ goto out;
+
+ args.fd = fd;
+ args.flags = flags;
+ args.dict = dict;
+
+ proc = &conf->fops->actor[GF_FOP_FXATTROP];
+ if (proc->fn)
+ ret = proc->fn (frame, this, conf->fops, &args);
+out:
+ if (ret)
+ STACK_UNWIND_STRICT (fxattrop, frame, -1, ENOTCONN, NULL);
+
+ return 0;
+}
+
+
+
+int32_t
+client_removexattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
+ const char *name)
+{
+ int ret = -1;
+ clnt_conf_t *conf = NULL;
+ rpc_clnt_procedure_t *proc = NULL;
+ clnt_args_t args = {0,};
+
+ conf = this->private;
+ if (!conf->fops)
+ goto out;
+
+ args.name = name;
+ args.loc = loc;
+
+ proc = &conf->fops->actor[GF_FOP_REMOVEXATTR];
+ if (proc->fn)
+ ret = proc->fn (frame, this, conf->fops, &args);
+out:
+ if (ret)
+ STACK_UNWIND_STRICT (removexattr, frame, -1, ENOTCONN);
+
+ return 0;
+}
+
+
+int32_t
+client_lk (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t cmd,
+ struct flock *lock)
+{
+ int ret = -1;
+ clnt_conf_t *conf = NULL;
+ rpc_clnt_procedure_t *proc = NULL;
+ clnt_args_t args = {0,};
+
+ conf = this->private;
+ if (!conf->fops)
+ goto out;
+
+ args.fd = fd;
+ args.cmd = cmd;
+ args.flock = lock;
+
+ proc = &conf->fops->actor[GF_FOP_LK];
+ if (proc->fn)
+ ret = proc->fn (frame, this, conf->fops, &args);
+out:
+ if (ret)
+ STACK_UNWIND_STRICT (lk, frame, -1, ENOTCONN, NULL);
+
+ return 0;
+}
+
+
+int32_t
+client_inodelk (call_frame_t *frame, xlator_t *this, const char *volume,
+ loc_t *loc, int32_t cmd, struct flock *lock)
+{
+ int ret = -1;
+ clnt_conf_t *conf = NULL;
+ rpc_clnt_procedure_t *proc = NULL;
+ clnt_args_t args = {0,};
+
+ conf = this->private;
+ if (!conf->fops)
+ goto out;
+
+ args.loc = loc;
+ args.cmd = cmd;
+ args.flock = lock;
+ args.volume = volume;
+
+ proc = &conf->fops->actor[GF_FOP_INODELK];
+ if (proc->fn)
+ ret = proc->fn (frame, this, conf->fops, &args);
+out:
+ if (ret)
+ STACK_UNWIND_STRICT (inodelk, frame, -1, ENOTCONN);
+
+ return 0;
+}
+
+
+
+int32_t
+client_finodelk (call_frame_t *frame, xlator_t *this, const char *volume,
+ fd_t *fd, int32_t cmd, struct flock *lock)
+{
+ int ret = -1;
+ clnt_conf_t *conf = NULL;
+ rpc_clnt_procedure_t *proc = NULL;
+ clnt_args_t args = {0,};
+
+ conf = this->private;
+ if (!conf->fops)
+ goto out;
+
+ args.fd = fd;
+ args.cmd = cmd;
+ args.flock = lock;
+ args.volume = volume;
+
+ proc = &conf->fops->actor[GF_FOP_FINODELK];
+ if (proc->fn)
+ ret = proc->fn (frame, this, conf->fops, &args);
+out:
+ if (ret)
+ STACK_UNWIND_STRICT (finodelk, frame, -1, ENOTCONN);
+
+ 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)
+{
+ int ret = -1;
+ clnt_conf_t *conf = NULL;
+ rpc_clnt_procedure_t *proc = NULL;
+ clnt_args_t args = {0,};
+
+ conf = this->private;
+ if (!conf->fops)
+ goto out;
+
+ args.loc = loc;
+ args.basename = basename;
+ args.type = type;
+ args.volume = volume;
+ args.cmd_entrylk = cmd;
+
+ proc = &conf->fops->actor[GF_FOP_ENTRYLK];
+ if (proc->fn)
+ ret = proc->fn (frame, this, conf->fops, &args);
+out:
+ if (ret)
+ STACK_UNWIND_STRICT (entrylk, frame, -1, ENOTCONN);
+
+ 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)
+{
+ int ret = -1;
+ clnt_conf_t *conf = NULL;
+ rpc_clnt_procedure_t *proc = NULL;
+ clnt_args_t args = {0,};
+
+ conf = this->private;
+ if (!conf->fops)
+ goto out;
+
+ args.fd = fd;
+ args.basename = basename;
+ args.type = type;
+ args.volume = volume;
+ args.cmd_entrylk = cmd;
+
+ proc = &conf->fops->actor[GF_FOP_FENTRYLK];
+ if (proc->fn)
+ ret = proc->fn (frame, this, conf->fops, &args);
+out:
+ if (ret)
+ STACK_UNWIND_STRICT (fentrylk, frame, -1, ENOTCONN);
+
+ return 0;
+}
+
+
+int32_t
+client_checksum (call_frame_t *frame, xlator_t *this, loc_t *loc,
+ int32_t flag)
+{
+ int ret = -1;
+ clnt_conf_t *conf = NULL;
+ rpc_clnt_procedure_t *proc = NULL;
+ clnt_args_t args = {0,};
+
+ conf = this->private;
+ if (!conf->fops)
+ goto out;
+
+ args.loc = loc;
+ args.flags = flag;
+
+ proc = &conf->fops->actor[GF_FOP_CHECKSUM];
+ if (proc->fn)
+ ret = proc->fn (frame, this, conf->fops, &args);
+out:
+ if (ret)
+ STACK_UNWIND_STRICT (checksum, frame, -1, ENOTCONN, NULL, NULL);
+
+ return 0;
+}
+
+
+
+int32_t
+client_rchecksum (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
+ int32_t len)
+{
+ int ret = -1;
+ clnt_conf_t *conf = NULL;
+ rpc_clnt_procedure_t *proc = NULL;
+ clnt_args_t args = {0,};
+
+ conf = this->private;
+ if (!conf->fops)
+ goto out;
+
+ args.fd = fd;
+ args.offset = offset;
+ args.len = len;
+
+ proc = &conf->fops->actor[GF_FOP_RCHECKSUM];
+ if (proc->fn)
+ ret = proc->fn (frame, this, conf->fops, &args);
+out:
+ if (ret)
+ STACK_UNWIND_STRICT (rchecksum, frame, -1, ENOTCONN, 0, NULL);
+
+ return 0;
+}
+
+int32_t
+client_readdir (call_frame_t *frame, xlator_t *this, fd_t *fd,
+ size_t size, off_t off)
+{
+ int ret = -1;
+ clnt_conf_t *conf = NULL;
+ rpc_clnt_procedure_t *proc = NULL;
+ clnt_args_t args = {0,};
+
+ conf = this->private;
+ if (!conf->fops)
+ goto out;
+
+ args.fd = fd;
+ args.size = size;
+ args.offset = off;
+
+ proc = &conf->fops->actor[GF_FOP_READDIR];
+ if (proc->fn)
+ ret = proc->fn (frame, this, conf->fops, &args);
+out:
+ if (ret)
+ STACK_UNWIND_STRICT (readdir, frame, -1, ENOTCONN, NULL);
+
+ return 0;
+}
+
+
+int32_t
+client_readdirp (call_frame_t *frame, xlator_t *this, fd_t *fd,
+ size_t size, off_t off)
+{
+ int ret = -1;
+ clnt_conf_t *conf = NULL;
+ rpc_clnt_procedure_t *proc = NULL;
+ clnt_args_t args = {0,};
+
+ conf = this->private;
+ if (!conf->fops)
+ goto out;
+
+ args.fd = fd;
+ args.size = size;
+ args.offset = off;
+
+ proc = &conf->fops->actor[GF_FOP_READDIRP];
+ if (proc->fn)
+ ret = proc->fn (frame, this, conf->fops, &args);
+out:
+ if (ret)
+ STACK_UNWIND_STRICT (readdirp, frame, -1, ENOTCONN, NULL);
+
+ return 0;
+}
+
+
+int32_t
+client_setattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
+ struct iatt *stbuf, int32_t valid)
+{
+ int ret = -1;
+ clnt_conf_t *conf = NULL;
+ rpc_clnt_procedure_t *proc = NULL;
+ clnt_args_t args = {0,};
+
+ conf = this->private;
+ if (!conf->fops)
+ goto out;
+
+ args.loc = loc;
+ args.stbuf = stbuf;
+ args.valid = valid;
+
+ proc = &conf->fops->actor[GF_FOP_SETATTR];
+ if (proc->fn)
+ ret = proc->fn (frame, this, conf->fops, &args);
+out:
+ if (ret)
+ STACK_UNWIND_STRICT (setattr, frame, -1, ENOTCONN, NULL, NULL);
+
+ return 0;
+}
+
+int32_t
+client_fsetattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
+ struct iatt *stbuf, int32_t valid)
+{
+ int ret = -1;
+ clnt_conf_t *conf = NULL;
+ rpc_clnt_procedure_t *proc = NULL;
+ clnt_args_t args = {0,};
+
+ conf = this->private;
+ if (!conf->fops)
+ goto out;
+
+ args.fd = fd;
+ args.stbuf = stbuf;
+ args.valid = valid;
+
+ proc = &conf->fops->actor[GF_FOP_FSETATTR];
+ if (proc->fn)
+ ret = proc->fn (frame, this, conf->fops, &args);
+out:
+ if (ret)
+ STACK_UNWIND_STRICT (fsetattr, frame, -1, ENOTCONN, 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;
+ gf_getspec_req req = {0,};
+
+ conf = this->private;
+ if (!conf->handshake)
+ goto out;
+
+ req.key = (char *)key;
+ req.flags = flags;
+
+ client_submit_request (this, &req, frame, conf->handshake,
+ GF_HNDSK_GETSPEC, NULL, xdr_from_getspec_req);
+ ret = 0;
+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;
+ conf = this->private;
+
+ switch (event) {
+ case RPC_CLNT_CONNECT:
+ {
+ // connect happened, send 'get_supported_versions' mop
+ ret = dict_get_str (this->options, "disable-handshake",
+ &handshake);
+
+ gf_log (this->name, GF_LOG_TRACE, "got RPC_CLNT_CONNECT");
+
+ if ((ret < 0) || (strcasecmp (handshake, "on"))) {
+ ret = client_handshake (this, conf->rpc);
+
+ } else {
+ //conf->rpc->connected = 1;
+ ret = default_notify (this, GF_EVENT_CHILD_UP, NULL);
+ }
+ break;
+ }
+ case RPC_CLNT_DISCONNECT:
+
+ client_mark_fd_bad (this);
+
+ gf_log (this->name, GF_LOG_TRACE, "got RPC_CLNT_DISCONNECT");
+
+ default_notify (this, GF_EVENT_CHILD_DOWN, NULL);
+ break;
+
+ default:
+ gf_log (this->name, GF_LOG_TRACE,
+ "got some other RPC event %d", event);
+
+ break;
+ }
+
+ return 0;
+}
+
+
+int
+notify (xlator_t *this, int32_t event, void *data, ...)
+{
+ clnt_conf_t *conf = NULL;
+ void *trans = NULL;
+
+ conf = this->private;
+
+ switch (event) {
+ case GF_EVENT_PARENT_UP:
+ {
+ if (conf->rpc)
+ trans = conf->rpc->conn.trans;
+
+ if (!trans) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "transport init failed");
+ return 0;
+ }
+
+ gf_log (this->name, GF_LOG_DEBUG,
+ "got GF_EVENT_PARENT_UP, attempting connect "
+ "on transport");
+
+ rpc_clnt_reconnect (trans);
+ }
+ break;
+
+ default:
+ gf_log (this->name, GF_LOG_DEBUG,
+ "got %d, calling default_notify ()", event);
+
+ default_notify (this, event, data);
+ break;
+ }
+
+ return 0;
+}
+
+int
+build_client_config (xlator_t *this, clnt_conf_t *conf)
+{
+ int ret = 0;
+
+ ret = dict_get_str (this->options, "remote-subvolume",
+ &conf->opt.remote_subvolume);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "option 'remote-subvolume' not given");
+ goto out;
+ }
+
+ ret = dict_get_int32 (this->options, "frame-timeout",
+ &conf->rpc_conf.rpc_timeout);
+ if (ret >= 0) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "setting frame-timeout to %d",
+ conf->rpc_conf.rpc_timeout);
+ } else {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "defaulting frame-timeout to 30mins");
+ conf->rpc_conf.rpc_timeout = 1800;
+ }
+
+ ret = dict_get_int32 (this->options, "remote-port",
+ &conf->rpc_conf.remote_port);
+ if (ret >= 0) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "remote-port is %d", conf->rpc_conf.remote_port);
+ } else {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "defaulting remote-port to %d",
+ GF_PROTOCOL_DEFAULT_PORT);
+ conf->rpc_conf.remote_port = GF_PROTOCOL_DEFAULT_PORT;
+ }
+
+ ret = dict_get_int32 (this->options, "ping-timeout",
+ &conf->opt.ping_timeout);
+ if (ret >= 0) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "setting ping-timeout to %d", conf->opt.ping_timeout);
+ } else {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "defaulting ping-timeout to 42");
+ conf->opt.ping_timeout = GF_UNIVERSAL_ANSWER;
+ }
+
+ ret = 0;
+out:
+ return ret;}
+
+
+static 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
+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. ");
+ }
+
+ ret = mem_acct_init (this);
+ if (ret)
+ goto out;
+
+ 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);
+
+ ret = build_client_config (this, conf);
+ if (ret)
+ goto out;
+
+ conf->rpc = rpc_clnt_init (&conf->rpc_conf, this->options, this->ctx,
+ this->name);
+ if (!conf->rpc)
+ goto out;
+ conf->rpc->xid = 42; /* It should be enough random everytime :O */
+ ret = rpc_clnt_register_notify (conf->rpc, client_rpc_notify, this);
+ if (ret)
+ goto out;
+
+ conf->handshake = &clnt_handshake_prog;
+ this->private = conf;
+
+ ret = 0;
+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)
+ rpc_clnt_destroy (conf->rpc);
+
+ /* Saved Fds */
+ /* TODO: */
+
+ pthread_mutex_destroy (&conf->lock);
+
+ GF_FREE (conf);
+ }
+ return;
+}
+
+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) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "conf null in xlator");
+ return -1;
+ }
+
+ ret = pthread_mutex_trylock(&conf->lock);
+ if (ret) {
+ gf_log("", GF_LOG_WARNING, "Unable to lock client %s"
+ " errno: %d", this->name, errno);
+ 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) {
+ gf_proc_dump_build_key(key, key_prefix,
+ "fd.%d.remote_fd", ++i);
+ gf_proc_dump_write(key, "%d", tmp->remote_fd);
+ }
+
+ gf_proc_dump_build_key(key, key_prefix, "connecting");
+ gf_proc_dump_write(key, "%d", conf->connecting);
+ gf_proc_dump_build_key(key, key_prefix, "last_sent");
+ gf_proc_dump_write(key, "%s", ctime(&conf->last_sent.tv_sec));
+ gf_proc_dump_build_key(key, key_prefix, "last_received");
+ gf_proc_dump_write(key, "%s", ctime(&conf->last_received.tv_sec));
+
+ pthread_mutex_unlock(&conf->lock);
+
+ return 0;
+
+}
+
+int32_t
+client_inodectx_dump (xlator_t *this, inode_t *inode)
+{
+ ino_t par = 0;
+ uint64_t gen = 0;
+ int ret = -1;
+ char key[GF_DUMP_MAX_BUF_LEN];
+
+ if (!inode)
+ return -1;
+
+ if (!this)
+ return -1;
+
+ ret = inode_ctx_get2 (inode, this, &par, &gen);
+
+ if (ret != 0)
+ return ret;
+
+ gf_proc_dump_build_key(key, "xlator.protocol.client",
+ "%s.inode.%ld.par",
+ this->name,inode->ino);
+ gf_proc_dump_write(key, "%ld, %ld", par, gen);
+
+ 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,
+ .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,
+ .checksum = client_checksum,
+ .rchecksum = client_rchecksum,
+ .xattrop = client_xattrop,
+ .fxattrop = client_fxattrop,
+ .setattr = client_setattr,
+ .fsetattr = client_fsetattr,
+ .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"},
+ .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",
+ "rpc-timeout" },
+ .type = GF_OPTION_TYPE_TIME,
+ .min = 0,
+ .max = 86400,
+ },
+ { .key = {"ping-timeout"},
+ .type = GF_OPTION_TYPE_TIME,
+ .min = 1,
+ .max = 1013,
+ },
+ { .key = {NULL} },
+};