diff options
Diffstat (limited to 'xlators/protocol/client/src')
| -rw-r--r-- | xlators/protocol/client/src/Makefile.am | 18 | ||||
| -rw-r--r-- | xlators/protocol/client/src/client-callback.c | 335 | ||||
| -rw-r--r-- | xlators/protocol/client/src/client-common.c | 3589 | ||||
| -rw-r--r-- | xlators/protocol/client/src/client-common.h | 630 | ||||
| -rw-r--r-- | xlators/protocol/client/src/client-handshake.c | 2369 | ||||
| -rw-r--r-- | xlators/protocol/client/src/client-helpers.c | 964 | ||||
| -rw-r--r-- | xlators/protocol/client/src/client-lk.c | 1129 | ||||
| -rw-r--r-- | xlators/protocol/client/src/client-mem-types.h | 38 | ||||
| -rw-r--r-- | xlators/protocol/client/src/client-messages.h | 174 | ||||
| -rw-r--r-- | xlators/protocol/client/src/client-rpc-fops.c | 6079 | ||||
| -rw-r--r-- | xlators/protocol/client/src/client-rpc-fops_v2.c | 6177 | ||||
| -rw-r--r-- | xlators/protocol/client/src/client.c | 4382 | ||||
| -rw-r--r-- | xlators/protocol/client/src/client.h | 527 | ||||
| -rw-r--r-- | xlators/protocol/client/src/client3_1-fops.c | 5352 |
14 files changed, 22192 insertions, 9571 deletions
diff --git a/xlators/protocol/client/src/Makefile.am b/xlators/protocol/client/src/Makefile.am index 29c6e9dde76..785a51fc3b4 100644 --- a/xlators/protocol/client/src/Makefile.am +++ b/xlators/protocol/client/src/Makefile.am @@ -2,16 +2,20 @@ xlator_LTLIBRARIES = client.la xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/protocol -client_la_LDFLAGS = -module -avoidversion +client_la_LDFLAGS = -module $(GF_XLATOR_DEFAULT_LDFLAGS) client_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la \ $(top_builddir)/rpc/rpc-lib/src/libgfrpc.la \ $(top_builddir)/rpc/xdr/src/libgfxdr.la -client_la_SOURCES = client.c client-helpers.c client3_1-fops.c \ - client-handshake.c client-callback.c client-lk.c -noinst_HEADERS = client.h client-mem-types.h +client_la_SOURCES = client.c client-helpers.c client-rpc-fops.c \ + client-handshake.c client-callback.c client-lk.c client-common.c \ + client-rpc-fops_v2.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) \ - -I$(top_srcdir)/rpc/xdr/src -I$(top_srcdir)/rpc/rpc-lib/src/
\ No newline at end of file +noinst_HEADERS = client.h client-mem-types.h client-messages.h client-common.h + +AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \ + -I$(top_srcdir)/rpc/xdr/src -I$(top_builddir)/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 index 2d960ab1aa2..d83d9c14899 100644 --- a/xlators/protocol/client/src/client-callback.c +++ b/xlators/protocol/client/src/client-callback.c @@ -1,65 +1,312 @@ /* - Copyright (c) 2010-2011 Gluster, Inc. <http://www.gluster.com> + Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com> This file is part of GlusterFS. - GlusterFS is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 3 of the License, - or (at your option) any later version. - - GlusterFS is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see - <http://www.gnu.org/licenses/>. + This file is licensed to you under your choice of the GNU Lesser + General Public License, version 3 or any later version (LGPLv3 or + later), or the GNU General Public License, version 2 (GPLv2), in all + cases as published by the Free Software Foundation. */ -#ifndef _CONFIG_H -#define _CONFIG_H -#include "config.h" -#endif - #include "client.h" #include "rpc-clnt.h" +#include <glusterfs/defaults.h> +#include "client-messages.h" -int -client_cbk_null (void *data) +static 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; + gf_smsg(THIS->name, GF_LOG_WARNING, 0, PC_MSG_FUNCTION_CALL_ERROR, NULL); + return 0; } -int -client_cbk_fetchspec (void *data) +static 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; + gf_smsg(THIS->name, GF_LOG_WARNING, 0, PC_MSG_FUNCTION_CALL_ERROR, NULL); + return 0; } -int -client_cbk_ino_flush (void *data) +static 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; + gf_smsg(THIS->name, GF_LOG_WARNING, 0, PC_MSG_FUNCTION_CALL_ERROR, NULL); + 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 }, -}; +static int +client_cbk_recall_lease(struct rpc_clnt *rpc, void *mydata, void *data) +{ + int ret = -1; + struct iovec *iov = NULL; + struct gf_upcall upcall_data = { + 0, + }; + struct gf_upcall_recall_lease rl_data = { + 0, + }; + gfs3_recall_lease_req recall_lease = { + { + 0, + }, + }; + + GF_VALIDATE_OR_GOTO("client-callback", data, out); + + iov = (struct iovec *)data; + ret = xdr_to_generic(*iov, &recall_lease, + (xdrproc_t)xdr_gfs3_recall_lease_req); + + if (ret < 0) { + gf_smsg(THIS->name, GF_LOG_WARNING, -ret, PC_MSG_RECALL_LEASE_FAIL, + NULL); + goto out; + } + + upcall_data.data = &rl_data; + ret = gf_proto_recall_lease_to_upcall(&recall_lease, &upcall_data); + if (ret < 0) + goto out; + + upcall_data.event_type = GF_UPCALL_RECALL_LEASE; + + gf_msg_trace(THIS->name, 0, "Upcall gfid = %s, ret = %d", recall_lease.gfid, + ret); + + default_notify(THIS, GF_EVENT_UPCALL, &upcall_data); + +out: + if (recall_lease.xdata.xdata_val) + free(recall_lease.xdata.xdata_val); + + if (rl_data.dict) + dict_unref(rl_data.dict); + + return ret; +} + +static int +client_cbk_cache_invalidation(struct rpc_clnt *rpc, void *mydata, void *data) +{ + int ret = -1; + struct iovec *iov = NULL; + struct gf_upcall upcall_data = { + 0, + }; + struct gf_upcall_cache_invalidation ca_data = { + 0, + }; + gfs3_cbk_cache_invalidation_req ca_req = { + 0, + }; + + gf_msg_trace(THIS->name, 0, "Upcall callback is called"); + + if (!data) + goto out; + + iov = (struct iovec *)data; + ret = xdr_to_generic(*iov, &ca_req, + (xdrproc_t)xdr_gfs3_cbk_cache_invalidation_req); + + if (ret < 0) { + gf_smsg(THIS->name, GF_LOG_WARNING, -ret, + PC_MSG_CACHE_INVALIDATION_FAIL, NULL); + goto out; + } + + upcall_data.data = &ca_data; + ret = gf_proto_cache_invalidation_to_upcall(THIS, &ca_req, &upcall_data); + if (ret < 0) + goto out; + + gf_msg_trace(THIS->name, 0, + "Cache invalidation cbk received for gfid:" + " %s, ret = %d", + ca_req.gfid, ret); + + default_notify(THIS, GF_EVENT_UPCALL, &upcall_data); + +out: + if (ca_req.gfid) + free(ca_req.gfid); + + if (ca_req.xdata.xdata_val) + free(ca_req.xdata.xdata_val); + + if (ca_data.dict) + dict_unref(ca_data.dict); + + return 0; +} + +static int +client_cbk_child_up(struct rpc_clnt *rpc, void *mydata, void *data) +{ + clnt_conf_t *conf = NULL; + xlator_t *this = THIS; + + GF_VALIDATE_OR_GOTO("client", this, out); + conf = this->private; + GF_VALIDATE_OR_GOTO(this->name, conf, out); + + gf_msg_debug(this->name, 0, "Received CHILD_UP"); + conf->child_up = _gf_true; + + this->notify(this, GF_EVENT_CHILD_UP, NULL); +out: + return 0; +} + +static int +client_cbk_child_down(struct rpc_clnt *rpc, void *mydata, void *data) +{ + clnt_conf_t *conf = NULL; + xlator_t *this = THIS; + + GF_VALIDATE_OR_GOTO("client", this, out); + conf = this->private; + GF_VALIDATE_OR_GOTO(this->name, conf, out); + + gf_msg_debug(this->name, 0, "Received CHILD_DOWN"); + conf->child_up = _gf_false; + + this->notify(this, GF_EVENT_CHILD_DOWN, NULL); +out: + return 0; +} + +static int +client_cbk_inodelk_contention(struct rpc_clnt *rpc, void *mydata, void *data) +{ + int ret = -1; + struct iovec *iov = NULL; + struct gf_upcall upcall_data = { + 0, + }; + struct gf_upcall_inodelk_contention lc = { + { + 0, + }, + }; + gfs4_inodelk_contention_req proto_lc = { + { + 0, + }, + }; + + GF_VALIDATE_OR_GOTO("client-callback", data, out); + + iov = (struct iovec *)data; + ret = xdr_to_generic(*iov, &proto_lc, + (xdrproc_t)xdr_gfs4_inodelk_contention_req); + + if (ret < 0) { + gf_smsg(THIS->name, GF_LOG_WARNING, -ret, + PC_MSG_INODELK_CONTENTION_FAIL, NULL); + goto out; + } + + upcall_data.data = &lc; + ret = gf_proto_inodelk_contention_to_upcall(&proto_lc, &upcall_data); + if (ret < 0) + goto out; + + upcall_data.event_type = GF_UPCALL_INODELK_CONTENTION; + + default_notify(THIS, GF_EVENT_UPCALL, &upcall_data); + +out: + if (proto_lc.domain) + free(proto_lc.domain); + + if (proto_lc.xdata.xdata_val) + free(proto_lc.xdata.xdata_val); + + if (lc.xdata) + dict_unref(lc.xdata); + return ret; +} + +static int +client_cbk_entrylk_contention(struct rpc_clnt *rpc, void *mydata, void *data) +{ + int ret = -1; + struct iovec *iov = NULL; + struct gf_upcall upcall_data = { + 0, + }; + struct gf_upcall_entrylk_contention lc = { + 0, + }; + gfs4_entrylk_contention_req proto_lc = { + { + 0, + }, + }; + + GF_VALIDATE_OR_GOTO("client-callback", data, out); + + iov = (struct iovec *)data; + ret = xdr_to_generic(*iov, &proto_lc, + (xdrproc_t)xdr_gfs4_entrylk_contention_req); + + if (ret < 0) { + gf_smsg(THIS->name, GF_LOG_WARNING, -ret, + PC_MSG_ENTRYLK_CONTENTION_FAIL, NULL); + goto out; + } + + upcall_data.data = &lc; + ret = gf_proto_entrylk_contention_to_upcall(&proto_lc, &upcall_data); + if (ret < 0) + goto out; + + upcall_data.event_type = GF_UPCALL_ENTRYLK_CONTENTION; + + default_notify(THIS, GF_EVENT_UPCALL, &upcall_data); + +out: + if (proto_lc.name) + free(proto_lc.name); + + if (proto_lc.domain) + free(proto_lc.domain); + + if (proto_lc.xdata.xdata_val) + free(proto_lc.xdata.xdata_val); + + if (lc.xdata) + dict_unref(lc.xdata); + + return ret; +} + +static rpcclnt_cb_actor_t gluster_cbk_actors[GF_CBK_MAXVALUE] = { + [GF_CBK_NULL] = {"NULL", client_cbk_null, GF_CBK_NULL}, + [GF_CBK_FETCHSPEC] = {"FETCHSPEC", client_cbk_fetchspec, GF_CBK_FETCHSPEC}, + [GF_CBK_INO_FLUSH] = {"INO_FLUSH", client_cbk_ino_flush, GF_CBK_INO_FLUSH}, + [GF_CBK_CACHE_INVALIDATION] = {"CACHE_INVALIDATION", + client_cbk_cache_invalidation, + GF_CBK_CACHE_INVALIDATION}, + [GF_CBK_CHILD_UP] = {"CHILD_UP", client_cbk_child_up, GF_CBK_CHILD_UP}, + [GF_CBK_CHILD_DOWN] = {"CHILD_DOWN", client_cbk_child_down, + GF_CBK_CHILD_DOWN}, + [GF_CBK_RECALL_LEASE] = {"RECALL_LEASE", client_cbk_recall_lease, + GF_CBK_RECALL_LEASE}, + [GF_CBK_INODELK_CONTENTION] = {"INODELK_CONTENTION", + client_cbk_inodelk_contention, + GF_CBK_INODELK_CONTENTION}, + [GF_CBK_ENTRYLK_CONTENTION] = {"ENTRYLK_CONTENTION", + client_cbk_entrylk_contention, + GF_CBK_ENTRYLK_CONTENTION}, +}; 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, + .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-common.c b/xlators/protocol/client/src/client-common.c new file mode 100644 index 00000000000..c112820e407 --- /dev/null +++ b/xlators/protocol/client/src/client-common.c @@ -0,0 +1,3589 @@ +/* + Copyright (c) 2016 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 <glusterfs/dict.h> +#include <glusterfs/xlator.h> +#include "rpc-common-xdr.h" +#include "glusterfs3-xdr.h" +#include "glusterfs4-xdr.h" +#include "glusterfs3.h" +#include "client.h" + +/* processing to be done before fops are woudn down */ +int +client_pre_stat(xlator_t *this, gfs3_stat_req *req, loc_t *loc, dict_t *xdata) +{ + int op_errno = ESTALE; + + if (!(loc && loc->inode)) + goto out; + + if (!gf_uuid_is_null(loc->inode->gfid)) + memcpy(req->gfid, loc->inode->gfid, 16); + else + memcpy(req->gfid, loc->gfid, 16); + + GF_ASSERT_AND_GOTO_WITH_ERROR(this->name, + !gf_uuid_is_null(*((uuid_t *)req->gfid)), out, + op_errno, EINVAL); + + GF_PROTOCOL_DICT_SERIALIZE(this, xdata, (&req->xdata.xdata_val), + req->xdata.xdata_len, op_errno, out); + + return 0; +out: + return -op_errno; +} + +int +client_pre_readlink(xlator_t *this, gfs3_readlink_req *req, loc_t *loc, + size_t size, dict_t *xdata) +{ + int op_errno = ESTALE; + + if (!(loc && loc->inode)) + goto out; + + if (!gf_uuid_is_null(loc->inode->gfid)) + memcpy(req->gfid, loc->inode->gfid, 16); + else + memcpy(req->gfid, loc->gfid, 16); + + GF_ASSERT_AND_GOTO_WITH_ERROR(this->name, + !gf_uuid_is_null(*((uuid_t *)req->gfid)), out, + op_errno, EINVAL); + req->size = size; + GF_PROTOCOL_DICT_SERIALIZE(this, xdata, (&req->xdata.xdata_val), + req->xdata.xdata_len, op_errno, out); + return 0; +out: + return -op_errno; +} + +int +client_pre_mknod(xlator_t *this, gfs3_mknod_req *req, loc_t *loc, mode_t mode, + dev_t rdev, mode_t umask, dict_t *xdata) +{ + int op_errno = ESTALE; + + if (!(loc && loc->parent)) + goto out; + + if (!gf_uuid_is_null(loc->parent->gfid)) + memcpy(req->pargfid, loc->parent->gfid, 16); + else + memcpy(req->pargfid, loc->pargfid, 16); + + GF_ASSERT_AND_GOTO_WITH_ERROR(this->name, + !gf_uuid_is_null(*((uuid_t *)req->pargfid)), + out, op_errno, EINVAL); + req->bname = (char *)loc->name; + req->mode = mode; + req->dev = rdev; + req->umask = umask; + + GF_PROTOCOL_DICT_SERIALIZE(this, xdata, (&req->xdata.xdata_val), + req->xdata.xdata_len, op_errno, out); + + return 0; +out: + return -op_errno; +} + +int +client_pre_mkdir(xlator_t *this, gfs3_mkdir_req *req, loc_t *loc, mode_t mode, + mode_t umask, dict_t *xdata) +{ + int op_errno = ESTALE; + + if (!(loc && loc->parent)) + goto out; + + if (!gf_uuid_is_null(loc->parent->gfid)) + memcpy(req->pargfid, loc->parent->gfid, 16); + else + memcpy(req->pargfid, loc->pargfid, 16); + + GF_ASSERT_AND_GOTO_WITH_ERROR(this->name, + !gf_uuid_is_null(*((uuid_t *)req->pargfid)), + out, op_errno, EINVAL); + + req->bname = (char *)loc->name; + req->mode = mode; + req->umask = umask; + + GF_PROTOCOL_DICT_SERIALIZE(this, xdata, (&req->xdata.xdata_val), + req->xdata.xdata_len, op_errno, out); + + return 0; +out: + return -op_errno; +} + +int +client_pre_unlink(xlator_t *this, gfs3_unlink_req *req, loc_t *loc, + int32_t flags, dict_t *xdata) +{ + int op_errno = 0; + + if (!(loc && loc->parent)) + goto out; + + if (!gf_uuid_is_null(loc->parent->gfid)) + memcpy(req->pargfid, loc->parent->gfid, 16); + else + memcpy(req->pargfid, loc->pargfid, 16); + + GF_ASSERT_AND_GOTO_WITH_ERROR(this->name, + !gf_uuid_is_null(*((uuid_t *)req->pargfid)), + out, op_errno, EINVAL); + req->bname = (char *)loc->name; + req->xflags = flags; + + GF_PROTOCOL_DICT_SERIALIZE(this, xdata, (&req->xdata.xdata_val), + req->xdata.xdata_len, op_errno, out); + + return 0; +out: + return -op_errno; +} + +int +client_pre_rmdir(xlator_t *this, gfs3_rmdir_req *req, loc_t *loc, int32_t flags, + dict_t *xdata) +{ + int op_errno = ESTALE; + + if (!(loc && loc->parent)) + goto out; + + if (!gf_uuid_is_null(loc->parent->gfid)) + memcpy(req->pargfid, loc->parent->gfid, 16); + else + memcpy(req->pargfid, loc->pargfid, 16); + + GF_ASSERT_AND_GOTO_WITH_ERROR(this->name, + !gf_uuid_is_null(*((uuid_t *)req->pargfid)), + out, op_errno, EINVAL); + req->bname = (char *)loc->name; + req->xflags = flags; + + GF_PROTOCOL_DICT_SERIALIZE(this, xdata, (&req->xdata.xdata_val), + req->xdata.xdata_len, op_errno, out); + + return 0; +out: + return -op_errno; +} + +int +client_pre_symlink(xlator_t *this, gfs3_symlink_req *req, loc_t *loc, + const char *linkname, mode_t umask, dict_t *xdata) +{ + int op_errno = ESTALE; + + if (!(loc && loc->parent)) + goto out; + + if (!gf_uuid_is_null(loc->parent->gfid)) + memcpy(req->pargfid, loc->parent->gfid, 16); + else + memcpy(req->pargfid, loc->pargfid, 16); + + GF_ASSERT_AND_GOTO_WITH_ERROR(this->name, + !gf_uuid_is_null(*((uuid_t *)req->pargfid)), + out, op_errno, EINVAL); + req->linkname = (char *)linkname; + req->bname = (char *)loc->name; + req->umask = umask; + + GF_PROTOCOL_DICT_SERIALIZE(this, xdata, (&req->xdata.xdata_val), + req->xdata.xdata_len, op_errno, out); + return 0; +out: + return -op_errno; +} + +int +client_pre_rename(xlator_t *this, gfs3_rename_req *req, loc_t *oldloc, + loc_t *newloc, dict_t *xdata) +{ + int op_errno = ESTALE; + + if (!(oldloc && newloc && oldloc->parent && newloc->parent)) + goto out; + + if (!gf_uuid_is_null(oldloc->parent->gfid)) + memcpy(req->oldgfid, oldloc->parent->gfid, 16); + else + memcpy(req->oldgfid, oldloc->pargfid, 16); + + if (!gf_uuid_is_null(newloc->parent->gfid)) + memcpy(req->newgfid, newloc->parent->gfid, 16); + else + memcpy(req->newgfid, newloc->pargfid, 16); + + GF_ASSERT_AND_GOTO_WITH_ERROR(this->name, + !gf_uuid_is_null(*((uuid_t *)req->oldgfid)), + out, op_errno, EINVAL); + GF_ASSERT_AND_GOTO_WITH_ERROR(this->name, + !gf_uuid_is_null(*((uuid_t *)req->newgfid)), + out, op_errno, EINVAL); + req->oldbname = (char *)oldloc->name; + req->newbname = (char *)newloc->name; + + GF_PROTOCOL_DICT_SERIALIZE(this, xdata, (&req->xdata.xdata_val), + req->xdata.xdata_len, op_errno, out); + + return 0; +out: + return -op_errno; +} + +int +client_pre_link(xlator_t *this, gfs3_link_req *req, loc_t *oldloc, + loc_t *newloc, dict_t *xdata) +{ + int op_errno = ESTALE; + + if (!(oldloc && oldloc->inode && newloc && newloc->parent)) + goto out; + + if (!gf_uuid_is_null(oldloc->inode->gfid)) + memcpy(req->oldgfid, oldloc->inode->gfid, 16); + else + memcpy(req->oldgfid, oldloc->gfid, 16); + + if (!gf_uuid_is_null(newloc->parent->gfid)) + memcpy(req->newgfid, newloc->parent->gfid, 16); + else + memcpy(req->newgfid, newloc->pargfid, 16); + + GF_ASSERT_AND_GOTO_WITH_ERROR(this->name, + !gf_uuid_is_null(*((uuid_t *)req->oldgfid)), + out, op_errno, EINVAL); + GF_ASSERT_AND_GOTO_WITH_ERROR(this->name, + !gf_uuid_is_null(*((uuid_t *)req->newgfid)), + out, op_errno, EINVAL); + req->newbname = (char *)newloc->name; + + GF_PROTOCOL_DICT_SERIALIZE(this, xdata, (&req->xdata.xdata_val), + req->xdata.xdata_len, op_errno, out); + + return 0; +out: + return -op_errno; +} + +int +client_pre_truncate(xlator_t *this, gfs3_truncate_req *req, loc_t *loc, + off_t offset, dict_t *xdata) +{ + int op_errno = ESTALE; + + if (!(loc && loc->inode)) + goto out; + + if (!gf_uuid_is_null(loc->inode->gfid)) + memcpy(req->gfid, loc->inode->gfid, 16); + else + memcpy(req->gfid, loc->gfid, 16); + + GF_ASSERT_AND_GOTO_WITH_ERROR(this->name, + !gf_uuid_is_null(*((uuid_t *)req->gfid)), out, + op_errno, EINVAL); + req->offset = offset; + + GF_PROTOCOL_DICT_SERIALIZE(this, xdata, (&req->xdata.xdata_val), + req->xdata.xdata_len, op_errno, out); + return 0; +out: + return -op_errno; +} + +int +client_pre_open(xlator_t *this, gfs3_open_req *req, loc_t *loc, fd_t *fd, + int32_t flags, dict_t *xdata) +{ + int op_errno = ESTALE; + + if (!(loc && loc->inode)) + goto out; + + if (!gf_uuid_is_null(loc->inode->gfid)) + memcpy(req->gfid, loc->inode->gfid, 16); + else + memcpy(req->gfid, loc->gfid, 16); + + GF_ASSERT_AND_GOTO_WITH_ERROR(this->name, + !gf_uuid_is_null(*((uuid_t *)req->gfid)), out, + op_errno, EINVAL); + req->flags = gf_flags_from_flags(flags); + + GF_PROTOCOL_DICT_SERIALIZE(this, xdata, (&req->xdata.xdata_val), + req->xdata.xdata_len, op_errno, out); + + return 0; +out: + return -op_errno; +} + +int +client_pre_readv(xlator_t *this, gfs3_read_req *req, fd_t *fd, size_t size, + off_t offset, int32_t flags, dict_t *xdata) +{ + int64_t remote_fd = -1; + int op_errno = ESTALE; + + CLIENT_GET_REMOTE_FD(this, fd, FALLBACK_TO_ANON_FD, remote_fd, op_errno, + out); + + req->size = size; + req->offset = offset; + req->fd = remote_fd; + req->flag = flags; + + memcpy(req->gfid, fd->inode->gfid, 16); + + GF_PROTOCOL_DICT_SERIALIZE(this, xdata, (&req->xdata.xdata_val), + req->xdata.xdata_len, op_errno, out); + + return 0; +out: + return -op_errno; +} + +int +client_pre_writev(xlator_t *this, gfs3_write_req *req, fd_t *fd, size_t size, + off_t offset, int32_t flags, dict_t **xdata) +{ + int64_t remote_fd = -1; + int op_errno = ESTALE; + + CLIENT_GET_REMOTE_FD(this, fd, FALLBACK_TO_ANON_FD, remote_fd, op_errno, + out); + + req->size = size; + req->offset = offset; + req->fd = remote_fd; + req->flag = flags; + + memcpy(req->gfid, fd->inode->gfid, 16); + +#ifdef GF_TESTING_IO_XDATA + if (!*xdata) + *xdata = dict_new(); + + ret = dict_set_str(*xdata, "testing-the-xdata-key", + "testing-the-xdata-value"); +#endif + + GF_PROTOCOL_DICT_SERIALIZE(this, *xdata, (&req->xdata.xdata_val), + req->xdata.xdata_len, op_errno, out); + + return 0; +out: + return -op_errno; +} + +int +client_pre_statfs(xlator_t *this, gfs3_statfs_req *req, loc_t *loc, + dict_t *xdata) +{ + int op_errno = ESTALE; + + if (!loc) + goto out; + + if (loc->inode) { + if (!gf_uuid_is_null(loc->inode->gfid)) + memcpy(req->gfid, loc->inode->gfid, 16); + else + memcpy(req->gfid, loc->gfid, 16); + } else { + req->gfid[15] = 1; + } + + GF_ASSERT_AND_GOTO_WITH_ERROR(this->name, + !gf_uuid_is_null(*((uuid_t *)req->gfid)), out, + op_errno, EINVAL); + + GF_PROTOCOL_DICT_SERIALIZE(this, xdata, (&req->xdata.xdata_val), + req->xdata.xdata_len, op_errno, out); + + return 0; +out: + return -op_errno; +} + +int +client_pre_flush(xlator_t *this, gfs3_flush_req *req, fd_t *fd, dict_t *xdata) +{ + int64_t remote_fd = -1; + int op_errno = ESTALE; + + CLIENT_GET_REMOTE_FD(this, fd, DEFAULT_REMOTE_FD, remote_fd, op_errno, out); + + req->fd = remote_fd; + memcpy(req->gfid, fd->inode->gfid, 16); + + GF_PROTOCOL_DICT_SERIALIZE(this, xdata, (&req->xdata.xdata_val), + req->xdata.xdata_len, op_errno, out); + + return 0; +out: + return -op_errno; +} + +int +client_pre_fsync(xlator_t *this, gfs3_fsync_req *req, fd_t *fd, int32_t flags, + dict_t *xdata) +{ + int64_t remote_fd = -1; + int op_errno = 0; + + CLIENT_GET_REMOTE_FD(this, fd, FALLBACK_TO_ANON_FD, remote_fd, op_errno, + out); + + req->fd = remote_fd; + req->data = flags; + memcpy(req->gfid, fd->inode->gfid, 16); + + GF_PROTOCOL_DICT_SERIALIZE(this, xdata, (&req->xdata.xdata_val), + req->xdata.xdata_len, op_errno, out); + + return 0; +out: + return -op_errno; +} + +int +client_pre_setxattr(xlator_t *this, gfs3_setxattr_req *req, loc_t *loc, + dict_t *xattr, int32_t flags, dict_t *xdata) +{ + int op_errno = ESTALE; + + if (!(loc && loc->inode)) + goto out; + + if (!gf_uuid_is_null(loc->inode->gfid)) + memcpy(req->gfid, loc->inode->gfid, 16); + else + memcpy(req->gfid, loc->gfid, 16); + + GF_ASSERT_AND_GOTO_WITH_ERROR(this->name, + !gf_uuid_is_null(*((uuid_t *)req->gfid)), out, + op_errno, EINVAL); + if (xattr) { + GF_PROTOCOL_DICT_SERIALIZE(this, xattr, (&req->dict.dict_val), + req->dict.dict_len, op_errno, out); + } + + req->flags = flags; + + GF_PROTOCOL_DICT_SERIALIZE(this, xdata, (&req->xdata.xdata_val), + req->xdata.xdata_len, op_errno, out); + + return 0; +out: + return -op_errno; +} + +int +client_pre_getxattr(xlator_t *this, gfs3_getxattr_req *req, loc_t *loc, + const char *name, dict_t *xdata) +{ + int op_errno = ESTALE; + + if (!loc) { + op_errno = EINVAL; + goto out; + } + + if (loc->inode && !gf_uuid_is_null(loc->inode->gfid)) + memcpy(req->gfid, loc->inode->gfid, 16); + else + memcpy(req->gfid, loc->gfid, 16); + + GF_ASSERT_AND_GOTO_WITH_ERROR(this->name, + !gf_uuid_is_null(*((uuid_t *)req->gfid)), out, + op_errno, EINVAL); + req->namelen = 1; /* Use it as a flag */ + + req->name = (char *)name; + if (!req->name) { + req->name = ""; + req->namelen = 0; + } + + GF_PROTOCOL_DICT_SERIALIZE(this, xdata, (&req->xdata.xdata_val), + req->xdata.xdata_len, op_errno, out); + + return 0; +out: + return -op_errno; +} + +int +client_pre_removexattr(xlator_t *this, gfs3_removexattr_req *req, loc_t *loc, + const char *name, dict_t *xdata) +{ + int op_errno = ESTALE; + + if (!(loc && loc->inode)) + goto out; + + if (!gf_uuid_is_null(loc->inode->gfid)) + memcpy(req->gfid, loc->inode->gfid, 16); + else + memcpy(req->gfid, loc->gfid, 16); + + GF_ASSERT_AND_GOTO_WITH_ERROR(this->name, + !gf_uuid_is_null(*((uuid_t *)req->gfid)), out, + op_errno, EINVAL); + req->name = (char *)name; + + GF_PROTOCOL_DICT_SERIALIZE(this, xdata, (&req->xdata.xdata_val), + req->xdata.xdata_len, op_errno, out); + + return 0; +out: + return -op_errno; +} + +int +client_pre_opendir(xlator_t *this, gfs3_opendir_req *req, loc_t *loc, fd_t *fd, + dict_t *xdata) +{ + int op_errno = ESTALE; + + if (!(loc && loc->inode)) + goto out; + + if (!gf_uuid_is_null(loc->inode->gfid)) + memcpy(req->gfid, loc->inode->gfid, 16); + else + memcpy(req->gfid, loc->gfid, 16); + + GF_ASSERT_AND_GOTO_WITH_ERROR(this->name, + !gf_uuid_is_null(*((uuid_t *)req->gfid)), out, + op_errno, EINVAL); + + GF_PROTOCOL_DICT_SERIALIZE(this, xdata, (&req->xdata.xdata_val), + req->xdata.xdata_len, op_errno, out); + + return 0; +out: + return -op_errno; +} + +int +client_pre_fsyncdir(xlator_t *this, gfs3_fsyncdir_req *req, fd_t *fd, + int32_t flags, dict_t *xdata) +{ + int32_t op_errno = ESTALE; + int64_t remote_fd = -1; + + CLIENT_GET_REMOTE_FD(this, fd, DEFAULT_REMOTE_FD, remote_fd, op_errno, out); + + req->fd = remote_fd; + req->data = flags; + memcpy(req->gfid, fd->inode->gfid, 16); + + GF_PROTOCOL_DICT_SERIALIZE(this, xdata, (&req->xdata.xdata_val), + req->xdata.xdata_len, op_errno, out); + + return 0; +out: + return -op_errno; +} + +int +client_pre_access(xlator_t *this, gfs3_access_req *req, loc_t *loc, + int32_t mask, dict_t *xdata) +{ + int op_errno = ESTALE; + + if (!(loc && loc->inode)) + goto out; + + if (!gf_uuid_is_null(loc->inode->gfid)) + memcpy(req->gfid, loc->inode->gfid, 16); + else + memcpy(req->gfid, loc->gfid, 16); + + GF_ASSERT_AND_GOTO_WITH_ERROR(this->name, + !gf_uuid_is_null(*((uuid_t *)req->gfid)), out, + op_errno, EINVAL); + req->mask = mask; + + GF_PROTOCOL_DICT_SERIALIZE(this, xdata, (&req->xdata.xdata_val), + req->xdata.xdata_len, op_errno, out); + return 0; +out: + return -op_errno; +} + +int +client_pre_create(xlator_t *this, gfs3_create_req *req, loc_t *loc, fd_t *fd, + mode_t mode, int32_t flags, mode_t umask, dict_t *xdata) +{ + int op_errno = ESTALE; + + if (!(loc && loc->parent)) + goto out; + + if (!gf_uuid_is_null(loc->parent->gfid)) + memcpy(req->pargfid, loc->parent->gfid, 16); + else + memcpy(req->pargfid, loc->pargfid, 16); + + GF_ASSERT_AND_GOTO_WITH_ERROR(this->name, + !gf_uuid_is_null(*((uuid_t *)req->pargfid)), + out, op_errno, EINVAL); + req->bname = (char *)loc->name; + req->mode = mode; + req->flags = gf_flags_from_flags(flags); + req->umask = umask; + + GF_PROTOCOL_DICT_SERIALIZE(this, xdata, (&req->xdata.xdata_val), + req->xdata.xdata_len, op_errno, out); + + return 0; +out: + return -op_errno; +} + +int +client_pre_ftruncate(xlator_t *this, gfs3_ftruncate_req *req, fd_t *fd, + off_t offset, dict_t *xdata) +{ + int64_t remote_fd = -1; + int op_errno = EINVAL; + + CLIENT_GET_REMOTE_FD(this, fd, DEFAULT_REMOTE_FD, remote_fd, op_errno, out); + + req->offset = offset; + req->fd = remote_fd; + memcpy(req->gfid, fd->inode->gfid, 16); + + GF_PROTOCOL_DICT_SERIALIZE(this, xdata, (&req->xdata.xdata_val), + req->xdata.xdata_len, op_errno, out); + return 0; +out: + return -op_errno; +} + +int +client_pre_fstat(xlator_t *this, gfs3_fstat_req *req, fd_t *fd, dict_t *xdata) +{ + int64_t remote_fd = -1; + int op_errno = ESTALE; + + CLIENT_GET_REMOTE_FD(this, fd, DEFAULT_REMOTE_FD, remote_fd, op_errno, out); + + req->fd = remote_fd; + memcpy(req->gfid, fd->inode->gfid, 16); + + GF_PROTOCOL_DICT_SERIALIZE(this, xdata, (&req->xdata.xdata_val), + req->xdata.xdata_len, op_errno, out); + + return 0; +out: + return -op_errno; +} + +int +client_pre_lk(xlator_t *this, gfs3_lk_req *req, int32_t cmd, + struct gf_flock *flock, fd_t *fd, dict_t *xdata) +{ + int64_t remote_fd = -1; + int op_errno = ESTALE; + int32_t gf_cmd = 0; + int32_t gf_type = 0; + int ret = 0; + + CLIENT_GET_REMOTE_FD(this, fd, DEFAULT_REMOTE_FD, remote_fd, op_errno, out); + + ret = client_cmd_to_gf_cmd(cmd, &gf_cmd); + if (ret) { + op_errno = EINVAL; + gf_smsg(this->name, GF_LOG_WARNING, EINVAL, PC_MSG_UNKNOWN_CMD, + "gf_cmd=%d", gf_cmd, NULL); + goto out; + } + + 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; + } + + req->fd = remote_fd; + req->cmd = gf_cmd; + req->type = gf_type; + gf_proto_flock_from_flock(&req->flock, flock); + + memcpy(req->gfid, fd->inode->gfid, 16); + + GF_PROTOCOL_DICT_SERIALIZE(this, xdata, (&req->xdata.xdata_val), + req->xdata.xdata_len, op_errno, out); + + return 0; +out: + return -op_errno; +} + +int +client_pre_lookup(xlator_t *this, gfs3_lookup_req *req, loc_t *loc, + dict_t *xdata) +{ + int op_errno = ESTALE; + + if (!(loc && loc->inode)) + goto out; + + if ((loc->parent) && (!gf_uuid_is_null(loc->parent->gfid))) + memcpy(req->pargfid, loc->parent->gfid, 16); + else + memcpy(req->pargfid, loc->pargfid, 16); + + if ((loc->inode) && (!gf_uuid_is_null(loc->inode->gfid))) + memcpy(req->gfid, loc->inode->gfid, 16); + else + memcpy(req->gfid, loc->gfid, 16); + + if (loc->name) + req->bname = (char *)loc->name; + else + req->bname = ""; + + if (xdata) { + GF_PROTOCOL_DICT_SERIALIZE(this, xdata, (&req->xdata.xdata_val), + req->xdata.xdata_len, op_errno, out); + } + return 0; +out: + return -op_errno; +} + +int +client_pre_readdir(xlator_t *this, gfs3_readdir_req *req, fd_t *fd, size_t size, + off_t offset, dict_t *xdata) +{ + int64_t remote_fd = -1; + int op_errno = ESTALE; + + CLIENT_GET_REMOTE_FD(this, fd, DEFAULT_REMOTE_FD, remote_fd, op_errno, out); + + req->size = size; + req->offset = offset; + req->fd = remote_fd; + + memcpy(req->gfid, fd->inode->gfid, 16); + GF_PROTOCOL_DICT_SERIALIZE(this, xdata, (&req->xdata.xdata_val), + req->xdata.xdata_len, op_errno, out); + + return 0; +out: + return -op_errno; +} + +int +client_pre_inodelk(xlator_t *this, gfs3_inodelk_req *req, loc_t *loc, int cmd, + struct gf_flock *flock, const char *volume, dict_t *xdata) +{ + int op_errno = ESTALE; + int32_t gf_cmd = 0; + int32_t gf_type = 0; + + if (!(loc && loc->inode)) + goto out; + + if (!gf_uuid_is_null(loc->gfid)) + memcpy(req->gfid, loc->gfid, 16); + else + memcpy(req->gfid, loc->inode->gfid, 16); + + GF_ASSERT_AND_GOTO_WITH_ERROR(this->name, + !gf_uuid_is_null(*((uuid_t *)req->gfid)), out, + op_errno, EINVAL); + 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_smsg(this->name, GF_LOG_WARNING, EINVAL, PC_MSG_UNKNOWN_CMD, + "gf_cmd=%d", gf_cmd, NULL); + op_errno = EINVAL; + goto out; + } + + 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; + } + + req->volume = (char *)volume; + req->cmd = gf_cmd; + req->type = gf_type; + gf_proto_flock_from_flock(&req->flock, flock); + + GF_PROTOCOL_DICT_SERIALIZE(this, xdata, (&req->xdata.xdata_val), + req->xdata.xdata_len, op_errno, out); + + return 0; +out: + return -op_errno; +} + +int +client_pre_finodelk(xlator_t *this, gfs3_finodelk_req *req, fd_t *fd, int cmd, + struct gf_flock *flock, const char *volume, dict_t *xdata) +{ + int op_errno = ESTALE; + int64_t remote_fd = -1; + int32_t gf_type = 0; + int32_t gf_cmd = 0; + + CLIENT_GET_REMOTE_FD(this, fd, FALLBACK_TO_ANON_FD, remote_fd, op_errno, + out); + + 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_smsg(this->name, GF_LOG_WARNING, EINVAL, PC_MSG_UNKNOWN_CMD, + "gf_cmd=%d", gf_cmd, NULL); + goto out; + } + + 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; + } + + req->volume = (char *)volume; + req->fd = remote_fd; + req->cmd = gf_cmd; + req->type = gf_type; + gf_proto_flock_from_flock(&req->flock, flock); + memcpy(req->gfid, fd->inode->gfid, 16); + + GF_PROTOCOL_DICT_SERIALIZE(this, xdata, (&req->xdata.xdata_val), + req->xdata.xdata_len, op_errno, out); + return 0; +out: + return -op_errno; +} + +int +client_pre_entrylk(xlator_t *this, gfs3_entrylk_req *req, loc_t *loc, + entrylk_cmd cmd_entrylk, entrylk_type type, + const char *volume, const char *basename, dict_t *xdata) +{ + int op_errno = ESTALE; + + if (!(loc && loc->inode)) + goto out; + + if (!gf_uuid_is_null(loc->gfid)) + memcpy(req->gfid, loc->gfid, 16); + else + memcpy(req->gfid, loc->inode->gfid, 16); + + GF_ASSERT_AND_GOTO_WITH_ERROR(this->name, + !gf_uuid_is_null(*((uuid_t *)req->gfid)), out, + op_errno, EINVAL); + req->cmd = cmd_entrylk; + req->type = type; + req->volume = (char *)volume; + req->name = ""; + if (basename) { + req->name = (char *)basename; + req->namelen = 1; + } + + GF_PROTOCOL_DICT_SERIALIZE(this, xdata, (&req->xdata.xdata_val), + req->xdata.xdata_len, op_errno, out); + + return 0; +out: + return -op_errno; +} + +int +client_pre_fentrylk(xlator_t *this, gfs3_fentrylk_req *req, fd_t *fd, + entrylk_cmd cmd_entrylk, entrylk_type type, + const char *volume, const char *basename, dict_t *xdata) +{ + int64_t remote_fd = -1; + int op_errno = ESTALE; + + CLIENT_GET_REMOTE_FD(this, fd, DEFAULT_REMOTE_FD, remote_fd, op_errno, out); + + req->fd = remote_fd; + req->cmd = cmd_entrylk; + req->type = type; + req->volume = (char *)volume; + req->name = ""; + if (basename) { + req->name = (char *)basename; + req->namelen = 1; + } + memcpy(req->gfid, fd->inode->gfid, 16); + + GF_PROTOCOL_DICT_SERIALIZE(this, xdata, (&req->xdata.xdata_val), + req->xdata.xdata_len, op_errno, out); + + return 0; +out: + return -op_errno; +} + +int +client_pre_xattrop(xlator_t *this, gfs3_xattrop_req *req, loc_t *loc, + dict_t *xattr, int32_t flags, dict_t *xdata) +{ + int op_errno = ESTALE; + + if (!(loc && loc->inode)) + goto out; + + if (!gf_uuid_is_null(loc->inode->gfid)) + memcpy(req->gfid, loc->inode->gfid, 16); + else + memcpy(req->gfid, loc->gfid, 16); + + GF_ASSERT_AND_GOTO_WITH_ERROR(this->name, + !gf_uuid_is_null(*((uuid_t *)req->gfid)), out, + op_errno, EINVAL); + if (xattr) { + GF_PROTOCOL_DICT_SERIALIZE(this, xattr, (&req->dict.dict_val), + req->dict.dict_len, op_errno, out); + } + + req->flags = flags; + + GF_PROTOCOL_DICT_SERIALIZE(this, xdata, (&req->xdata.xdata_val), + req->xdata.xdata_len, op_errno, out); + + return 0; +out: + return -op_errno; +} + +int +client_pre_fxattrop(xlator_t *this, gfs3_fxattrop_req *req, fd_t *fd, + dict_t *xattr, int32_t flags, dict_t *xdata) +{ + int op_errno = ESTALE; + int64_t remote_fd = -1; + + CLIENT_GET_REMOTE_FD(this, fd, FALLBACK_TO_ANON_FD, remote_fd, op_errno, + out); + + req->fd = remote_fd; + req->flags = flags; + memcpy(req->gfid, fd->inode->gfid, 16); + + if (xattr) { + GF_PROTOCOL_DICT_SERIALIZE(this, xattr, (&req->dict.dict_val), + req->dict.dict_len, op_errno, out); + } + + GF_PROTOCOL_DICT_SERIALIZE(this, xdata, (&req->xdata.xdata_val), + req->xdata.xdata_len, op_errno, out); + + return 0; +out: + return -op_errno; +} + +int +client_pre_fgetxattr(xlator_t *this, gfs3_fgetxattr_req *req, fd_t *fd, + const char *name, dict_t *xdata) +{ + int64_t remote_fd = -1; + int op_errno = ESTALE; + + CLIENT_GET_REMOTE_FD(this, fd, DEFAULT_REMOTE_FD, remote_fd, op_errno, out); + + req->namelen = 1; /* Use it as a flag */ + req->fd = remote_fd; + req->name = (char *)name; + if (!req->name) { + req->name = ""; + req->namelen = 0; + } + memcpy(req->gfid, fd->inode->gfid, 16); + + GF_PROTOCOL_DICT_SERIALIZE(this, xdata, (&req->xdata.xdata_val), + req->xdata.xdata_len, op_errno, out); + + return 0; +out: + return -op_errno; +} + +int +client_pre_fsetxattr(xlator_t *this, gfs3_fsetxattr_req *req, fd_t *fd, + int32_t flags, dict_t *xattr, dict_t *xdata) +{ + int64_t remote_fd = -1; + int op_errno = ESTALE; + + CLIENT_GET_REMOTE_FD(this, fd, DEFAULT_REMOTE_FD, remote_fd, op_errno, out); + + req->fd = remote_fd; + req->flags = flags; + memcpy(req->gfid, fd->inode->gfid, 16); + + if (xattr) { + GF_PROTOCOL_DICT_SERIALIZE(this, xattr, (&req->dict.dict_val), + req->dict.dict_len, op_errno, out); + } + + GF_PROTOCOL_DICT_SERIALIZE(this, xdata, (&req->xdata.xdata_val), + req->xdata.xdata_len, op_errno, out); + + return 0; +out: + return -op_errno; +} + +int +client_pre_rchecksum(xlator_t *this, gfs3_rchecksum_req *req, fd_t *fd, + int32_t len, off_t offset, dict_t *xdata) +{ + int64_t remote_fd = -1; + int op_errno = ESTALE; + + CLIENT_GET_REMOTE_FD(this, fd, DEFAULT_REMOTE_FD, remote_fd, op_errno, out); + + req->len = len; + req->offset = offset; + req->fd = remote_fd; + + GF_PROTOCOL_DICT_SERIALIZE(this, xdata, (&req->xdata.xdata_val), + req->xdata.xdata_len, op_errno, out); + + return 0; +out: + return -op_errno; +} + +int +client_pre_setattr(xlator_t *this, gfs3_setattr_req *req, loc_t *loc, + int32_t valid, struct iatt *stbuf, dict_t *xdata) +{ + int op_errno = ESTALE; + + if (!(loc && loc->inode)) + return -op_errno; + + if (!gf_uuid_is_null(loc->inode->gfid)) + memcpy(req->gfid, loc->inode->gfid, 16); + else + memcpy(req->gfid, loc->gfid, 16); + + GF_ASSERT_AND_GOTO_WITH_ERROR(this->name, + !gf_uuid_is_null(*((uuid_t *)req->gfid)), out, + op_errno, EINVAL); + + req->valid = valid; + gf_stat_from_iatt(&req->stbuf, stbuf); + + GF_PROTOCOL_DICT_SERIALIZE(this, xdata, (&req->xdata.xdata_val), + req->xdata.xdata_len, op_errno, out); + + return 0; +out: + return -op_errno; +} + +int +client_pre_fsetattr(xlator_t *this, gfs3_fsetattr_req *req, fd_t *fd, + int32_t valid, struct iatt *stbuf, dict_t *xdata) +{ + int op_errno = ESTALE; + int64_t remote_fd = -1; + + CLIENT_GET_REMOTE_FD(this, fd, DEFAULT_REMOTE_FD, remote_fd, op_errno, out); + + req->fd = remote_fd; + req->valid = valid; + gf_stat_from_iatt(&req->stbuf, stbuf); + + GF_PROTOCOL_DICT_SERIALIZE(this, xdata, (&req->xdata.xdata_val), + req->xdata.xdata_len, op_errno, out); + return 0; +out: + return -op_errno; +} + +int +client_pre_readdirp(xlator_t *this, gfs3_readdirp_req *req, fd_t *fd, + size_t size, off_t offset, dict_t *xdata) +{ + int op_errno = ESTALE; + int64_t remote_fd = -1; + + CLIENT_GET_REMOTE_FD(this, fd, DEFAULT_REMOTE_FD, remote_fd, op_errno, out); + + req->size = size; + req->offset = offset; + req->fd = remote_fd; + memcpy(req->gfid, fd->inode->gfid, 16); + + /* dict itself is 'xdata' here */ + GF_PROTOCOL_DICT_SERIALIZE(this, xdata, (&req->dict.dict_val), + req->dict.dict_len, op_errno, out); + + return 0; +out: + return -op_errno; +} + +int +client_pre_fremovexattr(xlator_t *this, gfs3_fremovexattr_req *req, fd_t *fd, + const char *name, dict_t *xdata) +{ + int64_t remote_fd = -1; + int op_errno = ESTALE; + + if (!(fd && fd->inode)) + goto out; + + CLIENT_GET_REMOTE_FD(this, fd, DEFAULT_REMOTE_FD, remote_fd, op_errno, out); + + memcpy(req->gfid, fd->inode->gfid, 16); + req->name = (char *)name; + req->fd = remote_fd; + + GF_PROTOCOL_DICT_SERIALIZE(this, xdata, (&req->xdata.xdata_val), + req->xdata.xdata_len, op_errno, out); + + return 0; +out: + return -op_errno; +} + +int +client_pre_fallocate(xlator_t *this, gfs3_fallocate_req *req, fd_t *fd, + int32_t flags, off_t offset, size_t size, dict_t *xdata) +{ + int op_errno = ESTALE; + int64_t remote_fd = -1; + + CLIENT_GET_REMOTE_FD(this, fd, DEFAULT_REMOTE_FD, remote_fd, op_errno, out); + + req->fd = remote_fd; + req->flags = flags; + req->offset = offset; + req->size = size; + memcpy(req->gfid, fd->inode->gfid, 16); + + GF_PROTOCOL_DICT_SERIALIZE(this, xdata, (&req->xdata.xdata_val), + req->xdata.xdata_len, op_errno, out); + return 0; +out: + return -op_errno; +} + +int +client_pre_discard(xlator_t *this, gfs3_discard_req *req, fd_t *fd, + off_t offset, size_t size, dict_t *xdata) +{ + int op_errno = ESTALE; + int64_t remote_fd = -1; + + CLIENT_GET_REMOTE_FD(this, fd, DEFAULT_REMOTE_FD, remote_fd, op_errno, out); + + req->fd = remote_fd; + req->offset = offset; + req->size = size; + memcpy(req->gfid, fd->inode->gfid, 16); + + GF_PROTOCOL_DICT_SERIALIZE(this, xdata, (&req->xdata.xdata_val), + req->xdata.xdata_len, op_errno, out); + return 0; +out: + return -op_errno; +} + +int +client_pre_zerofill(xlator_t *this, gfs3_zerofill_req *req, fd_t *fd, + off_t offset, size_t size, dict_t *xdata) +{ + int op_errno = ESTALE; + int64_t remote_fd = -1; + + CLIENT_GET_REMOTE_FD(this, fd, DEFAULT_REMOTE_FD, remote_fd, op_errno, out); + + req->fd = remote_fd; + req->offset = offset; + req->size = size; + memcpy(req->gfid, fd->inode->gfid, 16); + + GF_PROTOCOL_DICT_SERIALIZE(this, xdata, (&req->xdata.xdata_val), + req->xdata.xdata_len, op_errno, out); + return 0; +out: + return -op_errno; +} + +int +client_pre_ipc(xlator_t *this, gfs3_ipc_req *req, int32_t cmd, dict_t *xdata) +{ + int op_errno = ESTALE; + + req->op = cmd; + + GF_PROTOCOL_DICT_SERIALIZE(this, xdata, (&req->xdata.xdata_val), + req->xdata.xdata_len, op_errno, out); + return 0; +out: + return -op_errno; +} + +int +client_pre_seek(xlator_t *this, gfs3_seek_req *req, fd_t *fd, off_t offset, + gf_seek_what_t what, dict_t *xdata) +{ + int64_t remote_fd = -1; + int op_errno = ESTALE; + + CLIENT_GET_REMOTE_FD(this, fd, DEFAULT_REMOTE_FD, remote_fd, op_errno, out); + + memcpy(req->gfid, fd->inode->gfid, 16); + req->fd = remote_fd; + req->offset = offset; + req->what = what; + + GF_PROTOCOL_DICT_SERIALIZE(this, xdata, (&req->xdata.xdata_val), + req->xdata.xdata_len, op_errno, out); + + return 0; +out: + return -op_errno; +} + +int +client_pre_lease(xlator_t *this, gfs3_lease_req *req, loc_t *loc, + struct gf_lease *lease, dict_t *xdata) +{ + int op_errno = 0; + + if (!(loc && loc->inode)) + goto out; + + if (!gf_uuid_is_null(loc->inode->gfid)) + memcpy(req->gfid, loc->inode->gfid, 16); + else + memcpy(req->gfid, loc->gfid, 16); + + GF_ASSERT_AND_GOTO_WITH_ERROR(this->name, + !gf_uuid_is_null(*((uuid_t *)req->gfid)), out, + op_errno, EINVAL); + + gf_proto_lease_from_lease(&req->lease, lease); + + GF_PROTOCOL_DICT_SERIALIZE(this, xdata, (&req->xdata.xdata_val), + req->xdata.xdata_len, op_errno, out); +out: + return -op_errno; +} + +/* processing done after fop responses are obtained */ +int +client_post_stat(xlator_t *this, gfs3_stat_rsp *rsp, struct iatt *iatt, + dict_t **xdata) +{ + int ret = 0; + + 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: + return ret; +} + +int +client_post_readlink(xlator_t *this, gfs3_readlink_rsp *rsp, struct iatt *iatt, + dict_t **xdata) +{ + int ret = 0; + + 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: + + return ret; +} + +int +client_post_mknod(xlator_t *this, gfs3_mknod_rsp *rsp, struct iatt *stbuf, + struct iatt *preparent, struct iatt *postparent, + dict_t **xdata) +{ + int ret = 0; + + 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: + return ret; +} + +int +client_post_mkdir(xlator_t *this, gfs3_mkdir_rsp *rsp, struct iatt *stbuf, + struct iatt *preparent, struct iatt *postparent, + dict_t **xdata) +{ + int ret = 0; + + 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: + return ret; +} + +int +client_post_unlink(xlator_t *this, gfs3_unlink_rsp *rsp, struct iatt *preparent, + struct iatt *postparent, dict_t **xdata) +{ + int ret = 0; + + 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); + + ret = gf_replace_new_iatt_in_dict(*xdata); +out: + return ret; +} + +int +client_post_rmdir(xlator_t *this, gfs3_rmdir_rsp *rsp, struct iatt *preparent, + struct iatt *postparent, dict_t **xdata) +{ + int ret = 0; + + 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: + return ret; +} + +int +client_post_symlink(xlator_t *this, gfs3_symlink_rsp *rsp, struct iatt *stbuf, + struct iatt *preparent, struct iatt *postparent, + dict_t **xdata) +{ + int ret = 0; + + 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: + return ret; +} + +int +client_post_rename(xlator_t *this, gfs3_rename_rsp *rsp, struct iatt *stbuf, + struct iatt *preoldparent, struct iatt *postoldparent, + struct iatt *prenewparent, struct iatt *postnewparent, + dict_t **xdata) +{ + int ret = 0; + + 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: + return ret; +} + +int +client_post_link(xlator_t *this, gfs3_link_rsp *rsp, struct iatt *stbuf, + struct iatt *preparent, struct iatt *postparent, + dict_t **xdata) +{ + int ret = 0; + + 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: + return ret; +} + +int +client_post_truncate(xlator_t *this, gfs3_truncate_rsp *rsp, + struct iatt *prestat, struct iatt *poststat, + dict_t **xdata) +{ + int ret = 0; + + 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: + return ret; +} + +int +client_post_open(xlator_t *this, gfs3_open_rsp *rsp, dict_t **xdata) +{ + int ret = 0; + + GF_PROTOCOL_DICT_UNSERIALIZE(this, *xdata, (rsp->xdata.xdata_val), + (rsp->xdata.xdata_len), ret, rsp->op_errno, + out); +out: + return ret; +} + +int +client_post_readv(xlator_t *this, gfs3_read_rsp *rsp, struct iobref **iobref, + struct iobref *rsp_iobref, struct iatt *stat, + struct iovec *vector, struct iovec *rsp_vector, int *rspcount, + dict_t **xdata) +{ + int ret = 0; + + if (rsp->op_ret != -1) { + *iobref = 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 = rsp_vector->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_to_log(xdata); +#endif +out: + return ret; +} + +int +client_post_writev(xlator_t *this, gfs3_write_rsp *rsp, struct iatt *prestat, + struct iatt *poststat, dict_t **xdata) +{ + int ret = 0; + + 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: + return ret; +} + +int +client_post_statfs(xlator_t *this, gfs3_statfs_rsp *rsp, struct statvfs *statfs, + dict_t **xdata) +{ + int ret = 0; + + 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: + return ret; +} + +int +client_post_flush(xlator_t *this, gf_common_rsp *rsp, dict_t **xdata) +{ + int ret = 0; + + GF_PROTOCOL_DICT_UNSERIALIZE(this, *xdata, (rsp->xdata.xdata_val), + (rsp->xdata.xdata_len), ret, rsp->op_errno, + out); + +out: + return ret; +} + +int +client_post_fsync(xlator_t *this, gfs3_fsync_rsp *rsp, struct iatt *prestat, + struct iatt *poststat, dict_t **xdata) +{ + int ret = 0; + + 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: + return ret; +} + +int +client_post_setxattr(xlator_t *this, gf_common_rsp *rsp, dict_t **xdata) +{ + int ret = 0; + + GF_PROTOCOL_DICT_UNSERIALIZE(this, *xdata, (rsp->xdata.xdata_val), + (rsp->xdata.xdata_len), ret, rsp->op_errno, + out); + + ret = gf_replace_new_iatt_in_dict(*xdata); +out: + return ret; +} + +int +client_post_getxattr(xlator_t *this, gfs3_getxattr_rsp *rsp, dict_t **dict, + dict_t **xdata) +{ + int op_errno = 0; + int ret = 0; + + if (-1 != rsp->op_ret) { + GF_PROTOCOL_DICT_UNSERIALIZE(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: + return -op_errno; +} + +int +client_post_removexattr(xlator_t *this, gf_common_rsp *rsp, dict_t **xdata) +{ + int ret = 0; + + GF_PROTOCOL_DICT_UNSERIALIZE(this, *xdata, (rsp->xdata.xdata_val), + (rsp->xdata.xdata_len), ret, rsp->op_errno, + out); + + ret = gf_replace_new_iatt_in_dict(*xdata); +out: + return ret; +} + +int +client_post_opendir(xlator_t *this, gfs3_opendir_rsp *rsp, dict_t **xdata) +{ + int ret = 0; + + GF_PROTOCOL_DICT_UNSERIALIZE(this, *xdata, (rsp->xdata.xdata_val), + (rsp->xdata.xdata_len), ret, rsp->op_errno, + out); +out: + return ret; +} + +int +client_post_fsyncdir(xlator_t *this, gf_common_rsp *rsp, dict_t **xdata) +{ + int ret = 0; + + GF_PROTOCOL_DICT_UNSERIALIZE(this, *xdata, (rsp->xdata.xdata_val), + (rsp->xdata.xdata_len), ret, rsp->op_errno, + out); +out: + return ret; +} + +int +client_post_access(xlator_t *this, gf_common_rsp *rsp, dict_t **xdata) +{ + int ret = 0; + + GF_PROTOCOL_DICT_UNSERIALIZE(this, *xdata, (rsp->xdata.xdata_val), + (rsp->xdata.xdata_len), ret, rsp->op_errno, + out); +out: + return ret; +} + +int +client_post_create(xlator_t *this, gfs3_create_rsp *rsp, struct iatt *stbuf, + struct iatt *preparent, struct iatt *postparent, + clnt_local_t *local, dict_t **xdata) +{ + int ret = 0; + + 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_uuid_copy(local->loc.gfid, stbuf->ia_gfid); + } + GF_PROTOCOL_DICT_UNSERIALIZE(this, *xdata, (rsp->xdata.xdata_val), + (rsp->xdata.xdata_len), ret, rsp->op_errno, + out); +out: + return ret; +} + +int +client_post_ftruncate(xlator_t *this, gfs3_ftruncate_rsp *rsp, + struct iatt *prestat, struct iatt *poststat, + dict_t **xdata) +{ + int ret = 0; + + 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: + return ret; +} + +int +client_post_fstat(xlator_t *this, gfs3_fstat_rsp *rsp, struct iatt *stat, + dict_t **xdata) +{ + int ret = 0; + + 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: + return -ret; +} + +int +client_post_lk(xlator_t *this, gfs3_lk_rsp *rsp, struct gf_flock *lock, + dict_t **xdata) +{ + int ret = 0; + + if (rsp->op_ret >= 0) { + gf_proto_flock_to_flock(&rsp->flock, lock); + } + GF_PROTOCOL_DICT_UNSERIALIZE(this, *xdata, (rsp->xdata.xdata_val), + (rsp->xdata.xdata_len), ret, rsp->op_errno, + out); +out: + return ret; +} + +int +client_post_lookup(xlator_t *this, gfs3_lookup_rsp *rsp, struct iatt *stbuf, + struct iatt *postparent, dict_t **xdata) +{ + int ret = 0; + + if (-1 != rsp->op_ret) { + gf_stat_to_iatt(&rsp->postparent, postparent); + gf_stat_to_iatt(&rsp->stat, stbuf); + } + + GF_PROTOCOL_DICT_UNSERIALIZE(this, *xdata, (rsp->xdata.xdata_val), + (rsp->xdata.xdata_len), ret, rsp->op_errno, + out); +out: + return ret; +} + +int +client_post_readdir(xlator_t *this, gfs3_readdir_rsp *rsp, gf_dirent_t *entries, + dict_t **xdata) +{ + int ret = 0; + + if (rsp->op_ret > 0) { + unserialize_rsp_dirent(this, rsp, entries); + } + GF_PROTOCOL_DICT_UNSERIALIZE(this, *xdata, (rsp->xdata.xdata_val), + (rsp->xdata.xdata_len), ret, rsp->op_errno, + out); + +out: + return ret; +} + +int +client_post_inodelk(xlator_t *this, gf_common_rsp *rsp, dict_t **xdata) +{ + int ret = 0; + + GF_PROTOCOL_DICT_UNSERIALIZE(this, *xdata, (rsp->xdata.xdata_val), + (rsp->xdata.xdata_len), ret, rsp->op_errno, + out); + +out: + return ret; +} + +int +client_post_finodelk(xlator_t *this, gf_common_rsp *rsp, dict_t **xdata) +{ + int ret = 0; + + GF_PROTOCOL_DICT_UNSERIALIZE(this, *xdata, (rsp->xdata.xdata_val), + (rsp->xdata.xdata_len), ret, rsp->op_errno, + out); + +out: + return ret; +} + +int +client_post_entrylk(xlator_t *this, gf_common_rsp *rsp, dict_t **xdata) +{ + int ret = 0; + + GF_PROTOCOL_DICT_UNSERIALIZE(this, *xdata, (rsp->xdata.xdata_val), + (rsp->xdata.xdata_len), ret, rsp->op_errno, + out); + +out: + return ret; +} + +int +client_post_fentrylk(xlator_t *this, gf_common_rsp *rsp, dict_t **xdata) +{ + int ret = 0; + + GF_PROTOCOL_DICT_UNSERIALIZE(this, *xdata, (rsp->xdata.xdata_val), + (rsp->xdata.xdata_len), ret, rsp->op_errno, + out); + +out: + return ret; +} + +int +client_post_xattrop(xlator_t *this, gfs3_xattrop_rsp *rsp, dict_t **dict, + dict_t **xdata) +{ + int op_errno = 0; + int ret = 0; + + if (-1 != rsp->op_ret) { + GF_PROTOCOL_DICT_UNSERIALIZE(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: + return -op_errno; +} + +int +client_post_fxattrop(xlator_t *this, gfs3_fxattrop_rsp *rsp, dict_t **dict, + dict_t **xdata) +{ + int op_errno = 0; + int ret = 0; + + if (-1 != rsp->op_ret) { + GF_PROTOCOL_DICT_UNSERIALIZE(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: + return -op_errno; +} + +int +client_post_fgetxattr(xlator_t *this, gfs3_fgetxattr_rsp *rsp, dict_t **dict, + dict_t **xdata) +{ + int op_errno = 0; + int ret = 0; + + if (-1 != rsp->op_ret) { + GF_PROTOCOL_DICT_UNSERIALIZE(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: + return -op_errno; +} + +int +client_post_fsetxattr(xlator_t *this, gf_common_rsp *rsp, dict_t **xdata) +{ + int ret = 0; + + GF_PROTOCOL_DICT_UNSERIALIZE(this, *xdata, (rsp->xdata.xdata_val), + (rsp->xdata.xdata_len), ret, rsp->op_errno, + out); + + ret = gf_replace_new_iatt_in_dict(*xdata); +out: + return ret; +} + +int +client_post_rchecksum(xlator_t *this, gfs3_rchecksum_rsp *rsp, dict_t **xdata) +{ + int ret = 0; + + GF_PROTOCOL_DICT_UNSERIALIZE(this, *xdata, (rsp->xdata.xdata_val), + (rsp->xdata.xdata_len), ret, rsp->op_errno, + out); +out: + return ret; +} + +int +client_post_setattr(xlator_t *this, gfs3_setattr_rsp *rsp, struct iatt *prestat, + struct iatt *poststat, dict_t **xdata) +{ + int ret = 0; + + 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: + return ret; +} + +int +client_post_fsetattr(xlator_t *this, gfs3_fsetattr_rsp *rsp, + struct iatt *prestat, struct iatt *poststat, + dict_t **xdata) +{ + int ret = 0; + + 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: + return ret; +} + +int +client_post_readdirp(xlator_t *this, gfs3_readdirp_rsp *rsp, fd_t *fd, + gf_dirent_t *entries, dict_t **xdata) +{ + int ret = 0; + + if (rsp->op_ret > 0) { + unserialize_rsp_direntp(this, fd, rsp, entries); + } + + GF_PROTOCOL_DICT_UNSERIALIZE(this, *xdata, (rsp->xdata.xdata_val), + (rsp->xdata.xdata_len), ret, rsp->op_errno, + out); +out: + return ret; +} + +int +client_post_fremovexattr(xlator_t *this, gf_common_rsp *rsp, dict_t **xdata) +{ + int ret = 0; + + GF_PROTOCOL_DICT_UNSERIALIZE(this, *xdata, (rsp->xdata.xdata_val), + (rsp->xdata.xdata_len), ret, rsp->op_errno, + out); + + ret = gf_replace_new_iatt_in_dict(*xdata); +out: + return ret; +} + +int +client_post_fallocate(xlator_t *this, gfs3_fallocate_rsp *rsp, + struct iatt *prestat, struct iatt *poststat, + dict_t **xdata) +{ + int ret = 0; + + 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: + return ret; +} + +int +client_post_discard(xlator_t *this, gfs3_discard_rsp *rsp, struct iatt *prestat, + struct iatt *poststat, dict_t **xdata) +{ + int ret = 0; + + 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: + return ret; +} + +int +client_post_zerofill(xlator_t *this, gfs3_zerofill_rsp *rsp, + struct iatt *prestat, struct iatt *poststat, + dict_t **xdata) +{ + int ret = 0; + + 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: + return ret; +} + +int +client_post_ipc(xlator_t *this, gfs3_ipc_rsp *rsp, dict_t **xdata) +{ + int ret = 0; + + GF_PROTOCOL_DICT_UNSERIALIZE(this, *xdata, (rsp->xdata.xdata_val), + (rsp->xdata.xdata_len), ret, rsp->op_errno, + out); +out: + return ret; +} + +int +client_post_seek(xlator_t *this, gfs3_seek_rsp *rsp, dict_t **xdata) +{ + int ret = 0; + + GF_PROTOCOL_DICT_UNSERIALIZE(this, *xdata, (rsp->xdata.xdata_val), + (rsp->xdata.xdata_len), ret, rsp->op_errno, + out); +out: + return ret; +} + +int +client_post_lease(xlator_t *this, gfs3_lease_rsp *rsp, struct gf_lease *lease, + dict_t **xdata) +{ + int ret = 0; + + if (rsp->op_ret >= 0) { + gf_proto_lease_to_lease(&rsp->lease, lease); + } + + GF_PROTOCOL_DICT_UNSERIALIZE(this, *xdata, (rsp->xdata.xdata_val), + (rsp->xdata.xdata_len), ret, rsp->op_errno, + out); +out: + return ret; +} + +/* New PRE and POST functions */ + +int +client_post_common_iatt(xlator_t *this, gfx_common_iatt_rsp *rsp, + struct iatt *iatt, dict_t **xdata) +{ + if (-1 != rsp->op_ret) { + gfx_stat_to_iattx(&rsp->stat, iatt); + } + + return xdr_to_dict(&rsp->xdata, xdata); +} + +int +client_post_common_2iatt(xlator_t *this, gfx_common_2iatt_rsp *rsp, + struct iatt *iatt, struct iatt *iatt2, dict_t **xdata) +{ + if (-1 != rsp->op_ret) { + gfx_stat_to_iattx(&rsp->prestat, iatt); + gfx_stat_to_iattx(&rsp->poststat, iatt2); + } + + return xdr_to_dict(&rsp->xdata, xdata); +} + +int +client_post_common_3iatt(xlator_t *this, gfx_common_3iatt_rsp *rsp, + struct iatt *iatt, struct iatt *iatt2, + struct iatt *iatt3, dict_t **xdata) +{ + if (-1 != rsp->op_ret) { + gfx_stat_to_iattx(&rsp->stat, iatt); + gfx_stat_to_iattx(&rsp->preparent, iatt2); + gfx_stat_to_iattx(&rsp->postparent, iatt3); + } + + return xdr_to_dict(&rsp->xdata, xdata); +} + +int +client_post_common_dict(xlator_t *this, gfx_common_dict_rsp *rsp, dict_t **dict, + dict_t **xdata) +{ + int ret = 0; + ret = xdr_to_dict(&rsp->dict, dict); + if (ret) + gf_msg_debug(this->name, EINVAL, + "while decoding found empty dictionary"); + xdr_to_dict(&rsp->xdata, xdata); + + return ret; +} + +int +client_post_readv_v2(xlator_t *this, gfx_read_rsp *rsp, struct iobref **iobref, + struct iobref *rsp_iobref, struct iatt *stat, + struct iovec *vector, struct iovec *rsp_vector, + int *rspcount, dict_t **xdata) +{ + int ret = -1; + + if (rsp->op_ret != -1) { + *iobref = rsp_iobref; + gfx_stat_to_iattx(&rsp->stat, stat); + + vector[0].iov_len = rsp->op_ret; + if (rsp->op_ret > 0) + vector[0].iov_base = rsp_vector->iov_base; + *rspcount = 1; + } + + ret = xdr_to_dict(&rsp->xdata, xdata); + +#ifdef GF_TESTING_IO_XDATA + dict_dump_to_log(xdata); +#endif + return ret; +} + +int +client_pre_stat_v2(xlator_t *this, gfx_stat_req *req, loc_t *loc, dict_t *xdata) +{ + int op_errno = ESTALE; + + if (!(loc && loc->inode)) + goto out; + + if (!gf_uuid_is_null(loc->inode->gfid)) + memcpy(req->gfid, loc->inode->gfid, 16); + else + memcpy(req->gfid, loc->gfid, 16); + + GF_ASSERT_AND_GOTO_WITH_ERROR(this->name, + !gf_uuid_is_null(*((uuid_t *)req->gfid)), out, + op_errno, EINVAL); + + dict_to_xdr(xdata, &req->xdata); + + return 0; +out: + return -op_errno; +} + +int +client_pre_readlink_v2(xlator_t *this, gfx_readlink_req *req, loc_t *loc, + size_t size, dict_t *xdata) +{ + int op_errno = ESTALE; + + if (!(loc && loc->inode)) + goto out; + + if (!gf_uuid_is_null(loc->inode->gfid)) + memcpy(req->gfid, loc->inode->gfid, 16); + else + memcpy(req->gfid, loc->gfid, 16); + + GF_ASSERT_AND_GOTO_WITH_ERROR(this->name, + !gf_uuid_is_null(*((uuid_t *)req->gfid)), out, + op_errno, EINVAL); + req->size = size; + dict_to_xdr(xdata, &req->xdata); + return 0; +out: + return -op_errno; +} + +int +client_pre_mknod_v2(xlator_t *this, gfx_mknod_req *req, loc_t *loc, mode_t mode, + dev_t rdev, mode_t umask, dict_t *xdata) +{ + int op_errno = ESTALE; + + if (!(loc && loc->parent)) + goto out; + + if (!gf_uuid_is_null(loc->parent->gfid)) + memcpy(req->pargfid, loc->parent->gfid, 16); + else + memcpy(req->pargfid, loc->pargfid, 16); + + GF_ASSERT_AND_GOTO_WITH_ERROR(this->name, + !gf_uuid_is_null(*((uuid_t *)req->pargfid)), + out, op_errno, EINVAL); + req->bname = (char *)loc->name; + req->mode = mode; + req->dev = rdev; + req->umask = umask; + + dict_to_xdr(xdata, &req->xdata); + + return 0; +out: + return -op_errno; +} + +int +client_pre_mkdir_v2(xlator_t *this, gfx_mkdir_req *req, loc_t *loc, mode_t mode, + mode_t umask, dict_t *xdata) +{ + int op_errno = ESTALE; + + if (!(loc && loc->parent)) + goto out; + + if (!gf_uuid_is_null(loc->parent->gfid)) + memcpy(req->pargfid, loc->parent->gfid, 16); + else + memcpy(req->pargfid, loc->pargfid, 16); + + GF_ASSERT_AND_GOTO_WITH_ERROR(this->name, + !gf_uuid_is_null(*((uuid_t *)req->pargfid)), + out, op_errno, EINVAL); + + req->bname = (char *)loc->name; + req->mode = mode; + req->umask = umask; + + dict_to_xdr(xdata, &req->xdata); + + return 0; +out: + return -op_errno; +} + +int +client_pre_unlink_v2(xlator_t *this, gfx_unlink_req *req, loc_t *loc, + int32_t flags, dict_t *xdata) +{ + int op_errno = 0; + + if (!(loc && loc->parent)) + goto out; + + if (!gf_uuid_is_null(loc->parent->gfid)) + memcpy(req->pargfid, loc->parent->gfid, 16); + else + memcpy(req->pargfid, loc->pargfid, 16); + + GF_ASSERT_AND_GOTO_WITH_ERROR(this->name, + !gf_uuid_is_null(*((uuid_t *)req->pargfid)), + out, op_errno, EINVAL); + req->bname = (char *)loc->name; + req->xflags = flags; + + dict_to_xdr(xdata, &req->xdata); + + return 0; +out: + return -op_errno; +} + +int +client_pre_rmdir_v2(xlator_t *this, gfx_rmdir_req *req, loc_t *loc, + int32_t flags, dict_t *xdata) +{ + int op_errno = ESTALE; + + if (!(loc && loc->parent)) + goto out; + + if (!gf_uuid_is_null(loc->parent->gfid)) + memcpy(req->pargfid, loc->parent->gfid, 16); + else + memcpy(req->pargfid, loc->pargfid, 16); + + GF_ASSERT_AND_GOTO_WITH_ERROR(this->name, + !gf_uuid_is_null(*((uuid_t *)req->pargfid)), + out, op_errno, EINVAL); + req->bname = (char *)loc->name; + req->xflags = flags; + + dict_to_xdr(xdata, &req->xdata); + + return 0; +out: + return -op_errno; +} + +int +client_pre_symlink_v2(xlator_t *this, gfx_symlink_req *req, loc_t *loc, + const char *linkname, mode_t umask, dict_t *xdata) +{ + int op_errno = ESTALE; + + if (!(loc && loc->parent)) + goto out; + + if (!gf_uuid_is_null(loc->parent->gfid)) + memcpy(req->pargfid, loc->parent->gfid, 16); + else + memcpy(req->pargfid, loc->pargfid, 16); + + GF_ASSERT_AND_GOTO_WITH_ERROR(this->name, + !gf_uuid_is_null(*((uuid_t *)req->pargfid)), + out, op_errno, EINVAL); + req->linkname = (char *)linkname; + req->bname = (char *)loc->name; + req->umask = umask; + + dict_to_xdr(xdata, &req->xdata); + return 0; +out: + return -op_errno; +} + +int +client_pre_rename_v2(xlator_t *this, gfx_rename_req *req, loc_t *oldloc, + loc_t *newloc, dict_t *xdata) +{ + int op_errno = ESTALE; + + if (!(oldloc && newloc && oldloc->parent && newloc->parent)) + goto out; + + if (!gf_uuid_is_null(oldloc->parent->gfid)) + memcpy(req->oldgfid, oldloc->parent->gfid, 16); + else + memcpy(req->oldgfid, oldloc->pargfid, 16); + + if (!gf_uuid_is_null(newloc->parent->gfid)) + memcpy(req->newgfid, newloc->parent->gfid, 16); + else + memcpy(req->newgfid, newloc->pargfid, 16); + + GF_ASSERT_AND_GOTO_WITH_ERROR(this->name, + !gf_uuid_is_null(*((uuid_t *)req->oldgfid)), + out, op_errno, EINVAL); + GF_ASSERT_AND_GOTO_WITH_ERROR(this->name, + !gf_uuid_is_null(*((uuid_t *)req->newgfid)), + out, op_errno, EINVAL); + req->oldbname = (char *)oldloc->name; + req->newbname = (char *)newloc->name; + + dict_to_xdr(xdata, &req->xdata); + + return 0; +out: + return -op_errno; +} + +int +client_pre_link_v2(xlator_t *this, gfx_link_req *req, loc_t *oldloc, + loc_t *newloc, dict_t *xdata) +{ + int op_errno = ESTALE; + + if (!(oldloc && oldloc->inode && newloc && newloc->parent)) + goto out; + + if (!gf_uuid_is_null(oldloc->inode->gfid)) + memcpy(req->oldgfid, oldloc->inode->gfid, 16); + else + memcpy(req->oldgfid, oldloc->gfid, 16); + + if (!gf_uuid_is_null(newloc->parent->gfid)) + memcpy(req->newgfid, newloc->parent->gfid, 16); + else + memcpy(req->newgfid, newloc->pargfid, 16); + + GF_ASSERT_AND_GOTO_WITH_ERROR(this->name, + !gf_uuid_is_null(*((uuid_t *)req->oldgfid)), + out, op_errno, EINVAL); + GF_ASSERT_AND_GOTO_WITH_ERROR(this->name, + !gf_uuid_is_null(*((uuid_t *)req->newgfid)), + out, op_errno, EINVAL); + req->newbname = (char *)newloc->name; + + dict_to_xdr(xdata, &req->xdata); + + return 0; +out: + return -op_errno; +} + +int +client_pre_truncate_v2(xlator_t *this, gfx_truncate_req *req, loc_t *loc, + off_t offset, dict_t *xdata) +{ + int op_errno = ESTALE; + + if (!(loc && loc->inode)) + goto out; + + if (!gf_uuid_is_null(loc->inode->gfid)) + memcpy(req->gfid, loc->inode->gfid, 16); + else + memcpy(req->gfid, loc->gfid, 16); + + GF_ASSERT_AND_GOTO_WITH_ERROR(this->name, + !gf_uuid_is_null(*((uuid_t *)req->gfid)), out, + op_errno, EINVAL); + req->offset = offset; + + dict_to_xdr(xdata, &req->xdata); + return 0; +out: + return -op_errno; +} + +int +client_pre_open_v2(xlator_t *this, gfx_open_req *req, loc_t *loc, fd_t *fd, + int32_t flags, dict_t *xdata) +{ + int op_errno = ESTALE; + + if (!(loc && loc->inode)) + goto out; + + if (!gf_uuid_is_null(loc->inode->gfid)) + memcpy(req->gfid, loc->inode->gfid, 16); + else + memcpy(req->gfid, loc->gfid, 16); + + GF_ASSERT_AND_GOTO_WITH_ERROR(this->name, + !gf_uuid_is_null(*((uuid_t *)req->gfid)), out, + op_errno, EINVAL); + req->flags = gf_flags_from_flags(flags); + + dict_to_xdr(xdata, &req->xdata); + + return 0; +out: + return -op_errno; +} + +int +client_pre_readv_v2(xlator_t *this, gfx_read_req *req, fd_t *fd, size_t size, + off_t offset, int32_t flags, dict_t *xdata) +{ + int64_t remote_fd = -1; + int op_errno = ESTALE; + + CLIENT_GET_REMOTE_FD(this, fd, FALLBACK_TO_ANON_FD, remote_fd, op_errno, + out); + + req->size = size; + req->offset = offset; + req->fd = remote_fd; + req->flag = flags; + + memcpy(req->gfid, fd->inode->gfid, 16); + + dict_to_xdr(xdata, &req->xdata); + + return 0; +out: + return -op_errno; +} + +int +client_pre_writev_v2(xlator_t *this, gfx_write_req *req, fd_t *fd, size_t size, + off_t offset, int32_t flags, dict_t **xdata) +{ + int64_t remote_fd = -1; + int op_errno = ESTALE; + + CLIENT_GET_REMOTE_FD(this, fd, FALLBACK_TO_ANON_FD, remote_fd, op_errno, + out); + + req->size = size; + req->offset = offset; + req->fd = remote_fd; + req->flag = flags; + + memcpy(req->gfid, fd->inode->gfid, 16); + +#ifdef GF_TESTING_IO_XDATA + if (!*xdata) + *xdata = dict_new(); + + ret = dict_set_str(*xdata, "testing-the-xdata-key", + "testing-the-xdata-value"); +#endif + + dict_to_xdr(*xdata, &req->xdata); + + return 0; +out: + return -op_errno; +} + +int +client_pre_copy_file_range_v2(xlator_t *this, gfx_copy_file_range_req *req, + fd_t *fd_in, off64_t off_in, fd_t *fd_out, + off64_t off_out, size_t size, int32_t flags, + dict_t **xdata) +{ + int64_t remote_fd_in = -1; + int64_t remote_fd_out = -1; + int op_errno = ESTALE; + + CLIENT_GET_REMOTE_FD(this, fd_in, FALLBACK_TO_ANON_FD, remote_fd_in, + op_errno, out); + + CLIENT_GET_REMOTE_FD(this, fd_out, FALLBACK_TO_ANON_FD, remote_fd_out, + op_errno, out); + req->size = size; + req->off_in = off_in; + req->off_out = off_out; + req->fd_in = remote_fd_in; + req->fd_out = remote_fd_out; + req->flag = flags; + + memcpy(req->gfid1, fd_in->inode->gfid, 16); + memcpy(req->gfid2, fd_out->inode->gfid, 16); + + dict_to_xdr(*xdata, &req->xdata); + + return 0; +out: + return -op_errno; +} + +int +client_pre_statfs_v2(xlator_t *this, gfx_statfs_req *req, loc_t *loc, + dict_t *xdata) +{ + int op_errno = ESTALE; + + if (!loc) + goto out; + + if (loc->inode) { + if (!gf_uuid_is_null(loc->inode->gfid)) + memcpy(req->gfid, loc->inode->gfid, 16); + else + memcpy(req->gfid, loc->gfid, 16); + } else { + req->gfid[15] = 1; + } + + GF_ASSERT_AND_GOTO_WITH_ERROR(this->name, + !gf_uuid_is_null(*((uuid_t *)req->gfid)), out, + op_errno, EINVAL); + + dict_to_xdr(xdata, &req->xdata); + + return 0; +out: + return -op_errno; +} + +int +client_pre_flush_v2(xlator_t *this, gfx_flush_req *req, fd_t *fd, dict_t *xdata) +{ + int64_t remote_fd = -1; + int op_errno = ESTALE; + + CLIENT_GET_REMOTE_FD(this, fd, DEFAULT_REMOTE_FD, remote_fd, op_errno, out); + + req->fd = remote_fd; + memcpy(req->gfid, fd->inode->gfid, 16); + + dict_to_xdr(xdata, &req->xdata); + + return 0; +out: + return -op_errno; +} + +int +client_pre_fsync_v2(xlator_t *this, gfx_fsync_req *req, fd_t *fd, int32_t flags, + dict_t *xdata) +{ + int64_t remote_fd = -1; + int op_errno = 0; + + CLIENT_GET_REMOTE_FD(this, fd, FALLBACK_TO_ANON_FD, remote_fd, op_errno, + out); + + req->fd = remote_fd; + req->data = flags; + memcpy(req->gfid, fd->inode->gfid, 16); + + dict_to_xdr(xdata, &req->xdata); + + return 0; +out: + return -op_errno; +} + +int +client_pre_setxattr_v2(xlator_t *this, gfx_setxattr_req *req, loc_t *loc, + dict_t *xattr, int32_t flags, dict_t *xdata) +{ + int op_errno = ESTALE; + + if (!(loc && loc->inode)) + goto out; + + if (!gf_uuid_is_null(loc->inode->gfid)) + memcpy(req->gfid, loc->inode->gfid, 16); + else + memcpy(req->gfid, loc->gfid, 16); + + GF_ASSERT_AND_GOTO_WITH_ERROR(this->name, + !gf_uuid_is_null(*((uuid_t *)req->gfid)), out, + op_errno, EINVAL); + if (xattr) { + dict_to_xdr(xattr, &req->dict); + } + + req->flags = flags; + + dict_to_xdr(xdata, &req->xdata); + + return 0; +out: + return -op_errno; +} + +int +client_pre_getxattr_v2(xlator_t *this, gfx_getxattr_req *req, loc_t *loc, + const char *name, dict_t *xdata) +{ + int op_errno = ESTALE; + + if (!loc) { + op_errno = EINVAL; + goto out; + } + + if (loc->inode && !gf_uuid_is_null(loc->inode->gfid)) + memcpy(req->gfid, loc->inode->gfid, 16); + else + memcpy(req->gfid, loc->gfid, 16); + + GF_ASSERT_AND_GOTO_WITH_ERROR(this->name, + !gf_uuid_is_null(*((uuid_t *)req->gfid)), out, + op_errno, EINVAL); + req->namelen = 1; /* Use it as a flag */ + + req->name = (char *)name; + if (!req->name) { + req->name = ""; + req->namelen = 0; + } + + dict_to_xdr(xdata, &req->xdata); + + return 0; +out: + return -op_errno; +} + +int +client_pre_removexattr_v2(xlator_t *this, gfx_removexattr_req *req, loc_t *loc, + const char *name, dict_t *xdata) +{ + int op_errno = ESTALE; + + if (!(loc && loc->inode)) + goto out; + + if (!gf_uuid_is_null(loc->inode->gfid)) + memcpy(req->gfid, loc->inode->gfid, 16); + else + memcpy(req->gfid, loc->gfid, 16); + + GF_ASSERT_AND_GOTO_WITH_ERROR(this->name, + !gf_uuid_is_null(*((uuid_t *)req->gfid)), out, + op_errno, EINVAL); + req->name = (char *)name; + + dict_to_xdr(xdata, &req->xdata); + + return 0; +out: + return -op_errno; +} + +int +client_pre_opendir_v2(xlator_t *this, gfx_opendir_req *req, loc_t *loc, + fd_t *fd, dict_t *xdata) +{ + int op_errno = ESTALE; + + if (!(loc && loc->inode)) + goto out; + + if (!gf_uuid_is_null(loc->inode->gfid)) + memcpy(req->gfid, loc->inode->gfid, 16); + else + memcpy(req->gfid, loc->gfid, 16); + + GF_ASSERT_AND_GOTO_WITH_ERROR(this->name, + !gf_uuid_is_null(*((uuid_t *)req->gfid)), out, + op_errno, EINVAL); + + dict_to_xdr(xdata, &req->xdata); + + return 0; +out: + return -op_errno; +} + +int +client_pre_fsyncdir_v2(xlator_t *this, gfx_fsyncdir_req *req, fd_t *fd, + int32_t flags, dict_t *xdata) +{ + int32_t op_errno = ESTALE; + int64_t remote_fd = -1; + + CLIENT_GET_REMOTE_FD(this, fd, DEFAULT_REMOTE_FD, remote_fd, op_errno, out); + + req->fd = remote_fd; + req->data = flags; + memcpy(req->gfid, fd->inode->gfid, 16); + + dict_to_xdr(xdata, &req->xdata); + + return 0; +out: + return -op_errno; +} + +int +client_pre_access_v2(xlator_t *this, gfx_access_req *req, loc_t *loc, + int32_t mask, dict_t *xdata) +{ + int op_errno = ESTALE; + + if (!(loc && loc->inode)) + goto out; + + if (!gf_uuid_is_null(loc->inode->gfid)) + memcpy(req->gfid, loc->inode->gfid, 16); + else + memcpy(req->gfid, loc->gfid, 16); + + GF_ASSERT_AND_GOTO_WITH_ERROR(this->name, + !gf_uuid_is_null(*((uuid_t *)req->gfid)), out, + op_errno, EINVAL); + req->mask = mask; + + dict_to_xdr(xdata, &req->xdata); + return 0; +out: + return -op_errno; +} + +int +client_pre_create_v2(xlator_t *this, gfx_create_req *req, loc_t *loc, fd_t *fd, + mode_t mode, int32_t flags, mode_t umask, dict_t *xdata) +{ + int op_errno = ESTALE; + + if (!(loc && loc->parent)) + goto out; + + if (!gf_uuid_is_null(loc->parent->gfid)) + memcpy(req->pargfid, loc->parent->gfid, 16); + else + memcpy(req->pargfid, loc->pargfid, 16); + + GF_ASSERT_AND_GOTO_WITH_ERROR(this->name, + !gf_uuid_is_null(*((uuid_t *)req->pargfid)), + out, op_errno, EINVAL); + req->bname = (char *)loc->name; + req->mode = mode; + req->flags = gf_flags_from_flags(flags); + req->umask = umask; + + dict_to_xdr(xdata, &req->xdata); + + return 0; +out: + return -op_errno; +} + +int +client_pre_ftruncate_v2(xlator_t *this, gfx_ftruncate_req *req, fd_t *fd, + off_t offset, dict_t *xdata) +{ + int64_t remote_fd = -1; + int op_errno = EINVAL; + + CLIENT_GET_REMOTE_FD(this, fd, DEFAULT_REMOTE_FD, remote_fd, op_errno, out); + + req->offset = offset; + req->fd = remote_fd; + memcpy(req->gfid, fd->inode->gfid, 16); + + dict_to_xdr(xdata, &req->xdata); + return 0; +out: + return -op_errno; +} + +int +client_pre_fstat_v2(xlator_t *this, gfx_fstat_req *req, fd_t *fd, dict_t *xdata) +{ + int64_t remote_fd = -1; + int op_errno = ESTALE; + + CLIENT_GET_REMOTE_FD(this, fd, DEFAULT_REMOTE_FD, remote_fd, op_errno, out); + + req->fd = remote_fd; + memcpy(req->gfid, fd->inode->gfid, 16); + + dict_to_xdr(xdata, &req->xdata); + + return 0; +out: + return -op_errno; +} + +int +client_pre_lk_v2(xlator_t *this, gfx_lk_req *req, int32_t cmd, + struct gf_flock *flock, fd_t *fd, dict_t *xdata) +{ + int64_t remote_fd = -1; + int op_errno = ESTALE; + int32_t gf_cmd = 0; + int32_t gf_type = 0; + int ret = 0; + + CLIENT_GET_REMOTE_FD(this, fd, DEFAULT_REMOTE_FD, remote_fd, op_errno, out); + + ret = client_cmd_to_gf_cmd(cmd, &gf_cmd); + if (ret) { + op_errno = EINVAL; + gf_smsg(this->name, GF_LOG_WARNING, EINVAL, PC_MSG_UNKNOWN_CMD, + "gf_cmd=%d", gf_cmd, NULL); + goto out; + } + + 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; + } + + req->fd = remote_fd; + req->cmd = gf_cmd; + req->type = gf_type; + gf_proto_flock_from_flock(&req->flock, flock); + + memcpy(req->gfid, fd->inode->gfid, 16); + + dict_to_xdr(xdata, &req->xdata); + + return 0; +out: + return -op_errno; +} + +int +client_pre_lookup_v2(xlator_t *this, gfx_lookup_req *req, loc_t *loc, + dict_t *xdata) +{ + int op_errno = ESTALE; + + if (!(loc && loc->inode)) + goto out; + + if ((loc->parent) && (!gf_uuid_is_null(loc->parent->gfid))) + memcpy(req->pargfid, loc->parent->gfid, 16); + else + memcpy(req->pargfid, loc->pargfid, 16); + + if ((loc->inode) && (!gf_uuid_is_null(loc->inode->gfid))) + memcpy(req->gfid, loc->inode->gfid, 16); + else + memcpy(req->gfid, loc->gfid, 16); + + if (loc->name) + req->bname = (char *)loc->name; + else + req->bname = ""; + + if (xdata) { + dict_to_xdr(xdata, &req->xdata); + } + return 0; +out: + return -op_errno; +} + +int +client_pre_readdir_v2(xlator_t *this, gfx_readdir_req *req, fd_t *fd, + size_t size, off_t offset, dict_t *xdata) +{ + int64_t remote_fd = -1; + int op_errno = ESTALE; + + CLIENT_GET_REMOTE_FD(this, fd, DEFAULT_REMOTE_FD, remote_fd, op_errno, out); + + req->size = size; + req->offset = offset; + req->fd = remote_fd; + + memcpy(req->gfid, fd->inode->gfid, 16); + dict_to_xdr(xdata, &req->xdata); + + return 0; +out: + return -op_errno; +} + +int +client_pre_inodelk_v2(xlator_t *this, gfx_inodelk_req *req, loc_t *loc, int cmd, + struct gf_flock *flock, const char *volume, dict_t *xdata) +{ + int op_errno = ESTALE; + int32_t gf_cmd = 0; + int32_t gf_type = 0; + + if (!(loc && loc->inode)) + goto out; + + if (!gf_uuid_is_null(loc->gfid)) + memcpy(req->gfid, loc->gfid, 16); + else + memcpy(req->gfid, loc->inode->gfid, 16); + + GF_ASSERT_AND_GOTO_WITH_ERROR(this->name, + !gf_uuid_is_null(*((uuid_t *)req->gfid)), out, + op_errno, EINVAL); + 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_smsg(this->name, GF_LOG_WARNING, EINVAL, PC_MSG_UNKNOWN_CMD, + "gf_cmd=%d", gf_cmd, NULL); + op_errno = EINVAL; + goto out; + } + + 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; + } + + req->volume = (char *)volume; + req->cmd = gf_cmd; + req->type = gf_type; + gf_proto_flock_from_flock(&req->flock, flock); + + dict_to_xdr(xdata, &req->xdata); + + return 0; +out: + return -op_errno; +} + +int +client_pre_finodelk_v2(xlator_t *this, gfx_finodelk_req *req, fd_t *fd, int cmd, + struct gf_flock *flock, const char *volume, + dict_t *xdata) +{ + int op_errno = ESTALE; + int64_t remote_fd = -1; + int32_t gf_type = 0; + int32_t gf_cmd = 0; + + CLIENT_GET_REMOTE_FD(this, fd, FALLBACK_TO_ANON_FD, remote_fd, op_errno, + out); + + 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_smsg(this->name, GF_LOG_WARNING, EINVAL, PC_MSG_UNKNOWN_CMD, + "gf_cmd=%d", gf_cmd, NULL); + goto out; + } + + 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; + } + + req->volume = (char *)volume; + req->fd = remote_fd; + req->cmd = gf_cmd; + req->type = gf_type; + gf_proto_flock_from_flock(&req->flock, flock); + memcpy(req->gfid, fd->inode->gfid, 16); + + dict_to_xdr(xdata, &req->xdata); + return 0; +out: + return -op_errno; +} + +int +client_pre_entrylk_v2(xlator_t *this, gfx_entrylk_req *req, loc_t *loc, + entrylk_cmd cmd_entrylk, entrylk_type type, + const char *volume, const char *basename, dict_t *xdata) +{ + int op_errno = ESTALE; + + if (!(loc && loc->inode)) + goto out; + + if (!gf_uuid_is_null(loc->gfid)) + memcpy(req->gfid, loc->gfid, 16); + else + memcpy(req->gfid, loc->inode->gfid, 16); + + GF_ASSERT_AND_GOTO_WITH_ERROR(this->name, + !gf_uuid_is_null(*((uuid_t *)req->gfid)), out, + op_errno, EINVAL); + req->cmd = cmd_entrylk; + req->type = type; + req->volume = (char *)volume; + req->name = ""; + if (basename) { + req->name = (char *)basename; + req->namelen = 1; + } + + dict_to_xdr(xdata, &req->xdata); + + return 0; +out: + return -op_errno; +} + +int +client_pre_fentrylk_v2(xlator_t *this, gfx_fentrylk_req *req, fd_t *fd, + entrylk_cmd cmd_entrylk, entrylk_type type, + const char *volume, const char *basename, dict_t *xdata) +{ + int64_t remote_fd = -1; + int op_errno = ESTALE; + + CLIENT_GET_REMOTE_FD(this, fd, DEFAULT_REMOTE_FD, remote_fd, op_errno, out); + + req->fd = remote_fd; + req->cmd = cmd_entrylk; + req->type = type; + req->volume = (char *)volume; + req->name = ""; + if (basename) { + req->name = (char *)basename; + req->namelen = 1; + } + memcpy(req->gfid, fd->inode->gfid, 16); + + dict_to_xdr(xdata, &req->xdata); + + return 0; +out: + return -op_errno; +} + +int +client_pre_xattrop_v2(xlator_t *this, gfx_xattrop_req *req, loc_t *loc, + dict_t *xattr, int32_t flags, dict_t *xdata) +{ + int op_errno = ESTALE; + + if (!(loc && loc->inode)) + goto out; + + if (!gf_uuid_is_null(loc->inode->gfid)) + memcpy(req->gfid, loc->inode->gfid, 16); + else + memcpy(req->gfid, loc->gfid, 16); + + GF_ASSERT_AND_GOTO_WITH_ERROR(this->name, + !gf_uuid_is_null(*((uuid_t *)req->gfid)), out, + op_errno, EINVAL); + dict_to_xdr(xattr, &req->dict); + + req->flags = flags; + + dict_to_xdr(xdata, &req->xdata); + + return 0; +out: + return -op_errno; +} + +int +client_pre_fxattrop_v2(xlator_t *this, gfx_fxattrop_req *req, fd_t *fd, + dict_t *xattr, int32_t flags, dict_t *xdata) +{ + int op_errno = ESTALE; + int64_t remote_fd = -1; + + CLIENT_GET_REMOTE_FD(this, fd, FALLBACK_TO_ANON_FD, remote_fd, op_errno, + out); + + req->fd = remote_fd; + req->flags = flags; + memcpy(req->gfid, fd->inode->gfid, 16); + + dict_to_xdr(xattr, &req->dict); + + dict_to_xdr(xdata, &req->xdata); + + return 0; +out: + return -op_errno; +} + +int +client_pre_fgetxattr_v2(xlator_t *this, gfx_fgetxattr_req *req, fd_t *fd, + const char *name, dict_t *xdata) +{ + int64_t remote_fd = -1; + int op_errno = ESTALE; + + CLIENT_GET_REMOTE_FD(this, fd, DEFAULT_REMOTE_FD, remote_fd, op_errno, out); + + req->namelen = 1; /* Use it as a flag */ + req->fd = remote_fd; + req->name = (char *)name; + if (!req->name) { + req->name = ""; + req->namelen = 0; + } + memcpy(req->gfid, fd->inode->gfid, 16); + + dict_to_xdr(xdata, &req->xdata); + + return 0; +out: + return -op_errno; +} + +int +client_pre_fsetxattr_v2(xlator_t *this, gfx_fsetxattr_req *req, fd_t *fd, + int32_t flags, dict_t *xattr, dict_t *xdata) +{ + int64_t remote_fd = -1; + int op_errno = ESTALE; + + CLIENT_GET_REMOTE_FD(this, fd, DEFAULT_REMOTE_FD, remote_fd, op_errno, out); + + req->fd = remote_fd; + req->flags = flags; + memcpy(req->gfid, fd->inode->gfid, 16); + + if (xattr) { + dict_to_xdr(xattr, &req->dict); + } + + dict_to_xdr(xdata, &req->xdata); + + return 0; +out: + return -op_errno; +} + +int +client_pre_rchecksum_v2(xlator_t *this, gfx_rchecksum_req *req, fd_t *fd, + int32_t len, off_t offset, dict_t *xdata) +{ + int64_t remote_fd = -1; + int op_errno = ESTALE; + + CLIENT_GET_REMOTE_FD(this, fd, DEFAULT_REMOTE_FD, remote_fd, op_errno, out); + + req->len = len; + req->offset = offset; + req->fd = remote_fd; + + dict_to_xdr(xdata, &req->xdata); + + return 0; +out: + return -op_errno; +} + +int +client_pre_setattr_v2(xlator_t *this, gfx_setattr_req *req, loc_t *loc, + int32_t valid, struct iatt *stbuf, dict_t *xdata) +{ + int op_errno = ESTALE; + + if (!(loc && loc->inode)) + return -op_errno; + + if (!gf_uuid_is_null(loc->inode->gfid)) + memcpy(req->gfid, loc->inode->gfid, 16); + else + memcpy(req->gfid, loc->gfid, 16); + + GF_ASSERT_AND_GOTO_WITH_ERROR(this->name, + !gf_uuid_is_null(*((uuid_t *)req->gfid)), out, + op_errno, EINVAL); + + req->valid = valid; + gfx_stat_from_iattx(&req->stbuf, stbuf); + + dict_to_xdr(xdata, &req->xdata); + + return 0; +out: + return -op_errno; +} + +int +client_pre_fsetattr_v2(xlator_t *this, gfx_fsetattr_req *req, fd_t *fd, + int32_t valid, struct iatt *stbuf, dict_t *xdata) +{ + int op_errno = ESTALE; + int64_t remote_fd = -1; + + CLIENT_GET_REMOTE_FD(this, fd, DEFAULT_REMOTE_FD, remote_fd, op_errno, out); + + memcpy(req->gfid, fd->inode->gfid, 16); + req->fd = remote_fd; + req->valid = valid; + gfx_stat_from_iattx(&req->stbuf, stbuf); + + dict_to_xdr(xdata, &req->xdata); + return 0; +out: + return -op_errno; +} + +int +client_pre_readdirp_v2(xlator_t *this, gfx_readdirp_req *req, fd_t *fd, + size_t size, off_t offset, dict_t *xdata) +{ + int op_errno = ESTALE; + int64_t remote_fd = -1; + + CLIENT_GET_REMOTE_FD(this, fd, DEFAULT_REMOTE_FD, remote_fd, op_errno, out); + + req->size = size; + req->offset = offset; + req->fd = remote_fd; + memcpy(req->gfid, fd->inode->gfid, 16); + + /* dict itself is 'xdata' here */ + dict_to_xdr(xdata, &req->xdata); + + return 0; +out: + return -op_errno; +} + +int +client_pre_fremovexattr_v2(xlator_t *this, gfx_fremovexattr_req *req, fd_t *fd, + const char *name, dict_t *xdata) +{ + int64_t remote_fd = -1; + int op_errno = ESTALE; + + if (!(fd && fd->inode)) + goto out; + + CLIENT_GET_REMOTE_FD(this, fd, DEFAULT_REMOTE_FD, remote_fd, op_errno, out); + + memcpy(req->gfid, fd->inode->gfid, 16); + req->name = (char *)name; + req->fd = remote_fd; + + dict_to_xdr(xdata, &req->xdata); + + return 0; +out: + return -op_errno; +} + +int +client_pre_fallocate_v2(xlator_t *this, gfx_fallocate_req *req, fd_t *fd, + int32_t flags, off_t offset, size_t size, dict_t *xdata) +{ + int op_errno = ESTALE; + int64_t remote_fd = -1; + + CLIENT_GET_REMOTE_FD(this, fd, DEFAULT_REMOTE_FD, remote_fd, op_errno, out); + + req->fd = remote_fd; + req->flags = flags; + req->offset = offset; + req->size = size; + memcpy(req->gfid, fd->inode->gfid, 16); + + dict_to_xdr(xdata, &req->xdata); + return 0; +out: + return -op_errno; +} + +int +client_pre_discard_v2(xlator_t *this, gfx_discard_req *req, fd_t *fd, + off_t offset, size_t size, dict_t *xdata) +{ + int op_errno = ESTALE; + int64_t remote_fd = -1; + + CLIENT_GET_REMOTE_FD(this, fd, DEFAULT_REMOTE_FD, remote_fd, op_errno, out); + + req->fd = remote_fd; + req->offset = offset; + req->size = size; + memcpy(req->gfid, fd->inode->gfid, 16); + + dict_to_xdr(xdata, &req->xdata); + return 0; +out: + return -op_errno; +} + +int +client_pre_zerofill_v2(xlator_t *this, gfx_zerofill_req *req, fd_t *fd, + off_t offset, size_t size, dict_t *xdata) +{ + int op_errno = ESTALE; + int64_t remote_fd = -1; + + CLIENT_GET_REMOTE_FD(this, fd, DEFAULT_REMOTE_FD, remote_fd, op_errno, out); + + req->fd = remote_fd; + req->offset = offset; + req->size = size; + memcpy(req->gfid, fd->inode->gfid, 16); + + dict_to_xdr(xdata, &req->xdata); + return 0; +out: + return -op_errno; +} + +int +client_pre_ipc_v2(xlator_t *this, gfx_ipc_req *req, int32_t cmd, dict_t *xdata) +{ + req->op = cmd; + + dict_to_xdr(xdata, &req->xdata); + return 0; +} + +int +client_pre_seek_v2(xlator_t *this, gfx_seek_req *req, fd_t *fd, off_t offset, + gf_seek_what_t what, dict_t *xdata) +{ + int64_t remote_fd = -1; + int op_errno = ESTALE; + + CLIENT_GET_REMOTE_FD(this, fd, DEFAULT_REMOTE_FD, remote_fd, op_errno, out); + + memcpy(req->gfid, fd->inode->gfid, 16); + req->fd = remote_fd; + req->offset = offset; + req->what = what; + + dict_to_xdr(xdata, &req->xdata); + + return 0; +out: + return -op_errno; +} + +int +client_pre_lease_v2(xlator_t *this, gfx_lease_req *req, loc_t *loc, + struct gf_lease *lease, dict_t *xdata) +{ + int op_errno = 0; + + if (!(loc && loc->inode)) + goto out; + + if (!gf_uuid_is_null(loc->inode->gfid)) + memcpy(req->gfid, loc->inode->gfid, 16); + else + memcpy(req->gfid, loc->gfid, 16); + + GF_ASSERT_AND_GOTO_WITH_ERROR(this->name, + !gf_uuid_is_null(*((uuid_t *)req->gfid)), out, + op_errno, EINVAL); + + gf_proto_lease_from_lease(&req->lease, lease); + + dict_to_xdr(xdata, &req->xdata); +out: + return -op_errno; +} + +int +client_pre_put_v2(xlator_t *this, gfx_put_req *req, loc_t *loc, mode_t mode, + mode_t umask, int32_t flags, size_t size, off_t offset, + dict_t *xattr, dict_t *xdata) +{ + int op_errno = ESTALE; + + if (!(loc && loc->parent)) + goto out; + + if (!gf_uuid_is_null(loc->parent->gfid)) + memcpy(req->pargfid, loc->parent->gfid, 16); + else + memcpy(req->pargfid, loc->pargfid, 16); + + GF_ASSERT_AND_GOTO_WITH_ERROR(this->name, + !gf_uuid_is_null(*((uuid_t *)req->pargfid)), + out, op_errno, EINVAL); + req->bname = (char *)loc->name; + req->mode = mode; + req->umask = umask; + req->flag = gf_flags_from_flags(flags); + req->size = size; + req->offset = offset; + + if (xattr) + dict_to_xdr(xattr, &req->xattr); + + dict_to_xdr(xdata, &req->xdata); + + return 0; +out: + return -op_errno; +} + +int +client_post_create_v2(xlator_t *this, gfx_create_rsp *rsp, struct iatt *stbuf, + struct iatt *preparent, struct iatt *postparent, + clnt_local_t *local, dict_t **xdata) +{ + if (-1 != rsp->op_ret) { + gfx_stat_to_iattx(&rsp->stat, stbuf); + + gfx_stat_to_iattx(&rsp->preparent, preparent); + gfx_stat_to_iattx(&rsp->postparent, postparent); + gf_uuid_copy(local->loc.gfid, stbuf->ia_gfid); + } + return xdr_to_dict(&rsp->xdata, xdata); +} + +int +client_post_lease_v2(xlator_t *this, gfx_lease_rsp *rsp, struct gf_lease *lease, + dict_t **xdata) +{ + if (rsp->op_ret >= 0) { + gf_proto_lease_to_lease(&rsp->lease, lease); + } + + return xdr_to_dict(&rsp->xdata, xdata); +} + +int +client_post_lk_v2(xlator_t *this, gfx_lk_rsp *rsp, struct gf_flock *lock, + dict_t **xdata) +{ + if (rsp->op_ret >= 0) { + gf_proto_flock_to_flock(&rsp->flock, lock); + } + return xdr_to_dict(&rsp->xdata, xdata); +} + +int +client_post_readdir_v2(xlator_t *this, gfx_readdir_rsp *rsp, + gf_dirent_t *entries, dict_t **xdata) +{ + if (rsp->op_ret > 0) { + unserialize_rsp_dirent_v2(this, rsp, entries); + } + return xdr_to_dict(&rsp->xdata, xdata); +} + +int +client_post_readdirp_v2(xlator_t *this, gfx_readdirp_rsp *rsp, fd_t *fd, + gf_dirent_t *entries, dict_t **xdata) +{ + if (rsp->op_ret > 0) { + unserialize_rsp_direntp_v2(this, fd, rsp, entries); + } + return xdr_to_dict(&rsp->xdata, xdata); +} + +int +client_post_rename_v2(xlator_t *this, gfx_rename_rsp *rsp, struct iatt *stbuf, + struct iatt *preoldparent, struct iatt *postoldparent, + struct iatt *prenewparent, struct iatt *postnewparent, + dict_t **xdata) +{ + if (-1 != rsp->op_ret) { + gfx_stat_to_iattx(&rsp->stat, stbuf); + + gfx_stat_to_iattx(&rsp->preoldparent, preoldparent); + gfx_stat_to_iattx(&rsp->postoldparent, postoldparent); + + gfx_stat_to_iattx(&rsp->prenewparent, prenewparent); + gfx_stat_to_iattx(&rsp->postnewparent, postnewparent); + } + + return xdr_to_dict(&rsp->xdata, xdata); +} diff --git a/xlators/protocol/client/src/client-common.h b/xlators/protocol/client/src/client-common.h new file mode 100644 index 00000000000..a2043d8742a --- /dev/null +++ b/xlators/protocol/client/src/client-common.h @@ -0,0 +1,630 @@ +/* + Copyright (c); 2016 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_COMMON_H__ +#define __CLIENT_COMMON_H__ + +#include <glusterfs/dict.h> +#include <glusterfs/xlator.h> +#include "rpc-common-xdr.h" +#include "glusterfs3-xdr.h" +#include "glusterfs4-xdr.h" +#include "glusterfs3.h" +#include "client.h" + +int +client_pre_stat(xlator_t *this, gfs3_stat_req *req, loc_t *loc, dict_t *xdata); + +int +client_pre_readlink(xlator_t *this, gfs3_readlink_req *req, loc_t *loc, + size_t size, dict_t *xdata); + +int +client_pre_mknod(xlator_t *this, gfs3_mknod_req *req, loc_t *loc, mode_t mode, + dev_t rdev, mode_t umask, dict_t *xdata); + +int +client_pre_mkdir(xlator_t *this, gfs3_mkdir_req *req, loc_t *loc, mode_t mode, + mode_t umask, dict_t *xdata); + +int +client_pre_unlink(xlator_t *this, gfs3_unlink_req *req, loc_t *loc, + int32_t flags, dict_t *xdata); + +int +client_pre_rmdir(xlator_t *this, gfs3_rmdir_req *req, loc_t *loc, int32_t flags, + dict_t *xdata); + +int +client_pre_symlink(xlator_t *this, gfs3_symlink_req *req, loc_t *loc, + const char *linkname, mode_t umask, dict_t *xdata); + +int +client_pre_rename(xlator_t *this, gfs3_rename_req *req, loc_t *oldloc, + loc_t *newloc, dict_t *xdata); + +int +client_pre_link(xlator_t *this, gfs3_link_req *req, loc_t *oldloc, + loc_t *newloc, dict_t *xdata); + +int +client_pre_truncate(xlator_t *this, gfs3_truncate_req *req, loc_t *loc, + off_t offset, dict_t *xdata); + +int +client_pre_open(xlator_t *this, gfs3_open_req *req, loc_t *loc, fd_t *fd, + int32_t flags, dict_t *xdata); + +int +client_pre_readv(xlator_t *this, gfs3_read_req *req, fd_t *fd, size_t size, + off_t offset, int32_t flags, dict_t *xdata); + +int +client_pre_writev(xlator_t *this, gfs3_write_req *req, fd_t *fd, size_t size, + off_t offset, int32_t flags, dict_t **xdata); + +int +client_pre_statfs(xlator_t *this, gfs3_statfs_req *req, loc_t *loc, + dict_t *xdata); + +int +client_pre_flush(xlator_t *this, gfs3_flush_req *req, fd_t *fd, dict_t *xdata); + +int +client_pre_fsync(xlator_t *this, gfs3_fsync_req *req, fd_t *fd, int32_t flags, + dict_t *xdata); + +int +client_pre_setxattr(xlator_t *this, gfs3_setxattr_req *req, loc_t *loc, + dict_t *xattr, int32_t flags, dict_t *xdata); + +int +client_pre_getxattr(xlator_t *this, gfs3_getxattr_req *req, loc_t *loc, + const char *name, dict_t *xdata); + +int +client_pre_removexattr(xlator_t *this, gfs3_removexattr_req *req, loc_t *loc, + const char *name, dict_t *xdata); + +int +client_pre_opendir(xlator_t *this, gfs3_opendir_req *req, loc_t *loc, fd_t *fd, + dict_t *xdata); + +int +client_pre_fsyncdir(xlator_t *this, gfs3_fsyncdir_req *req, fd_t *fd, + int32_t flags, dict_t *xdata); + +int +client_pre_access(xlator_t *this, gfs3_access_req *req, loc_t *loc, + int32_t mask, dict_t *xdata); + +int +client_pre_create(xlator_t *this, gfs3_create_req *req, loc_t *loc, fd_t *fd, + mode_t mode, int32_t flags, mode_t umask, dict_t *xdata); + +int +client_pre_ftruncate(xlator_t *this, gfs3_ftruncate_req *req, fd_t *fd, + off_t offset, dict_t *xdata); + +int +client_pre_fstat(xlator_t *this, gfs3_fstat_req *req, fd_t *fd, dict_t *xdata); + +int +client_pre_lk(xlator_t *this, gfs3_lk_req *req, int32_t cmd, + struct gf_flock *flock, fd_t *fd, dict_t *xdata); + +int +client_pre_lookup(xlator_t *this, gfs3_lookup_req *req, loc_t *loc, + dict_t *xdata); + +int +client_pre_readdir(xlator_t *this, gfs3_readdir_req *req, fd_t *fd, size_t size, + off_t offset, dict_t *xdata); + +int +client_pre_inodelk(xlator_t *this, gfs3_inodelk_req *req, loc_t *loc, int cmd, + struct gf_flock *flock, const char *volume, dict_t *xdata); + +int +client_pre_finodelk(xlator_t *this, gfs3_finodelk_req *req, fd_t *fd, int cmd, + struct gf_flock *flock, const char *volume, dict_t *xdata); + +int +client_pre_entrylk(xlator_t *this, gfs3_entrylk_req *req, loc_t *loc, + entrylk_cmd cmd_entrylk, entrylk_type type, + const char *volume, const char *basename, dict_t *xdata); + +int +client_pre_fentrylk(xlator_t *this, gfs3_fentrylk_req *req, fd_t *fd, + entrylk_cmd cmd_entrylk, entrylk_type type, + const char *volume, const char *basename, dict_t *xdata); + +int +client_pre_xattrop(xlator_t *this, gfs3_xattrop_req *req, loc_t *loc, + dict_t *xattr, int32_t flags, dict_t *xdata); + +int +client_pre_fxattrop(xlator_t *this, gfs3_fxattrop_req *req, fd_t *fd, + dict_t *xattr, int32_t flags, dict_t *xdata); + +int +client_pre_fgetxattr(xlator_t *this, gfs3_fgetxattr_req *req, fd_t *fd, + const char *name, dict_t *xdata); + +int +client_pre_fsetxattr(xlator_t *this, gfs3_fsetxattr_req *req, fd_t *fd, + int32_t flags, dict_t *xattr, dict_t *xdata); +int +client_pre_seek(xlator_t *this, gfs3_seek_req *req, fd_t *fd, off_t offset, + gf_seek_what_t what, dict_t *xdata); + +int +client_pre_rchecksum(xlator_t *this, gfs3_rchecksum_req *req, fd_t *fd, + int32_t len, off_t offset, dict_t *xdata); + +int +client_pre_setattr(xlator_t *this, gfs3_setattr_req *req, loc_t *loc, + int32_t valid, struct iatt *stbuf, dict_t *xdata); +int +client_pre_fsetattr(xlator_t *this, gfs3_fsetattr_req *req, fd_t *fd, + int32_t valid, struct iatt *stbuf, dict_t *xdata); + +int +client_pre_readdirp(xlator_t *this, gfs3_readdirp_req *req, fd_t *fd, + size_t size, off_t offset, dict_t *xdata); + +int +client_pre_fremovexattr(xlator_t *this, gfs3_fremovexattr_req *req, fd_t *fd, + const char *name, dict_t *xdata); + +int +client_pre_fallocate(xlator_t *this, gfs3_fallocate_req *req, fd_t *fd, + int32_t flags, off_t offset, size_t size, dict_t *xdata); +int +client_pre_discard(xlator_t *this, gfs3_discard_req *req, fd_t *fd, + off_t offset, size_t size, dict_t *xdata); +int +client_pre_zerofill(xlator_t *this, gfs3_zerofill_req *req, fd_t *fd, + off_t offset, size_t size, dict_t *xdata); +int +client_pre_ipc(xlator_t *this, gfs3_ipc_req *req, int32_t cmd, dict_t *xdata); + +int +client_pre_lease(xlator_t *this, gfs3_lease_req *req, loc_t *loc, + struct gf_lease *lease, dict_t *xdata); + +int +client_post_stat(xlator_t *this, gfs3_stat_rsp *rsp, struct iatt *iatt, + dict_t **xdata); + +int +client_post_readlink(xlator_t *this, gfs3_readlink_rsp *rsp, struct iatt *iatt, + dict_t **xdata); + +int +client_post_mknod(xlator_t *this, gfs3_mknod_rsp *rsp, struct iatt *stbuf, + struct iatt *preparent, struct iatt *postparent, + dict_t **xdata); + +int +client_post_mkdir(xlator_t *this, gfs3_mkdir_rsp *rsp, struct iatt *stbuf, + struct iatt *preparent, struct iatt *postparent, + dict_t **xdata); + +int +client_post_unlink(xlator_t *this, gfs3_unlink_rsp *rsp, struct iatt *preparent, + struct iatt *postparent, dict_t **xdata); + +int +client_post_rmdir(xlator_t *this, gfs3_rmdir_rsp *rsp, struct iatt *preparent, + struct iatt *postparent, dict_t **xdata); + +int +client_post_symlink(xlator_t *this, gfs3_symlink_rsp *rsp, struct iatt *stbuf, + struct iatt *preparent, struct iatt *postparent, + dict_t **xdata); + +int +client_post_rename(xlator_t *this, gfs3_rename_rsp *rsp, struct iatt *stbuf, + struct iatt *preoldparent, struct iatt *postoldparent, + struct iatt *prenewparent, struct iatt *postnewparent, + dict_t **xdata); +int +client_post_link(xlator_t *this, gfs3_link_rsp *rsp, struct iatt *stbuf, + struct iatt *preparent, struct iatt *postparent, + dict_t **xdata); + +int +client_post_truncate(xlator_t *this, gfs3_truncate_rsp *rsp, + struct iatt *prestat, struct iatt *poststat, + dict_t **xdata); + +int +client_post_open(xlator_t *this, gfs3_open_rsp *rsp, dict_t **xdata); + +int +client_post_readv(xlator_t *this, gfs3_read_rsp *rsp, struct iobref **iobref, + struct iobref *rsp_iobref, struct iatt *stat, + struct iovec *vector, struct iovec *rsp_vector, int *rspcount, + dict_t **xdata); + +int +client_post_writev(xlator_t *this, gfs3_write_rsp *rsp, struct iatt *prestat, + struct iatt *poststat, dict_t **xdata); + +int +client_post_statfs(xlator_t *this, gfs3_statfs_rsp *rsp, struct statvfs *statfs, + dict_t **xdata); + +int +client_post_flush(xlator_t *this, gf_common_rsp *rsp, dict_t **xdata); + +int +client_post_fsync(xlator_t *this, gfs3_fsync_rsp *rsp, struct iatt *prestat, + struct iatt *poststat, dict_t **xdata); +int +client_post_setxattr(xlator_t *this, gf_common_rsp *rsp, dict_t **xdata); + +int +client_post_getxattr(xlator_t *this, gfs3_getxattr_rsp *rsp, dict_t **dict, + dict_t **xdata); + +int +client_post_removexattr(xlator_t *this, gf_common_rsp *rsp, dict_t **xdata); + +int +client_post_opendir(xlator_t *this, gfs3_opendir_rsp *rsp, dict_t **xdata); + +int +client_post_fsyncdir(xlator_t *this, gf_common_rsp *rsp, dict_t **xdata); + +int +client_post_access(xlator_t *this, gf_common_rsp *rsp, dict_t **xdata); + +int +client_post_create(xlator_t *this, gfs3_create_rsp *rsp, struct iatt *stbuf, + struct iatt *preparent, struct iatt *postparent, + clnt_local_t *local, dict_t **xdata); + +int +client_post_ftruncate(xlator_t *this, gfs3_ftruncate_rsp *rsp, + struct iatt *prestat, struct iatt *poststat, + dict_t **xdata); + +int +client_post_fstat(xlator_t *this, gfs3_fstat_rsp *rsp, struct iatt *stat, + dict_t **xdata); + +int +client_post_lk(xlator_t *this, gfs3_lk_rsp *rsp, struct gf_flock *lock, + dict_t **xdata); + +int +client_post_lookup(xlator_t *this, gfs3_lookup_rsp *rsp, struct iatt *stbuf, + struct iatt *postparent, dict_t **xdata); + +int +client_post_readdir(xlator_t *this, gfs3_readdir_rsp *rsp, gf_dirent_t *entries, + dict_t **xdata); + +int +client_post_inodelk(xlator_t *this, gf_common_rsp *rsp, dict_t **xdata); + +int +client_post_finodelk(xlator_t *this, gf_common_rsp *rsp, dict_t **xdata); + +int +client_post_entrylk(xlator_t *this, gf_common_rsp *rsp, dict_t **xdata); + +int +client_post_fentrylk(xlator_t *this, gf_common_rsp *rsp, dict_t **xdata); + +int +client_post_xattrop(xlator_t *this, gfs3_xattrop_rsp *rsp, dict_t **dict, + dict_t **xdata); + +int +client_post_fxattrop(xlator_t *this, gfs3_fxattrop_rsp *rsp, dict_t **dict, + dict_t **xdata); + +int +client_post_fgetxattr(xlator_t *this, gfs3_fgetxattr_rsp *rsp, dict_t **dict, + dict_t **xdata); + +int +client_post_fsetxattr(xlator_t *this, gf_common_rsp *rsp, dict_t **xdata); + +int +client_post_rchecksum(xlator_t *this, gfs3_rchecksum_rsp *rsp, dict_t **xdata); + +int +client_post_setattr(xlator_t *this, gfs3_setattr_rsp *rsp, struct iatt *prestat, + struct iatt *poststat, dict_t **xdata); + +int +client_post_fsetattr(xlator_t *this, gfs3_fsetattr_rsp *rsp, + struct iatt *prestat, struct iatt *poststat, + dict_t **xdata); + +int +client_post_readdirp(xlator_t *this, gfs3_readdirp_rsp *rsp, fd_t *fd, + gf_dirent_t *entries, dict_t **xdata); + +int +client_post_fremovexattr(xlator_t *this, gf_common_rsp *rsp, dict_t **xdata); + +int +client_post_fallocate(xlator_t *this, gfs3_fallocate_rsp *rsp, + struct iatt *prestat, struct iatt *poststat, + dict_t **xdata); + +int +client_post_discard(xlator_t *this, gfs3_discard_rsp *rsp, struct iatt *prestat, + struct iatt *poststat, dict_t **xdata); + +int +client_post_zerofill(xlator_t *this, gfs3_zerofill_rsp *rsp, + struct iatt *prestat, struct iatt *poststat, + dict_t **xdata); + +int +client_post_ipc(xlator_t *this, gfs3_ipc_rsp *rsp, dict_t **xdata); + +int +client_post_seek(xlator_t *this, gfs3_seek_rsp *rsp, dict_t **xdata); + +int +client_post_lease(xlator_t *this, gfs3_lease_rsp *rsp, struct gf_lease *lease, + dict_t **xdata); + +/* New functions for version 4 */ +int +client_post_common_dict(xlator_t *this, gfx_common_dict_rsp *rsp, dict_t **dict, + dict_t **xdata); +int +client_post_common_3iatt(xlator_t *this, gfx_common_3iatt_rsp *rsp, + struct iatt *iatt, struct iatt *iatt2, + struct iatt *iatt3, dict_t **xdata); +int +client_post_common_2iatt(xlator_t *this, gfx_common_2iatt_rsp *rsp, + struct iatt *iatt, struct iatt *iatt2, dict_t **xdata); +int +client_post_common_iatt(xlator_t *this, gfx_common_iatt_rsp *rsp, + struct iatt *iatt, dict_t **xdata); +int +client_post_common_rsp(xlator_t *this, gfx_common_rsp *rsp, dict_t **xdata); + +int +client_pre_stat_v2(xlator_t *this, gfx_stat_req *req, loc_t *loc, + dict_t *xdata); + +int +client_pre_readlink_v2(xlator_t *this, gfx_readlink_req *req, loc_t *loc, + size_t size, dict_t *xdata); + +int +client_pre_mknod_v2(xlator_t *this, gfx_mknod_req *req, loc_t *loc, mode_t mode, + dev_t rdev, mode_t umask, dict_t *xdata); + +int +client_pre_mkdir_v2(xlator_t *this, gfx_mkdir_req *req, loc_t *loc, mode_t mode, + mode_t umask, dict_t *xdata); + +int +client_pre_unlink_v2(xlator_t *this, gfx_unlink_req *req, loc_t *loc, + int32_t flags, dict_t *xdata); + +int +client_pre_rmdir_v2(xlator_t *this, gfx_rmdir_req *req, loc_t *loc, + int32_t flags, dict_t *xdata); + +int +client_pre_symlink_v2(xlator_t *this, gfx_symlink_req *req, loc_t *loc, + const char *linkname, mode_t umask, dict_t *xdata); + +int +client_pre_rename_v2(xlator_t *this, gfx_rename_req *req, loc_t *oldloc, + loc_t *newloc, dict_t *xdata); + +int +client_pre_link_v2(xlator_t *this, gfx_link_req *req, loc_t *oldloc, + loc_t *newloc, dict_t *xdata); + +int +client_pre_truncate_v2(xlator_t *this, gfx_truncate_req *req, loc_t *loc, + off_t offset, dict_t *xdata); + +int +client_pre_open_v2(xlator_t *this, gfx_open_req *req, loc_t *loc, fd_t *fd, + int32_t flags, dict_t *xdata); + +int +client_pre_readv_v2(xlator_t *this, gfx_read_req *req, fd_t *fd, size_t size, + off_t offset, int32_t flags, dict_t *xdata); + +int +client_pre_writev_v2(xlator_t *this, gfx_write_req *req, fd_t *fd, size_t size, + off_t offset, int32_t flags, dict_t **xdata); + +int +client_pre_statfs_v2(xlator_t *this, gfx_statfs_req *req, loc_t *loc, + dict_t *xdata); + +int +client_pre_flush_v2(xlator_t *this, gfx_flush_req *req, fd_t *fd, + dict_t *xdata); + +int +client_pre_fsync_v2(xlator_t *this, gfx_fsync_req *req, fd_t *fd, int32_t flags, + dict_t *xdata); + +int +client_pre_setxattr_v2(xlator_t *this, gfx_setxattr_req *req, loc_t *loc, + dict_t *xattr, int32_t flags, dict_t *xdata); + +int +client_pre_getxattr_v2(xlator_t *this, gfx_getxattr_req *req, loc_t *loc, + const char *name, dict_t *xdata); + +int +client_pre_removexattr_v2(xlator_t *this, gfx_removexattr_req *req, loc_t *loc, + const char *name, dict_t *xdata); + +int +client_pre_opendir_v2(xlator_t *this, gfx_opendir_req *req, loc_t *loc, + fd_t *fd, dict_t *xdata); + +int +client_pre_fsyncdir_v2(xlator_t *this, gfx_fsyncdir_req *req, fd_t *fd, + int32_t flags, dict_t *xdata); + +int +client_pre_access_v2(xlator_t *this, gfx_access_req *req, loc_t *loc, + int32_t mask, dict_t *xdata); + +int +client_pre_create_v2(xlator_t *this, gfx_create_req *req, loc_t *loc, fd_t *fd, + mode_t mode, int32_t flags, mode_t umask, dict_t *xdata); + +int +client_pre_ftruncate_v2(xlator_t *this, gfx_ftruncate_req *req, fd_t *fd, + off_t offset, dict_t *xdata); + +int +client_pre_fstat_v2(xlator_t *this, gfx_fstat_req *req, fd_t *fd, + dict_t *xdata); + +int +client_pre_lk_v2(xlator_t *this, gfx_lk_req *req, int32_t cmd, + struct gf_flock *flock, fd_t *fd, dict_t *xdata); + +int +client_pre_lookup_v2(xlator_t *this, gfx_lookup_req *req, loc_t *loc, + dict_t *xdata); + +int +client_pre_readdir_v2(xlator_t *this, gfx_readdir_req *req, fd_t *fd, + size_t size, off_t offset, dict_t *xdata); + +int +client_pre_inodelk_v2(xlator_t *this, gfx_inodelk_req *req, loc_t *loc, int cmd, + struct gf_flock *flock, const char *volume, + dict_t *xdata); + +int +client_pre_finodelk_v2(xlator_t *this, gfx_finodelk_req *req, fd_t *fd, int cmd, + struct gf_flock *flock, const char *volume, + dict_t *xdata); + +int +client_pre_entrylk_v2(xlator_t *this, gfx_entrylk_req *req, loc_t *loc, + entrylk_cmd cmd_entrylk, entrylk_type type, + const char *volume, const char *basename, dict_t *xdata); + +int +client_pre_fentrylk_v2(xlator_t *this, gfx_fentrylk_req *req, fd_t *fd, + entrylk_cmd cmd_entrylk, entrylk_type type, + const char *volume, const char *basename, dict_t *xdata); + +int +client_pre_xattrop_v2(xlator_t *this, gfx_xattrop_req *req, loc_t *loc, + dict_t *xattr, int32_t flags, dict_t *xdata); + +int +client_pre_fxattrop_v2(xlator_t *this, gfx_fxattrop_req *req, fd_t *fd, + dict_t *xattr, int32_t flags, dict_t *xdata); + +int +client_pre_fgetxattr_v2(xlator_t *this, gfx_fgetxattr_req *req, fd_t *fd, + const char *name, dict_t *xdata); + +int +client_pre_fsetxattr_v2(xlator_t *this, gfx_fsetxattr_req *req, fd_t *fd, + int32_t flags, dict_t *xattr, dict_t *xdata); +int +client_pre_seek_v2(xlator_t *this, gfx_seek_req *req, fd_t *fd, off_t offset, + gf_seek_what_t what, dict_t *xdata); + +int +client_pre_rchecksum_v2(xlator_t *this, gfx_rchecksum_req *req, fd_t *fd, + int32_t len, off_t offset, dict_t *xdata); + +int +client_pre_setattr_v2(xlator_t *this, gfx_setattr_req *req, loc_t *loc, + int32_t valid, struct iatt *stbuf, dict_t *xdata); +int +client_pre_fsetattr_v2(xlator_t *this, gfx_fsetattr_req *req, fd_t *fd, + int32_t valid, struct iatt *stbuf, dict_t *xdata); + +int +client_pre_readdirp_v2(xlator_t *this, gfx_readdirp_req *req, fd_t *fd, + size_t size, off_t offset, dict_t *xdata); + +int +client_pre_fremovexattr_v2(xlator_t *this, gfx_fremovexattr_req *req, fd_t *fd, + const char *name, dict_t *xdata); + +int +client_pre_fallocate_v2(xlator_t *this, gfx_fallocate_req *req, fd_t *fd, + int32_t flags, off_t offset, size_t size, + dict_t *xdata); +int +client_pre_discard_v2(xlator_t *this, gfx_discard_req *req, fd_t *fd, + off_t offset, size_t size, dict_t *xdata); +int +client_pre_zerofill_v2(xlator_t *this, gfx_zerofill_req *req, fd_t *fd, + off_t offset, size_t size, dict_t *xdata); +int +client_pre_ipc_v2(xlator_t *this, gfx_ipc_req *req, int32_t cmd, dict_t *xdata); + +int +client_pre_lease_v2(xlator_t *this, gfx_lease_req *req, loc_t *loc, + struct gf_lease *lease, dict_t *xdata); + +int +client_pre_put_v2(xlator_t *this, gfx_put_req *req, loc_t *loc, mode_t mode, + mode_t umask, int32_t flags, size_t size, off_t offset, + dict_t *xattr, dict_t *xdata); + +int +client_post_readv_v2(xlator_t *this, gfx_read_rsp *rsp, struct iobref **iobref, + struct iobref *rsp_iobref, struct iatt *stat, + struct iovec *vector, struct iovec *rsp_vector, + int *rspcount, dict_t **xdata); + +int +client_post_create_v2(xlator_t *this, gfx_create_rsp *rsp, struct iatt *stbuf, + struct iatt *preparent, struct iatt *postparent, + clnt_local_t *local, dict_t **xdata); +int +client_post_lease_v2(xlator_t *this, gfx_lease_rsp *rsp, struct gf_lease *lease, + dict_t **xdata); +int +client_post_lk_v2(xlator_t *this, gfx_lk_rsp *rsp, struct gf_flock *lock, + dict_t **xdata); +int +client_post_readdir_v2(xlator_t *this, gfx_readdir_rsp *rsp, + gf_dirent_t *entries, dict_t **xdata); +int +client_post_readdirp_v2(xlator_t *this, gfx_readdirp_rsp *rsp, fd_t *fd, + gf_dirent_t *entries, dict_t **xdata); +int +client_post_rename_v2(xlator_t *this, gfx_rename_rsp *rsp, struct iatt *stbuf, + struct iatt *preoldparent, struct iatt *postoldparent, + struct iatt *prenewparent, struct iatt *postnewparent, + dict_t **xdata); + +int +client_pre_copy_file_range_v2(xlator_t *this, gfx_copy_file_range_req *req, + fd_t *fd_in, off64_t off_in, fd_t *fd_out, + off64_t off_out, size_t size, int32_t flags, + dict_t **xdata); + +#endif /* __CLIENT_COMMON_H__ */ diff --git a/xlators/protocol/client/src/client-handshake.c b/xlators/protocol/client/src/client-handshake.c index 7bf95e912d0..ea5ef5c1800 100644 --- a/xlators/protocol/client/src/client-handshake.c +++ b/xlators/protocol/client/src/client-handshake.c @@ -1,1382 +1,1415 @@ /* - Copyright (c) 2010-2011 Gluster, Inc. <http://www.gluster.com> + Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com> This file is part of GlusterFS. - GlusterFS is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 3 of the License, - or (at your option) any later version. - - GlusterFS is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see - <http://www.gnu.org/licenses/>. + This file is licensed to you under your choice of the GNU Lesser + General Public License, version 3 or any later version (LGPLv3 or + later), or the GNU General Public License, version 2 (GPLv2), in all + cases as published by the Free Software Foundation. */ -#ifndef _CONFIG_H -#define _CONFIG_H -#include "config.h" -#endif - +#include <glusterfs/fd-lk.h> #include "client.h" -#include "xlator.h" -#include "defaults.h" -#include "glusterfs.h" -#include "statedump.h" -#include "compat-errno.h" +#include <glusterfs/xlator.h> +#include <glusterfs/defaults.h> +#include <glusterfs/glusterfs.h> +#include <glusterfs/statedump.h> +#include <glusterfs/compat-errno.h> #include "glusterfs3.h" #include "portmap-xdr.h" +#include "rpc-common-xdr.h" +#include "client-messages.h" +#include "xdr-rpc.h" -extern rpc_clnt_prog_t clnt3_1_fop_prog; +#define CLIENT_REOPEN_MAX_ATTEMPTS 1024 +extern rpc_clnt_prog_t clnt3_3_fop_prog; +extern rpc_clnt_prog_t clnt4_0_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); - -/* Handshake */ - -void -rpc_client_ping_timer_expired (void *data) +int32_t +client3_getspec(call_frame_t *frame, xlator_t *this, void *data) { - rpc_transport_t *trans = NULL; - rpc_clnt_connection_t *conn = NULL; - int disconnect = 0; - int transport_activity = 0; - struct timeval 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; - } + CLIENT_STACK_UNWIND(getspec, frame, -1, ENOSYS, NULL); + return 0; +} - pthread_mutex_lock (&conn->lock); - { - if (conn->ping_timer) - gf_timer_call_cancel (this->ctx, - conn->ping_timer); - gettimeofday (¤t, 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_usec = 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); +static int +client_notify_parents_child_up(xlator_t *this) +{ + clnt_conf_t *conf = NULL; + int ret = 0; - 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); + GF_VALIDATE_OR_GOTO("client", this, out); + conf = this->private; + GF_VALIDATE_OR_GOTO(this->name, conf, out); - rpc_transport_disconnect (conn->trans); + if (conf->child_up) { + ret = client_notify_dispatch_uniq(this, GF_EVENT_CHILD_UP, NULL); + if (ret) { + gf_smsg(this->name, GF_LOG_INFO, 0, PC_MSG_CHILD_UP_NOTIFY_FAILED, + NULL); + goto out; } + } else { + gf_smsg(this->name, GF_LOG_INFO, 0, PC_MSG_CHILD_STATUS, NULL); + } out: - return; + return 0; } void -client_start_ping (void *data) +client_default_reopen_done(clnt_fd_ctx_t *fdctx, int64_t rfd, xlator_t *this) { - xlator_t *this = NULL; - clnt_conf_t *conf = NULL; - rpc_clnt_connection_t *conn = NULL; - int32_t ret = -1; - struct timeval 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_usec = 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) - goto fail; - - return; -fail: - gf_log (THIS->name, GF_LOG_ERROR, - "failed to start ping timer"); - - if (frame) { - STACK_DESTROY (frame->root); - } - - return; + gf_log_callingfn(this->name, GF_LOG_WARNING, + "This function should never be called"); } - -int -client_ping_cbk (struct rpc_req *req, struct iovec *iov, int count, - void *myframe) +static void +client_reopen_done(clnt_fd_ctx_t *fdctx, int64_t rfd, xlator_t *this) { - xlator_t *this = NULL; - rpc_clnt_connection_t *conn = NULL; - struct timeval 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; - - 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 out; - } - - pthread_mutex_lock (&conn->lock); - { - timeout.tv_sec = conf->opt.ping_timeout; - timeout.tv_usec = 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"); - } - pthread_mutex_unlock (&conn->lock); -out: - if (frame) - STACK_DESTROY (frame->root); - return 0; + clnt_conf_t *conf = this->private; + gf_boolean_t destroy = _gf_false; + + pthread_spin_lock(&conf->fd_lock); + { + fdctx->remote_fd = rfd; + fdctx->reopen_attempts = 0; + fdctx->reopen_done = client_default_reopen_done; + if (!fdctx->released) + list_add_tail(&fdctx->sfd_pos, &conf->saved_fds); + else + destroy = _gf_true; + } + pthread_spin_unlock(&conf->fd_lock); + + if (destroy) + client_fdctx_destroy(this, fdctx); } +static void +client_child_up_reopen_done(clnt_fd_ctx_t *fdctx, int64_t rfd, xlator_t *this) +{ + clnt_conf_t *conf = this->private; + uint64_t fd_count = 0; + + LOCK(&conf->rec_lock); + { + fd_count = --(conf->reopen_fd_count); + } + UNLOCK(&conf->rec_lock); + + client_reopen_done(fdctx, rfd, this); + if (fd_count == 0) { + gf_smsg(this->name, GF_LOG_INFO, 0, PC_MSG_CHILD_UP_NOTIFY, NULL); + client_notify_parents_child_up(this); + } +} int -client3_getspec_cbk (struct rpc_req *req, struct iovec *iov, int count, +client3_3_reopen_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; - } + int32_t ret = -1; + gfs3_open_rsp rsp = { + 0, + }; + call_frame_t *frame = myframe; + xlator_t *this = frame->this; + clnt_local_t *local = frame->local; + clnt_fd_ctx_t *fdctx = local->fdctx; + + if (-1 == req->rpc_status) { + gf_smsg(frame->this->name, GF_LOG_WARNING, ENOTCONN, + PC_MSG_RPC_STATUS_ERROR, NULL); + 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_smsg(frame->this->name, GF_LOG_ERROR, EINVAL, + PC_MSG_XDR_DECODING_FAILED, NULL); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; + } + + if (rsp.op_ret < 0) { + gf_smsg(frame->this->name, GF_LOG_WARNING, rsp.op_errno, + PC_MSG_REOPEN_FAILED, "path=%s", local->loc.path); + } else { + gf_msg_debug(frame->this->name, 0, + "reopen on %s succeeded (remote-fd = %" PRId64 ")", + local->loc.path, rsp.fd); + } + + if (rsp.op_ret == -1) { + goto out; + } out: - STACK_UNWIND_STRICT (getspec, frame, rsp.op_ret, rsp.op_errno, rsp.spec); + fdctx->reopen_done(fdctx, (rsp.op_ret) ? -1 : rsp.fd, this); - /* Don't use 'GF_FREE', this is allocated by libc */ - if (rsp.spec) - 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) - goto unwind; + frame->local = NULL; + STACK_DESTROY(frame->root); - return 0; -unwind: - gf_log (this->name, GF_LOG_WARNING, "failed to send the request"); - STACK_UNWIND_STRICT (getspec, frame, -1, op_errno, NULL); - return 0; + client_local_wipe(local); + return 0; } int -client_notify_parents_child_up (xlator_t *this) +client3_3_reopendir_cbk(struct rpc_req *req, struct iovec *iov, int count, + void *myframe) { - clnt_conf_t *conf = NULL; - int ret = 0; + int32_t ret = -1; + gfs3_open_rsp rsp = { + 0, + }; + call_frame_t *frame = myframe; + clnt_local_t *local = frame->local; + clnt_fd_ctx_t *fdctx = local->fdctx; + + if (-1 == req->rpc_status) { + gf_smsg(frame->this->name, GF_LOG_WARNING, ENOTCONN, + PC_MSG_RPC_STATUS_ERROR, NULL); + 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_smsg(frame->this->name, GF_LOG_ERROR, EINVAL, + PC_MSG_XDR_DECODING_FAILED, NULL); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; + } + + if (rsp.op_ret < 0) { + gf_smsg(frame->this->name, GF_LOG_WARNING, rsp.op_errno, + PC_MSG_REOPEN_FAILED, "path=%s", local->loc.path, NULL); + } else { + gf_smsg(frame->this->name, GF_LOG_INFO, 0, PC_MSG_DIR_OP_SUCCESS, + "path=%s", local->loc.path, "fd=%" PRId64, rsp.fd, NULL); + } + + if (-1 == rsp.op_ret) { + goto out; + } - 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"); +out: + fdctx->reopen_done(fdctx, (rsp.op_ret) ? -1 : rsp.fd, frame->this); + + frame->local = NULL; + STACK_DESTROY(frame->root); + client_local_wipe(local); - conf->last_sent_event = GF_EVENT_CHILD_UP; - return 0; + return 0; } -int -client3_1_reopen_cbk (struct rpc_req *req, struct iovec *iov, int count, - void *myframe) +static int +protocol_client_reopendir(clnt_fd_ctx_t *fdctx, xlator_t *this) { - int32_t ret = -1; - gfs3_open_rsp rsp = {0,}; - int attempt_lock_recovery = _gf_false; - uint64_t fd_count = 0; - clnt_local_t *local = NULL; - clnt_conf_t *conf = NULL; - clnt_fd_ctx_t *fdctx = NULL; - call_frame_t *frame = NULL; - - frame = myframe; - if (!frame || !frame->this) - goto out; + int ret = -1; + gfs3_opendir_req req = { + { + 0, + }, + }; + clnt_local_t *local = NULL; + call_frame_t *frame = NULL; + clnt_conf_t *conf = NULL; - local = frame->local; - conf = frame->this->private; + conf = 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; - } + local = mem_get0(this->local_pool); + if (!local) { + goto out; + } + local->fdctx = fdctx; - 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; - } + gf_uuid_copy(local->loc.gfid, fdctx->gfid); + ret = loc_path(&local->loc, NULL); + if (ret < 0) + 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); - } + frame = create_frame(this, this->ctx->pool); + if (!frame) { + goto out; + } - if (rsp.op_ret == -1) { - ret = -1; - goto out; - } + memcpy(req.gfid, fdctx->gfid, 16); - fdctx = local->fdctx; + gf_msg_debug(frame->this->name, 0, "attempting reopen on %s", + local->loc.path); - if (!fdctx) { - gf_log (frame->this->name, GF_LOG_WARNING, "fdctx not found"); - ret = -1; - goto out; - } + frame->local = local; - pthread_mutex_lock (&conf->lock); - { - fdctx->remote_fd = rsp.fd; - if (!fdctx->released) { - list_add_tail (&fdctx->sfd_pos, &conf->saved_fds); - if (!list_empty (&fdctx->lock_list)) - attempt_lock_recovery = _gf_true; - fdctx = NULL; - } - } - pthread_mutex_unlock (&conf->lock); + ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_OPENDIR, + client3_3_reopendir_cbk, NULL, + (xdrproc_t)xdr_gfs3_opendir_req); + if (ret) { + gf_smsg(this->name, GF_LOG_ERROR, 0, PC_MSG_DIR_OP_FAILED, NULL); + } - ret = 0; + return 0; - attempt_lock_recovery = _gf_false; /* temporarily */ - - if (attempt_lock_recovery) { - ret = client_attempt_lock_recovery (frame->this, local->fdctx); - if (ret < 0) { - gf_log (frame->this->name, GF_LOG_DEBUG, - "lock recovery not attempted on fd"); - } else { - gf_log (frame->this->name, GF_LOG_INFO, - "need to attempt lock recovery on %"PRIu64 - " open fds", fd_count); - } - } else { - fd_count = decrement_reopen_fd_count (frame->this, conf); - } out: + if (local) + client_local_wipe(local); - if (fdctx) - client_fdctx_destroy (frame->this, fdctx); - - if ((ret < 0) && frame && frame->this && conf) - decrement_reopen_fd_count (frame->this, conf); + fdctx->reopen_done(fdctx, fdctx->remote_fd, this); - frame->local = NULL; - STACK_DESTROY (frame->root); - - client_local_wipe (local); - - return 0; + return 0; } -int -client3_1_reopendir_cbk (struct rpc_req *req, struct iovec *iov, int count, - void *myframe) +static int +protocol_client_reopenfile(clnt_fd_ctx_t *fdctx, xlator_t *this) { - 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; - if (!frame || !frame->this) - goto out; + int ret = -1; + gfs3_open_req req = { + { + 0, + }, + }; + clnt_local_t *local = NULL; + call_frame_t *frame = NULL; + clnt_conf_t *conf = NULL; - local = frame->local; - conf = frame->this->private; + conf = 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; - } + frame = create_frame(this, this->ctx->pool); + if (!frame) { + 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; - } + local = mem_get0(this->local_pool); + if (!local) { + 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); - } + local->fdctx = fdctx; + gf_uuid_copy(local->loc.gfid, fdctx->gfid); + ret = loc_path(&local->loc, NULL); + if (ret < 0) + goto out; - if (-1 == rsp.op_ret) { - ret = -1; - goto out; - } + frame->local = local; - fdctx = local->fdctx; - if (!fdctx) { - gf_log (frame->this->name, GF_LOG_WARNING, "fdctx not found"); - ret = -1; - goto out; - } + memcpy(req.gfid, fdctx->gfid, 16); + req.flags = gf_flags_from_flags(fdctx->flags); + req.flags = req.flags & (~(O_TRUNC | O_CREAT | O_EXCL)); - pthread_mutex_lock (&conf->lock); - { - fdctx->remote_fd = rsp.fd; + gf_msg_debug(frame->this->name, 0, "attempting reopen on %s", + local->loc.path); - if (!fdctx->released) { - list_add_tail (&fdctx->sfd_pos, &conf->saved_fds); - fdctx = NULL; - } - } - pthread_mutex_unlock (&conf->lock); + ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_OPEN, + client3_3_reopen_cbk, NULL, + (xdrproc_t)xdr_gfs3_open_req); + if (ret) { + gf_smsg(this->name, GF_LOG_ERROR, 0, PC_MSG_DIR_OP_FAILED, NULL); + } - decrement_reopen_fd_count (frame->this, conf); - ret = 0; + return 0; out: - if (fdctx) - client_fdctx_destroy (frame->this, fdctx); + if (frame) { + frame->local = NULL; + STACK_DESTROY(frame->root); + } - if ((ret < 0) && frame && frame->this && conf) - decrement_reopen_fd_count (frame->this, conf); + if (local) + client_local_wipe(local); - if (frame) { - frame->local = NULL; - STACK_DESTROY (frame->root); - } + fdctx->reopen_done(fdctx, fdctx->remote_fd, this); - client_local_wipe (local); + return 0; +} - 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); } +/* v4.x + */ int -protocol_client_reopendir (xlator_t *this, clnt_fd_ctx_t *fdctx) +client4_0_reopen_cbk(struct rpc_req *req, struct iovec *iov, int count, + void *myframe) { - int ret = -1; - gfs3_opendir_req req = {{0,},}; - clnt_local_t *local = NULL; - inode_t *inode = NULL; - char *path = NULL; - call_frame_t *frame = NULL; - clnt_conf_t *conf = NULL; - - if (!this || !fdctx) - goto out; - - inode = fdctx->inode; - conf = this->private; - - ret = inode_path (inode, NULL, &path); - if (ret < 0) { - gf_log (this->name, GF_LOG_WARNING, - "couldn't build path from inode %s", - uuid_utoa (inode->gfid)); - goto out; - } - - local = GF_CALLOC (1, sizeof (*local), gf_client_mt_clnt_local_t); - if (!local) { - ret = -1; - goto out; - } - - local->fdctx = fdctx; - local->loc.path = path; - path = NULL; - - frame = create_frame (this, this->ctx->pool); - if (!frame) { - ret = -1; - goto out; - } + int32_t ret = -1; + gfx_open_rsp rsp = { + 0, + }; + call_frame_t *frame = myframe; + xlator_t *this = frame->this; + clnt_local_t *local = frame->local; + clnt_fd_ctx_t *fdctx = local->fdctx; + + if (-1 == req->rpc_status) { + gf_smsg(frame->this->name, GF_LOG_WARNING, ENOTCONN, + PC_MSG_RPC_STATUS_ERROR, NULL); + rsp.op_ret = -1; + rsp.op_errno = ENOTCONN; + goto out; + } + + ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gfx_open_rsp); + if (ret < 0) { + gf_smsg(frame->this->name, GF_LOG_ERROR, EINVAL, + PC_MSG_XDR_DECODING_FAILED, NULL); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; + } + + if (rsp.op_ret < 0) { + gf_smsg(frame->this->name, GF_LOG_WARNING, rsp.op_errno, + PC_MSG_REOPEN_FAILED, "path=%s", local->loc.path, NULL); + } else { + gf_msg_debug(frame->this->name, 0, + "reopen on %s succeeded (remote-fd = %" PRId64 ")", + local->loc.path, rsp.fd); + } + + if (rsp.op_ret == -1) { + goto out; + } - memcpy (req.gfid, inode->gfid, 16); - req.path = (char *)local->loc.path; +out: + fdctx->reopen_done(fdctx, (rsp.op_ret) ? -1 : rsp.fd, this); - gf_log (frame->this->name, GF_LOG_DEBUG, - "attempting reopen on %s", local->loc.path); + frame->local = NULL; + STACK_DESTROY(frame->root); - frame->local = local; local = NULL; + client_local_wipe(local); - ret = client_submit_request (this, &req, frame, conf->fops, - GFS3_OP_OPENDIR, - client3_1_reopendir_cbk, NULL, - NULL, 0, NULL, 0, NULL, - (xdrproc_t)xdr_gfs3_opendir_req); - if (ret) - goto out; + return 0; +} - return ret; +int +client4_0_reopendir_cbk(struct rpc_req *req, struct iovec *iov, int count, + void *myframe) +{ + int32_t ret = -1; + gfx_open_rsp rsp = { + 0, + }; + call_frame_t *frame = myframe; + clnt_local_t *local = frame->local; + clnt_fd_ctx_t *fdctx = local->fdctx; + + if (-1 == req->rpc_status) { + gf_smsg(frame->this->name, GF_LOG_WARNING, ENOTCONN, + PC_MSG_RPC_STATUS_ERROR, NULL); + rsp.op_ret = -1; + rsp.op_errno = ENOTCONN; + goto out; + } + + ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gfx_open_rsp); + if (ret < 0) { + gf_smsg(frame->this->name, GF_LOG_ERROR, EINVAL, + PC_MSG_XDR_DECODING_FAILED, NULL); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; + } + + if (rsp.op_ret < 0) { + gf_smsg(frame->this->name, GF_LOG_WARNING, rsp.op_errno, + PC_MSG_DIR_OP_FAILED, "dir-path=%s", local->loc.path, NULL); + } else { + gf_smsg(frame->this->name, GF_LOG_INFO, 0, PC_MSG_DIR_OP_SUCCESS, + "path=%s", local->loc.path, "fd=%" PRId64, rsp.fd, NULL); + } + + if (-1 == rsp.op_ret) { + goto out; + } out: - gf_log (THIS->name, GF_LOG_ERROR, - "failed to send the re-opendir request"); + fdctx->reopen_done(fdctx, (rsp.op_ret) ? -1 : rsp.fd, frame->this); - if (frame) { - frame->local = NULL; - STACK_DESTROY (frame->root); - } - - if (local) - client_local_wipe (local); - - if (path) - GF_FREE (path); - if ((ret < 0) && this && conf) { - decrement_reopen_fd_count (this, conf); - } - - return 0; + frame->local = NULL; + STACK_DESTROY(frame->root); + client_local_wipe(local); + return 0; } -int -protocol_client_reopen (xlator_t *this, clnt_fd_ctx_t *fdctx) +static int +protocol_client_reopendir_v2(clnt_fd_ctx_t *fdctx, xlator_t *this) { - int ret = -1; - gfs3_open_req req = {{0,},}; - clnt_local_t *local = NULL; - inode_t *inode = NULL; - char *path = NULL; - call_frame_t *frame = NULL; - clnt_conf_t *conf = NULL; - - if (!this || !fdctx) - goto out; - - inode = fdctx->inode; - conf = this->private; + int ret = -1; + gfx_opendir_req req = { + { + 0, + }, + }; + call_frame_t *frame = NULL; + clnt_conf_t *conf = this->private; + clnt_local_t *local = mem_get0(this->local_pool); + + if (!local) { + ret = -1; + goto out; + } + local->fdctx = fdctx; + + gf_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_msg_debug(frame->this->name, 0, "attempting reopen on %s", + local->loc.path); + + frame->local = local; + + ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_OPENDIR, + client4_0_reopendir_cbk, NULL, + (xdrproc_t)xdr_gfx_opendir_req); + if (ret) { + gf_smsg(this->name, GF_LOG_ERROR, 0, PC_MSG_DIR_OP_FAILED, NULL); + } + + return 0; - ret = inode_path (inode, NULL, &path); - if (ret < 0) { - gf_log (this->name, GF_LOG_WARNING, - "couldn't build path from inode %s", - uuid_utoa (inode->gfid)); - goto out; - } +out: + if (local) + client_local_wipe(local); - frame = create_frame (this, this->ctx->pool); - if (!frame) { - ret = -1; - goto out; - } + fdctx->reopen_done(fdctx, fdctx->remote_fd, this); - local = GF_CALLOC (1, sizeof (*local), gf_client_mt_clnt_local_t); - if (!local) { - ret = -1; - goto out; - } + return 0; +} - local->fdctx = fdctx; - local->loc.path = path; - path = NULL; - frame->local = local; +static int +protocol_client_reopenfile_v2(clnt_fd_ctx_t *fdctx, xlator_t *this) +{ + int ret = -1; + gfx_open_req req = { + { + 0, + }, + }; + clnt_local_t *local = NULL; + clnt_conf_t *conf = this->private; + call_frame_t *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; + gf_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_msg_debug(frame->this->name, 0, "attempting reopen on %s", + local->loc.path); + + ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_OPEN, + client4_0_reopen_cbk, NULL, + (xdrproc_t)xdr_gfx_open_req); + if (ret) { + gf_smsg(this->name, GF_LOG_ERROR, 0, PC_MSG_DIR_OP_FAILED, NULL); + } + + return 0; - memcpy (req.gfid, inode->gfid, 16); - req.flags = gf_flags_from_flags (fdctx->flags); - req.wbflags = fdctx->wbflags; - req.path = (char *)local->loc.path; +out: + if (frame) { + frame->local = NULL; + STACK_DESTROY(frame->root); + } - gf_log (frame->this->name, GF_LOG_DEBUG, - "attempting reopen on %s", local->loc.path); + if (local) + client_local_wipe(local); - local = NULL; - ret = client_submit_request (this, &req, frame, conf->fops, - GFS3_OP_OPEN, client3_1_reopen_cbk, NULL, - NULL, 0, NULL, 0, NULL, - (xdrproc_t)xdr_gfs3_open_req); - if (ret) - goto out; + fdctx->reopen_done(fdctx, fdctx->remote_fd, this); - return ret; + return 0; +} -out: - gf_log (THIS->name, GF_LOG_ERROR, - "failed to send the re-open request"); +static void +protocol_client_reopen_v2(clnt_fd_ctx_t *fdctx, xlator_t *this) +{ + if (fdctx->is_dir) + protocol_client_reopendir_v2(fdctx, this); + else + protocol_client_reopenfile_v2(fdctx, this); +} - if (frame) { - frame->local = NULL; - STACK_DESTROY (frame->root); - } +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; +} - if (local) - client_local_wipe (local); +void +client_attempt_reopen(fd_t *fd, xlator_t *this) +{ + if (!fd || !this) + goto out; - if (path) - GF_FREE (path); + clnt_conf_t *conf = this->private; + clnt_fd_ctx_t *fdctx = NULL; + gf_boolean_t reopen = _gf_false; - if ((ret < 0) && this && conf) { - decrement_reopen_fd_count (this, conf); + pthread_spin_lock(&conf->fd_lock); + { + fdctx = this_fd_get_ctx(fd, this); + if (!fdctx) { + pthread_spin_unlock(&conf->fd_lock); + goto out; } - return 0; + 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_spin_unlock(&conf->fd_lock); + if (reopen) { + if (conf->fops->progver == GLUSTER_FOP_VERSION_v2) + protocol_client_reopen_v2(fdctx, this); + else + protocol_client_reopen(fdctx, this); + } +out: + return; } - -int -client_post_handshake (call_frame_t *frame, xlator_t *this) +static 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; + 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; + int count = 0; - if (!this || !this->private) - goto out; + if (!this || !this->private) + goto out; - conf = this->private; - INIT_LIST_HEAD (&reopen_head); + conf = this->private; + INIT_LIST_HEAD(&reopen_head); - pthread_mutex_lock (&conf->lock); + pthread_spin_lock(&conf->fd_lock); + { + list_for_each_entry_safe(fdctx, tmp, &conf->saved_fds, sfd_pos) { - list_for_each_entry_safe (fdctx, tmp, &conf->saved_fds, - sfd_pos) { - if (fdctx->remote_fd != -1) - continue; - - 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); - - if (fdctx->is_dir) - protocol_client_reopendir (this, fdctx); - else - protocol_client_reopen (this, fdctx); - } - } else { - gf_log (this->name, GF_LOG_DEBUG, - "no open fds - notifying all parents child up"); - client_notify_parents_child_up (this); - } + if (fdctx->remote_fd != -1 || + (!list_empty(&fdctx->lock_list) && conf->strict_locks)) + 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_spin_unlock(&conf->fd_lock); + + /* Delay notifying CHILD_UP to parents + until all locks are recovered */ + if (count > 0) { + gf_smsg(this->name, GF_LOG_INFO, 0, PC_MSG_CHILD_UP_NOTIFY_DELAY, + "count=%d", count, NULL); + client_save_number_fds(conf, count); + + list_for_each_entry_safe(fdctx, tmp, &reopen_head, sfd_pos) + { + list_del_init(&fdctx->sfd_pos); + + if (conf->fops->progver == GLUSTER_FOP_VERSION_v2) + protocol_client_reopen_v2(fdctx, this); + else + protocol_client_reopen(fdctx, this); + } + } else { + gf_msg_debug(this->name, 0, + "No fds to open - notifying all parents child " + "up"); + client_notify_parents_child_up(this); + } out: - return 0; + return 0; } int -client_setvolume_cbk (struct rpc_req *req, struct iovec *iov, int count, void *myframe) +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; - - 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); + call_frame_t *frame = myframe; + xlator_t *this = frame->this; + clnt_conf_t *conf = this->private; + dict_t *reply = NULL; + char *process_uuid = NULL; + char *volume_id = 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; + glusterfs_ctx_t *ctx = NULL; + + GF_VALIDATE_OR_GOTO(this->name, conf, out); + ctx = this->ctx; + GF_VALIDATE_OR_GOTO(this->name, ctx, out); + + if (-1 == req->rpc_status) { + gf_smsg(frame->this->name, GF_LOG_WARNING, ENOTCONN, + PC_MSG_RPC_STATUS_ERROR, NULL); + op_ret = -1; + goto out; + } + + ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gf_setvolume_rsp); + if (ret < 0) { + gf_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, + NULL); + 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_smsg(frame->this->name, GF_LOG_WARNING, op_errno, + PC_MSG_VOL_SET_FAIL, NULL); + } + + 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 (this->name, GF_LOG_ERROR, "XDR decoding failed"); + gf_smsg(frame->this->name, GF_LOG_WARNING, 0, + PC_MSG_DICT_UNSERIALIZE_FAIL, NULL); + goto out; + } + } + + ret = dict_get_str_sizen(reply, "ERROR", &remote_error); + if (ret < 0) { + gf_smsg(this->name, GF_LOG_WARNING, EINVAL, PC_MSG_DICT_GET_FAILED, + "ERROR string", NULL); + } + + ret = dict_get_str_sizen(reply, "process-uuid", &process_uuid); + if (ret < 0) { + gf_smsg(this->name, GF_LOG_WARNING, EINVAL, PC_MSG_DICT_GET_FAILED, + "process-uuid", NULL); + } + + if (op_ret < 0) { + gf_smsg(this->name, GF_LOG_ERROR, op_errno, PC_MSG_SETVOLUME_FAIL, + "remote-error=%s", remote_error, NULL); + + errno = op_errno; + if (remote_error && (op_errno == EACCES)) { + auth_fail = _gf_true; + op_ret = 0; + } + if ((op_errno == ENOENT) && this->ctx->cmd_args.subdir_mount && + (ctx->graph_id <= 1)) { + /* A case of subdir not being present at the moment, + ride on auth_fail framework to notify the error */ + /* Make sure this case is handled only in the new + graph, so mount may fail in this case. In case + of 'add-brick' etc, we need to continue retry */ + auth_fail = _gf_true; + op_ret = 0; + } + if (op_errno == ESTALE) { + ret = client_notify_dispatch(this, GF_EVENT_VOLFILE_MODIFIED, NULL); + if (ret) + gf_smsg(this->name, GF_LOG_INFO, 0, + PC_MSG_VOLFILE_NOTIFY_FAILED, NULL); + } + goto out; + } + + ret = dict_get_str_sizen(this->options, "remote-subvolume", &remote_subvol); + if (ret || !remote_subvol) { + gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FIND_KEY_FAILED, + "remote-subvolume", NULL); + goto out; + } + + ret = dict_get_str_sizen(reply, "volume-id", &volume_id); + if (ret < 0) { + /* this can happen if the server is of old version, so treat it as + just debug message */ + gf_msg_debug(this->name, EINVAL, + "failed to get 'volume-id' from reply dict"); + } else if (ctx->master && strncmp("snapd", remote_subvol, 5)) { + /* TODO: if it is a fuse mount or a snapshot enabled client, don't + bother */ + /* If any value is set, the first element will be non-0. + It would be '0', but not '\0' :-) */ + if (ctx->volume_id[0]) { + if (strcmp(ctx->volume_id, volume_id)) { + /* Ideally it shouldn't even come here, as server itself + should fail the handshake in that case */ + gf_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_VOL_ID_CHANGED, + "vol-id=%s", volume_id, "ctx->vol-id=%s", + ctx->volume_id, NULL); op_ret = -1; goto out; + } + } else { + strncpy(ctx->volume_id, volume_id, GF_UUID_BUF_SIZE); } - 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 (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; - } + } - /* TODO: currently setpeer path is broken */ + uint32_t child_up_int; + ret = dict_get_uint32(reply, "child_up", &child_up_int); + if (ret) { /* - 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; - - /* TODO: more to test */ - client_post_handshake (frame, frame->this); - + * This would happen in cases where the server trying to * + * connect to this client is running an older version. Hence * + * setting the child_up to _gf_true in this case. * + */ + gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FIND_KEY_FAILED, + "child_up", NULL); + conf->child_up = _gf_true; + } else { + conf->child_up = (child_up_int != 0); + } + + /* 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); + } + */ + + conf->client_id = glusterfs_leaf_position(this); + + gf_smsg(this->name, GF_LOG_INFO, 0, PC_MSG_REMOTE_VOL_CONNECTED, + "conn-name=%s", conf->rpc->conn.name, "remote_subvol=%s", + remote_subvol, NULL); + + op_ret = 0; + conf->connected = 1; + + client_post_handshake(frame, frame->this); out: + if (auth_fail) { + gf_smsg(this->name, GF_LOG_INFO, 0, PC_MSG_AUTH_FAILED, NULL); + ret = client_notify_dispatch(this, GF_EVENT_AUTH_FAILED, NULL); + if (ret) + gf_smsg(this->name, GF_LOG_INFO, 0, + PC_MSG_AUTH_FAILED_NOTIFY_FAILED, NULL); + conf->connected = 0; + 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_smsg(this->name, GF_LOG_INFO, 0, PC_MSG_CHILD_CONNECTING_EVENT, + NULL); + ret = client_notify_dispatch(this, GF_EVENT_CHILD_CONNECTING, NULL); + if (ret) + gf_smsg(this->name, GF_LOG_INFO, 0, + PC_MSG_CHILD_CONNECTING_NOTIFY_FAILED, NULL); + /* + * The reconnection *won't* happen in the background (see + * previous comment) unless we kill the current connection. + */ + rpc_transport_disconnect(conf->rpc->conn.trans, _gf_false); + ret = 0; + } - 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; - } - - if (rsp.dict.dict_val) - free (rsp.dict.dict_val); + free(rsp.dict.dict_val); - STACK_DESTROY (frame->root); + STACK_DESTROY(frame->root); - if (reply) - dict_unref (reply); + if (reply) + dict_unref(reply); - return 0; + return ret; } int -client_setvolume (xlator_t *this, struct rpc_clnt *rpc) +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; - } - } - - ret = gf_asprintf (&process_uuid_xl, "%s-%s", this->ctx->process_uuid, - this->name); - 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); + int ret = 0; + gf_setvolume_req req = { + { + 0, + }, + }; + call_frame_t *fr = NULL; + char *process_uuid_xl = NULL; + char *remote_subvol = NULL; + clnt_conf_t *conf = this->private; + dict_t *options = this->options; + char counter_str[32] = {0}; + char hostname[256] = { + 0, + }; + + if (conf->fops) { + ret = dict_set_int32_sizen(options, "fops-version", + conf->fops->prognum); if (ret < 0) { - gf_log (this->name, GF_LOG_ERROR, - "failed to set process-uuid(%s) in handshake msg", - process_uuid_xl); - goto fail; + gf_smsg(this->name, GF_LOG_ERROR, 0, PC_MSG_DICT_SET_FAILED, + "version-fops=%d", conf->fops->prognum, NULL); + goto fail; } + } - ret = dict_set_str (options, "client-version", PACKAGE_VERSION); + if (conf->mgmt) { + ret = dict_set_int32_sizen(options, "mgmt-version", + conf->mgmt->prognum); 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'"); - } - - req.dict.dict_len = dict_serialized_length (options); - if (req.dict.dict_len < 0) { - gf_log (this->name, GF_LOG_ERROR, - "failed to get serialized length of dict"); - ret = -1; - goto fail; - } - 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); + gf_smsg(this->name, GF_LOG_ERROR, 0, PC_MSG_DICT_SET_FAILED, + "version-mgmt=%d", conf->mgmt->prognum, NULL); + goto fail; + } + } + + /* + * Connection-id should always be unique so that server never gets to + * reuse the previous connection resources so it cleans up the resources + * on every disconnect. Otherwise it may lead to stale resources, i.e. + * leaked file descriptors, inode/entry locks + */ + + snprintf(counter_str, sizeof(counter_str), "-%" PRIu64, conf->setvol_count); + conf->setvol_count++; + + if (gethostname(hostname, 256) == -1) { + gf_smsg(this->name, GF_LOG_ERROR, errno, PC_MSG_GETHOSTNAME_FAILED, + NULL); + + goto fail; + } + + ret = gf_asprintf(&process_uuid_xl, GLUSTER_PROCESS_UUID_FMT, + this->ctx->process_uuid, this->graph->id, getpid(), + hostname, this->name, counter_str); + if (-1 == ret) { + gf_smsg(this->name, GF_LOG_ERROR, 0, PC_MSG_PROCESS_UUID_SET_FAIL, + NULL); + goto fail; + } + + ret = dict_set_dynstr_sizen(options, "process-uuid", process_uuid_xl); + if (ret < 0) { + gf_smsg(this->name, GF_LOG_ERROR, 0, PC_MSG_DICT_SET_FAILED, + "process-uuid=%s", process_uuid_xl, NULL); + goto fail; + } + + if (this->ctx->cmd_args.process_name) { + ret = dict_set_str_sizen(options, "process-name", + this->ctx->cmd_args.process_name); 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; + gf_smsg(this->name, GF_LOG_INFO, 0, PC_MSG_DICT_SET_FAILED, + "process-name", NULL); + } + } + + ret = dict_set_str_sizen(options, "client-version", PACKAGE_VERSION); + if (ret < 0) { + gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_DICT_SET_FAILED, + "client-version=%s", PACKAGE_VERSION, NULL); + } + + ret = dict_get_str_sizen(this->options, "remote-subvolume", &remote_subvol); + if (ret || !remote_subvol) { + gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FIND_KEY_FAILED, + "remote-subvolume", NULL); + goto fail; + } + + /* volume-id to be sent only for regular volume, not snap volume */ + if (strncmp("snapd", remote_subvol, 5)) { + /* If any value is set, the first element will be non-0. + It would be '0', but not '\0' :-) */ + if (!this->ctx->volume_id[0]) { + strncpy(this->ctx->volume_id, this->graph->volume_id, + GF_UUID_BUF_SIZE); + } + if (this->ctx->volume_id[0]) { + ret = dict_set_str(options, "volume-id", this->ctx->volume_id); + if (ret < 0) { + gf_smsg(this->name, GF_LOG_INFO, 0, PC_MSG_DICT_SET_FAILED, + "volume-id", NULL); + } + } + } + + if (this->ctx->cmd_args.volfile_server) { + if (this->ctx->cmd_args.volfile_id) { + ret = dict_set_str_sizen(options, "volfile-key", + this->ctx->cmd_args.volfile_id); + if (ret) + gf_smsg(this->name, GF_LOG_ERROR, 0, + PC_MSG_VOLFILE_KEY_SET_FAILED, NULL); + } + ret = dict_set_uint32(options, "volfile-checksum", + this->graph->volfile_checksum); + if (ret) + gf_smsg(this->name, GF_LOG_ERROR, 0, PC_MSG_VOLFILE_CHECKSUM_FAILED, + NULL); + } - 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); + if (this->ctx->cmd_args.subdir_mount) { + ret = dict_set_str_sizen(options, "subdir-mount", + this->ctx->cmd_args.subdir_mount); + if (ret) { + gf_log(THIS->name, GF_LOG_ERROR, "Failed to set subdir_mount"); + /* It makes sense to fail, as per the CLI, we + should be doing a subdir_mount */ + goto fail; + } + } + + /* Insert a dummy key value pair to avoid failure at server side for + * clnt-lk-version with new clients. + */ + ret = dict_set_uint32(options, "clnt-lk-version", 1); + if (ret < 0) { + gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_DICT_SET_FAILED, + "clnt-lk-version(1)", NULL); + } + + ret = dict_set_int32_sizen(options, "opversion", GD_OP_VERSION_MAX); + if (ret < 0) { + gf_smsg(this->name, GF_LOG_ERROR, 0, PC_MSG_DICT_SET_FAILED, + "client opversion", NULL); + } + + ret = dict_allocate_and_serialize(options, (char **)&req.dict.dict_val, + &req.dict.dict_len); + if (ret != 0) { + ret = -1; + gf_smsg(this->name, GF_LOG_ERROR, 0, PC_MSG_DICT_SERIALIZE_FAIL, NULL); + 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, + (xdrproc_t)xdr_gf_setvolume_req); fail: - if (req.dict.dict_val) - GF_FREE (req.dict.dict_val); + GF_FREE(req.dict.dict_val); - return ret; + return ret; } -int -select_server_supported_programs (xlator_t *this, gf_prog_detail *prog) +static 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; + gf_prog_detail *trav = NULL; + clnt_conf_t *conf = NULL; + int ret = -1; + + if (!this || !prog) { + gf_smsg(THIS->name, GF_LOG_WARNING, 0, PC_MSG_PGM_NOT_FOUND, NULL); + 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; + if (conf->rpc) + conf->rpc->auth_value = AUTH_GLUSTERFS_v2; + ret = 0; + /* In normal flow, we don't want to use old protocol type. + but if it is for testing, lets use it */ + if (conf->old_protocol) + goto done; + } + + if ((clnt4_0_fop_prog.prognum == trav->prognum) && + (clnt4_0_fop_prog.progver == trav->progver)) { + conf->fops = &clnt4_0_fop_prog; + if (conf->rpc) + conf->rpc->auth_value = AUTH_GLUSTERFS_v3; + ret = 0; + /* this is latest program, lets use this program only */ + /* if we are testing for old-protocol, lets not break this */ + if (!conf->old_protocol) + goto done; } - conf = this->private; - trav = prog; - - while (trav) { - /* Select 'programs' */ - if ((clnt3_1_fop_prog.prognum == trav->prognum) && - (clnt3_1_fop_prog.progver == trav->progver)) { - conf->fops = &clnt3_1_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; + if (ret) { + gf_msg_debug(this->name, 0, "%s (%" PRId64 ") not supported", + trav->progname, trav->progver); } + trav = trav->next; + } + +done: + if (!ret) + gf_smsg(this->name, GF_LOG_INFO, 0, PC_MSG_VERSION_INFO, + "Program-name=%s", conf->fops->progname, "Num=%d", + conf->fops->prognum, "Version=%d", conf->fops->progver, NULL); out: - return ret; + return ret; } - int -server_has_portmap (xlator_t *this, gf_prog_detail *prog) +server_has_portmap(xlator_t *this, gf_prog_detail *prog) { - gf_prog_detail *trav = NULL; - int ret = -1; + 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; - } + if (!this || !prog) { + gf_smsg(THIS->name, GF_LOG_WARNING, 0, PC_MSG_PGM_NOT_FOUND, NULL); + goto out; + } - trav = prog; + 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; + while (trav) { + if ((trav->prognum == GLUSTER_PMAP_PROGRAM) && + (trav->progver == GLUSTER_PMAP_VERSION)) { + gf_msg_debug(this->name, 0, "detected portmapper on server"); + ret = 0; + break; } + trav = trav->next; + } out: - return ret; + return ret; } - int -client_query_portmap_cbk (struct rpc_req *req, struct iovec *iov, int count, void *myframe) +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"); - conf->portmap_err_logged = 1; - goto out; + 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_smsg(THIS->name, GF_LOG_WARNING, EINVAL, PC_MSG_FRAME_NOT_FOUND, + NULL); + goto out; + } + this = frame->this; + conf = frame->this->private; + + if (-1 == req->rpc_status) { + gf_smsg(this->name, GF_LOG_WARNING, ENOTCONN, PC_MSG_RPC_STATUS_ERROR, + NULL); + goto out; + } + + ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_pmap_port_by_brick_rsp); + if (ret < 0) { + gf_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, + NULL); + goto out; + } + + if (-1 == rsp.op_ret) { + ret = -1; + if (!conf->portmap_err_logged) { + gf_smsg(this->name, GF_LOG_ERROR, 0, PC_MSG_PORT_NUM_ERROR, NULL); + } else { + gf_msg_debug(this->name, 0, + "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->portmap_err_logged = 0; + conf->disconnect_err_logged = 0; + config.remote_port = rsp.port; + rpc_clnt_reconfig(conf->rpc, &config); - config.remote_port = rsp.port; - rpc_clnt_reconfig (conf->rpc, &config); - conf->skip_notify = 1; + 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); - rpc_clnt_reconnect (conf->rpc->conn.trans); - } + if (frame) + STACK_DESTROY(frame->root); - return ret; -} + if (conf) { + /* Need this to connect the same transport on different port */ + /* ie, glusterd to glusterfsd */ + rpc_transport_disconnect(conf->rpc->conn.trans, _gf_false); + } + return ret; +} int -client_query_portmap (xlator_t *this, struct rpc_clnt *rpc) +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); + int ret = -1; + pmap_port_by_brick_req req = { + 0, + }; + call_frame_t *fr = NULL; + dict_t *options = NULL; + char *remote_subvol = NULL; + char *xprt = NULL; + char brick_name[PATH_MAX] = { + 0, + }; + + options = this->options; + + ret = dict_get_str_sizen(options, "remote-subvolume", &remote_subvol); + if (ret < 0) { + gf_smsg(this->name, GF_LOG_ERROR, 0, PC_MSG_REMOTE_SUBVOL_SET_FAIL, + NULL); + goto fail; + } + + req.brick = remote_subvol; + + if (!dict_get_str_sizen(options, "transport-type", &xprt)) { + if (!strcmp(xprt, "rdma")) { + snprintf(brick_name, sizeof(brick_name), "%s.rdma", remote_subvol); + req.brick = brick_name; + } + } + + 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, (xdrproc_t)xdr_pmap_port_by_brick_req); fail: - return ret; + return ret; } - -int -client_dump_version_cbk (struct rpc_req *req, struct iovec *iov, int count, - void *myframe) +static 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); + 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_smsg(frame->this->name, GF_LOG_WARNING, ENOTCONN, + PC_MSG_RPC_STATUS_ERROR, NULL); + goto out; + } + + ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gf_dump_rsp); + if (ret < 0) { + gf_smsg(frame->this->name, GF_LOG_ERROR, EINVAL, + PC_MSG_XDR_DECODING_FAILED, NULL); + goto out; + } + if (-1 == rsp.op_ret) { + gf_smsg(frame->this->name, GF_LOG_WARNING, 0, PC_MSG_VERSION_ERROR, + NULL); + 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_smsg(frame->this->name, GF_LOG_ERROR, 0, PC_MSG_VERSION_ERROR, NULL); + 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; - } + /* 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); + STACK_DESTROY(frame->root); - if (ret != 0) - rpc_transport_disconnect (conf->rpc->conn.trans); + if (ret != 0) + rpc_transport_disconnect(conf->rpc->conn.trans, _gf_false); - return ret; + return ret; } int -client_handshake (xlator_t *this, struct rpc_clnt *rpc) +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); + 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_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_HANDSHAKE_PGM_NOT_FOUND, + NULL); + 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, + (xdrproc_t)xdr_gf_dump_req); out: - return ret; + 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_NULL] = "NULL", + [GF_HNDSK_SETVOLUME] = "SETVOLUME", + [GF_HNDSK_GETSPEC] = "GETSPEC", + [GF_HNDSK_PING] = "PING", }; rpc_clnt_prog_t clnt_handshake_prog = { - .progname = "GlusterFS Handshake", - .prognum = GLUSTER_HNDSK_PROGRAM, - .progver = GLUSTER_HNDSK_VERSION, - .procnames = clnt_handshake_procs, + .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", + [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, + .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", + [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, + .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 index 2a12573e2bb..189dfddd021 100644 --- a/xlators/protocol/client/src/client-helpers.c +++ b/xlators/protocol/client/src/client-helpers.c @@ -1,227 +1,899 @@ /* - Copyright (c) 2010-2011 Gluster, Inc. <http://www.gluster.com> + Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com> This file is part of GlusterFS. - GlusterFS is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 3 of the License, - or (at your option) any later version. - - GlusterFS is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see - <http://www.gnu.org/licenses/>. + This file is licensed to you under your choice of the GNU Lesser + General Public License, version 3 or any later version (LGPLv3 or + later), or the GNU General Public License, version 2 (GPLv2), in all + cases as published by the Free Software Foundation. */ -#ifndef _CONFIG_H -#define _CONFIG_H -#include "config.h" -#endif - #include "client.h" -#include "fd.h" +#include <glusterfs/fd.h> +#include "client-messages.h" +#include "client-common.h" +#include <glusterfs/compat-errno.h> +#include <glusterfs/common-utils.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) +this_fd_del_ctx(fd_t *file, xlator_t *this) { - int dict_ret = -1; - uint64_t ctxaddr = 0; + int dict_ret = -1; + uint64_t ctxaddr = 0; - GF_VALIDATE_OR_GOTO ("client", this, out); - GF_VALIDATE_OR_GOTO (this->name, file, out); + GF_VALIDATE_OR_GOTO("client", this, out); + GF_VALIDATE_OR_GOTO(this->name, file, out); - dict_ret = fd_ctx_del (file, this, &ctxaddr); + dict_ret = fd_ctx_del(file, this, &ctxaddr); - if (dict_ret < 0) { - ctxaddr = 0; - } + if (dict_ret < 0) { + ctxaddr = 0; + } out: - return (clnt_fd_ctx_t *)(unsigned long)ctxaddr; + return (clnt_fd_ctx_t *)(unsigned long)ctxaddr; } - clnt_fd_ctx_t * -this_fd_get_ctx (fd_t *file, xlator_t *this) +this_fd_get_ctx(fd_t *file, xlator_t *this) { - int dict_ret = -1; - uint64_t ctxaddr = 0; + int dict_ret = -1; + uint64_t ctxaddr = 0; - GF_VALIDATE_OR_GOTO ("client", this, out); - GF_VALIDATE_OR_GOTO (this->name, file, out); + GF_VALIDATE_OR_GOTO("client", this, out); + GF_VALIDATE_OR_GOTO(this->name, file, out); - dict_ret = fd_ctx_get (file, this, &ctxaddr); + dict_ret = fd_ctx_get(file, this, &ctxaddr); - if (dict_ret < 0) { - ctxaddr = 0; - } + if (dict_ret < 0) { + ctxaddr = 0; + } out: - return (clnt_fd_ctx_t *)(unsigned long)ctxaddr; + 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); +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_smsg(this->name, GF_LOG_INFO, 0, PC_MSG_FD_DUPLICATE_TRY, + "path=%s", loc->path, "gfid=%s", + uuid_utoa(loc->inode->gfid), NULL); + else + gf_smsg(this->name, GF_LOG_INFO, 0, PC_MSG_FD_DUPLICATE_TRY, + "file=%p", file, NULL); + } + + ret = fd_ctx_set(file, this, (uint64_t)(unsigned long)ctx); + if (ret < 0) { + if (loc) + gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FD_SET_FAIL, + "path=%s", loc->path, "gfid=%s", + uuid_utoa(loc->inode->gfid), NULL); + else + gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FD_SET_FAIL, + "file=%p", file, NULL); + } +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); } - 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); + if (local->iobref) { + iobref_unref(local->iobref); } + + GF_FREE(local->name); + mem_put(local); + } + + return 0; +} +int +unserialize_rsp_dirent(xlator_t *this, 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; + clnt_conf_t *conf = NULL; + + conf = this->private; + + 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; + gf_itransform(this, trav->d_off, &entry->d_off, conf->client_id); + 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; + gf_dirent_t *entry = NULL; + inode_table_t *itable = NULL; + int entry_len = 0; + int ret = -1; + clnt_conf_t *conf = NULL; + + trav = rsp->reply; + + if (fd) + itable = fd->inode->table; + + conf = this->private; + if (!conf) + goto out; + + 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; + gf_itransform(this, trav->d_off, &entry->d_off, conf->client_id); + 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) { + entry->dict = dict_new(); + if (!entry->dict) + goto out; + + ret = dict_unserialize(trav->dict.dict_val, trav->dict.dict_len, + &entry->dict); + if (ret < 0) { + gf_smsg(THIS->name, GF_LOG_WARNING, EINVAL, + PC_MSG_DICT_UNSERIALIZE_FAIL, "xattr", NULL); + goto out; + } + } + + 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; + entry = NULL; + } + + ret = 0; out: - return; + if (entry) + gf_dirent_entry_free(entry); + 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 -client_local_wipe (clnt_local_t *local) +unserialize_rsp_dirent_v2(xlator_t *this, struct gfx_readdir_rsp *rsp, + gf_dirent_t *entries) { - if (local) { - loc_wipe (&local->loc); + struct gfx_dirlist *trav = NULL; + gf_dirent_t *entry = NULL; + int entry_len = 0; + int ret = -1; + clnt_conf_t *conf = NULL; - if (local->fd) { - fd_unref (local->fd); - } + conf = this->private; - if (local->iobref) { - iobref_unref (local->iobref); - } + 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; - GF_FREE (local); - } + entry->d_ino = trav->d_ino; + gf_itransform(this, trav->d_off, &entry->d_off, conf->client_id); + 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_v2(xlator_t *this, fd_t *fd, + struct gfx_readdirp_rsp *rsp, gf_dirent_t *entries) +{ + struct gfx_dirplist *trav = NULL; + gf_dirent_t *entry = NULL; + inode_table_t *itable = NULL; + int entry_len = 0; + int ret = -1; + clnt_conf_t *conf = NULL; + + trav = rsp->reply; + + if (fd) + itable = fd->inode->table; + + conf = this->private; + if (!conf) + goto out; - return 0; + 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; + gf_itransform(this, trav->d_off, &entry->d_off, conf->client_id); + entry->d_len = trav->d_len; + entry->d_type = trav->d_type; + + gfx_stat_to_iattx(&trav->stat, &entry->d_stat); + + strcpy(entry->d_name, trav->name); + + xdr_to_dict(&trav->dict, &entry->dict); + + 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 -unserialize_rsp_dirent (struct gfs3_readdir_rsp *rsp, gf_dirent_t *entries) +clnt_readdirp_rsp_cleanup_v2(gfx_readdirp_rsp *rsp) { - struct gfs3_dirlist *trav = NULL; - gf_dirent_t *entry = NULL; - int entry_len = 0; - int ret = -1; + gfx_dirplist *prev = NULL; + gfx_dirplist *trav = NULL; + + trav = rsp->reply; + prev = trav; + while (trav) { + trav = trav->nextentry; + free(prev->name); + free(prev); + prev = trav; + } - 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; + 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; + } - entry->d_ino = trav->d_ino; - entry->d_off = trav->d_off; - entry->d_len = trav->d_len; - entry->d_type = trav->d_type; + return 0; +} - strcpy (entry->d_name, trav->name); +int +clnt_readdir_rsp_cleanup_v2(gfx_readdir_rsp *rsp) +{ + gfx_dirlist *prev = NULL; + gfx_dirlist *trav = NULL; + + trav = rsp->reply; + prev = trav; + while (trav) { + trav = trav->nextentry; + /* on client, the rpc lib allocates this */ + free(prev->name); + free(prev); + prev = trav; + } - list_add_tail (&entry->list, &entries->list); + return 0; +} - trav = trav->nextentry; +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_boolean_t locks_held = _gf_false; + + GF_VALIDATE_OR_GOTO(this->name, fd, out); + GF_VALIDATE_OR_GOTO(this->name, remote_fd, out); + + conf = this->private; + pthread_spin_lock(&conf->fd_lock); + { + fdctx = this_fd_get_ctx(fd, this); + if (!fdctx) { + if (fd->anonymous) { + *remote_fd = GF_ANON_FD_NO; + } else { + *remote_fd = -1; + gf_msg_debug(this->name, EBADF, "not a valid fd for gfid: %s", + uuid_utoa(fd->inode->gfid)); + } + } else { + if (__is_fd_reopen_in_progress(fdctx)) + *remote_fd = -1; + else + *remote_fd = fdctx->remote_fd; + + locks_held = !list_empty(&fdctx->lock_list); } + } + pthread_spin_unlock(&conf->fd_lock); + + if ((flags & FALLBACK_TO_ANON_FD) && (*remote_fd == -1) && (!locks_held)) + *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_conf_t *conf = NULL; + clnt_fd_ctx_t *fdctx = NULL; + gf_boolean_t res = _gf_false; + + conf = this->private; + pthread_spin_lock(&conf->fd_lock); + { + fdctx = this_fd_get_ctx(fd, this); + if (fdctx && (fdctx->remote_fd == -1) && (remote_fd == GF_ANON_FD_NO)) + res = _gf_true; + } + pthread_spin_unlock(&conf->fd_lock); + + return res; +} + +int +client_fd_fop_prepare_local(call_frame_t *frame, fd_t *fd, int64_t remote_fd) +{ + xlator_t *this = NULL; + clnt_local_t *local = NULL; + int ret = 0; + + if (!frame || !fd) { + ret = -EINVAL; + goto out; + } + + this = frame->this; + + frame->local = mem_get0(this->local_pool); + if (frame->local == NULL) { + ret = -ENOMEM; + goto out; + } - ret = 0; + local = frame->local; + local->fd = fd_ref(fd); + local->attempt_reopen = client_is_reopen_needed(fd, this, remote_fd); + + return 0; out: - return ret; + return ret; +} + +void +clnt_getactivelk_rsp_cleanup(gfs3_getactivelk_rsp *rsp) +{ + gfs3_locklist *trav = NULL; + gfs3_locklist *next = NULL; + + trav = rsp->reply; + + while (trav) { + next = trav->nextentry; + free(trav->client_uid); + free(trav); + trav = next; + } } +void +clnt_getactivelk_rsp_cleanup_v2(gfx_getactivelk_rsp *rsp) +{ + gfs3_locklist *trav = NULL; + gfs3_locklist *next = NULL; + + trav = rsp->reply; + + while (trav) { + next = trav->nextentry; + free(trav->client_uid); + free(trav); + trav = next; + } +} int -unserialize_rsp_direntp (struct gfs3_readdirp_rsp *rsp, gf_dirent_t *entries) +clnt_unserialize_rsp_locklist(xlator_t *this, struct gfs3_getactivelk_rsp *rsp, + lock_migration_info_t *lmi) { - struct gfs3_dirplist *trav = NULL; - gf_dirent_t *entry = NULL; - int entry_len = 0; - int ret = -1; + struct gfs3_locklist *trav = NULL; + lock_migration_info_t *temp = NULL; + int ret = -1; + clnt_conf_t *conf = NULL; + + trav = rsp->reply; + + conf = this->private; + if (!conf) + goto out; + + while (trav) { + temp = GF_CALLOC(1, sizeof(*lmi), gf_common_mt_lock_mig); + if (temp == NULL) { + gf_smsg(this->name, GF_LOG_ERROR, 0, PC_MSG_NO_MEM, NULL); + goto out; + } - trav = rsp->reply; + INIT_LIST_HEAD(&temp->list); - 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; + gf_proto_flock_to_flock(&trav->flock, &temp->flock); - entry->d_ino = trav->d_ino; - entry->d_off = trav->d_off; - entry->d_len = trav->d_len; - entry->d_type = trav->d_type; + temp->lk_flags = trav->lk_flags; - gf_stat_to_iatt (&trav->stat, &entry->d_stat); + temp->client_uid = gf_strdup(trav->client_uid); - strcpy (entry->d_name, trav->name); + list_add_tail(&temp->list, &lmi->list); - list_add_tail (&entry->list, &entries->list); + trav = trav->nextentry; + } - trav = trav->nextentry; + ret = 0; +out: + return ret; +} +int +clnt_unserialize_rsp_locklist_v2(xlator_t *this, + struct gfx_getactivelk_rsp *rsp, + lock_migration_info_t *lmi) +{ + struct gfs3_locklist *trav = NULL; + lock_migration_info_t *temp = NULL; + int ret = -1; + clnt_conf_t *conf = NULL; + + trav = rsp->reply; + + conf = this->private; + if (!conf) + goto out; + + while (trav) { + temp = GF_CALLOC(1, sizeof(*lmi), gf_common_mt_lock_mig); + if (temp == NULL) { + gf_smsg(this->name, GF_LOG_ERROR, 0, PC_MSG_NO_MEM, NULL); + goto out; } - ret = 0; + INIT_LIST_HEAD(&temp->list); + + gf_proto_flock_to_flock(&trav->flock, &temp->flock); + + temp->lk_flags = trav->lk_flags; + + temp->client_uid = gf_strdup(trav->client_uid); + + list_add_tail(&temp->list, &lmi->list); + + trav = trav->nextentry; + } + + ret = 0; out: - return ret; + return ret; +} + +void +clnt_setactivelk_req_cleanup(gfs3_setactivelk_req *req) +{ + gfs3_locklist *trav = NULL; + gfs3_locklist *next = NULL; + + trav = req->request; + + while (trav) { + next = trav->nextentry; + GF_FREE(trav->client_uid); + GF_FREE(trav); + trav = next; + } +} + +void +clnt_setactivelk_req_cleanup_v2(gfx_setactivelk_req *req) +{ + gfs3_locklist *trav = NULL; + gfs3_locklist *next = NULL; + + trav = req->request; + + while (trav) { + next = trav->nextentry; + GF_FREE(trav->client_uid); + GF_FREE(trav); + trav = next; + } } int -clnt_readdirp_rsp_cleanup (gfs3_readdirp_rsp *rsp) +serialize_req_locklist(lock_migration_info_t *locklist, + gfs3_setactivelk_req *req) { - gfs3_dirplist *prev = NULL; - gfs3_dirplist *trav = NULL; + lock_migration_info_t *tmp = NULL; + gfs3_locklist *trav = NULL; + gfs3_locklist *prev = NULL; + int ret = -1; + + GF_VALIDATE_OR_GOTO("server", locklist, out); + GF_VALIDATE_OR_GOTO("server", req, out); + + list_for_each_entry(tmp, &locklist->list, list) + { + trav = GF_CALLOC(1, sizeof(*trav), gf_client_mt_clnt_lock_request_t); + if (!trav) + goto out; + + switch (tmp->flock.l_type) { + case F_RDLCK: + tmp->flock.l_type = GF_LK_F_RDLCK; + break; + case F_WRLCK: + tmp->flock.l_type = GF_LK_F_WRLCK; + break; + case F_UNLCK: + tmp->flock.l_type = GF_LK_F_UNLCK; + break; + + default: + gf_smsg(THIS->name, GF_LOG_ERROR, 0, PC_MSG_UNKNOWN_LOCK_TYPE, + "type=%" PRId32, tmp->flock.l_type, NULL); + break; + } - trav = rsp->reply; - prev = trav; - while (trav) { - trav = trav->nextentry; - /* on client, the rpc lib allocates this */ - free (prev->name); - free (prev); - prev = trav; + gf_proto_flock_from_flock(&trav->flock, &tmp->flock); + + trav->lk_flags = tmp->lk_flags; + + trav->client_uid = gf_strdup(tmp->client_uid); + if (!trav->client_uid) { + gf_smsg(THIS->name, GF_LOG_ERROR, 0, PC_MSG_CLIENT_UID_ALLOC_FAILED, + NULL); + ret = -1; + goto out; } - return 0; + if (prev) + prev->nextentry = trav; + else + req->request = trav; + + prev = trav; + trav = NULL; + } + + ret = 0; +out: + GF_FREE(trav); + + return ret; } int -clnt_readdir_rsp_cleanup (gfs3_readdir_rsp *rsp) +serialize_req_locklist_v2(lock_migration_info_t *locklist, + gfx_setactivelk_req *req) { - gfs3_dirlist *prev = NULL; - gfs3_dirlist *trav = NULL; + lock_migration_info_t *tmp = NULL; + gfs3_locklist *trav = NULL; + gfs3_locklist *prev = NULL; + int ret = -1; + + GF_VALIDATE_OR_GOTO("server", locklist, out); + GF_VALIDATE_OR_GOTO("server", req, out); + + list_for_each_entry(tmp, &locklist->list, list) + { + trav = GF_CALLOC(1, sizeof(*trav), gf_client_mt_clnt_lock_request_t); + if (!trav) + goto out; + + switch (tmp->flock.l_type) { + case F_RDLCK: + tmp->flock.l_type = GF_LK_F_RDLCK; + break; + case F_WRLCK: + tmp->flock.l_type = GF_LK_F_WRLCK; + break; + case F_UNLCK: + tmp->flock.l_type = GF_LK_F_UNLCK; + break; + + default: + gf_smsg(THIS->name, GF_LOG_ERROR, 0, PC_MSG_UNKNOWN_LOCK_TYPE, + "type=%" PRId32, tmp->flock.l_type, NULL); + break; + } - trav = rsp->reply; - prev = trav; - while (trav) { - trav = trav->nextentry; - /* on client, the rpc lib allocates this */ - free (prev->name); - free (prev); - prev = trav; + gf_proto_flock_from_flock(&trav->flock, &tmp->flock); + + trav->lk_flags = tmp->lk_flags; + + trav->client_uid = gf_strdup(tmp->client_uid); + if (!trav->client_uid) { + gf_smsg(THIS->name, GF_LOG_ERROR, 0, PC_MSG_CLIENT_UID_ALLOC_FAILED, + NULL); + ret = -1; + goto out; } - return 0; + if (prev) + prev->nextentry = trav; + else + req->request = trav; + + prev = trav; + trav = NULL; + } + + ret = 0; +out: + GF_FREE(trav); + + return ret; +} + +extern int +client3_3_releasedir_cbk(struct rpc_req *req, struct iovec *iov, int count, + void *myframe); +extern int +client3_3_release_cbk(struct rpc_req *req, struct iovec *iov, int count, + void *myframe); +extern int +client4_0_releasedir_cbk(struct rpc_req *req, struct iovec *iov, int count, + void *myframe); +extern int +client4_0_release_cbk(struct rpc_req *req, struct iovec *iov, int count, + void *myframe); + +static int +send_release4_0_over_wire(xlator_t *this, clnt_fd_ctx_t *fdctx, + call_frame_t *fr) +{ + clnt_conf_t *conf = NULL; + conf = (clnt_conf_t *)this->private; + if (fdctx->is_dir) { + gfx_releasedir_req req = { + { + 0, + }, + }; + memcpy(req.gfid, fdctx->gfid, 16); + req.fd = fdctx->remote_fd; + + gf_msg_trace(this->name, 0, "sending releasedir on fd"); + (void)client_submit_request( + this, &req, fr, conf->fops, GFS3_OP_RELEASEDIR, + client4_0_releasedir_cbk, NULL, (xdrproc_t)xdr_gfx_releasedir_req); + } else { + gfx_release_req req = { + { + 0, + }, + }; + memcpy(req.gfid, fdctx->gfid, 16); + req.fd = fdctx->remote_fd; + gf_msg_trace(this->name, 0, "sending release on fd"); + (void)client_submit_request(this, &req, fr, conf->fops, GFS3_OP_RELEASE, + client4_0_release_cbk, NULL, + (xdrproc_t)xdr_gfx_release_req); + } + + return 0; +} + +static int +send_release3_3_over_wire(xlator_t *this, clnt_fd_ctx_t *fdctx, + call_frame_t *fr) +{ + clnt_conf_t *conf = NULL; + conf = (clnt_conf_t *)this->private; + if (fdctx->is_dir) { + gfs3_releasedir_req req = { + { + 0, + }, + }; + memcpy(req.gfid, fdctx->gfid, 16); + req.fd = fdctx->remote_fd; + gf_msg_trace(this->name, 0, "sending releasedir on fd"); + (void)client_submit_request( + this, &req, fr, conf->fops, GFS3_OP_RELEASEDIR, + client3_3_releasedir_cbk, NULL, (xdrproc_t)xdr_gfs3_releasedir_req); + } else { + gfs3_release_req req = { + { + 0, + }, + }; + memcpy(req.gfid, fdctx->gfid, 16); + req.fd = fdctx->remote_fd; + gf_msg_trace(this->name, 0, "sending release on fd"); + (void)client_submit_request(this, &req, fr, conf->fops, GFS3_OP_RELEASE, + client3_3_release_cbk, NULL, + (xdrproc_t)xdr_gfs3_release_req); + } + + 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_msg_debug(this->name, 0, "not a valid fd"); + goto out; + } + + pthread_mutex_lock(&conf->lock); + { + parent_down = conf->parent_down; + } + pthread_mutex_unlock(&conf->lock); + lk_ctx = fdctx->lk_ctx; + fdctx->lk_ctx = NULL; + + 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 (conf->fops->progver == GLUSTER_FOP_VERSION) + send_release3_3_over_wire(this, fdctx, fr); + else + send_release4_0_over_wire(this, fdctx, fr); + + rpc_clnt_unref(conf->rpc); +out: + if (fdctx) { + fdctx->remote_fd = -1; + GF_FREE(fdctx); + } + + return ret; } diff --git a/xlators/protocol/client/src/client-lk.c b/xlators/protocol/client/src/client-lk.c index 5334500a96c..795839734c5 100644 --- a/xlators/protocol/client/src/client-lk.c +++ b/xlators/protocol/client/src/client-lk.c @@ -1,946 +1,515 @@ /* - Copyright (c) 2008-2011 Gluster, Inc. <http://www.gluster.com> + Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com> This file is part of GlusterFS. - GlusterFS is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 3 of the License, - or (at your option) any later version. - - GlusterFS is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see - <http://www.gnu.org/licenses/>. + This file is licensed to you under your choice of the GNU Lesser + General Public License, version 3 or any later version (LGPLv3 or + later), or the GNU General Public License, version 2 (GPLv2), in all + cases as published by the Free Software Foundation. */ -#include "common-utils.h" -#include "xlator.h" +#include <glusterfs/common-utils.h> +#include <glusterfs/xlator.h> #include "client.h" +#include <glusterfs/lkowner.h> +#include "client-messages.h" static void -__insert_and_merge (clnt_fd_ctx_t *fdctx, client_posix_lock_t *lock); +__insert_and_merge(clnt_fd_ctx_t *fdctx, client_posix_lock_t *lock); -static int -client_send_recovery_lock (call_frame_t *frame, xlator_t *this, - client_posix_lock_t *lock); static void -__dump_client_lock (client_posix_lock_t *lock) +__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:%"PRIu64" %"PRId64" - %"PRId64"}" - "{start=%"PRId64" end=%"PRId64"}", - lock->fd, - lock->fl_type == F_WRLCK ? "Write-Lock" : "Read-Lock", - lock->owner, - lock->user_flock.l_start, - lock->user_flock.l_len, - lock->fl_start, - lock->fl_end); + xlator_t *this = NULL; + + this = THIS; + + gf_smsg( + this->name, GF_LOG_INFO, 0, PC_MSG_CLIENT_LOCK_INFO, "fd=%p", lock->fd, + "fl_type=%s", lock->fl_type == F_WRLCK ? "Write-Lock" : "Read-Lock", + "lk-owner=%s", lkowner_utoa(&lock->owner), "l_start=%" PRId64, + lock->user_flock.l_start, "l_len=%" PRId64, lock->user_flock.l_len, + "start=%" PRId64, lock->fl_start, "end=%" PRId64, lock->fl_end, NULL); } static int -dump_client_locks_fd (clnt_fd_ctx_t *fdctx) +dump_client_locks_fd(clnt_fd_ctx_t *fdctx) { - client_posix_lock_t *lock = NULL; - int count = 0; + 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; + list_for_each_entry(lock, &fdctx->lock_list, list) + { + __dump_client_lock(lock); + count++; + } + return count; } int -dump_client_locks (inode_t *inode) +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; + fd_t *fd = NULL; + xlator_t *this = NULL; + clnt_fd_ctx_t *fdctx = NULL; + clnt_conf_t *conf = NULL; - int total_count = 0; - int locks_fd_count = 0; + int total_count = 0; + int locks_fd_count = 0; - this = THIS; - conf = this->private; + this = THIS; + conf = this->private; - LOCK (&inode->lock); + LOCK(&inode->lock); + { + list_for_each_entry(fd, &inode->fd_list, inode_list) { - 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); + locks_fd_count = 0; - if (fdctx) - locks_fd_count = dump_client_locks_fd (fdctx); - - total_count += locks_fd_count; - } + pthread_spin_lock(&conf->fd_lock); + fdctx = this_fd_get_ctx(fd, this); + if (fdctx) + locks_fd_count = dump_client_locks_fd(fdctx); + pthread_spin_unlock(&conf->fd_lock); + total_count += locks_fd_count; } - UNLOCK (&inode->lock); - - return total_count; + } + UNLOCK(&inode->lock); + return total_count; } static off_t -__get_lock_length (off_t start, off_t end) +__get_lock_length(off_t start, off_t end) { - if (end == LLONG_MAX) - return 0; - else - return (end - start + 1); + 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) +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; + client_posix_lock_t *sum = NULL; - sum->fl_start = min (l1->fl_start, l2->fl_start); - sum->fl_end = max (l1->fl_end, l2->fl_end); + sum = GF_CALLOC(1, sizeof(*sum), gf_client_mt_clnt_lock_t); + if (!sum) + return NULL; - sum->user_flock.l_start = sum->fl_start; - sum->user_flock.l_len = __get_lock_length (sum->fl_start, - sum->fl_end); + sum->fl_start = min(l1->fl_start, l2->fl_start); + sum->fl_end = max(l1->fl_end, l2->fl_end); - return sum; -} + sum->user_flock.l_start = sum->fl_start; + sum->user_flock.l_len = __get_lock_length(sum->fl_start, sum->fl_end); -/* Return true if the locks have the same owner */ -static int -same_owner (client_posix_lock_t *l1, client_posix_lock_t *l2) -{ - return ((l1->owner == l2->owner)); + return sum; } /* Return true if the locks overlap, false otherwise */ static int -locks_overlap (client_posix_lock_t *l1, client_posix_lock_t *l2) +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)); + /* + 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) +__delete_client_lock(client_posix_lock_t *lock) { - list_del_init (&lock->list); + list_del_init(&lock->list); } /* Destroy a posix_lock */ static void -__destroy_client_lock (client_posix_lock_t *lock) +__destroy_client_lock(client_posix_lock_t *lock) { - GF_FREE (lock); + GF_FREE(lock); } /* Subtract two locks */ struct _values { - client_posix_lock_t *locks[3]; + 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; +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_MALLOC(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_MALLOC(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_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); + v.locks[1] = GF_MALLOC(sizeof(client_posix_lock_t), + gf_client_mt_clnt_lock_t); + GF_ASSERT(v.locks[1]); + memcpy(v.locks[1], small, sizeof(client_posix_lock_t)); + v.locks[2] = GF_MALLOC(sizeof(client_posix_lock_t), + gf_client_mt_clnt_lock_t); + GF_ASSERT(v.locks[2]); + 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_MALLOC(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_start = small->fl_end + 1; + v.locks[0]->user_flock.l_start = small->fl_end + 1; + v.locks[1] = GF_MALLOC(sizeof(client_posix_lock_t), + gf_client_mt_clnt_lock_t); + GF_ASSERT(v.locks[1]); + memcpy(v.locks[1], small, sizeof(client_posix_lock_t)); + } else if (small->fl_end == big->fl_end) { + v.locks[0] = GF_MALLOC(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_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); + + v.locks[1] = GF_MALLOC(sizeof(client_posix_lock_t), + gf_client_mt_clnt_lock_t); + GF_ASSERT(v.locks[1]); + memcpy(v.locks[1], small, sizeof(client_posix_lock_t)); + } else { + /* LOG-TODO : decide what more info is required here*/ + gf_smsg("client-protocol", GF_LOG_CRITICAL, 0, PC_MSG_LOCK_ERROR, NULL); + } + + return v; } static void -__delete_unlck_locks (clnt_fd_ctx_t *fdctx) +__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); - } - } + 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) +__insert_lock(clnt_fd_ctx_t *fdctx, client_posix_lock_t *lock) { - list_add_tail (&lock->list, &fdctx->lock_list); + list_add_tail(&lock->list, &fdctx->lock_list); - return; + return; } static void -__insert_and_merge (clnt_fd_ctx_t *fdctx, client_posix_lock_t *lock) +__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; + 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}}; - if (same_owner (conf, lock)) { - if (conf->fl_type == lock->fl_type) { - sum = add_locks (lock, conf); + list_for_each_entry_safe(conf, t, &fdctx->lock_list, list) + { + if (!locks_overlap(conf, lock)) + continue; - sum->fd = lock->fd; + if (is_same_lkowner(&conf->owner, &lock->owner)) { + if (conf->fl_type == lock->fl_type) { + sum = add_locks(lock, conf); - __delete_client_lock (conf); - __destroy_client_lock (conf); + sum->fd = lock->fd; - __destroy_client_lock (lock); - __insert_and_merge (fdctx, sum); + __delete_client_lock(conf); + __destroy_client_lock(conf); - return; - } else { - sum = add_locks (lock, conf); + __destroy_client_lock(lock); + __insert_and_merge(fdctx, sum); - sum->fd = conf->fd; - sum->owner = conf->owner; + return; + } else { + sum = add_locks(lock, conf); - v = subtract_locks (sum, lock); + sum->fd = conf->fd; + sum->owner = conf->owner; - __delete_client_lock (conf); - __destroy_client_lock (conf); + v = subtract_locks(sum, lock); - __delete_client_lock (lock); - __destroy_client_lock (lock); + __delete_client_lock(conf); + __destroy_client_lock(conf); - __destroy_client_lock (sum); + __delete_client_lock(lock); + __destroy_client_lock(lock); - for (i = 0; i < 3; i++) { - if (!v.locks[i]) - continue; + __destroy_client_lock(sum); - 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) { + for (i = 0; i < 3; i++) { + if (!v.locks[i]) continue; - } - if ((conf->fl_type == F_RDLCK) && (lock->fl_type == F_RDLCK)) { - __insert_lock (fdctx, lock); - return; + INIT_LIST_HEAD(&v.locks[i]->list); + __insert_and_merge(fdctx, v.locks[i]); } - } - - /* 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, uint64_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; + __delete_unlck_locks(fdctx); + return; + } } - pthread_mutex_lock (&fdctx->mutex); - { - list_for_each_entry_safe (lock, tmp, &fdctx->lock_list, list) { - if (lock->owner == owner) { - list_del_init (&lock->list); - list_add_tail (&lock->list, &delete_list); - count++; - } - } + if (lock->fl_type == F_UNLCK) { + continue; } - pthread_mutex_unlock (&fdctx->mutex); - list_for_each_entry_safe (lock, tmp, &delete_list, list) { - list_del_init (&lock->list); - destroy_client_lock (lock); + if ((conf->fl_type == F_RDLCK) && (lock->fl_type == F_RDLCK)) { + __insert_lock(fdctx, lock); + return; } + } - /* 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; + /* no conflicts, so just insert */ + if (lock->fl_type != F_UNLCK) { + __insert_lock(fdctx, lock); + } else { + __destroy_client_lock(lock); + } } -int32_t -delete_granted_locks_fd (clnt_fd_ctx_t *fdctx) +static void +client_setlk(clnt_fd_ctx_t *fdctx, client_posix_lock_t *lock) { - 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; + __insert_and_merge(fdctx, lock); } static void -client_mark_bad_fd (fd_t *fd, clnt_fd_ctx_t *fdctx) +destroy_client_lock(client_posix_lock_t *lock) { - xlator_t *this = NULL; - - this = THIS; - if (fdctx) - fdctx->remote_fd = -1; - - gf_log (this->name, GF_LOG_WARNING, - "marking the file descriptor (%p) bad", fd); - - this_fd_set_ctx (fd, this, NULL, fdctx); + GF_FREE(lock); } 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, uint64_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; +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; + clnt_conf_t *conf = NULL; + + struct list_head delete_list; + int ret = 0; + int count = 0; + + INIT_LIST_HEAD(&delete_list); + this = THIS; + conf = this->private; + + pthread_spin_lock(&conf->fd_lock); + + fdctx = this_fd_get_ctx(fd, this); + if (!fdctx) { + pthread_spin_unlock(&conf->fd_lock); + + gf_smsg(this->name, GF_LOG_WARNING, EINVAL, PC_MSG_FD_CTX_INVALID, + NULL); + ret = -1; + goto out; + } + + 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++; } - UNLOCK (&conf->rec_lock); -} - -int -client_add_lock_for_recovery (fd_t *fd, struct gf_flock *flock, uint64_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_spin_unlock(&conf->fd_lock); - pthread_mutex_lock (&conf->lock); + if (!list_empty(&delete_list)) { + list_for_each_entry_safe(lock, tmp, &delete_list, list) { - 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; + list_del_init(&lock->list); + destroy_client_lock(lock); } + } - client_setlk (fdctx, lock); + /* FIXME: Need to actually print the locks instead of count */ + gf_msg_trace(this->name, 0, "Number of locks cleared=%d", count); out: - return ret; - -} - -static int -construct_reserve_unlock (struct gf_flock *lock, call_frame_t *frame, - client_posix_lock_t *client_lock) -{ - GF_ASSERT (lock); - GF_ASSERT (frame); - GF_ASSERT (frame->root->lk_owner); - - lock->l_type = F_UNLCK; - lock->l_start = 0; - lock->l_whence = SEEK_SET; - lock->l_len = 0; /* Whole file */ - lock->l_pid = (uint64_t)(unsigned long)frame->root; - - frame->root->lk_owner = client_lock->owner; - - return 0; -} - -static int -construct_reserve_lock (client_posix_lock_t *client_lock, call_frame_t *frame, - struct gf_flock *lock) -{ - GF_ASSERT (client_lock); - - memcpy (lock, &(client_lock->user_flock), sizeof (struct gf_flock)); - - frame->root->lk_owner = client_lock->owner; - - return 0; -} - -uint64_t -decrement_reopen_fd_count (xlator_t *this, clnt_conf_t *conf) -{ - uint64_t fd_count = 0; - - LOCK (&conf->rec_lock); - { - fd_count = --(conf->reopen_fd_count); - } - UNLOCK (&conf->rec_lock); - - if (fd_count == 0) { - gf_log (this->name, GF_LOG_INFO, - "last fd open'd/lock-self-heal'd - notifying CHILD-UP"); - client_notify_parents_child_up (this); - } - - return fd_count; + return ret; } int32_t -client_remove_reserve_lock_cbk (call_frame_t *frame, - void *cookie, - xlator_t *this, - int32_t op_ret, - int32_t op_errno, - struct gf_flock *lock) -{ - clnt_local_t *local = NULL; - clnt_conf_t *conf = NULL; - - uint64_t fd_count = 0; - - local = frame->local; - conf = this->private; - - if (op_ret < 0) { - gf_log (this->name, GF_LOG_WARNING, - "removing reserver lock on fd failed: %s", - strerror(op_errno)); - goto cleanup; - } - - gf_log (this->name, GF_LOG_DEBUG, - "Removing reserve lock was successful."); - -cleanup: - frame->local = NULL; - - client_mark_bad_fd (local->client_lock->fd, local->fdctx); - - destroy_client_lock (local->client_lock); - client_local_wipe (local); - STACK_DESTROY (frame->root); - - fd_count = decrement_reopen_fd_count (this, conf); - gf_log (this->name, GF_LOG_TRACE, - "Need to attempt lock recovery on %lld open fds", - (unsigned long long) fd_count); - return 0; -} - -static void -client_remove_reserve_lock (xlator_t *this, call_frame_t *frame, - client_posix_lock_t *lock) -{ - struct gf_flock unlock; - - construct_reserve_unlock (&unlock, frame, lock); - - STACK_WIND (frame, client_remove_reserve_lock_cbk, - this, this->fops->lk, - lock->fd, F_RESLK_UNLCK, &unlock); +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 * -get_next_recovery_lock (xlator_t *this, clnt_local_t *local) -{ - client_posix_lock_t *lock = NULL; - - pthread_mutex_lock (&local->mutex); - { - if (list_empty (&local->lock_list)) { - gf_log (this->name, GF_LOG_DEBUG, - "lock-list empty"); - goto unlock; - } - - lock = list_entry ((local->lock_list).next, typeof (*lock), list); - list_del_init (&lock->list); - } -unlock: - pthread_mutex_unlock (&local->mutex); - - return lock; - -} - -int32_t -client_reserve_lock_cbk (call_frame_t *frame, - void *cookie, - xlator_t *this, - int32_t op_ret, - int32_t op_errno, - struct gf_flock *lock) +new_client_lock(struct gf_flock *flock, gf_lkowner_t *owner, int32_t cmd, + fd_t *fd) { + client_posix_lock_t *new_lock = NULL; - clnt_local_t *local = NULL; - clnt_conf_t *conf = NULL; + new_lock = GF_CALLOC(1, sizeof(*new_lock), gf_client_mt_clnt_lock_t); + if (!new_lock) { + goto out; + } - uint64_t fd_count = 0; + INIT_LIST_HEAD(&new_lock->list); + new_lock->fd = fd; + memcpy(&new_lock->user_flock, flock, sizeof(struct gf_flock)); - local = frame->local; - conf = this->private; + new_lock->fl_type = flock->l_type; + new_lock->fl_start = flock->l_start; - /* Got the reserve lock. Check if lock is grantable and proceed - with the real lk call */ + if (flock->l_len == 0) + new_lock->fl_end = LLONG_MAX; + else + new_lock->fl_end = flock->l_start + flock->l_len - 1; - if (op_ret >= 0) { - /* Lock is grantable if flock reflects a successful getlk() call*/ - if (lock->l_type == F_UNLCK && lock->l_pid) { - gf_log (this->name, GF_LOG_INFO, - "Got the reservelk, but the lock is not grantable. "); - client_remove_reserve_lock (this, frame, local->client_lock); - goto out; - } - - gf_log (this->name, GF_LOG_DEBUG, "reserve lock succeeded"); - client_send_recovery_lock (frame, this, local->client_lock); - goto out; - } - - /* Somebody else has a reserve lk. Lock conflict detected. - Mark fd as bad */ - - gf_log (this->name, GF_LOG_WARNING, - "reservelk OP failed. aborting lock recovery"); - - client_mark_bad_fd (local->client_lock->fd, - local->fdctx); - destroy_client_lock (local->client_lock); - frame->local = NULL; - client_local_wipe (local); - STACK_DESTROY (frame->root); - - fd_count = decrement_reopen_fd_count (this, conf); - gf_log (this->name, GF_LOG_DEBUG, - "need to attempt lock recovery on %"PRIu64" open fds", - fd_count); - -out: - return 0; -} - -int32_t -client_recovery_lock_cbk (call_frame_t *frame, - void *cookie, - xlator_t *this, - int32_t op_ret, - int32_t op_errno, - struct gf_flock *lock) -{ - clnt_local_t *local = NULL; - clnt_fd_ctx_t *fdctx = NULL; - clnt_conf_t *conf = NULL; - client_posix_lock_t *next_lock = NULL; - - struct gf_flock reserve_flock; - uint64_t fd_count = 0; - - local = frame->local; - conf = this->private; - - if (op_ret < 0) { - gf_log (this->name, GF_LOG_ERROR, - "lock recovery failed: %s", - strerror(op_errno)); - - client_mark_bad_fd (local->client_lock->fd, - local->fdctx); - goto cleanup; - - /* Lock recovered. Continue with reserve lock for next lock */ - } else { - gf_log (this->name, GF_LOG_DEBUG, - "lock recovered successfully - continuing with next lock."); - - next_lock = get_next_recovery_lock (this, local); - if (!next_lock) { - gf_log (this->name, GF_LOG_DEBUG, - "all locks recovered on fd"); - goto cleanup; - } - - construct_reserve_lock (next_lock, frame, &reserve_flock); - local->fdctx = fdctx; - local->client_lock = next_lock; - - STACK_WIND (frame, client_reserve_lock_cbk, - this, this->fops->lk, - next_lock->fd, F_RESLK_LCK, &reserve_flock); - goto out; - - } + new_lock->owner = *owner; -cleanup: - - frame->local = NULL; - client_local_wipe (local); - - if (local->client_lock) - destroy_client_lock (local->client_lock); - - STACK_DESTROY (frame->root); - - fd_count = decrement_reopen_fd_count (this, conf); - - gf_log (this->name, GF_LOG_DEBUG, - "need to attempt lock recovery on %"PRIu64" open fds", - fd_count); + new_lock->cmd = cmd; /* Not really useful */ out: - return 0; -} - -static int -client_send_recovery_lock (call_frame_t *frame, xlator_t *this, - client_posix_lock_t *lock) -{ - - frame->root->lk_owner = lock->owner; - - /* Send all locks as F_SETLK to prevent the frame - from blocking if there is a conflict */ - - STACK_WIND (frame, client_recovery_lock_cbk, - this, this->fops->lk, - lock->fd, F_SETLK, - &(lock->user_flock)); - - return 0; + return new_lock; } -static int -client_lockrec_init (clnt_fd_ctx_t *fdctx, clnt_local_t *local) +void +client_save_number_fds(clnt_conf_t *conf, int count) { - - INIT_LIST_HEAD (&local->lock_list); - pthread_mutex_init (&local->mutex, NULL); - - pthread_mutex_lock (&fdctx->mutex); - { - list_splice_init (&fdctx->lock_list, &local->lock_list); - } - pthread_mutex_unlock (&fdctx->mutex); - - return 0; + LOCK(&conf->rec_lock); + { + conf->reopen_fd_count = count; + } + UNLOCK(&conf->rec_lock); } - int -client_attempt_lock_recovery (xlator_t *this, clnt_fd_ctx_t *fdctx) +client_add_lock_for_recovery(fd_t *fd, struct gf_flock *flock, + gf_lkowner_t *owner, int32_t cmd) { - call_frame_t *frame = NULL; - clnt_local_t *local = NULL; - client_posix_lock_t *lock = NULL; - - struct gf_flock reserve_flock; - int ret = 0; + clnt_fd_ctx_t *fdctx = NULL; + xlator_t *this = NULL; + client_posix_lock_t *lock = NULL; + clnt_conf_t *conf = NULL; - local = GF_CALLOC (1, sizeof (*local), gf_client_mt_clnt_local_t); - if (!local) { - ret = -ENOMEM; - goto out; - } + int ret = 0; - client_lockrec_init (fdctx, local); + this = THIS; + conf = this->private; - lock = get_next_recovery_lock (this, local); - if (!lock) { - gf_log (this->name, GF_LOG_DEBUG, - "no locks found on fd"); - ret = -1; - goto out; - } + pthread_spin_lock(&conf->fd_lock); - frame = create_frame (this, this->ctx->pool); - if (!frame) { - gf_log (this->name, GF_LOG_ERROR, - "creating of frame failed, lock recovery failed"); - ret = -1; - goto out; - } + fdctx = this_fd_get_ctx(fd, this); + if (!fdctx) { + pthread_spin_unlock(&conf->fd_lock); - construct_reserve_lock (lock, frame, &reserve_flock); + gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FD_GET_FAIL, NULL); + ret = -EBADFD; + goto out; + } - frame->local = local; - local->fdctx = fdctx; - local->client_lock = lock; + lock = new_client_lock(flock, owner, cmd, fd); + if (!lock) { + pthread_spin_unlock(&conf->fd_lock); - STACK_WIND (frame, client_reserve_lock_cbk, - this, this->fops->lk, - lock->fd, F_RESLK_LCK, &reserve_flock); + ret = -ENOMEM; + goto out; + } -out: - return ret; + client_setlk(fdctx, lock); + pthread_spin_unlock(&conf->fd_lock); +out: + return ret; } int32_t -client_dump_locks (char *name, inode_t *inode, - dict_t *dict) +client_dump_locks(char *name, inode_t *inode, dict_t *dict) { - int ret = 0; - dict_t *new_dict = NULL; - char dict_string[256]; + int ret = 0; + dict_t *new_dict = NULL; + char dict_string[256]; - GF_ASSERT (dict); - new_dict = dict; + GF_ASSERT(dict); + new_dict = dict; - ret = dump_client_locks (inode); - snprintf (dict_string, 256, "%d locks dumped in log file", ret); + 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; - } + ret = dict_set_dynstr(new_dict, CLIENT_DUMP_LOCKS, dict_string); + if (ret) { + gf_smsg(THIS->name, GF_LOG_WARNING, 0, PC_MSG_DICT_SET_FAIL, "lock=%s", + CLIENT_DUMP_LOCKS, NULL); + goto out; + } out: - return ret; + return ret; } int32_t -is_client_dump_locks_cmd (char *name) +is_client_dump_locks_cmd(char *name) { - int ret = 0; + int ret = 0; - if (strcmp (name, CLIENT_DUMP_LOCKS) == 0) - ret = 1; + if (strcmp(name, CLIENT_DUMP_LOCKS) == 0) + ret = 1; - return ret; + return ret; } diff --git a/xlators/protocol/client/src/client-mem-types.h b/xlators/protocol/client/src/client-mem-types.h index c2aa690b1c5..f61fa0c1828 100644 --- a/xlators/protocol/client/src/client-mem-types.h +++ b/xlators/protocol/client/src/client-mem-types.h @@ -1,34 +1,26 @@ /* - Copyright (c) 2010-2011 Gluster, Inc. <http://www.gluster.com> - This file is part of GlusterFS. + Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com> + This file is part of GlusterFS. - GlusterFS is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 3 of the License, - or (at your option) any later version. - - GlusterFS is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see - <http://www.gnu.org/licenses/>. + This file is licensed to you under your choice of the GNU Lesser + General Public License, version 3 or any later version (LGPLv3 or + later), or the GNU General Public License, version 2 (GPLv2), in all + cases as published by the Free Software Foundation. */ - #ifndef __CLIENT_MEM_TYPES_H__ #define __CLIENT_MEM_TYPES_H__ -#include "mem-types.h" +#include <glusterfs/mem-types.h> enum gf_client_mem_types_ { - gf_client_mt_clnt_conf_t = gf_common_mt_end + 1, - gf_client_mt_clnt_local_t, - gf_client_mt_clnt_req_buf_t, - gf_client_mt_clnt_fdctx_t, - gf_client_mt_clnt_lock_t, - gf_client_mt_end, + 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_compound_req_t, + gf_client_mt_clnt_lock_request_t, + gf_client_mt_end, }; #endif /* __CLIENT_MEM_TYPES_H__ */ diff --git a/xlators/protocol/client/src/client-messages.h b/xlators/protocol/client/src/client-messages.h new file mode 100644 index 00000000000..25a851d80b9 --- /dev/null +++ b/xlators/protocol/client/src/client-messages.h @@ -0,0 +1,174 @@ +/* + Copyright (c) 2015 Red Hat, Inc. <http://www.redhat.com> + This file is part of GlusterFS. + + This file is licensed to you under your choice of the GNU Lesser + General Public License, version 3 or any later version (LGPLv3 or + later), or the GNU General Public License, version 2 (GPLv2), in all + cases as published by the Free Software Foundation. +*/ + +#ifndef _PC_MESSAGES_H__ +#define _PC_MESSAGES_H__ + +#include <glusterfs/glfs-message-id.h> + +/* To add new message IDs, append new identifiers at the end of the list. + * + * Never remove a message ID. If it's not used anymore, you can rename it or + * leave it as it is, but not delete it. This is to prevent reutilization of + * IDs by other messages. + * + * The component name must match one of the entries defined in + * glfs-message-id.h. + */ + +GLFS_MSGID( + PC, PC_MSG_TIMER_EXPIRED, PC_MSG_DIR_OP_FAILED, PC_MSG_FILE_OP_FAILED, + PC_MSG_TIMER_REG, PC_MSG_GRACE_TIMER_CANCELLED, PC_MSG_DICT_SET_FAILED, + PC_MSG_DICT_GET_FAILED, PC_MSG_NO_MEMORY, PC_MSG_RPC_CBK_FAILED, + PC_MSG_FUNCTION_CALL_ERROR, PC_MSG_RPC_INITED_ALREADY, PC_MSG_RPC_INIT, + PC_MSG_RPC_DESTROY, PC_MSG_RPC_INVALID_CALL, PC_MSG_INVALID_ENTRY, + PC_MSG_HANDSHAKE_RETURN, PC_MSG_CHILD_UP_NOTIFY_FAILED, + PC_MSG_CLIENT_DISCONNECTED, PC_MSG_CHILD_DOWN_NOTIFY_FAILED, + PC_MSG_PARENT_UP, PC_MSG_PARENT_DOWN, PC_MSG_RPC_INIT_FAILED, + PC_MSG_RPC_NOTIFY_FAILED, PC_MSG_FD_DUPLICATE_TRY, PC_MSG_FD_SET_FAIL, + PC_MSG_DICT_UNSERIALIZE_FAIL, PC_MSG_FD_GET_FAIL, PC_MSG_FD_CTX_INVALID, + PC_MSG_FOP_SEND_FAILED, PC_MSG_XDR_DECODING_FAILED, PC_MSG_REMOTE_OP_FAILED, + PC_MSG_RPC_STATUS_ERROR, PC_MSG_VOL_FILE_NOT_FOUND, PC_MSG_SEND_REQ_FAIL, + PC_MSG_LOCK_VERSION_SERVER, PC_MSG_SET_LK_VERSION_ERROR, + PC_MSG_LOCK_REQ_FAIL, PC_MSG_CLIENT_REQ_FAIL, PC_MSG_LOCK_ERROR, + PC_MSG_LOCK_REACQUIRE, PC_MSG_CHILD_UP_NOTIFY, PC_MSG_CHILD_UP_NOTIFY_DELAY, + PC_MSG_VOL_SET_FAIL, PC_MSG_SETVOLUME_FAIL, PC_MSG_VOLFILE_NOTIFY_FAILED, + PC_MSG_REMOTE_VOL_CONNECTED, PC_MSG_LOCK_MISMATCH, PC_MSG_LOCK_MATCH, + PC_MSG_AUTH_FAILED, PC_MSG_AUTH_FAILED_NOTIFY_FAILED, + PC_MSG_CHILD_CONNECTING_EVENT, PC_MSG_CHILD_CONNECTING_NOTIFY_FAILED, + PC_MSG_PROCESS_UUID_SET_FAIL, PC_MSG_DICT_ERROR, PC_MSG_DICT_SERIALIZE_FAIL, + PC_MSG_PGM_NOT_FOUND, PC_MSG_VERSION_INFO, PC_MSG_PORT_NUM_ERROR, + PC_MSG_VERSION_ERROR, PC_MSG_DIR_OP_SUCCESS, PC_MSG_BAD_FD, + PC_MSG_CLIENT_LOCK_INFO, PC_MSG_CACHE_INVALIDATION_FAIL, + PC_MSG_CHILD_STATUS, PC_MSG_GFID_NULL, PC_MSG_RECALL_LEASE_FAIL, + PC_MSG_INODELK_CONTENTION_FAIL, PC_MSG_ENTRYLK_CONTENTION_FAIL, + PC_MSG_BIGGER_SIZE, PC_MSG_CLIENT_DUMP_LOCKS_FAILED, PC_MSG_UNKNOWN_CMD, + PC_MSG_REOPEN_FAILED, PC_MSG_FIND_KEY_FAILED, PC_MSG_VOL_ID_CHANGED, + PC_MSG_GETHOSTNAME_FAILED, PC_MSG_VOLFILE_KEY_SET_FAILED, + PC_MSG_VOLFILE_CHECKSUM_FAILED, PC_MSG_FRAME_NOT_FOUND, + PC_MSG_REMOTE_SUBVOL_SET_FAIL, PC_MSG_HANDSHAKE_PGM_NOT_FOUND, + PC_MSG_MERGE_IOBREF_FAILED, PC_MSG_ADD_IOBUF_FAILED, + PC_MSG_RELEASE_DIR_OP_FAILED, PC_MSG_REMOTE_HOST_SET_FAILED, + PC_MSG_REMOTE_PORT_SET_FAILED, PC_MSG_REMOTE_HOST_NOT_SET, + PC_MSG_NOREMOTE_HOST, PC_MSG_REMOTE_SUBVOL_NOT_GIVEN, + PC_MSG_FATAL_CLIENT_PROTOCOL, PC_MSG_VOL_DANGLING, + PC_MSG_CREATE_MEM_POOL_FAILED, PC_MSG_PVT_XLATOR_NULL, PC_MSG_XLATOR_NULL, + PC_MSG_LEASE_FOP_FAILED, PC_MSG_DICT_SET_FAIL, PC_MSG_NO_MEM, + PC_MSG_UNKNOWN_LOCK_TYPE, PC_MSG_CLIENT_UID_ALLOC_FAILED); + +#define PC_MSG_REMOTE_OP_FAILED_STR "remote operation failed." +#define PC_MSG_XDR_DECODING_FAILED_STR "XDR decoding failed" +#define PC_MSG_FOP_SEND_FAILED_STR "failed to send the fop" +#define PC_MSG_BIGGER_SIZE_STR "read-size is bigger than iobuf isze" +#define PC_MSG_CLIENT_DUMP_LOCKS_FAILED_STR "client dump locks failed" +#define PC_MSG_UNKNOWN_CMD_STR "Unknown cmd" +#define PC_MSG_CHILD_UP_NOTIFY_FAILED_STR "notify of CHILD_UP failed" +#define PC_MSG_CHILD_STATUS_STR \ + "Defering sending CHILD_UP message as the client translators are not yet " \ + "ready to serve" +#define PC_MSG_CHILD_UP_NOTIFY_STR "last fd open'd - notifying CHILD_UP" +#define PC_MSG_RPC_STATUS_ERROR_STR \ + "received RPC status error, returning ENOTCONN" +#define PC_MSG_REOPEN_FAILED_STR "reopen failed" +#define PC_MSG_DIR_OP_SUCCESS_STR "reopen dir succeeded" +#define PC_MSG_DIR_OP_FAILED_STR "failed to send the re-opendir request" +#define PC_MSG_CHILD_UP_NOTIFY_DELAY_STR \ + "fds open - Delaying child_up until they are re-opened" +#define PC_MSG_VOL_SET_FAIL_STR "failed to set the volume" +#define PC_MSG_DICT_UNSERIALIZE_FAIL_STR "failed to unserialize buffer to dict" +#define PC_MSG_DICT_GET_FAILED_STR "failed to get from reply dict" +#define PC_MSG_SETVOLUME_FAIL_STR "SETVOLUME on remote-host failed" +#define PC_MSG_VOLFILE_NOTIFY_FAILED_STR "notify of VOLFILE_MODIFIED failed" +#define PC_MSG_FIND_KEY_FAILED_STR "failed to find key in the options" +#define PC_MSG_VOL_ID_CHANGED_STR \ + "volume-id changed, can't connect to server. Needs remount" +#define PC_MSG_REMOTE_VOL_CONNECTED_STR "Connected, attached to remote volume" +#define PC_MSG_AUTH_FAILED_STR "sending AUTH_FAILED event" +#define PC_MSG_AUTH_FAILED_NOTIFY_FAILED_STR "notify of AUTH_FAILED failed" +#define PC_MSG_CHILD_CONNECTING_EVENT_STR "sending CHILD_CONNECTING event" +#define PC_MSG_CHILD_CONNECTING_NOTIFY_FAILED_STR \ + "notify of CHILD_CONNECTING failed" +#define PC_MSG_DICT_SET_FAILED_STR "failed to set in handshake msg" +#define PC_MSG_GETHOSTNAME_FAILED_STR "gethostname: failed" +#define PC_MSG_PROCESS_UUID_SET_FAIL_STR \ + "asprintf failed while setting process_uuid" +#define PC_MSG_VOLFILE_KEY_SET_FAILED_STR "failed to set volfile-key" +#define PC_MSG_VOLFILE_CHECKSUM_FAILED_STR "failed to set volfile-checksum" +#define PC_MSG_DICT_SERIALIZE_FAIL_STR "failed to serialize dictionary" +#define PC_MSG_PGM_NOT_FOUND_STR "xlator not found OR RPC program not found" +#define PC_MSG_VERSION_INFO_STR "Using Program" +#define PC_MSG_FRAME_NOT_FOUND_STR "frame not found with rpc request" +#define PC_MSG_PORT_NUM_ERROR_STR \ + "failed to get the port number for remote subvolume. Please run gluster " \ + "volume status on server to see if brick process is running" +#define PC_MSG_REMOTE_SUBVOL_SET_FAIL_STR "remote-subvolume not set in volfile" +#define PC_MSG_VERSION_ERROR_STR "failed to get the version from server" +#define PC_MSG_NO_VERSION_SUPPORT_STR "server doesn't support the version" +#define PC_MSG_HANDSHAKE_PGM_NOT_FOUND_STR "handshake program not found" +#define PC_MSG_MERGE_IOBREF_FAILED_STR \ + "cannot merge iobref passed from caller into new_iobref" +#define PC_MSG_ADD_IOBUF_FAILED_STR "cannot add iobuf into iobref" +#define PC_MSG_RELEASE_DIR_OP_FAILED_STR "release dir op failed" +#define PC_MSG_FILE_OP_FAILED_STR "release fop failed" +#define PC_MSG_REMOTE_HOST_SET_FAILED_STR "failed to set remote-host" +#define PC_MSG_REMOTE_PORT_SET_FAILED_STR "failed to set remote-port" +#define PC_MSG_RPC_INIT_STR "client rpc init command" +#define PC_MSG_RPC_DESTROY_STR "client rpc destroy command" +#define PC_MSG_HANDSHAKE_RETURN_STR "handshake msg returned" +#define PC_MSG_CLIENT_DISCONNECTED_STR \ + "disconnected from client, process will keep trying to connect glusterd " \ + "until brick's port is available" +#define PC_MSG_CHILD_DOWN_NOTIFY_FAILED_STR "CHILD_DOWN notify failed" +#define PC_MSG_PARENT_UP_STR \ + "parent translators are ready, attempting connect on transport" +#define PC_MSG_PARENT_DOWN_STR \ + "current graph is no longer active, destroying rpc_client" +#define PC_MSG_REMOTE_HOST_NOT_SET_STR \ + "Remote host is not set. Assuming the volfile server as remote host" +#define PC_MSG_NOREMOTE_HOST_STR "No remote host to connect" +#define PC_MSG_REMOTE_SUBVOL_NOT_GIVEN_STR "option 'remote-subvolume' not given" +#define PC_MSG_NO_MEMORY_STR "Memory accounting init failed" +#define PC_MSG_RPC_INVALID_CALL_STR \ + "RPC destroy called on already destroyed connection" +#define PC_MSG_RPC_INITED_ALREADY_STR "client rpc already init'ed" +#define PC_MSG_RPC_INIT_FAILED_STR "failed to initialize RPC" +#define PC_MSG_RPC_NOTIFY_FAILED_STR "failed to register notify" +#define PC_MSG_RPC_CBK_FAILED_STR "failed to reister callback program" +#define PC_MSG_FATAL_CLIENT_PROTOCOL_STR \ + "FATAL: client protocol, translator cannot have any subvolumes" +#define PC_MSG_VOL_DANGLING_STR "Volume is dangling" +#define PC_MSG_CREATE_MEM_POOL_FAILED_STR \ + "failed to create local_t's memory pool" +#define PC_MSG_XLATOR_NULL_STR "xlator is NULL" +#define PC_MSG_PVT_XLATOR_NULL_STR "private structure of the xlator is NULL" +#define PC_MSG_LEASE_FOP_FAILED_STR "Lease fop failed" +#define PC_MSG_LOCK_ERROR_STR \ + "Unexpected case in subtract_locks. Please send a bug report to " \ + "gluster-devel@gluster.org" +#define PC_MSG_FD_CTX_INVALID_STR "fdctx not valid" +#define PC_MSG_FD_GET_FAIL_STR "failed to get fd context. sending EBADFD" +#define PC_MSG_DICT_SET_FAIL_STR "could not set dict" +#define PC_MSG_CLIENT_LOCK_INFO_STR "client lock info" +#define PC_MSG_BAD_FD_STR "remote_fd is -1. EBADFD" +#define PC_MSG_FUNCTION_CALL_ERROR_STR "this function should not be called" +#define PC_MSG_RECALL_LEASE_FAIL_STR "XDR decode of recall lease failed" +#define PC_MSG_CACHE_INVALIDATION_FAIL_STR \ + "XDR decode of cache_invalidation failed" +#define PC_MSG_INODELK_CONTENTION_FAIL_STR \ + "XDR decode of inodelk contention failed" +#define PC_MSG_ENTRYLK_CONTENTION_FAIL_STR \ + "XDR decode of entrylk contention failed" +#define PC_MSG_FD_DUPLICATE_TRY_STR "trying duplicate remote fd set" +#define PC_MSG_FD_SET_FAIL_STR "failed to set remote-fd" +#define PC_MSG_NO_MEM_STR "No memory" +#define PC_MSG_UNKNOWN_LOCK_TYPE_STR "Unknown lock type" +#define PC_MSG_CLIENT_UID_ALLOC_FAILED_STR "client-uid could not be allocated" + +#endif /* !_PC_MESSAGES_H__ */ 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 00000000000..f402121c15b --- /dev/null +++ b/xlators/protocol/client/src/client-rpc-fops.c @@ -0,0 +1,6079 @@ +/* + 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 "client.h" +#include "rpc-common-xdr.h" +#include "glusterfs3-xdr.h" +#include "glusterfs3.h" +#include <glusterfs/compat-errno.h> +#include "client-messages.h" +#include <glusterfs/defaults.h> +#include "client-common.h" + +int32_t +client3_getspec(call_frame_t *frame, xlator_t *this, void *data); +rpc_clnt_prog_t clnt3_3_fop_prog; + +int +client_is_setlk(int32_t cmd) +{ + if ((cmd == F_SETLK) || (cmd == F_SETLK64) || (cmd == F_SETLKW) || + (cmd == F_SETLKW64)) { + return 1; + } + + return 0; +} + +/* 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_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, + NULL); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; + } + + ret = client_post_symlink(this, &rsp, &stbuf, &preparent, &postparent, + &xdata); + +out: + if (rsp.op_ret == -1) { + if (GF_IGNORE_IF_GSYNCD_SAFE_ERROR(frame, rsp.op_errno)) { + /* no need to print the gfid, because it will be null, + * since symlink operation failed. + */ + gf_smsg(this->name, GF_LOG_WARNING, gf_error_to_errno(rsp.op_errno), + PC_MSG_REMOTE_OP_FAILED, "loc1=%s", local->loc.path, + "loc2=%s", local->loc2.path, NULL); + } + } + + 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_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, + NULL); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; + } + + ret = client_post_mknod(this, &rsp, &stbuf, &preparent, &postparent, + &xdata); + +out: + if (rsp.op_ret == -1 && + GF_IGNORE_IF_GSYNCD_SAFE_ERROR(frame, rsp.op_errno)) { + gf_smsg(this->name, + fop_log_level(GF_FOP_MKNOD, gf_error_to_errno(rsp.op_errno)), + gf_error_to_errno(rsp.op_errno), PC_MSG_REMOTE_OP_FAILED, + "path=%s", local->loc.path, NULL); + } + + 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_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, + NULL); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; + } + + ret = client_post_mkdir(this, &rsp, &stbuf, &preparent, &postparent, + &xdata); + +out: + if (rsp.op_ret == -1 && + GF_IGNORE_IF_GSYNCD_SAFE_ERROR(frame, rsp.op_errno)) { + gf_smsg(this->name, + fop_log_level(GF_FOP_MKDIR, gf_error_to_errno(rsp.op_errno)), + gf_error_to_errno(rsp.op_errno), PC_MSG_REMOTE_OP_FAILED, + "Path=%s", local->loc.path, NULL); + } + + 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 && !gf_uuid_is_null(fd->inode->gfid)) { + gf_uuid_copy(gfid, fd->inode->gfid); + goto out; + } + + if (!loc) { + GF_ASSERT(0); + ret = -1; + goto out; + } + + if (loc->inode && !gf_uuid_is_null(loc->inode->gfid)) { + gf_uuid_copy(gfid, loc->inode->gfid); + } else if (!gf_uuid_is_null(loc->gfid)) { + gf_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; + } + + gf_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->reopen_done = client_default_reopen_done; + + INIT_LIST_HEAD(&fdctx->sfd_pos); + INIT_LIST_HEAD(&fdctx->lock_list); + + pthread_spin_lock(&conf->fd_lock); + { + this_fd_set_ctx(fd, this, loc, fdctx); + + list_add_tail(&fdctx->sfd_pos, &conf->saved_fds); + } + pthread_spin_unlock(&conf->fd_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; + 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; + + 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_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, + NULL); + 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; + } + } + + ret = client_post_open(this, &rsp, &xdata); +out: + if (rsp.op_ret == -1) { + gf_smsg(this->name, + fop_log_level(GF_FOP_OPEN, gf_error_to_errno(rsp.op_errno)), + gf_error_to_errno(rsp.op_errno), PC_MSG_REMOTE_OP_FAILED, + "Path=%s", local->loc.path, "gfid=%s", + loc_gfid_utoa(&local->loc), NULL); + } + + 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_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, + NULL); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; + } + + ret = client_post_stat(this, &rsp, &iatt, &xdata); +out: + if (rsp.op_ret == -1) { + /* stale filehandles are possible during normal operations, no + * need to spam the logs with these */ + if (rsp.op_errno == ESTALE) { + gf_msg_debug(this->name, 0, "remote operation failed: %s", + strerror(gf_error_to_errno(rsp.op_errno))); + } else { + gf_smsg(this->name, GF_LOG_WARNING, gf_error_to_errno(rsp.op_errno), + PC_MSG_REMOTE_OP_FAILED, NULL); + } + } + + 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_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, + NULL); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; + } + + ret = client_post_readlink(this, &rsp, &iatt, &xdata); + +out: + if (rsp.op_ret == -1) { + if (gf_error_to_errno(rsp.op_errno) == ENOENT) { + gf_msg_debug(this->name, 0, + "remote operation failed:" + " %s", + strerror(gf_error_to_errno(rsp.op_errno))); + } else { + gf_smsg(this->name, GF_LOG_WARNING, gf_error_to_errno(rsp.op_errno), + PC_MSG_REMOTE_OP_FAILED, NULL); + } + } + + 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_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, + NULL); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; + } + + ret = client_post_unlink(this, &rsp, &preparent, &postparent, &xdata); + +out: + if (rsp.op_ret == -1) { + if (gf_error_to_errno(rsp.op_errno) == ENOENT) { + gf_msg_debug(this->name, 0, + "remote operation failed:" + " %s", + strerror(gf_error_to_errno(rsp.op_errno))); + } else { + gf_smsg(this->name, GF_LOG_WARNING, gf_error_to_errno(rsp.op_errno), + PC_MSG_REMOTE_OP_FAILED, NULL); + } + } + + 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_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, + NULL); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; + } + + ret = client_post_rmdir(this, &rsp, &preparent, &postparent, &xdata); + +out: + if (rsp.op_ret == -1) { + if (GF_IGNORE_IF_GSYNCD_SAFE_ERROR(frame, rsp.op_errno)) { + gf_smsg(this->name, GF_LOG_WARNING, gf_error_to_errno(rsp.op_errno), + PC_MSG_REMOTE_OP_FAILED, NULL); + } + } + 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_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, + NULL); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; + } + + ret = client_post_truncate(this, &rsp, &prestat, &poststat, &xdata); + +out: + if (rsp.op_ret == -1) { + gf_smsg(this->name, GF_LOG_WARNING, gf_error_to_errno(rsp.op_errno), + PC_MSG_REMOTE_OP_FAILED, NULL); + } + 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_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, + NULL); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; + } + + ret = client_post_statfs(this, &rsp, &statfs, &xdata); + +out: + if (rsp.op_ret == -1) { + gf_smsg(this->name, GF_LOG_WARNING, gf_error_to_errno(rsp.op_errno), + PC_MSG_REMOTE_OP_FAILED, NULL); + } + 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_write_rsp); + if (ret < 0) { + gf_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, + NULL); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; + } + + ret = client_post_writev(this, &rsp, &prestat, &poststat, &xdata); + if (ret < 0) + goto out; +out: + if (rsp.op_ret == -1) { + gf_smsg(this->name, GF_LOG_WARNING, gf_error_to_errno(rsp.op_errno), + PC_MSG_REMOTE_OP_FAILED, NULL); + } 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_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, + NULL); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; + } + + if ((rsp.op_ret >= 0 || (rsp.op_errno == ENOTCONN)) && + !fd_is_anonymous(local->fd)) { + /* Delete all saved locks of the owner issuing flush */ + ret = delete_granted_locks_owner(local->fd, &local->owner); + gf_msg_trace(this->name, 0, "deleting locks of owner (%s) returned %d", + lkowner_utoa(&local->owner), ret); + } + + ret = client_post_flush(this, &rsp, &xdata); + +out: + if (rsp.op_ret == -1) { + gf_smsg(this->name, + fop_log_level(GF_FOP_FLUSH, gf_error_to_errno(rsp.op_errno)), + gf_error_to_errno(rsp.op_errno), PC_MSG_REMOTE_OP_FAILED, NULL); + } + 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_fsync_rsp); + if (ret < 0) { + gf_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, + NULL); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; + } + + ret = client_post_fsync(this, &rsp, &prestat, &poststat, &xdata); + if (ret < 0) + goto out; + +out: + if (rsp.op_ret == -1) { + gf_smsg(this->name, GF_LOG_WARNING, gf_error_to_errno(rsp.op_errno), + PC_MSG_REMOTE_OP_FAILED, NULL); + } + 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_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, + NULL); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; + } + + ret = client_post_setxattr(this, &rsp, &xdata); + if (ret < 0) + goto out; + +out: + op_errno = gf_error_to_errno(rsp.op_errno); + if (rsp.op_ret == -1) { + if (op_errno == ENOTSUP) { + gf_msg_debug(this->name, 0, + "remote operation failed:" + " %s", + strerror(op_errno)); + } else { + gf_smsg(this->name, GF_LOG_WARNING, op_errno, + PC_MSG_REMOTE_OP_FAILED, NULL); + } + } + + 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_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, + NULL); + rsp.op_ret = -1; + op_errno = EINVAL; + goto out; + } + + op_errno = gf_error_to_errno(rsp.op_errno); + ret = client_post_getxattr(this, &rsp, &dict, &xdata); + if (ret) { + op_errno = -ret; + goto out; + } + +out: + if (rsp.op_ret == -1) { + if ((op_errno == ENOTSUP) || (op_errno == ENODATA) || + (op_errno == ESTALE) || (op_errno == ENOENT)) { + gf_msg_debug(this->name, 0, + "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)"); + } else { + gf_smsg(this->name, GF_LOG_WARNING, op_errno, + PC_MSG_REMOTE_OP_FAILED, "Path=%s", local->loc.path, + "gfid=%s", loc_gfid_utoa(&local->loc), "Key=%s", + (local->name) ? local->name : "(null)", 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; + xlator_t *this = NULL; + dict_t *xdata = NULL; + + this = THIS; + + frame = myframe; + + 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_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, + NULL); + rsp.op_ret = -1; + op_errno = EINVAL; + goto out; + } + + op_errno = gf_error_to_errno(rsp.op_errno); + ret = client_post_fgetxattr(this, &rsp, &dict, &xdata); + if (ret) { + op_errno = -ret; + goto out; + } +out: + if (rsp.op_ret == -1) { + if ((op_errno == ENOTSUP) || (op_errno == ERANGE) || + (op_errno == ENODATA) || (op_errno == ENOENT)) { + gf_msg_debug(this->name, 0, "remote operation failed: %s", + strerror(op_errno)); + } else { + gf_smsg(this->name, GF_LOG_WARNING, op_errno, + PC_MSG_REMOTE_OP_FAILED, NULL); + } + } + + 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; + gf_loglevel_t loglevel = GF_LOG_NONE; + + 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_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, + NULL); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; + } + + ret = client_post_removexattr(this, &rsp, &xdata); +out: + if (rsp.op_ret == -1) { + /* EPERM/EACCESS is returned some times in case of selinux + attributes, or other system attributes which may not be + possible to remove from an user process is encountered. + we can't treat it as an error */ + if ((ENODATA == rsp.op_errno) || (ENOATTR == rsp.op_errno) || + (EPERM == rsp.op_errno) || (EACCES == rsp.op_errno)) + loglevel = GF_LOG_DEBUG; + else + loglevel = GF_LOG_WARNING; + + gf_smsg(this->name, loglevel, gf_error_to_errno(rsp.op_errno), + PC_MSG_REMOTE_OP_FAILED, NULL); + } + + 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_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, + NULL); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; + } + + ret = client_post_fremovexattr(this, &rsp, &xdata); +out: + if (rsp.op_ret == -1) { + gf_smsg(this->name, GF_LOG_WARNING, gf_error_to_errno(rsp.op_errno), + PC_MSG_REMOTE_OP_FAILED, NULL); + } + 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_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, + NULL); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; + } + + ret = client_post_fsyncdir(this, &rsp, &xdata); + +out: + if (rsp.op_ret == -1) { + gf_smsg(this->name, GF_LOG_WARNING, gf_error_to_errno(rsp.op_errno), + PC_MSG_REMOTE_OP_FAILED, NULL); + } + 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_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, + NULL); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; + } + + ret = client_post_access(this, &rsp, &xdata); + +out: + if (rsp.op_ret == -1) { + gf_smsg(this->name, GF_LOG_WARNING, gf_error_to_errno(rsp.op_errno), + PC_MSG_REMOTE_OP_FAILED, NULL); + } + 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_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, + NULL); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; + } + + ret = client_post_ftruncate(this, &rsp, &prestat, &poststat, &xdata); + +out: + if (rsp.op_ret == -1) { + gf_smsg(this->name, GF_LOG_WARNING, gf_error_to_errno(rsp.op_errno), + PC_MSG_REMOTE_OP_FAILED, NULL); + } + 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_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, + NULL); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; + } + + ret = client_post_fstat(this, &rsp, &stat, &xdata); + +out: + if (rsp.op_ret == -1) { + gf_smsg(this->name, GF_LOG_WARNING, gf_error_to_errno(rsp.op_errno), + PC_MSG_REMOTE_OP_FAILED, NULL); + } + 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_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, + NULL); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; + } + + ret = client_post_inodelk(this, &rsp, &xdata); +out: + if (rsp.op_ret == -1) { + gf_smsg(this->name, + fop_log_level(GF_FOP_INODELK, gf_error_to_errno(rsp.op_errno)), + gf_error_to_errno(rsp.op_errno), PC_MSG_REMOTE_OP_FAILED, NULL); + } + 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_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, + NULL); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; + } + + ret = client_post_finodelk(this, &rsp, &xdata); +out: + if (rsp.op_ret == -1) { + gf_smsg(this->name, + fop_log_level(GF_FOP_FINODELK, gf_error_to_errno(rsp.op_errno)), + gf_error_to_errno(rsp.op_errno), PC_MSG_REMOTE_OP_FAILED, NULL); + } 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_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, + NULL); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; + } + + ret = client_post_entrylk(this, &rsp, &xdata); +out: + if (rsp.op_ret == -1) { + gf_smsg(this->name, + fop_log_level(GF_FOP_ENTRYLK, gf_error_to_errno(rsp.op_errno)), + gf_error_to_errno(rsp.op_errno), PC_MSG_REMOTE_OP_FAILED, NULL); + } + + 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_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, + NULL); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; + } + + ret = client_post_fentrylk(this, &rsp, &xdata); + +out: + if ((rsp.op_ret == -1) && (EAGAIN != gf_error_to_errno(rsp.op_errno))) { + gf_smsg(this->name, GF_LOG_WARNING, gf_error_to_errno(rsp.op_errno), + PC_MSG_REMOTE_OP_FAILED, NULL); + } + + 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_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, + NULL); + rsp.op_ret = -1; + op_errno = EINVAL; + goto out; + } + + op_errno = rsp.op_errno; + ret = client_post_xattrop(this, &rsp, &dict, &xdata); + if (ret) { + op_errno = -ret; + goto out; + } +out: + if (rsp.op_ret == -1) { + gf_smsg(this->name, fop_log_level(GF_FOP_XATTROP, op_errno), + gf_error_to_errno(rsp.op_errno), PC_MSG_REMOTE_OP_FAILED, + "Path=%s", local->loc.path, "gfid=%s", + loc_gfid_utoa(&local->loc), NULL); + } + + 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_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, + NULL); + goto out; + } + op_errno = rsp.op_errno; + ret = client_post_fxattrop(this, &rsp, &dict, &xdata); + if (ret) { + rsp.op_ret = -1; + op_errno = -ret; + goto out; + } +out: + + if (rsp.op_ret == -1) { + gf_smsg(this->name, GF_LOG_WARNING, gf_error_to_errno(rsp.op_errno), + PC_MSG_REMOTE_OP_FAILED, NULL); + } 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_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, + NULL); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; + } + + ret = client_post_setxattr(this, &rsp, &xdata); + +out: + op_errno = gf_error_to_errno(rsp.op_errno); + if (rsp.op_ret == -1) { + if (op_errno == ENOTSUP) { + gf_msg_debug(this->name, 0, + "remote operation failed:" + " %s", + strerror(op_errno)); + } else { + gf_smsg(this->name, GF_LOG_WARNING, rsp.op_errno, + PC_MSG_REMOTE_OP_FAILED, NULL); + } + } + + 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_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, + NULL); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; + } + + ret = client_post_fsetattr(this, &rsp, &prestat, &poststat, &xdata); +out: + if (rsp.op_ret == -1) { + gf_smsg(this->name, GF_LOG_WARNING, gf_error_to_errno(rsp.op_errno), + PC_MSG_REMOTE_OP_FAILED, NULL); + } + 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_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, + NULL); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; + } + + ret = client_post_fallocate(this, &rsp, &prestat, &poststat, &xdata); + if (ret < 0) + 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_smsg(this->name, GF_LOG_WARNING, gf_error_to_errno(rsp.op_errno), + PC_MSG_REMOTE_OP_FAILED, NULL); + } + 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_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, + NULL); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; + } + + ret = client_post_discard(this, &rsp, &prestat, &poststat, &xdata); + +out: + if (rsp.op_ret == -1) { + gf_smsg(this->name, GF_LOG_WARNING, gf_error_to_errno(rsp.op_errno), + PC_MSG_REMOTE_OP_FAILED, NULL); + } + 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_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, + NULL); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; + } + + ret = client_post_zerofill(this, &rsp, &prestat, &poststat, &xdata); +out: + if (rsp.op_ret == -1) { + gf_smsg(this->name, GF_LOG_WARNING, gf_error_to_errno(rsp.op_errno), + PC_MSG_REMOTE_OP_FAILED, NULL); + } + 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_ipc_cbk(struct rpc_req *req, struct iovec *iov, int count, + void *myframe) +{ + call_frame_t *frame = NULL; + gfs3_ipc_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_ipc_rsp); + if (ret < 0) { + gf_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, + NULL); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; + } + + ret = client_post_ipc(this, &rsp, &xdata); +out: + if (rsp.op_ret == -1) { + gf_smsg(this->name, GF_LOG_WARNING, gf_error_to_errno(rsp.op_errno), + PC_MSG_REMOTE_OP_FAILED, NULL); + } + CLIENT_STACK_UNWIND(ipc, 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_seek_cbk(struct rpc_req *req, struct iovec *iov, int count, + void *myframe) +{ + call_frame_t *frame = NULL; + struct gfs3_seek_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_seek_rsp); + if (ret < 0) { + gf_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, + NULL); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; + } + + ret = client_post_seek(this, &rsp, &xdata); + +out: + if (rsp.op_ret == -1) { + gf_smsg(this->name, GF_LOG_WARNING, gf_error_to_errno(rsp.op_errno), + PC_MSG_REMOTE_OP_FAILED, NULL); + } + CLIENT_STACK_UNWIND(seek, frame, rsp.op_ret, + gf_error_to_errno(rsp.op_errno), rsp.offset, 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_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, + NULL); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; + } + + ret = client_post_setattr(this, &rsp, &prestat, &poststat, &xdata); + +out: + if (rsp.op_ret == -1) { + gf_smsg(this->name, GF_LOG_WARNING, gf_error_to_errno(rsp.op_errno), + PC_MSG_REMOTE_OP_FAILED, NULL); + } + 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_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, + NULL); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; + } + + if (-1 != rsp.op_ret) { + ret = client_post_create(this, &rsp, &stbuf, &preparent, &postparent, + local, &xdata); + if (ret < 0) + goto out; + 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; + } + } + +out: + if (rsp.op_ret == -1) { + gf_smsg(this->name, GF_LOG_WARNING, gf_error_to_errno(rsp.op_errno), + PC_MSG_REMOTE_OP_FAILED, "Path=%s", local->loc.path, NULL); + } + + 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_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, + NULL); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; + } + + ret = client_post_rchecksum(this, &rsp, &xdata); + +out: + if (rsp.op_ret == -1) { + gf_smsg(this->name, GF_LOG_WARNING, gf_error_to_errno(rsp.op_errno), + PC_MSG_REMOTE_OP_FAILED, NULL); + } + 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_lease_cbk(struct rpc_req *req, struct iovec *iov, int count, + void *myframe) +{ + call_frame_t *frame = NULL; + struct gf_lease lease = { + 0, + }; + gfs3_lease_rsp rsp = { + 0, + }; + int ret = 0; + xlator_t *this = NULL; + dict_t *xdata = NULL; + + this = THIS; + + frame = myframe; + + if (-1 == req->rpc_status) { + gf_smsg(this->name, GF_LOG_ERROR, ENOTCONN, PC_MSG_LEASE_FOP_FAILED, + NULL); + rsp.op_ret = -1; + rsp.op_errno = ENOTCONN; + goto out; + } + + ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gfs3_lease_rsp); + if (ret < 0) { + gf_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, + NULL); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; + } + + ret = client_post_lease(this, &rsp, &lease, &xdata); + +out: + if (rsp.op_ret == -1) { + gf_smsg(this->name, GF_LOG_WARNING, gf_error_to_errno(rsp.op_errno), + PC_MSG_REMOTE_OP_FAILED, NULL); + } + + CLIENT_STACK_UNWIND(lease, frame, rsp.op_ret, + gf_error_to_errno(rsp.op_errno), &lease, xdata); + + 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; + struct gf_flock lock = { + 0, + }; + gfs3_lk_rsp rsp = { + 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_lk_rsp); + if (ret < 0) { + gf_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, + NULL); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; + } + + if (rsp.op_ret >= 0) { + ret = client_post_lk(this, &rsp, &lock, &xdata); + if (ret < 0) + goto out; + + /* Save the lock to the client lock cache to be able + to recover in the case of server reboot.*/ + + if (client_is_setlk(local->cmd)) { + ret = client_add_lock_for_recovery(local->fd, &lock, &local->owner, + local->cmd); + if (ret < 0) { + rsp.op_ret = -1; + rsp.op_errno = -ret; + } + } + } + +out: + if ((rsp.op_ret == -1) && (EAGAIN != gf_error_to_errno(rsp.op_errno))) { + gf_smsg(this->name, GF_LOG_WARNING, gf_error_to_errno(rsp.op_errno), + PC_MSG_REMOTE_OP_FAILED, NULL); + } + + 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; + + INIT_LIST_HEAD(&entries.list); + + 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_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, + NULL); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; + } + + ret = client_post_readdir(this, &rsp, &entries, &xdata); + +out: + if (rsp.op_ret == -1) { + gf_smsg(this->name, GF_LOG_WARNING, gf_error_to_errno(rsp.op_errno), + PC_MSG_REMOTE_OP_FAILED, "remote_fd=%d", local->cmd, NULL); + } + 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; + + INIT_LIST_HEAD(&entries.list); + + 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_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, + NULL); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; + } + + ret = client_post_readdirp(this, &rsp, local->fd, &entries, &xdata); +out: + if (rsp.op_ret == -1) { + gf_smsg(this->name, GF_LOG_WARNING, gf_error_to_errno(rsp.op_errno), + PC_MSG_REMOTE_OP_FAILED, NULL); + } + 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_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, + NULL); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; + } + + ret = client_post_rename(this, &rsp, &stbuf, &preoldparent, &postoldparent, + &prenewparent, &postnewparent, &xdata); + +out: + if (rsp.op_ret == -1) { + gf_smsg(this->name, GF_LOG_WARNING, gf_error_to_errno(rsp.op_errno), + PC_MSG_REMOTE_OP_FAILED, NULL); + } + 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_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, + NULL); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; + } + + ret = client_post_link(this, &rsp, &stbuf, &preparent, &postparent, &xdata); +out: + if (rsp.op_ret == -1) { + if (GF_IGNORE_IF_GSYNCD_SAFE_ERROR(frame, rsp.op_errno)) { + gf_smsg(this->name, GF_LOG_WARNING, gf_error_to_errno(rsp.op_errno), + PC_MSG_REMOTE_OP_FAILED, "loc1=%s", local->loc.path, + "loc2=%s", local->loc2.path, NULL); + } + } + + 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; + 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; + + 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_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, + NULL); + 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; + } + } + + ret = client_post_opendir(this, &rsp, &xdata); +out: + if (rsp.op_ret == -1) { + gf_smsg(this->name, + fop_log_level(GF_FOP_OPENDIR, gf_error_to_errno(rsp.op_errno)), + gf_error_to_errno(rsp.op_errno), PC_MSG_REMOTE_OP_FAILED, + "Path=%s", local->loc.path, "gfid=%s", + loc_gfid_utoa(&local->loc), NULL); + } + 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_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, + NULL); + rsp.op_ret = -1; + op_errno = EINVAL; + goto out; + } + + /* Preserve the op_errno received from the server */ + op_errno = gf_error_to_errno(rsp.op_errno); + + ret = client_post_lookup(this, &rsp, &stbuf, &postparent, &xdata); + if (ret < 0) { + /* Don't change the op_errno if the fop failed on server */ + if (rsp.op_ret == 0) + op_errno = rsp.op_errno; + rsp.op_ret = -1; + goto out; + } + + if (rsp.op_ret < 0) + goto out; + + if ((!gf_uuid_is_null(inode->gfid)) && + (gf_uuid_compare(stbuf.ia_gfid, inode->gfid) != 0)) { + gf_msg_debug(frame->this->name, 0, "gfid changed for %s", + local->loc.path); + + rsp.op_ret = -1; + op_errno = ESTALE; + if (xdata) + ret = dict_set_int32(xdata, "gfid-changed", 1); + + goto out; + } + + rsp.op_ret = 0; + +out: + /* Restore the correct op_errno to rsp.op_errno */ + rsp.op_errno = op_errno; + if (rsp.op_ret == -1) { + /* any error other than ENOENT */ + if (!(local->loc.name && rsp.op_errno == ENOENT) && + !(rsp.op_errno == ESTALE)) + gf_smsg(this->name, GF_LOG_WARNING, rsp.op_errno, + PC_MSG_REMOTE_OP_FAILED, "Path=%s", local->loc.path, + "gfid=%s", loc_gfid_utoa(&local->loc), NULL); + else + gf_msg_trace(this->name, 0, + "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; + + 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_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, + NULL); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; + } + + memset(vector, 0, sizeof(vector)); + + ret = client_post_readv(this, &rsp, &iobref, req->rsp_iobref, &stat, vector, + &req->rsp[1], &rspcount, &xdata); +out: + if (rsp.op_ret == -1) { + gf_smsg(this->name, GF_LOG_WARNING, gf_error_to_errno(rsp.op_errno), + PC_MSG_REMOTE_OP_FAILED, NULL); + } 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; +} + +static int +client3_3_getactivelk_cbk(struct rpc_req *req, struct iovec *iov, int count, + void *myframe) +{ + call_frame_t *frame = NULL; + gfs3_getactivelk_rsp rsp = { + 0, + }; + int32_t ret = 0; + lock_migration_info_t locklist; + 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_getactivelk_rsp); + if (ret < 0) { + gf_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, + NULL); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; + } + + INIT_LIST_HEAD(&locklist.list); + + if (rsp.op_ret > 0) { + clnt_unserialize_rsp_locklist(this, &rsp, &locklist); + } + + 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_smsg(this->name, GF_LOG_WARNING, gf_error_to_errno(rsp.op_errno), + PC_MSG_REMOTE_OP_FAILED, NULL); + } + + CLIENT_STACK_UNWIND(getactivelk, frame, rsp.op_ret, + gf_error_to_errno(rsp.op_errno), &locklist, xdata); + + free(rsp.xdata.xdata_val); + + if (xdata) + dict_unref(xdata); + + clnt_getactivelk_rsp_cleanup(&rsp); + + return 0; +} + +static int +client3_3_setactivelk_cbk(struct rpc_req *req, struct iovec *iov, int count, + void *myframe) +{ + call_frame_t *frame = NULL; + gfs3_getactivelk_rsp rsp = { + 0, + }; + int32_t 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_setactivelk_rsp); + if (ret < 0) { + gf_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, + NULL); + 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_smsg(this->name, GF_LOG_WARNING, gf_error_to_errno(rsp.op_errno), + PC_MSG_REMOTE_OP_FAILED, NULL); + } + + CLIENT_STACK_UNWIND(setactivelk, frame, rsp.op_ret, + gf_error_to_errno(rsp.op_errno), xdata); + + free(rsp.xdata.xdata_val); + + if (xdata) + dict_unref(xdata); + + return 0; +} + +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; + gf_boolean_t destroy = _gf_false; + + if (!this || !data) + goto out; + + args = data; + conf = this->private; + + pthread_spin_lock(&conf->fd_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) { + fdctx->released = 1; + } else { + list_del_init(&fdctx->sfd_pos); + destroy = _gf_true; + } + } + } + pthread_spin_unlock(&conf->fd_lock); + + if (destroy) + 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; + gf_boolean_t destroy = _gf_false; + + if (!this || !data) + goto out; + + args = data; + conf = this->private; + + pthread_spin_lock(&conf->fd_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) { + fdctx->released = 1; + } else { + list_del_init(&fdctx->sfd_pos); + destroy = _gf_true; + } + } + } + pthread_spin_unlock(&conf->fd_lock); + + if (destroy) + 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; + client_payload_t cp; + + if (!frame || !this || !data) + goto unwind; + + conf = this->private; + args = data; + local = mem_get0(this->local_pool); + if (!local) { + op_errno = ENOMEM; + goto unwind; + } + frame->local = local; + + if (!(args->loc && args->loc->inode)) + goto unwind; + + loc_copy(&local->loc, args->loc); + loc_path(&local->loc, NULL); + + if (args->xdata) { + content = dict_get_sizen(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); + memset(vector, 0, sizeof(vector)); + rsphdr = &vector[0]; + rsphdr->iov_base = iobuf_ptr(rsp_iobuf); + rsphdr->iov_len = iobuf_pagesize(rsp_iobuf); + count = 1; + local->iobref = rsp_iobref; + iobuf_unref(rsp_iobuf); + rsp_iobuf = NULL; + rsp_iobref = NULL; + } + } + + ret = client_pre_lookup(this, &req, args->loc, args->xdata); + if (ret) { + op_errno = -ret; + goto unwind; + } + + memset(&cp, 0, sizeof(client_payload_t)); + cp.rsphdr = rsphdr; + cp.rsphdr_cnt = count; + cp.rsp_iobref = local->iobref; + ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_LOOKUP, + client3_3_lookup_cbk, &cp, + (xdrproc_t)xdr_gfs3_lookup_req); + + if (ret) { + gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); + } + + GF_FREE(req.xdata.xdata_val); + + 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); + + 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; + conf = this->private; + + ret = client_pre_stat(this, &req, args->loc, args->xdata); + if (ret) { + op_errno = -ret; + goto unwind; + } + ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_STAT, + client3_3_stat_cbk, NULL, + (xdrproc_t)xdr_gfs3_stat_req); + if (ret) { + gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); + } + + 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; + conf = this->private; + + ret = client_pre_truncate(this, &req, args->loc, args->offset, args->xdata); + if (ret) { + op_errno = -ret; + goto unwind; + } + ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_TRUNCATE, + client3_3_truncate_cbk, NULL, + (xdrproc_t)xdr_gfs3_truncate_req); + if (ret) { + gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); + } + + 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; + 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; + + ret = client_pre_ftruncate(this, &req, args->fd, args->offset, args->xdata); + if (ret) { + op_errno = -ret; + goto unwind; + } + ret = client_submit_request(this, &req, frame, conf->fops, + GFS3_OP_FTRUNCATE, client3_3_ftruncate_cbk, + NULL, (xdrproc_t)xdr_gfs3_ftruncate_req); + if (ret) { + gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); + } + + 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; + + conf = this->private; + + ret = client_pre_access(this, &req, args->loc, args->mask, args->xdata); + if (ret) { + op_errno = -ret; + goto unwind; + } + ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_ACCESS, + client3_3_access_cbk, NULL, + (xdrproc_t)xdr_gfs3_access_req); + if (ret) { + gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); + } + + 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}, + }; + client_payload_t cp; + + if (!frame || !this || !data) + goto unwind; + + args = data; + + conf = this->private; + + local = mem_get0(this->local_pool); + if (!local) { + op_errno = ENOMEM; + goto unwind; + } + + frame->local = local; + + ret = client_pre_readlink(this, &req, args->loc, args->size, args->xdata); + if (ret) { + op_errno = -ret; + goto 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; + } + + rsphdr = &vector[0]; + rsphdr->iov_base = iobuf_ptr(rsp_iobuf); + rsphdr->iov_len = iobuf_pagesize(rsp_iobuf); + count = 1; + local->iobref = rsp_iobref; + iobref_add(rsp_iobref, rsp_iobuf); + iobuf_unref(rsp_iobuf); + rsp_iobuf = NULL; + rsp_iobref = NULL; + + memset(&cp, 0, sizeof(client_payload_t)); + cp.rsphdr = rsphdr; + cp.rsphdr_cnt = count; + cp.rsp_iobref = local->iobref; + ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_READLINK, + client3_3_readlink_cbk, &cp, + (xdrproc_t)xdr_gfs3_readlink_req); + if (ret) { + gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); + } + + 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; + conf = this->private; + + ret = client_pre_unlink(this, &req, args->loc, args->flags, args->xdata); + if (ret) { + op_errno = -ret; + goto unwind; + } + ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_UNLINK, + client3_3_unlink_cbk, NULL, + (xdrproc_t)xdr_gfs3_unlink_req); + if (ret) { + gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); + } + + 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; + conf = this->private; + + ret = client_pre_rmdir(this, &req, args->loc, args->flags, args->xdata); + + if (ret) { + op_errno = -ret; + goto unwind; + } + ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_RMDIR, + client3_3_rmdir_cbk, NULL, + (xdrproc_t)xdr_gfs3_rmdir_req); + if (ret) { + gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); + } + 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; + conf = this->private; + + 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); + + local->loc2.path = gf_strdup(args->linkname); + + ret = client_pre_symlink(this, &req, args->loc, args->linkname, args->umask, + args->xdata); + if (ret) { + op_errno = -ret; + goto unwind; + } + ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_SYMLINK, + client3_3_symlink_cbk, NULL, + (xdrproc_t)xdr_gfs3_symlink_req); + if (ret) { + gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); + } + + 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; + conf = this->private; + + ret = client_pre_rename(this, &req, args->oldloc, args->newloc, + args->xdata); + if (ret) { + op_errno = -ret; + goto unwind; + } + ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_RENAME, + client3_3_rename_cbk, NULL, + (xdrproc_t)xdr_gfs3_rename_req); + if (ret) { + gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); + } + + 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; + conf = this->private; + + local = mem_get0(this->local_pool); + if (!local) { + op_errno = ENOMEM; + goto unwind; + } + + frame->local = local; + + ret = client_pre_link(this, &req, args->oldloc, args->newloc, args->xdata); + if (ret) { + op_errno = -ret; + goto unwind; + } + + loc_copy(&local->loc, args->oldloc); + loc_path(&local->loc, NULL); + loc_copy(&local->loc2, args->newloc); + loc_path(&local->loc2, NULL); + + ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_LINK, + client3_3_link_cbk, NULL, + (xdrproc_t)xdr_gfs3_link_req); + if (ret) { + gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); + } + + 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; + conf = this->private; + + local = mem_get0(this->local_pool); + if (!local) { + op_errno = ENOMEM; + goto unwind; + } + frame->local = local; + + loc_copy(&local->loc, args->loc); + loc_path(&local->loc, NULL); + + ret = client_pre_mknod(this, &req, args->loc, args->mode, args->rdev, + args->umask, args->xdata); + if (ret) { + op_errno = -ret; + goto unwind; + } + ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_MKNOD, + client3_3_mknod_cbk, NULL, + (xdrproc_t)xdr_gfs3_mknod_req); + if (ret) { + gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); + } + 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; + conf = this->private; + + if (!args->xdata || !dict_get_sizen(args->xdata, "gfid-req")) { + op_errno = EPERM; + gf_msg_callingfn(this->name, GF_LOG_WARNING, op_errno, PC_MSG_GFID_NULL, + "mkdir: %s is received " + "without gfid-req %p", + args->loc->path, args->xdata); + goto unwind; + } + + 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); + + ret = client_pre_mkdir(this, &req, args->loc, args->mode, args->umask, + args->xdata); + if (ret) { + op_errno = -ret; + goto unwind; + } + ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_MKDIR, + client3_3_mkdir_cbk, NULL, + (xdrproc_t)xdr_gfs3_mkdir_req); + if (ret) { + gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); + } + 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; + conf = this->private; + + local = mem_get0(this->local_pool); + if (!local) { + op_errno = ENOMEM; + goto unwind; + } + frame->local = local; + + local->fd = fd_ref(args->fd); + local->flags = args->flags; + + loc_copy(&local->loc, args->loc); + loc_path(&local->loc, NULL); + + ret = client_pre_create(this, &req, args->loc, args->fd, args->mode, + args->flags, args->umask, args->xdata); + if (ret) { + op_errno = -ret; + goto unwind; + } + ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_CREATE, + client3_3_create_cbk, NULL, + (xdrproc_t)xdr_gfs3_create_req); + if (ret) { + gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); + } + + 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; + + conf = this->private; + + local = mem_get0(this->local_pool); + if (!local) { + op_errno = ENOMEM; + goto unwind; + } + frame->local = local; + + local->flags = args->flags; + + local->fd = fd_ref(args->fd); + loc_copy(&local->loc, args->loc); + loc_path(&local->loc, NULL); + + ret = client_pre_open(this, &req, args->loc, args->fd, args->flags, + args->xdata); + + if (ret) { + op_errno = -ret; + goto unwind; + } + ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_OPEN, + client3_3_open_cbk, NULL, + (xdrproc_t)xdr_gfs3_open_req); + if (ret) { + gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); + } + + 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; + 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; + client_payload_t cp; + + if (!frame || !this || !data) + goto unwind; + + args = data; + conf = this->private; + + ret = client_pre_readv(this, &req, args->fd, args->size, args->offset, + args->flags, args->xdata); + if (ret) { + op_errno = -ret; + goto unwind; + } + + ret = client_fd_fop_prepare_local(frame, args->fd, req.fd); + if (ret) { + op_errno = -ret; + goto unwind; + } + local = frame->local; + + 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; + } + + rsp_vec.iov_base = iobuf_ptr(rsp_iobuf); + rsp_vec.iov_len = iobuf_pagesize(rsp_iobuf); + + iobref_add(rsp_iobref, rsp_iobuf); + iobuf_unref(rsp_iobuf); + rsp_iobuf = NULL; + + if (args->size > rsp_vec.iov_len) { + gf_smsg(this->name, GF_LOG_WARNING, ENOMEM, PC_MSG_BIGGER_SIZE, + "read-size=%lu", (unsigned long)args->size, "iobuf size=%lu", + (unsigned long)rsp_vec.iov_len, NULL); + op_errno = EINVAL; + goto unwind; + } + + local->iobref = rsp_iobref; + rsp_iobref = NULL; + + memset(&cp, 0, sizeof(client_payload_t)); + cp.rsp_payload = &rsp_vec; + cp.rsp_payload_cnt = 1; + cp.rsp_iobref = local->iobref; + ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_READ, + client3_3_readv_cbk, &cp, + (xdrproc_t)xdr_gfs3_read_req); + if (ret) { + // unwind is done in the cbk + gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); + } + + 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; + clnt_conf_t *conf = NULL; + gfs3_write_req req = { + { + 0, + }, + }; + int op_errno = ESTALE; + int ret = 0; + client_payload_t cp; + + if (!frame || !this || !data) + goto unwind; + + args = data; + conf = this->private; + + ret = client_pre_writev(this, &req, args->fd, args->size, args->offset, + args->flags, &args->xdata); + + if (ret) { + op_errno = -ret; + goto unwind; + } + + ret = client_fd_fop_prepare_local(frame, args->fd, req.fd); + if (ret) { + op_errno = -ret; + goto unwind; + } + + memset(&cp, 0, sizeof(client_payload_t)); + cp.iobref = args->iobref; + cp.payload = args->vector; + cp.payload_cnt = args->count; + ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_WRITE, + client3_3_writev_cbk, &cp, + (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_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); + } + + 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, + }, + }; + 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; + + local = mem_get0(this->local_pool); + if (!local) { + op_errno = ENOMEM; + goto unwind; + } + + frame->local = local; + + local->fd = fd_ref(args->fd); + local->owner = frame->root->lk_owner; + ret = client_pre_flush(this, &req, args->fd, args->xdata); + if (ret) { + op_errno = -ret; + if (op_errno == EBADF) { + ret = delete_granted_locks_owner(local->fd, &local->owner); + gf_msg_trace(this->name, 0, + "deleting locks of owner (%s) returned %d", + lkowner_utoa(&local->owner), ret); + } + + goto unwind; + } + + ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_FLUSH, + client3_3_flush_cbk, NULL, + (xdrproc_t)xdr_gfs3_flush_req); + if (ret) { + gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); + } + + 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, + }, + }; + clnt_conf_t *conf = NULL; + int op_errno = 0; + int ret = 0; + + if (!frame || !this || !data) + goto unwind; + + args = data; + conf = this->private; + + ret = client_pre_fsync(this, &req, args->fd, args->flags, args->xdata); + if (ret) { + op_errno = -ret; + goto unwind; + } + ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_FSYNC, + client3_3_fsync_cbk, NULL, + (xdrproc_t)xdr_gfs3_fsync_req); + if (ret) { + gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); + } + + 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, + }, + }; + clnt_conf_t *conf = NULL; + int op_errno = ESTALE; + int ret = 0; + + if (!frame || !this || !data) + goto unwind; + + args = data; + conf = this->private; + + ret = client_pre_fstat(this, &req, args->fd, args->xdata); + + if (ret) { + op_errno = -ret; + goto unwind; + } + + ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_FSTAT, + client3_3_fstat_cbk, NULL, + (xdrproc_t)xdr_gfs3_fstat_req); + if (ret) { + gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); + } + + 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; + conf = this->private; + + local = mem_get0(this->local_pool); + if (!local) { + op_errno = ENOMEM; + goto unwind; + } + frame->local = local; + + local->fd = fd_ref(args->fd); + loc_copy(&local->loc, args->loc); + loc_path(&local->loc, NULL); + + ret = client_pre_opendir(this, &req, args->loc, args->fd, args->xdata); + if (ret) { + op_errno = -ret; + goto unwind; + } + ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_OPENDIR, + client3_3_opendir_cbk, NULL, + (xdrproc_t)xdr_gfs3_opendir_req); + if (ret) { + gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); + } + + 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; + 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; + + ret = client_pre_fsyncdir(this, &req, args->fd, args->flags, args->xdata); + if (ret) { + op_errno = -ret; + goto unwind; + } + ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_FSYNCDIR, + client3_3_fsyncdir_cbk, NULL, + (xdrproc_t)xdr_gfs3_fsyncdir_req); + if (ret) { + gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); + } + + 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; + + conf = this->private; + + ret = client_pre_statfs(this, &req, args->loc, args->xdata); + if (ret) { + op_errno = -ret; + goto unwind; + } + ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_STATFS, + client3_3_statfs_cbk, NULL, + (xdrproc_t)xdr_gfs3_statfs_req); + if (ret) { + gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); + } + + 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; + conf = this->private; + + ret = client_pre_setxattr(this, &req, args->loc, args->xattr, args->flags, + args->xdata); + if (ret) { + op_errno = -ret; + goto unwind; + } + ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_SETXATTR, + client3_3_setxattr_cbk, NULL, + (xdrproc_t)xdr_gfs3_setxattr_req); + if (ret) { + gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); + } + 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; + 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; + + ret = client_pre_fsetxattr(this, &req, args->fd, args->flags, args->xattr, + args->xdata); + if (ret) { + op_errno = -ret; + goto unwind; + } + ret = client_submit_request(this, &req, frame, conf->fops, + GFS3_OP_FSETXATTR, client3_3_fsetxattr_cbk, + NULL, (xdrproc_t)xdr_gfs3_fsetxattr_req); + if (ret) { + gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); + } + + 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; + 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}, + }; + client_payload_t cp; + + if (!frame || !this || !data) + goto unwind; + + args = data; + conf = this->private; + + 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; + } + + rsphdr = &vector[0]; + rsphdr->iov_base = iobuf_ptr(rsp_iobuf); + rsphdr->iov_len = iobuf_pagesize(rsp_iobuf); + ; + count = 1; + local->iobref = rsp_iobref; + iobref_add(rsp_iobref, rsp_iobuf); + iobuf_unref(rsp_iobuf); + rsp_iobuf = NULL; + rsp_iobref = NULL; + + ret = client_pre_fgetxattr(this, &req, args->fd, args->name, args->xdata); + if (ret) { + op_errno = -ret; + goto unwind; + } + + memset(&cp, 0, sizeof(client_payload_t)); + cp.rsphdr = rsphdr; + cp.rsphdr_cnt = count; + cp.rsp_iobref = local->iobref; + ret = client_submit_request(this, &req, frame, conf->fops, + GFS3_OP_FGETXATTR, client3_3_fgetxattr_cbk, &cp, + (xdrproc_t)xdr_gfs3_fgetxattr_req); + if (ret) { + gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); + } + + GF_FREE(req.xdata.xdata_val); + + return 0; +unwind: + CLIENT_STACK_UNWIND(fgetxattr, frame, -1, op_errno, NULL, NULL); + + 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}, + }; + client_payload_t cp; + + if (!frame || !this || !data) { + op_errno = 0; + goto unwind; + } + + args = data; + + local = mem_get0(this->local_pool); + if (!local) { + op_errno = ENOMEM; + goto unwind; + } + + frame->local = local; + + loc_copy(&local->loc, args->loc); + loc_path(&local->loc, NULL); + + if (args->name) + local->name = gf_strdup(args->name); + + 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; + } + + rsphdr = &vector[0]; + rsphdr->iov_base = iobuf_ptr(rsp_iobuf); + rsphdr->iov_len = iobuf_pagesize(rsp_iobuf); + count = 1; + local->iobref = rsp_iobref; + iobref_add(rsp_iobref, rsp_iobuf); + iobuf_unref(rsp_iobuf); + rsp_iobuf = NULL; + rsp_iobref = NULL; + + conf = this->private; + + if (args && args->name) { + if (is_client_dump_locks_cmd((char *)args->name)) { + dict = dict_new(); + + if (!dict) { + op_errno = ENOMEM; + goto unwind; + } + + ret = client_dump_locks((char *)args->name, args->loc->inode, dict); + if (ret) { + gf_smsg(this->name, GF_LOG_WARNING, EINVAL, + PC_MSG_CLIENT_DUMP_LOCKS_FAILED, NULL); + op_errno = ENOMEM; + goto unwind; + } + + GF_ASSERT(dict); + op_ret = 0; + op_errno = 0; + goto unwind; + } + } + + ret = client_pre_getxattr(this, &req, args->loc, args->name, args->xdata); + if (ret) { + op_errno = -ret; + goto unwind; + } + + memset(&cp, 0, sizeof(client_payload_t)); + cp.rsphdr = rsphdr; + cp.rsphdr_cnt = count; + cp.rsp_iobref = local->iobref; + ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_GETXATTR, + client3_3_getxattr_cbk, &cp, + (xdrproc_t)xdr_gfs3_getxattr_req); + if (ret) { + gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); + } + + GF_FREE(req.xdata.xdata_val); + + return 0; +unwind: + if (rsp_iobref) + iobref_unref(rsp_iobref); + + CLIENT_STACK_UNWIND(getxattr, frame, op_ret, op_errno, dict, NULL); + + if (dict) { + dict_unref(dict); + } + + 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}, + }; + client_payload_t cp; + + 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; + } + + rsphdr = &vector[0]; + rsphdr->iov_base = iobuf_ptr(rsp_iobuf); + rsphdr->iov_len = iobuf_pagesize(rsp_iobuf); + count = 1; + local->iobref = rsp_iobref; + iobref_add(rsp_iobref, rsp_iobuf); + iobuf_unref(rsp_iobuf); + rsp_iobuf = NULL; + rsp_iobref = NULL; + + loc_copy(&local->loc, args->loc); + loc_path(&local->loc, NULL); + conf = this->private; + + ret = client_pre_xattrop(this, &req, args->loc, args->xattr, args->flags, + args->xdata); + if (ret) { + op_errno = -ret; + goto unwind; + } + + memset(&cp, 0, sizeof(client_payload_t)); + cp.rsphdr = rsphdr; + cp.rsphdr_cnt = count; + cp.rsp_iobref = local->iobref; + ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_XATTROP, + client3_3_xattrop_cbk, &cp, + (xdrproc_t)xdr_gfs3_xattrop_req); + if (ret) { + gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); + } + + GF_FREE(req.dict.dict_val); + + GF_FREE(req.xdata.xdata_val); + + return 0; +unwind: + CLIENT_STACK_UNWIND(xattrop, frame, -1, op_errno, NULL, NULL); + + GF_FREE(req.dict.dict_val); + + 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; + 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}, + }; + client_payload_t cp; + + if (!frame || !this || !data) + goto unwind; + + args = data; + conf = this->private; + + ret = client_pre_fxattrop(this, &req, args->fd, args->xattr, args->flags, + args->xdata); + if (ret) { + op_errno = -ret; + goto unwind; + } + ret = client_fd_fop_prepare_local(frame, args->fd, req.fd); + if (ret) { + op_errno = -ret; + goto unwind; + } + + local = frame->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; + } + + rsphdr = &vector[0]; + rsphdr->iov_base = iobuf_ptr(rsp_iobuf); + rsphdr->iov_len = iobuf_pagesize(rsp_iobuf); + count = 1; + local->iobref = rsp_iobref; + iobref_add(rsp_iobref, rsp_iobuf); + iobuf_unref(rsp_iobuf); + rsp_iobuf = NULL; + rsp_iobref = NULL; + + memset(&cp, 0, sizeof(client_payload_t)); + cp.rsphdr = rsphdr; + cp.rsphdr_cnt = count; + cp.rsp_iobref = local->iobref; + ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_FXATTROP, + client3_3_fxattrop_cbk, &cp, + (xdrproc_t)xdr_gfs3_fxattrop_req); + if (ret) { + gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); + } + + 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); + + 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; + conf = this->private; + + ret = client_pre_removexattr(this, &req, args->loc, args->name, + args->xdata); + if (ret) { + op_errno = -ret; + goto unwind; + } + ret = client_submit_request(this, &req, frame, conf->fops, + GFS3_OP_REMOVEXATTR, client3_3_removexattr_cbk, + NULL, (xdrproc_t)xdr_gfs3_removexattr_req); + if (ret) { + gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); + } + + 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; + int op_errno = ESTALE; + + if (!frame || !this || !data) + goto unwind; + + args = data; + + conf = this->private; + + ret = client_pre_fremovexattr(this, &req, args->fd, args->name, + args->xdata); + if (ret) { + op_errno = -ret; + goto unwind; + } + ret = client_submit_request( + this, &req, frame, conf->fops, GFS3_OP_FREMOVEXATTR, + client3_3_fremovexattr_cbk, NULL, (xdrproc_t)xdr_gfs3_fremovexattr_req); + if (ret) { + gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); + } + + 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_lease(call_frame_t *frame, xlator_t *this, void *data) +{ + clnt_args_t *args = NULL; + gfs3_lease_req req = { + { + 0, + }, + }; + clnt_conf_t *conf = NULL; + int op_errno = ESTALE; + int ret = 0; + + GF_VALIDATE_OR_GOTO("client", this, unwind); + GF_VALIDATE_OR_GOTO(this->name, frame, unwind); + GF_VALIDATE_OR_GOTO(this->name, data, unwind); + + args = data; + conf = this->private; + + ret = client_pre_lease(this, &req, args->loc, args->lease, args->xdata); + if (ret < 0) { + op_errno = -ret; + goto unwind; + } + ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_LEASE, + client3_3_lease_cbk, NULL, + (xdrproc_t)xdr_gfs3_lease_req); + if (ret) { + gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); + } + + GF_FREE(req.xdata.xdata_val); + + return 0; +unwind: + CLIENT_STACK_UNWIND(lease, frame, -1, op_errno, NULL, 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; + 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; + } + frame->local = local; + + ret = client_cmd_to_gf_cmd(args->cmd, &gf_cmd); + if (ret) { + op_errno = EINVAL; + gf_smsg(this->name, GF_LOG_WARNING, EINVAL, PC_MSG_UNKNOWN_CMD, + "gf_cmd=%d", gf_cmd, NULL); + goto unwind; + } + + local->owner = frame->root->lk_owner; + local->cmd = args->cmd; + local->fd = fd_ref(args->fd); + + ret = client_pre_lk(this, &req, args->cmd, args->flock, args->fd, + args->xdata); + if (ret) { + op_errno = -ret; + + if ((op_errno == EBADF) && (args->flock->l_type == F_UNLCK) && + client_is_setlk(local->cmd)) { + client_add_lock_for_recovery(local->fd, args->flock, &local->owner, + local->cmd); + } + + goto unwind; + } + + ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_LK, + client3_3_lk_cbk, NULL, + (xdrproc_t)xdr_gfs3_lk_req); + if (ret) { + gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); + } + + 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; + int op_errno = ESTALE; + + if (!frame || !this || !data) + goto unwind; + + args = data; + conf = this->private; + + ret = client_pre_inodelk(this, &req, args->loc, args->cmd, args->flock, + args->volume, args->xdata); + if (ret) { + op_errno = -ret; + goto unwind; + } + ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_INODELK, + client3_3_inodelk_cbk, NULL, + (xdrproc_t)xdr_gfs3_inodelk_req); + if (ret) { + gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); + } + + 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, + }, + }; + clnt_conf_t *conf = NULL; + int op_errno = ESTALE; + int ret = 0; + + if (!frame || !this || !data) + goto unwind; + + args = data; + conf = this->private; + + ret = client_pre_finodelk(this, &req, args->fd, args->cmd, args->flock, + args->volume, args->xdata); + if (ret) { + op_errno = -ret; + goto unwind; + } + + ret = client_fd_fop_prepare_local(frame, args->fd, req.fd); + if (ret) { + op_errno = -ret; + goto unwind; + } + + ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_FINODELK, + client3_3_finodelk_cbk, NULL, + (xdrproc_t)xdr_gfs3_finodelk_req); + if (ret) { + gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); + } + + 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; + + conf = this->private; + + ret = client_pre_entrylk(this, &req, args->loc, args->cmd_entrylk, + args->type, args->volume, args->basename, + args->xdata); + if (ret) { + op_errno = -ret; + goto unwind; + } + + ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_ENTRYLK, + client3_3_entrylk_cbk, NULL, + (xdrproc_t)xdr_gfs3_entrylk_req); + if (ret) { + gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); + } + + 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, + }, + }; + clnt_conf_t *conf = NULL; + int op_errno = ESTALE; + int ret = 0; + + if (!frame || !this || !data) + goto unwind; + + args = data; + conf = this->private; + + ret = client_pre_fentrylk(this, &req, args->fd, args->cmd_entrylk, + args->type, args->volume, args->basename, + args->xdata); + if (ret) { + op_errno = -ret; + goto unwind; + } + ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_FENTRYLK, + client3_3_fentrylk_cbk, NULL, + (xdrproc_t)xdr_gfs3_fentrylk_req); + if (ret) { + gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); + } + + 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; + 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; + + ret = client_pre_rchecksum(this, &req, args->fd, args->len, args->offset, + args->xdata); + if (ret) { + op_errno = -ret; + goto unwind; + } + ret = client_submit_request(this, &req, frame, conf->fops, + GFS3_OP_RCHECKSUM, client3_3_rchecksum_cbk, + NULL, (xdrproc_t)xdr_gfs3_rchecksum_req); + if (ret) { + gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); + } + + 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; + client_payload_t cp; + + if (!frame || !this || !data) + goto unwind; + + args = data; + conf = this->private; + + readdir_rsp_size = xdr_sizeof((xdrproc_t)xdr_gfs3_readdir_rsp, &rsp) + + args->size; + + local = mem_get0(this->local_pool); + if (!local) { + op_errno = ENOMEM; + goto unwind; + } + frame->local = local; + + local->cmd = remote_fd; + + if ((readdir_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); + + rsphdr = &vector[0]; + rsphdr->iov_base = iobuf_ptr(rsp_iobuf); + rsphdr->iov_len = iobuf_pagesize(rsp_iobuf); + count = 1; + local->iobref = rsp_iobref; + iobuf_unref(rsp_iobuf); + rsp_iobuf = NULL; + rsp_iobref = NULL; + } + + ret = client_pre_readdir(this, &req, args->fd, args->size, args->offset, + args->xdata); + if (ret) { + op_errno = -ret; + goto unwind; + } + + memset(&cp, 0, sizeof(client_payload_t)); + cp.rsphdr = rsphdr; + cp.rsphdr_cnt = count; + cp.rsp_iobref = rsp_iobref; + ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_READDIR, + client3_3_readdir_cbk, &cp, + (xdrproc_t)xdr_gfs3_readdir_req); + + if (ret) { + gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); + } + + GF_FREE(req.xdata.xdata_val); + + return 0; + +unwind: + if (rsp_iobref) + iobref_unref(rsp_iobref); + + 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, + }; + 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; + client_payload_t cp; + + if (!frame || !this || !data) + goto unwind; + + args = data; + conf = this->private; + + local = mem_get0(this->local_pool); + if (!local) { + op_errno = ENOMEM; + goto unwind; + } + frame->local = local; + + ret = client_pre_readdirp(this, &req, args->fd, args->size, args->offset, + args->xdata); + + if (ret) { + op_errno = -ret; + goto unwind; + } + + readdirp_rsp_size = xdr_sizeof((xdrproc_t)xdr_gfs3_readdirp_rsp, &rsp) + + args->size; + + 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; + } + + rsphdr = &vector[0]; + rsphdr->iov_base = iobuf_ptr(rsp_iobuf); + rsphdr->iov_len = iobuf_pagesize(rsp_iobuf); + count = 1; + local->iobref = rsp_iobref; + iobref_add(rsp_iobref, rsp_iobuf); + iobuf_unref(rsp_iobuf); + rsp_iobuf = NULL; + rsp_iobref = NULL; + } + + local->fd = fd_ref(args->fd); + + memset(&cp, 0, sizeof(client_payload_t)); + cp.rsphdr = rsphdr; + cp.rsphdr_cnt = count; + cp.rsp_iobref = rsp_iobref; + ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_READDIRP, + client3_3_readdirp_cbk, &cp, + (xdrproc_t)xdr_gfs3_readdirp_req); + if (ret) { + gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); + } + + GF_FREE(req.dict.dict_val); + + return 0; +unwind: + if (rsp_iobref) + iobref_unref(rsp_iobref); + + 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; + conf = this->private; + + ret = client_pre_setattr(this, &req, args->loc, args->valid, args->stbuf, + args->xdata); + + if (ret) { + op_errno = -ret; + goto unwind; + } + + ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_SETATTR, + client3_3_setattr_cbk, NULL, + (xdrproc_t)xdr_gfs3_setattr_req); + if (ret) { + gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); + } + + 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; + 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; + + ret = client_pre_fsetattr(this, &req, args->fd, args->valid, args->stbuf, + args->xdata); + + if (ret) { + op_errno = -ret; + goto unwind; + } + ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_FSETATTR, + client3_3_fsetattr_cbk, NULL, + (xdrproc_t)xdr_gfs3_fsetattr_req); + if (ret) { + gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); + } + + 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; + 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; + + ret = client_pre_fallocate(this, &req, args->fd, args->flags, args->offset, + args->size, args->xdata); + if (ret) { + op_errno = -ret; + goto unwind; + } + + ret = client_submit_request(this, &req, frame, conf->fops, + GFS3_OP_FALLOCATE, client3_3_fallocate_cbk, + NULL, (xdrproc_t)xdr_gfs3_fallocate_req); + if (ret) { + gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); + } + + 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; + 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; + + ret = client_pre_discard(this, &req, args->fd, args->offset, args->size, + args->xdata); + if (ret) { + op_errno = -ret; + goto unwind; + } + + ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_DISCARD, + client3_3_discard_cbk, NULL, + (xdrproc_t)xdr_gfs3_discard_req); + if (ret) + gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); + + 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; + clnt_conf_t *conf = NULL; + gfs3_zerofill_req req = { + {0}, + }; + int op_errno = ESTALE; + int ret = 0; + + GF_ASSERT(frame); + + if (!this || !data) + goto unwind; + + args = data; + conf = this->private; + + ret = client_pre_zerofill(this, &req, args->fd, args->offset, args->size, + args->xdata); + if (ret) { + op_errno = -ret; + goto unwind; + } + + ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_ZEROFILL, + client3_3_zerofill_cbk, NULL, + (xdrproc_t)xdr_gfs3_zerofill_req); + if (ret) + gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); + + 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; +} + +int32_t +client3_3_ipc(call_frame_t *frame, xlator_t *this, void *data) +{ + clnt_args_t *args = NULL; + clnt_conf_t *conf = NULL; + gfs3_ipc_req req = { + 0, + }; + int op_errno = ESTALE; + int ret = 0; + + GF_ASSERT(frame); + + if (!this || !data) + goto unwind; + + args = data; + conf = this->private; + + ret = client_pre_ipc(this, &req, args->cmd, args->xdata); + + if (ret) { + op_errno = -ret; + goto unwind; + } + + ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_IPC, + client3_3_ipc_cbk, NULL, + (xdrproc_t)xdr_gfs3_ipc_req); + if (ret) + gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); + + GF_FREE(req.xdata.xdata_val); + + return 0; +unwind: + CLIENT_STACK_UNWIND(ipc, frame, -1, op_errno, NULL); + GF_FREE(req.xdata.xdata_val); + + return 0; +} + +int32_t +client3_3_seek(call_frame_t *frame, xlator_t *this, void *data) +{ + clnt_args_t *args = NULL; + clnt_conf_t *conf = NULL; + struct gfs3_seek_req req = { + { + 0, + }, + }; + int op_errno = ESTALE; + int ret = 0; + + GF_ASSERT(frame); + + if (!this || !data) + goto unwind; + + args = data; + conf = this->private; + + ret = client_pre_seek(this, &req, args->fd, args->offset, args->what, + args->xdata); + if (ret) { + op_errno = -ret; + goto unwind; + } + + ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_SEEK, + client3_3_seek_cbk, NULL, + (xdrproc_t)xdr_gfs3_seek_req); + if (ret) + gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); + + GF_FREE(req.xdata.xdata_val); + + return 0; +unwind: + CLIENT_STACK_UNWIND(ipc, frame, -1, op_errno, NULL); + GF_FREE(req.xdata.xdata_val); + + return 0; +} + +static int32_t +client3_3_getactivelk(call_frame_t *frame, xlator_t *this, void *data) +{ + clnt_conf_t *conf = NULL; + clnt_args_t *args = NULL; + gfs3_getactivelk_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 (!gf_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, + !gf_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_GETACTIVELK, client3_3_getactivelk_cbk, + NULL, (xdrproc_t)xdr_gfs3_getactivelk_req); + if (ret) { + gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); + } + + GF_FREE(req.xdata.xdata_val); + + return 0; +unwind: + CLIENT_STACK_UNWIND(getactivelk, frame, -1, op_errno, NULL, NULL); + + GF_FREE(req.xdata.xdata_val); + + return 0; +} + +static int32_t +client3_3_setactivelk(call_frame_t *frame, xlator_t *this, void *data) +{ + clnt_conf_t *conf = NULL; + clnt_args_t *args = NULL; + gfs3_setactivelk_req req = { + { + 0, + }, + }; + int ret = 0; + int op_errno = ESTALE; + + if (!frame || !this || !data) + goto unwind; + + args = data; + if (!(args->loc && args->loc->inode && args->locklist)) + goto unwind; + + if (!gf_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, + !gf_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 = serialize_req_locklist(args->locklist, &req); + + if (ret) + goto unwind; + + ret = client_submit_request(this, &req, frame, conf->fops, + GFS3_OP_SETACTIVELK, client3_3_setactivelk_cbk, + NULL, (xdrproc_t)xdr_gfs3_setactivelk_req); + if (ret) { + gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); + } + + clnt_setactivelk_req_cleanup(&req); + + GF_FREE(req.xdata.xdata_val); + + return 0; + +unwind: + + CLIENT_STACK_UNWIND(setactivelk, frame, -1, op_errno, NULL); + + GF_FREE(req.xdata.xdata_val); + + clnt_setactivelk_req_cleanup(&req); + + 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}, + [GF_FOP_IPC] = {"IPC", client3_3_ipc}, + [GF_FOP_SEEK] = {"SEEK", client3_3_seek}, + [GF_FOP_LEASE] = {"LEASE", client3_3_lease}, + [GF_FOP_GETACTIVELK] = {"GETACTIVELK", client3_3_getactivelk}, + [GF_FOP_SETACTIVELK] = {"SETACTIVELK", client3_3_setactivelk}, + [GF_FOP_COMPOUND] = {"COMPOUND", NULL}, +}; + +/* 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", + [GFS3_OP_IPC] = "IPC", + [GFS3_OP_SEEK] = "SEEK", + [GFS3_OP_LEASE] = "LEASE", + [GFS3_OP_GETACTIVELK] = "GETACTIVELK", + [GFS3_OP_SETACTIVELK] = "SETACTIVELK", + [GFS3_OP_COMPOUND] = "COMPOUND", +}; + +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-rpc-fops_v2.c b/xlators/protocol/client/src/client-rpc-fops_v2.c new file mode 100644 index 00000000000..0d80d4e8efb --- /dev/null +++ b/xlators/protocol/client/src/client-rpc-fops_v2.c @@ -0,0 +1,6177 @@ +/* + 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 "client.h" +#include "rpc-common-xdr.h" +#include "glusterfs4-xdr.h" +#include "glusterfs3.h" +#include <glusterfs/compat-errno.h> +#include "client-messages.h" +#include <glusterfs/defaults.h> +#include "client-common.h" + +extern int32_t +client3_getspec(call_frame_t *frame, xlator_t *this, void *data); +extern int32_t +client3_3_getxattr(call_frame_t *frame, xlator_t *this, void *data); + +int +client4_0_symlink_cbk(struct rpc_req *req, struct iovec *iov, int count, + void *myframe) +{ + gfx_common_3iatt_rsp rsp = { + 0, + }; + call_frame_t *frame = NULL; + 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_gfx_common_3iatt_rsp); + if (ret < 0) { + gf_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, + NULL); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; + } + + ret = client_post_common_3iatt(this, &rsp, &stbuf, &preparent, &postparent, + &xdata); + +out: + if (rsp.op_ret == -1) { + if (GF_IGNORE_IF_GSYNCD_SAFE_ERROR(frame, rsp.op_errno)) { + /* no need to print the gfid, because it will be null, + * since symlink operation failed. + */ + gf_smsg(this->name, GF_LOG_WARNING, gf_error_to_errno(rsp.op_errno), + PC_MSG_REMOTE_OP_FAILED, "source=%s", local->loc.path, + "target=%s", local->loc2.path, NULL); + } + } + + CLIENT_STACK_UNWIND(symlink, frame, rsp.op_ret, + gf_error_to_errno(rsp.op_errno), inode, &stbuf, + &preparent, &postparent, xdata); + + if (xdata) + dict_unref(xdata); + + return 0; +} + +int +client4_0_mknod_cbk(struct rpc_req *req, struct iovec *iov, int count, + void *myframe) +{ + gfx_common_3iatt_rsp rsp = { + 0, + }; + call_frame_t *frame = NULL; + 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_gfx_common_3iatt_rsp); + if (ret < 0) { + gf_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, + NULL); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; + } + + ret = client_post_common_3iatt(this, &rsp, &stbuf, &preparent, &postparent, + &xdata); + +out: + if (rsp.op_ret == -1 && + GF_IGNORE_IF_GSYNCD_SAFE_ERROR(frame, rsp.op_errno)) { + gf_smsg(this->name, + fop_log_level(GF_FOP_MKNOD, gf_error_to_errno(rsp.op_errno)), + gf_error_to_errno(rsp.op_errno), PC_MSG_REMOTE_OP_FAILED, + "path=%s", local->loc.path, NULL); + } + + CLIENT_STACK_UNWIND(mknod, frame, rsp.op_ret, + gf_error_to_errno(rsp.op_errno), inode, &stbuf, + &preparent, &postparent, xdata); + + if (xdata) + dict_unref(xdata); + + return 0; +} + +int +client4_0_mkdir_cbk(struct rpc_req *req, struct iovec *iov, int count, + void *myframe) +{ + gfx_common_3iatt_rsp rsp = { + 0, + }; + call_frame_t *frame = NULL; + 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_gfx_common_3iatt_rsp); + if (ret < 0) { + gf_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, + NULL); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; + } + + ret = client_post_common_3iatt(this, &rsp, &stbuf, &preparent, &postparent, + &xdata); + +out: + if (rsp.op_ret == -1 && + GF_IGNORE_IF_GSYNCD_SAFE_ERROR(frame, rsp.op_errno)) { + gf_smsg(this->name, + fop_log_level(GF_FOP_MKDIR, gf_error_to_errno(rsp.op_errno)), + gf_error_to_errno(rsp.op_errno), PC_MSG_REMOTE_OP_FAILED, + "path=%s", local->loc.path, NULL); + } + + CLIENT_STACK_UNWIND(mkdir, frame, rsp.op_ret, + gf_error_to_errno(rsp.op_errno), inode, &stbuf, + &preparent, &postparent, xdata); + + if (xdata) + dict_unref(xdata); + + return 0; +} + +int +client4_0_open_cbk(struct rpc_req *req, struct iovec *iov, int count, + void *myframe) +{ + clnt_local_t *local = NULL; + call_frame_t *frame = NULL; + fd_t *fd = NULL; + int ret = 0; + gfx_open_rsp rsp = { + 0, + }; + xlator_t *this = NULL; + dict_t *xdata = NULL; + + this = THIS; + + frame = myframe; + local = frame->local; + + 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_gfx_open_rsp); + if (ret < 0) { + gf_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, + NULL); + 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; + } + } + + ret = xdr_to_dict(&rsp.xdata, &xdata); +out: + if (rsp.op_ret == -1) { + gf_smsg(this->name, + fop_log_level(GF_FOP_OPEN, gf_error_to_errno(rsp.op_errno)), + gf_error_to_errno(rsp.op_errno), PC_MSG_REMOTE_OP_FAILED, + "path=%s", local->loc.path, "gfid=%s", + loc_gfid_utoa(&local->loc), NULL); + } + + CLIENT_STACK_UNWIND(open, frame, rsp.op_ret, + gf_error_to_errno(rsp.op_errno), fd, xdata); + + if (xdata) + dict_unref(xdata); + + return 0; +} + +int +client4_0_stat_cbk(struct rpc_req *req, struct iovec *iov, int count, + void *myframe) +{ + gfx_common_iatt_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_gfx_common_iatt_rsp); + if (ret < 0) { + gf_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, + NULL); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; + } + + ret = client_post_common_iatt(this, &rsp, &iatt, &xdata); +out: + if (rsp.op_ret == -1) { + /* stale filehandles are possible during normal operations, no + * need to spam the logs with these */ + if (rsp.op_errno == ESTALE) { + gf_msg_debug(this->name, 0, "remote operation failed: %s", + strerror(gf_error_to_errno(rsp.op_errno))); + } else { + gf_smsg(this->name, GF_LOG_WARNING, gf_error_to_errno(rsp.op_errno), + PC_MSG_REMOTE_OP_FAILED, NULL); + } + } + + CLIENT_STACK_UNWIND(stat, frame, rsp.op_ret, + gf_error_to_errno(rsp.op_errno), &iatt, xdata); + + if (xdata) + dict_unref(xdata); + + return 0; +} + +int +client4_0_readlink_cbk(struct rpc_req *req, struct iovec *iov, int count, + void *myframe) +{ + gfx_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_gfx_readlink_rsp); + if (ret < 0) { + gf_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, + NULL); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; + } + gfx_stat_to_iattx(&rsp.buf, &iatt); + + ret = xdr_to_dict(&rsp.xdata, &xdata); +out: + if (rsp.op_ret == -1) { + if (gf_error_to_errno(rsp.op_errno) == ENOENT) { + gf_msg_debug(this->name, 0, + "remote operation failed:" + " %s", + strerror(gf_error_to_errno(rsp.op_errno))); + } else { + gf_smsg(this->name, GF_LOG_WARNING, gf_error_to_errno(rsp.op_errno), + PC_MSG_REMOTE_OP_FAILED, NULL); + } + } + + 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); + + if (xdata) + dict_unref(xdata); + + return 0; +} + +int +client4_0_unlink_cbk(struct rpc_req *req, struct iovec *iov, int count, + void *myframe) +{ + call_frame_t *frame = NULL; + gfx_common_2iatt_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_gfx_common_2iatt_rsp); + if (ret < 0) { + gf_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, + NULL); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; + } + + ret = client_post_common_2iatt(this, &rsp, &preparent, &postparent, &xdata); + +out: + if (rsp.op_ret == -1) { + if (gf_error_to_errno(rsp.op_errno) == ENOENT) { + gf_msg_debug(this->name, 0, + "remote operation failed:" + " %s", + strerror(gf_error_to_errno(rsp.op_errno))); + } else { + gf_smsg(this->name, GF_LOG_WARNING, gf_error_to_errno(rsp.op_errno), + PC_MSG_REMOTE_OP_FAILED, NULL); + } + } + + CLIENT_STACK_UNWIND(unlink, frame, rsp.op_ret, + gf_error_to_errno(rsp.op_errno), &preparent, + &postparent, xdata); + + if (xdata) + dict_unref(xdata); + + return 0; +} + +int +client4_0_rmdir_cbk(struct rpc_req *req, struct iovec *iov, int count, + void *myframe) +{ + gfx_common_2iatt_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_gfx_common_2iatt_rsp); + if (ret < 0) { + gf_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, + NULL); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; + } + + ret = client_post_common_2iatt(this, &rsp, &preparent, &postparent, &xdata); + +out: + if (rsp.op_ret == -1) { + if (GF_IGNORE_IF_GSYNCD_SAFE_ERROR(frame, rsp.op_errno)) { + gf_smsg(this->name, GF_LOG_WARNING, gf_error_to_errno(rsp.op_errno), + PC_MSG_REMOTE_OP_FAILED, NULL); + } + } + CLIENT_STACK_UNWIND(rmdir, frame, rsp.op_ret, + gf_error_to_errno(rsp.op_errno), &preparent, + &postparent, xdata); + + if (xdata) + dict_unref(xdata); + + return 0; +} + +int +client4_0_truncate_cbk(struct rpc_req *req, struct iovec *iov, int count, + void *myframe) +{ + gfx_common_2iatt_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_gfx_common_2iatt_rsp); + if (ret < 0) { + gf_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, + NULL); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; + } + + ret = client_post_common_2iatt(this, &rsp, &prestat, &poststat, &xdata); + +out: + if (rsp.op_ret == -1) { + gf_smsg(this->name, GF_LOG_WARNING, gf_error_to_errno(rsp.op_errno), + PC_MSG_REMOTE_OP_FAILED, NULL); + } + CLIENT_STACK_UNWIND(truncate, frame, rsp.op_ret, + gf_error_to_errno(rsp.op_errno), &prestat, &poststat, + xdata); + + if (xdata) + dict_unref(xdata); + + return 0; +} + +int +client4_0_statfs_cbk(struct rpc_req *req, struct iovec *iov, int count, + void *myframe) +{ + gfx_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_gfx_statfs_rsp); + if (ret < 0) { + gf_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, + NULL); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; + } + + if (-1 != rsp.op_ret) { + gf_statfs_to_statfs(&rsp.statfs, &statfs); + } + ret = xdr_to_dict(&rsp.xdata, &xdata); +out: + if (rsp.op_ret == -1) { + gf_smsg(this->name, GF_LOG_WARNING, gf_error_to_errno(rsp.op_errno), + PC_MSG_REMOTE_OP_FAILED, NULL); + } + CLIENT_STACK_UNWIND(statfs, frame, rsp.op_ret, + gf_error_to_errno(rsp.op_errno), &statfs, xdata); + + if (xdata) + dict_unref(xdata); + + return 0; +} + +int +client4_0_writev_cbk(struct rpc_req *req, struct iovec *iov, int count, + void *myframe) +{ + gfx_common_2iatt_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_gfx_common_2iatt_rsp); + if (ret < 0) { + gf_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, + NULL); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; + } + + ret = client_post_common_2iatt(this, &rsp, &prestat, &poststat, &xdata); + if (ret < 0) + goto out; +out: + if (rsp.op_ret == -1) { + gf_smsg(this->name, GF_LOG_WARNING, gf_error_to_errno(rsp.op_errno), + PC_MSG_REMOTE_OP_FAILED, NULL); + } 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); + + if (xdata) + dict_unref(xdata); + + return 0; +} + +int +client4_0_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; + gfx_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_gfx_common_rsp); + if (ret < 0) { + gf_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, + NULL); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; + } + + if ((rsp.op_ret >= 0 || (rsp.op_errno == ENOTCONN)) && + !fd_is_anonymous(local->fd)) { + /* Delete all saved locks of the owner issuing flush */ + ret = delete_granted_locks_owner(local->fd, &local->owner); + gf_msg_trace(this->name, 0, "deleting locks of owner (%s) returned %d", + lkowner_utoa(&local->owner), ret); + } + + xdr_to_dict(&rsp.xdata, &xdata); + +out: + if (rsp.op_ret == -1) { + gf_smsg(this->name, + fop_log_level(GF_FOP_FLUSH, gf_error_to_errno(rsp.op_errno)), + gf_error_to_errno(rsp.op_errno), PC_MSG_REMOTE_OP_FAILED, NULL); + } + CLIENT_STACK_UNWIND(flush, frame, rsp.op_ret, + gf_error_to_errno(rsp.op_errno), xdata); + + if (xdata) + dict_unref(xdata); + + return 0; +} + +int +client4_0_fsync_cbk(struct rpc_req *req, struct iovec *iov, int count, + void *myframe) +{ + gfx_common_2iatt_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_gfx_common_2iatt_rsp); + if (ret < 0) { + gf_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, + NULL); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; + } + + ret = client_post_common_2iatt(this, &rsp, &prestat, &poststat, &xdata); + if (ret < 0) + goto out; + +out: + if (rsp.op_ret == -1) { + gf_smsg(this->name, GF_LOG_WARNING, gf_error_to_errno(rsp.op_errno), + PC_MSG_REMOTE_OP_FAILED, NULL); + } + CLIENT_STACK_UNWIND(fsync, frame, rsp.op_ret, + gf_error_to_errno(rsp.op_errno), &prestat, &poststat, + xdata); + if (xdata) + dict_unref(xdata); + + return 0; +} + +int +client4_0_setxattr_cbk(struct rpc_req *req, struct iovec *iov, int count, + void *myframe) +{ + call_frame_t *frame = NULL; + gfx_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_gfx_common_rsp); + if (ret < 0) { + gf_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, + NULL); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; + } + + xdr_to_dict(&rsp.xdata, &xdata); +out: + op_errno = gf_error_to_errno(rsp.op_errno); + if (rsp.op_ret == -1) { + if (op_errno == ENOTSUP) { + gf_msg_debug(this->name, 0, + "remote operation failed:" + " %s", + strerror(op_errno)); + } else { + gf_smsg(this->name, GF_LOG_WARNING, op_errno, + PC_MSG_REMOTE_OP_FAILED, NULL); + } + } + + CLIENT_STACK_UNWIND(setxattr, frame, rsp.op_ret, op_errno, xdata); + + if (xdata) + dict_unref(xdata); + + return 0; +} + +int +client4_0_getxattr_cbk(struct rpc_req *req, struct iovec *iov, int count, + void *myframe) +{ + gfx_common_dict_rsp rsp = { + 0, + }; + call_frame_t *frame = NULL; + dict_t *dict = NULL; + int op_errno = EINVAL; + 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_gfx_common_dict_rsp); + if (ret < 0) { + gf_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, + NULL); + rsp.op_ret = -1; + op_errno = EINVAL; + goto out; + } + + op_errno = gf_error_to_errno(rsp.op_errno); + ret = client_post_common_dict(this, &rsp, &dict, &xdata); + if (ret) { + op_errno = -ret; + goto out; + } + +out: + if (rsp.op_ret == -1) { + if ((op_errno == ENOTSUP) || (op_errno == ENODATA) || + (op_errno == ESTALE) || (op_errno == ENOENT)) { + gf_msg_debug(this->name, 0, + "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)"); + } else { + gf_smsg(this->name, GF_LOG_WARNING, op_errno, + PC_MSG_REMOTE_OP_FAILED, "path=%s", local->loc.path, + "gfid=%s", loc_gfid_utoa(&local->loc), "key=%s", + (local->name) ? local->name : "(null)", NULL); + } + } else { + /* This is required as many places, `if (ret)` is checked + for syncop_getxattr() */ + gf_msg_debug(this->name, 0, "resetting op_ret to 0 from %d", + rsp.op_ret); + rsp.op_ret = 0; + } + + CLIENT_STACK_UNWIND(getxattr, frame, rsp.op_ret, op_errno, dict, xdata); + + if (xdata) + dict_unref(xdata); + + if (dict) + dict_unref(dict); + + return 0; +} + +int +client4_0_fgetxattr_cbk(struct rpc_req *req, struct iovec *iov, int count, + void *myframe) +{ + gfx_common_dict_rsp rsp = { + 0, + }; + call_frame_t *frame = NULL; + dict_t *dict = NULL; + int ret = 0; + int op_errno = EINVAL; + xlator_t *this = NULL; + dict_t *xdata = NULL; + + this = THIS; + + frame = myframe; + + if (-1 == req->rpc_status) { + rsp.op_ret = -1; + op_errno = ENOTCONN; + goto out; + } + ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gfx_common_dict_rsp); + if (ret < 0) { + gf_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, + NULL); + rsp.op_ret = -1; + op_errno = EINVAL; + goto out; + } + + op_errno = gf_error_to_errno(rsp.op_errno); + ret = client_post_common_dict(this, &rsp, &dict, &xdata); + if (ret) { + op_errno = -ret; + goto out; + } +out: + if (rsp.op_ret == -1) { + if ((op_errno == ENOTSUP) || (op_errno == ERANGE) || + (op_errno == ENODATA) || (op_errno == ENOENT)) { + gf_msg_debug(this->name, 0, "remote operation failed: %s", + strerror(op_errno)); + } else { + gf_smsg(this->name, GF_LOG_WARNING, op_errno, + PC_MSG_REMOTE_OP_FAILED, NULL); + } + } else { + /* This is required as many places, `if (ret)` is checked + for syncop_fgetxattr() */ + gf_msg_debug(this->name, 0, "resetting op_ret to 0 from %d", + rsp.op_ret); + rsp.op_ret = 0; + } + + CLIENT_STACK_UNWIND(fgetxattr, frame, rsp.op_ret, op_errno, dict, xdata); + + if (xdata) + dict_unref(xdata); + + if (dict) + dict_unref(dict); + + return 0; +} + +int +client4_0_removexattr_cbk(struct rpc_req *req, struct iovec *iov, int count, + void *myframe) +{ + call_frame_t *frame = NULL; + gfx_common_rsp rsp = { + 0, + }; + int ret = 0; + xlator_t *this = NULL; + dict_t *xdata = NULL; + gf_loglevel_t loglevel = GF_LOG_NONE; + + 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_gfx_common_rsp); + if (ret < 0) { + gf_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, + NULL); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; + } + + xdr_to_dict(&rsp.xdata, &xdata); +out: + if (rsp.op_ret == -1) { + /* EPERM/EACCESS is returned some times in case of selinux + attributes, or other system attributes which may not be + possible to remove from an user process is encountered. + we can't treat it as an error */ + if ((ENODATA == rsp.op_errno) || (ENOATTR == rsp.op_errno) || + (EPERM == rsp.op_errno) || (EACCES == rsp.op_errno)) + loglevel = GF_LOG_DEBUG; + else + loglevel = GF_LOG_WARNING; + + gf_smsg(this->name, loglevel, gf_error_to_errno(rsp.op_errno), + PC_MSG_REMOTE_OP_FAILED, NULL); + } + + CLIENT_STACK_UNWIND(removexattr, frame, rsp.op_ret, + gf_error_to_errno(rsp.op_errno), xdata); + + if (xdata) + dict_unref(xdata); + + return 0; +} + +int +client4_0_fremovexattr_cbk(struct rpc_req *req, struct iovec *iov, int count, + void *myframe) +{ + call_frame_t *frame = NULL; + gfx_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_gfx_common_rsp); + if (ret < 0) { + gf_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, + NULL); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; + } + + xdr_to_dict(&rsp.xdata, &xdata); +out: + if (rsp.op_ret == -1) { + gf_smsg(this->name, GF_LOG_WARNING, gf_error_to_errno(rsp.op_errno), + PC_MSG_REMOTE_OP_FAILED, NULL); + } + CLIENT_STACK_UNWIND(fremovexattr, frame, rsp.op_ret, + gf_error_to_errno(rsp.op_errno), xdata); + + if (xdata) + dict_unref(xdata); + + return 0; +} + +int +client4_0_fsyncdir_cbk(struct rpc_req *req, struct iovec *iov, int count, + void *myframe) +{ + call_frame_t *frame = NULL; + gfx_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_gfx_common_rsp); + if (ret < 0) { + gf_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, + NULL); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; + } + + xdr_to_dict(&rsp.xdata, &xdata); + +out: + if (rsp.op_ret == -1) { + gf_smsg(this->name, GF_LOG_WARNING, gf_error_to_errno(rsp.op_errno), + PC_MSG_REMOTE_OP_FAILED, NULL); + } + CLIENT_STACK_UNWIND(fsyncdir, frame, rsp.op_ret, + gf_error_to_errno(rsp.op_errno), xdata); + + if (xdata) + dict_unref(xdata); + + return 0; +} + +int +client4_0_access_cbk(struct rpc_req *req, struct iovec *iov, int count, + void *myframe) +{ + call_frame_t *frame = NULL; + gfx_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_gfx_common_rsp); + if (ret < 0) { + gf_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, + NULL); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; + } + + xdr_to_dict(&rsp.xdata, &xdata); + +out: + if (rsp.op_ret == -1) { + gf_smsg(this->name, GF_LOG_WARNING, gf_error_to_errno(rsp.op_errno), + PC_MSG_REMOTE_OP_FAILED, NULL); + } + CLIENT_STACK_UNWIND(access, frame, rsp.op_ret, + gf_error_to_errno(rsp.op_errno), xdata); + + if (xdata) + dict_unref(xdata); + + return 0; +} + +int +client4_0_ftruncate_cbk(struct rpc_req *req, struct iovec *iov, int count, + void *myframe) +{ + gfx_common_2iatt_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_gfx_common_2iatt_rsp); + if (ret < 0) { + gf_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, + NULL); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; + } + + ret = client_post_common_2iatt(this, &rsp, &prestat, &poststat, &xdata); + +out: + if (rsp.op_ret == -1) { + gf_smsg(this->name, GF_LOG_WARNING, gf_error_to_errno(rsp.op_errno), + PC_MSG_REMOTE_OP_FAILED, NULL); + } + CLIENT_STACK_UNWIND(ftruncate, frame, rsp.op_ret, + gf_error_to_errno(rsp.op_errno), &prestat, &poststat, + xdata); + + if (xdata) + dict_unref(xdata); + + return 0; +} + +int +client4_0_fstat_cbk(struct rpc_req *req, struct iovec *iov, int count, + void *myframe) +{ + gfx_common_iatt_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_gfx_common_iatt_rsp); + if (ret < 0) { + gf_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, + NULL); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; + } + + ret = client_post_common_iatt(this, &rsp, &stat, &xdata); + +out: + if (rsp.op_ret == -1) { + gf_smsg(this->name, GF_LOG_WARNING, gf_error_to_errno(rsp.op_errno), + PC_MSG_REMOTE_OP_FAILED, NULL); + } + CLIENT_STACK_UNWIND(fstat, frame, rsp.op_ret, + gf_error_to_errno(rsp.op_errno), &stat, xdata); + + if (xdata) + dict_unref(xdata); + + return 0; +} + +int +client4_0_inodelk_cbk(struct rpc_req *req, struct iovec *iov, int count, + void *myframe) +{ + call_frame_t *frame = NULL; + gfx_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_gfx_common_rsp); + if (ret < 0) { + gf_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, + NULL); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; + } + + xdr_to_dict(&rsp.xdata, &xdata); +out: + if (rsp.op_ret == -1) { + gf_smsg(this->name, + fop_log_level(GF_FOP_INODELK, gf_error_to_errno(rsp.op_errno)), + gf_error_to_errno(rsp.op_errno), PC_MSG_REMOTE_OP_FAILED, NULL); + } + CLIENT_STACK_UNWIND(inodelk, frame, rsp.op_ret, + gf_error_to_errno(rsp.op_errno), xdata); + + if (xdata) + dict_unref(xdata); + + return 0; +} + +int +client4_0_finodelk_cbk(struct rpc_req *req, struct iovec *iov, int count, + void *myframe) +{ + call_frame_t *frame = NULL; + gfx_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_gfx_common_rsp); + if (ret < 0) { + gf_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, + NULL); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; + } + + xdr_to_dict(&rsp.xdata, &xdata); +out: + if (rsp.op_ret == -1) { + gf_smsg(this->name, + fop_log_level(GF_FOP_FINODELK, gf_error_to_errno(rsp.op_errno)), + gf_error_to_errno(rsp.op_errno), PC_MSG_REMOTE_OP_FAILED, NULL); + } 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); + + if (xdata) + dict_unref(xdata); + + return 0; +} + +int +client4_0_entrylk_cbk(struct rpc_req *req, struct iovec *iov, int count, + void *myframe) +{ + call_frame_t *frame = NULL; + gfx_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_gfx_common_rsp); + if (ret < 0) { + gf_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, + NULL); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; + } + + xdr_to_dict(&rsp.xdata, &xdata); +out: + if (rsp.op_ret == -1) { + gf_smsg(this->name, + fop_log_level(GF_FOP_ENTRYLK, gf_error_to_errno(rsp.op_errno)), + gf_error_to_errno(rsp.op_errno), PC_MSG_REMOTE_OP_FAILED, NULL); + } + + CLIENT_STACK_UNWIND(entrylk, frame, rsp.op_ret, + gf_error_to_errno(rsp.op_errno), xdata); + + if (xdata) + dict_unref(xdata); + + return 0; +} + +int +client4_0_fentrylk_cbk(struct rpc_req *req, struct iovec *iov, int count, + void *myframe) +{ + call_frame_t *frame = NULL; + gfx_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_gfx_common_rsp); + if (ret < 0) { + gf_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, + NULL); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; + } + + xdr_to_dict(&rsp.xdata, &xdata); + +out: + if ((rsp.op_ret == -1) && (EAGAIN != gf_error_to_errno(rsp.op_errno))) { + gf_smsg(this->name, GF_LOG_WARNING, gf_error_to_errno(rsp.op_errno), + PC_MSG_REMOTE_OP_FAILED, NULL); + } + + CLIENT_STACK_UNWIND(fentrylk, frame, rsp.op_ret, + gf_error_to_errno(rsp.op_errno), xdata); + + if (xdata) + dict_unref(xdata); + + return 0; +} + +int +client4_0_xattrop_cbk(struct rpc_req *req, struct iovec *iov, int count, + void *myframe) +{ + call_frame_t *frame = NULL; + dict_t *dict = NULL; + gfx_common_dict_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_gfx_common_dict_rsp); + if (ret < 0) { + gf_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, + NULL); + rsp.op_ret = -1; + op_errno = EINVAL; + goto out; + } + + op_errno = rsp.op_errno; + ret = client_post_common_dict(this, &rsp, &dict, &xdata); + if (ret) { + op_errno = -ret; + goto out; + } +out: + if (rsp.op_ret == -1) { + gf_smsg(this->name, fop_log_level(GF_FOP_XATTROP, op_errno), + gf_error_to_errno(rsp.op_errno), PC_MSG_REMOTE_OP_FAILED, + "Path=%s", local->loc.path, "gfid=%s", + loc_gfid_utoa(&local->loc), NULL); + } else { + /* This is required as many places, `if (ret)` is checked + for syncop_xattrop() */ + gf_msg_debug(this->name, 0, "resetting op_ret to 0 from %d", + rsp.op_ret); + rsp.op_ret = 0; + } + + CLIENT_STACK_UNWIND(xattrop, frame, rsp.op_ret, gf_error_to_errno(op_errno), + dict, xdata); + + if (xdata) + dict_unref(xdata); + + if (dict) + dict_unref(dict); + + return 0; +} + +int +client4_0_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; + gfx_common_dict_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_gfx_common_dict_rsp); + if (ret < 0) { + rsp.op_ret = -1; + op_errno = EINVAL; + gf_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, + NULL); + goto out; + } + op_errno = rsp.op_errno; + ret = client_post_common_dict(this, &rsp, &dict, &xdata); + if (ret) { + rsp.op_ret = -1; + op_errno = -ret; + goto out; + } +out: + + if (rsp.op_ret == -1) { + gf_smsg(this->name, GF_LOG_WARNING, gf_error_to_errno(rsp.op_errno), + PC_MSG_REMOTE_OP_FAILED, NULL); + } else { + /* This is required as many places, `if (ret)` is checked + for syncop_fxattrop() */ + gf_msg_debug(this->name, 0, "resetting op_ret to 0 from %d", + rsp.op_ret); + 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); + if (xdata) + dict_unref(xdata); + + if (dict) + dict_unref(dict); + + return 0; +} + +int +client4_0_fsetxattr_cbk(struct rpc_req *req, struct iovec *iov, int count, + void *myframe) +{ + call_frame_t *frame = NULL; + gfx_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_gfx_common_rsp); + if (ret < 0) { + gf_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, + NULL); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; + } + + xdr_to_dict(&rsp.xdata, &xdata); + +out: + op_errno = gf_error_to_errno(rsp.op_errno); + if (rsp.op_ret == -1) { + if (op_errno == ENOTSUP) { + gf_msg_debug(this->name, 0, + "remote operation failed:" + " %s", + strerror(op_errno)); + } else { + gf_smsg(this->name, GF_LOG_WARNING, rsp.op_errno, + PC_MSG_REMOTE_OP_FAILED, NULL); + } + } + + CLIENT_STACK_UNWIND(fsetxattr, frame, rsp.op_ret, op_errno, xdata); + + if (xdata) + dict_unref(xdata); + + return 0; +} + +int +client4_0_fallocate_cbk(struct rpc_req *req, struct iovec *iov, int count, + void *myframe) +{ + call_frame_t *frame = NULL; + gfx_common_2iatt_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_gfx_common_2iatt_rsp); + if (ret < 0) { + gf_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, + NULL); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; + } + + ret = client_post_common_2iatt(this, &rsp, &prestat, &poststat, &xdata); + if (ret < 0) + goto out; + +out: + if (rsp.op_ret == -1) { + gf_smsg(this->name, GF_LOG_WARNING, gf_error_to_errno(rsp.op_errno), + PC_MSG_REMOTE_OP_FAILED, NULL); + } + CLIENT_STACK_UNWIND(fallocate, frame, rsp.op_ret, + gf_error_to_errno(rsp.op_errno), &prestat, &poststat, + xdata); + + if (xdata) + dict_unref(xdata); + + return 0; +} + +int +client4_0_discard_cbk(struct rpc_req *req, struct iovec *iov, int count, + void *myframe) +{ + gfx_common_2iatt_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_gfx_common_2iatt_rsp); + if (ret < 0) { + gf_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, + NULL); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; + } + + ret = client_post_common_2iatt(this, &rsp, &prestat, &poststat, &xdata); + +out: + if (rsp.op_ret == -1) { + gf_smsg(this->name, GF_LOG_WARNING, gf_error_to_errno(rsp.op_errno), + PC_MSG_REMOTE_OP_FAILED, NULL); + } + CLIENT_STACK_UNWIND(discard, frame, rsp.op_ret, + gf_error_to_errno(rsp.op_errno), &prestat, &poststat, + xdata); + if (xdata) + dict_unref(xdata); + + return 0; +} + +int +client4_0_zerofill_cbk(struct rpc_req *req, struct iovec *iov, int count, + void *myframe) +{ + call_frame_t *frame = NULL; + gfx_common_2iatt_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_gfx_common_2iatt_rsp); + if (ret < 0) { + gf_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, + NULL); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; + } + + ret = client_post_common_2iatt(this, &rsp, &prestat, &poststat, &xdata); +out: + if (rsp.op_ret == -1) { + gf_smsg(this->name, GF_LOG_WARNING, gf_error_to_errno(rsp.op_errno), + PC_MSG_REMOTE_OP_FAILED, NULL); + } + CLIENT_STACK_UNWIND(zerofill, frame, rsp.op_ret, + gf_error_to_errno(rsp.op_errno), &prestat, &poststat, + xdata); + + if (xdata) + dict_unref(xdata); + + return 0; +} + +int +client4_0_ipc_cbk(struct rpc_req *req, struct iovec *iov, int count, + void *myframe) +{ + call_frame_t *frame = NULL; + gfx_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_gfx_common_rsp); + if (ret < 0) { + gf_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, + NULL); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; + } + + xdr_to_dict(&rsp.xdata, &xdata); +out: + if (rsp.op_ret == -1) { + gf_smsg(this->name, GF_LOG_WARNING, gf_error_to_errno(rsp.op_errno), + PC_MSG_REMOTE_OP_FAILED, NULL); + } + CLIENT_STACK_UNWIND(ipc, frame, rsp.op_ret, gf_error_to_errno(rsp.op_errno), + xdata); + + if (xdata) + dict_unref(xdata); + + return 0; +} + +int +client4_0_seek_cbk(struct rpc_req *req, struct iovec *iov, int count, + void *myframe) +{ + call_frame_t *frame = NULL; + struct gfx_seek_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_gfx_seek_rsp); + if (ret < 0) { + gf_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, + NULL); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; + } + + xdr_to_dict(&rsp.xdata, &xdata); +out: + if (rsp.op_ret == -1) { + gf_smsg(this->name, GF_LOG_WARNING, gf_error_to_errno(rsp.op_errno), + PC_MSG_REMOTE_OP_FAILED, NULL); + } + CLIENT_STACK_UNWIND(seek, frame, rsp.op_ret, + gf_error_to_errno(rsp.op_errno), rsp.offset, xdata); + + if (xdata) + dict_unref(xdata); + + return 0; +} + +int +client4_0_setattr_cbk(struct rpc_req *req, struct iovec *iov, int count, + void *myframe) +{ + gfx_common_2iatt_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_gfx_common_2iatt_rsp); + if (ret < 0) { + gf_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, + NULL); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; + } + + ret = client_post_common_2iatt(this, &rsp, &prestat, &poststat, &xdata); + +out: + if (rsp.op_ret == -1) { + gf_smsg(this->name, GF_LOG_WARNING, gf_error_to_errno(rsp.op_errno), + PC_MSG_REMOTE_OP_FAILED, NULL); + } + CLIENT_STACK_UNWIND(setattr, frame, rsp.op_ret, + gf_error_to_errno(rsp.op_errno), &prestat, &poststat, + xdata); + + if (xdata) + dict_unref(xdata); + + return 0; +} + +int +client4_0_fsetattr_cbk(struct rpc_req *req, struct iovec *iov, int count, + void *myframe) +{ + gfx_common_2iatt_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_gfx_common_2iatt_rsp); + if (ret < 0) { + gf_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, + NULL); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; + } + + ret = client_post_common_2iatt(this, &rsp, &prestat, &poststat, &xdata); + +out: + if (rsp.op_ret == -1) { + gf_smsg(this->name, GF_LOG_WARNING, gf_error_to_errno(rsp.op_errno), + PC_MSG_REMOTE_OP_FAILED, NULL); + } + CLIENT_STACK_UNWIND(fsetattr, frame, rsp.op_ret, + gf_error_to_errno(rsp.op_errno), &prestat, &poststat, + xdata); + + if (xdata) + dict_unref(xdata); + + return 0; +} + +int +client4_0_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; + gfx_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_gfx_create_rsp); + if (ret < 0) { + gf_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, + NULL); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; + } + + ret = client_post_create_v2(this, &rsp, &stbuf, &preparent, &postparent, + local, &xdata); + if (ret < 0) + 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; + } + } + +out: + if (rsp.op_ret == -1) { + gf_smsg(this->name, GF_LOG_WARNING, gf_error_to_errno(rsp.op_errno), + PC_MSG_REMOTE_OP_FAILED, "path=%s", local->loc.path, NULL); + } + + CLIENT_STACK_UNWIND(create, frame, rsp.op_ret, + gf_error_to_errno(rsp.op_errno), fd, inode, &stbuf, + &preparent, &postparent, xdata); + + if (xdata) + dict_unref(xdata); + + return 0; +} + +int +client4_0_lease_cbk(struct rpc_req *req, struct iovec *iov, int count, + void *myframe) +{ + call_frame_t *frame = NULL; + struct gf_lease lease = { + 0, + }; + gfx_lease_rsp rsp = { + 0, + }; + int ret = 0; + xlator_t *this = NULL; + dict_t *xdata = NULL; + + this = THIS; + + frame = myframe; + + if (-1 == req->rpc_status) { + gf_smsg(this->name, GF_LOG_ERROR, ENOTCONN, PC_MSG_REMOTE_OP_FAILED, + NULL); + rsp.op_ret = -1; + rsp.op_errno = ENOTCONN; + goto out; + } + + ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gfx_lease_rsp); + if (ret < 0) { + gf_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, + NULL); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; + } + + ret = client_post_lease_v2(this, &rsp, &lease, &xdata); + +out: + if (rsp.op_ret == -1) { + gf_smsg(this->name, GF_LOG_WARNING, gf_error_to_errno(rsp.op_errno), + PC_MSG_REMOTE_OP_FAILED, NULL); + } + + CLIENT_STACK_UNWIND(lease, frame, rsp.op_ret, + gf_error_to_errno(rsp.op_errno), &lease, xdata); + + if (xdata) + dict_unref(xdata); + + return 0; +} + +int +client4_0_lk_cbk(struct rpc_req *req, struct iovec *iov, int count, + void *myframe) +{ + call_frame_t *frame = NULL; + struct gf_flock lock = { + 0, + }; + gfx_lk_rsp rsp = { + 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_gfx_lk_rsp); + if (ret < 0) { + gf_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, + NULL); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; + } + + if (rsp.op_ret >= 0) { + ret = client_post_lk_v2(this, &rsp, &lock, &xdata); + if (ret < 0) + goto out; + + /* Save the lock to the client lock cache to be able + to recover in the case of server reboot.*/ + + if (client_is_setlk(local->cmd)) { + ret = client_add_lock_for_recovery(local->fd, &lock, &local->owner, + local->cmd); + if (ret < 0) { + rsp.op_ret = -1; + rsp.op_errno = -ret; + } + } + } + +out: + if ((rsp.op_ret == -1) && (EAGAIN != gf_error_to_errno(rsp.op_errno))) { + gf_smsg(this->name, GF_LOG_WARNING, gf_error_to_errno(rsp.op_errno), + PC_MSG_REMOTE_OP_FAILED, NULL); + } + + CLIENT_STACK_UNWIND(lk, frame, rsp.op_ret, gf_error_to_errno(rsp.op_errno), + &lock, xdata); + + free(rsp.flock.lk_owner.lk_owner_val); + + if (xdata) + dict_unref(xdata); + + return 0; +} + +int +client4_0_readdir_cbk(struct rpc_req *req, struct iovec *iov, int count, + void *myframe) +{ + call_frame_t *frame = NULL; + gfx_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; + + INIT_LIST_HEAD(&entries.list); + + if (-1 == req->rpc_status) { + rsp.op_ret = -1; + rsp.op_errno = ENOTCONN; + goto out; + } + + ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gfx_readdir_rsp); + if (ret < 0) { + gf_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, + NULL); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; + } + + ret = client_post_readdir_v2(this, &rsp, &entries, &xdata); + +out: + if (rsp.op_ret == -1) { + gf_smsg(this->name, GF_LOG_WARNING, gf_error_to_errno(rsp.op_errno), + PC_MSG_REMOTE_OP_FAILED, "remote_fd=%d", local->cmd, NULL); + } + 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); + } + + if (xdata) + dict_unref(xdata); + + clnt_readdir_rsp_cleanup_v2(&rsp); + + return 0; +} + +int +client4_0_readdirp_cbk(struct rpc_req *req, struct iovec *iov, int count, + void *myframe) +{ + call_frame_t *frame = NULL; + gfx_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; + + INIT_LIST_HEAD(&entries.list); + + if (-1 == req->rpc_status) { + rsp.op_ret = -1; + rsp.op_errno = ENOTCONN; + goto out; + } + + ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gfx_readdirp_rsp); + if (ret < 0) { + gf_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, + NULL); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; + } + + ret = client_post_readdirp_v2(this, &rsp, local->fd, &entries, &xdata); +out: + if (rsp.op_ret == -1) { + gf_smsg(this->name, GF_LOG_WARNING, gf_error_to_errno(rsp.op_errno), + PC_MSG_REMOTE_OP_FAILED, NULL); + } + 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); + } + + if (xdata) + dict_unref(xdata); + + clnt_readdirp_rsp_cleanup_v2(&rsp); + + return 0; +} + +int +client4_0_rename_cbk(struct rpc_req *req, struct iovec *iov, int count, + void *myframe) +{ + call_frame_t *frame = NULL; + gfx_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_gfx_rename_rsp); + if (ret < 0) { + gf_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, + NULL); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; + } + + client_post_rename_v2(this, &rsp, &stbuf, &preoldparent, &postoldparent, + &prenewparent, &postnewparent, &xdata); +out: + if (rsp.op_ret == -1) { + gf_smsg(this->name, GF_LOG_WARNING, gf_error_to_errno(rsp.op_errno), + PC_MSG_REMOTE_OP_FAILED, NULL); + } + CLIENT_STACK_UNWIND(rename, frame, rsp.op_ret, + gf_error_to_errno(rsp.op_errno), &stbuf, &preoldparent, + &postoldparent, &prenewparent, &postnewparent, xdata); + + if (xdata) + dict_unref(xdata); + + return 0; +} + +int +client4_0_link_cbk(struct rpc_req *req, struct iovec *iov, int count, + void *myframe) +{ + gfx_common_3iatt_rsp rsp = { + 0, + }; + call_frame_t *frame = NULL; + 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_gfx_common_3iatt_rsp); + if (ret < 0) { + gf_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, + NULL); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; + } + + ret = client_post_common_3iatt(this, &rsp, &stbuf, &preparent, &postparent, + &xdata); +out: + if (rsp.op_ret == -1) { + if (GF_IGNORE_IF_GSYNCD_SAFE_ERROR(frame, rsp.op_errno)) { + gf_smsg(this->name, GF_LOG_WARNING, gf_error_to_errno(rsp.op_errno), + PC_MSG_REMOTE_OP_FAILED, "source=%s", local->loc.path, + "target=%s", local->loc2.path, NULL); + } + } + + CLIENT_STACK_UNWIND(link, frame, rsp.op_ret, + gf_error_to_errno(rsp.op_errno), inode, &stbuf, + &preparent, &postparent, xdata); + + if (xdata) + dict_unref(xdata); + + return 0; +} + +int +client4_0_opendir_cbk(struct rpc_req *req, struct iovec *iov, int count, + void *myframe) +{ + clnt_local_t *local = NULL; + call_frame_t *frame = NULL; + fd_t *fd = NULL; + int ret = 0; + gfx_open_rsp rsp = { + 0, + }; + xlator_t *this = NULL; + dict_t *xdata = NULL; + + this = THIS; + + frame = myframe; + local = frame->local; + + fd = local->fd; + + if (-1 == req->rpc_status) { + rsp.op_ret = -1; + rsp.op_errno = ENOTCONN; + goto out; + } + + /* open and opendir are two operations dealing with same thing, + but separated by fop number only */ + ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gfx_open_rsp); + if (ret < 0) { + gf_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, + NULL); + 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; + } + } + + ret = xdr_to_dict(&rsp.xdata, &xdata); +out: + if (rsp.op_ret == -1) { + gf_smsg(this->name, + fop_log_level(GF_FOP_OPENDIR, gf_error_to_errno(rsp.op_errno)), + gf_error_to_errno(rsp.op_errno), PC_MSG_REMOTE_OP_FAILED, + "path=%s", local->loc.path, "gfid=%s", + loc_gfid_utoa(&local->loc), NULL); + } + CLIENT_STACK_UNWIND(opendir, frame, rsp.op_ret, + gf_error_to_errno(rsp.op_errno), fd, xdata); + + if (xdata) + dict_unref(xdata); + + return 0; +} + +int +client4_0_lookup_cbk(struct rpc_req *req, struct iovec *iov, int count, + void *myframe) +{ + gfx_common_2iatt_rsp rsp = { + 0, + }; + clnt_local_t *local = NULL; + call_frame_t *frame = NULL; + int ret = 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_gfx_common_2iatt_rsp); + if (ret < 0) { + gf_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, + NULL); + rsp.op_ret = -1; + op_errno = EINVAL; + goto out; + } + + /* Preserve the op_errno received from the server */ + op_errno = gf_error_to_errno(rsp.op_errno); + + ret = client_post_common_2iatt(this, &rsp, &stbuf, &postparent, &xdata); + if (ret < 0) { + /* Don't change the op_errno if the fop failed on server */ + if (rsp.op_ret == 0) + op_errno = rsp.op_errno; + rsp.op_ret = -1; + goto out; + } + + if (rsp.op_ret < 0) + goto out; + + if ((!gf_uuid_is_null(inode->gfid)) && + (gf_uuid_compare(stbuf.ia_gfid, inode->gfid) != 0)) { + gf_msg_debug(frame->this->name, 0, "gfid changed for %s", + local->loc.path); + + rsp.op_ret = -1; + op_errno = ESTALE; + if (xdata) + ret = dict_set_int32_sizen(xdata, "gfid-changed", 1); + + goto out; + } + + rsp.op_ret = 0; + +out: + /* Restore the correct op_errno to rsp.op_errno */ + rsp.op_errno = op_errno; + if (rsp.op_ret == -1) { + /* any error other than ENOENT */ + if (!(local->loc.name && rsp.op_errno == ENOENT) && + !(rsp.op_errno == ESTALE)) + gf_smsg(this->name, GF_LOG_WARNING, rsp.op_errno, + PC_MSG_REMOTE_OP_FAILED, "path=%s", local->loc.path, + "gfid=%s", loc_gfid_utoa(&local->loc), NULL); + else + gf_msg_trace(this->name, 0, + "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); + + return 0; +} + +int +client4_0_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, + }; + gfx_read_rsp rsp = { + 0, + }; + int ret = 0, rspcount = 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; + rsp.op_errno = ENOTCONN; + goto out; + } + + ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gfx_read_rsp); + if (ret < 0) { + gf_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, + NULL); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; + } + + memset(vector, 0, sizeof(vector)); + + ret = client_post_readv_v2(this, &rsp, &iobref, req->rsp_iobref, &stat, + vector, &req->rsp[1], &rspcount, &xdata); +out: + if (rsp.op_ret == -1) { + gf_smsg(this->name, GF_LOG_WARNING, gf_error_to_errno(rsp.op_errno), + PC_MSG_REMOTE_OP_FAILED, NULL); + } 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); + + if (xdata) + dict_unref(xdata); + + return 0; +} + +int +client4_0_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 +client4_0_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 +client4_0_getactivelk_cbk(struct rpc_req *req, struct iovec *iov, int count, + void *myframe) +{ + call_frame_t *frame = NULL; + gfx_getactivelk_rsp rsp = { + 0, + }; + int32_t ret = 0; + lock_migration_info_t locklist; + 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_gfx_getactivelk_rsp); + if (ret < 0) { + gf_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, + NULL); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; + } + + INIT_LIST_HEAD(&locklist.list); + + if (rsp.op_ret > 0) { + clnt_unserialize_rsp_locklist_v2(this, &rsp, &locklist); + } + + xdr_to_dict(&rsp.xdata, &xdata); + +out: + if (rsp.op_ret == -1) { + gf_smsg(this->name, GF_LOG_WARNING, gf_error_to_errno(rsp.op_errno), + PC_MSG_REMOTE_OP_FAILED, NULL); + } + + CLIENT_STACK_UNWIND(getactivelk, frame, rsp.op_ret, + gf_error_to_errno(rsp.op_errno), &locklist, xdata); + if (xdata) + dict_unref(xdata); + + clnt_getactivelk_rsp_cleanup_v2(&rsp); + + return 0; +} + +int +client4_0_setactivelk_cbk(struct rpc_req *req, struct iovec *iov, int count, + void *myframe) +{ + call_frame_t *frame = NULL; + gfx_common_rsp rsp = { + 0, + }; + int32_t 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_gfx_common_rsp); + if (ret < 0) { + gf_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, + NULL); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; + } + + xdr_to_dict(&rsp.xdata, &xdata); +out: + if (rsp.op_ret == -1) { + gf_smsg(this->name, GF_LOG_WARNING, gf_error_to_errno(rsp.op_errno), + PC_MSG_REMOTE_OP_FAILED, NULL); + } + + CLIENT_STACK_UNWIND(setactivelk, frame, rsp.op_ret, + gf_error_to_errno(rsp.op_errno), xdata); + + if (xdata) + dict_unref(xdata); + + return 0; +} + +int +client4_0_copy_file_range_cbk(struct rpc_req *req, struct iovec *iov, int count, + void *myframe) +{ + gfx_common_3iatt_rsp rsp = { + 0, + }; + call_frame_t *frame = NULL; + struct iatt stbuf = { + 0, + }; + 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_gfx_common_3iatt_rsp); + if (ret < 0) { + gf_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, + NULL); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; + } + + ret = client_post_common_3iatt(this, &rsp, &stbuf, &prestat, &poststat, + &xdata); + if (ret < 0) + goto out; +out: + if (rsp.op_ret == -1) { + gf_smsg(this->name, GF_LOG_WARNING, gf_error_to_errno(rsp.op_errno), + PC_MSG_REMOTE_OP_FAILED, NULL); + } else if (rsp.op_ret >= 0) { + if (local->attempt_reopen) + client_attempt_reopen(local->fd, this); + if (local->attempt_reopen_out) + client_attempt_reopen(local->fd_out, this); + } + CLIENT_STACK_UNWIND(copy_file_range, frame, rsp.op_ret, + gf_error_to_errno(rsp.op_errno), &stbuf, &prestat, + &poststat, xdata); + + if (xdata) + dict_unref(xdata); + + return 0; +} + +int32_t +client4_0_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; + gf_boolean_t destroy = _gf_false; + + if (!this || !data) + goto out; + + args = data; + conf = this->private; + + pthread_spin_lock(&conf->fd_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) { + fdctx->released = 1; + } else { + list_del_init(&fdctx->sfd_pos); + destroy = _gf_true; + } + } + } + pthread_spin_unlock(&conf->fd_lock); + + if (destroy) + client_fdctx_destroy(this, fdctx); + +out: + + return 0; +} + +int32_t +client4_0_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; + gf_boolean_t destroy = _gf_false; + + if (!this || !data) + goto out; + + args = data; + conf = this->private; + + pthread_spin_lock(&conf->fd_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) { + fdctx->released = 1; + } else { + list_del_init(&fdctx->sfd_pos); + destroy = _gf_true; + } + } + } + pthread_spin_unlock(&conf->fd_lock); + + if (destroy) + client_fdctx_destroy(this, fdctx); +out: + return 0; +} + +int32_t +client4_0_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; + gfx_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; + client_payload_t cp; + + if (!frame || !this || !data) + goto unwind; + + conf = this->private; + args = data; + local = mem_get0(this->local_pool); + if (!local) { + op_errno = ENOMEM; + goto unwind; + } + frame->local = local; + + if (!(args->loc && args->loc->inode)) + goto unwind; + + loc_copy(&local->loc, args->loc); + loc_path(&local->loc, NULL); + + if (args->xdata) { + content = dict_get_sizen(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); + memset(vector, 0, sizeof(vector)); + rsphdr = &vector[0]; + rsphdr->iov_base = iobuf_ptr(rsp_iobuf); + rsphdr->iov_len = iobuf_pagesize(rsp_iobuf); + count = 1; + local->iobref = rsp_iobref; + iobuf_unref(rsp_iobuf); + rsp_iobuf = NULL; + rsp_iobref = NULL; + } + } + + ret = client_pre_lookup_v2(this, &req, args->loc, args->xdata); + if (ret) { + op_errno = -ret; + goto unwind; + } + + memset(&cp, 0, sizeof(client_payload_t)); + + cp.rsphdr = rsphdr; + cp.rsphdr_cnt = count; + cp.rsp_iobref = local->iobref; + ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_LOOKUP, + client4_0_lookup_cbk, &cp, + (xdrproc_t)xdr_gfx_lookup_req); + + if (ret) { + gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); + } + + GF_FREE(req.xdata.pairs.pairs_val); + + return 0; + +unwind: + CLIENT_STACK_UNWIND(lookup, frame, -1, op_errno, NULL, NULL, NULL, NULL); + + GF_FREE(req.xdata.pairs.pairs_val); + + if (rsp_iobref) + iobref_unref(rsp_iobref); + + return 0; +} + +int32_t +client4_0_stat(call_frame_t *frame, xlator_t *this, void *data) +{ + clnt_conf_t *conf = NULL; + clnt_args_t *args = NULL; + gfx_stat_req req = { + { + 0, + }, + }; + int ret = 0; + int op_errno = ESTALE; + + if (!frame || !this || !data) + goto unwind; + + args = data; + conf = this->private; + + ret = client_pre_stat_v2(this, &req, args->loc, args->xdata); + if (ret) { + op_errno = -ret; + goto unwind; + } + ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_STAT, + client4_0_stat_cbk, NULL, + (xdrproc_t)xdr_gfx_stat_req); + if (ret) { + gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); + } + + GF_FREE(req.xdata.pairs.pairs_val); + + return 0; +unwind: + CLIENT_STACK_UNWIND(stat, frame, -1, op_errno, NULL, NULL); + + GF_FREE(req.xdata.pairs.pairs_val); + + return 0; +} + +int32_t +client4_0_truncate(call_frame_t *frame, xlator_t *this, void *data) +{ + clnt_conf_t *conf = NULL; + clnt_args_t *args = NULL; + gfx_truncate_req req = { + { + 0, + }, + }; + int ret = 0; + int op_errno = ESTALE; + + if (!frame || !this || !data) + goto unwind; + + args = data; + conf = this->private; + + ret = client_pre_truncate_v2(this, &req, args->loc, args->offset, + args->xdata); + if (ret) { + op_errno = -ret; + goto unwind; + } + ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_TRUNCATE, + client4_0_truncate_cbk, NULL, + (xdrproc_t)xdr_gfx_truncate_req); + if (ret) { + gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); + } + + GF_FREE(req.xdata.pairs.pairs_val); + + return 0; +unwind: + CLIENT_STACK_UNWIND(truncate, frame, -1, op_errno, NULL, NULL, NULL); + GF_FREE(req.xdata.pairs.pairs_val); + + return 0; +} + +int32_t +client4_0_ftruncate(call_frame_t *frame, xlator_t *this, void *data) +{ + clnt_args_t *args = NULL; + clnt_conf_t *conf = NULL; + gfx_ftruncate_req req = { + { + 0, + }, + }; + int op_errno = EINVAL; + int ret = 0; + + if (!frame || !this || !data) + goto unwind; + + args = data; + + conf = this->private; + + ret = client_pre_ftruncate_v2(this, &req, args->fd, args->offset, + args->xdata); + if (ret) { + op_errno = -ret; + goto unwind; + } + ret = client_submit_request(this, &req, frame, conf->fops, + GFS3_OP_FTRUNCATE, client4_0_ftruncate_cbk, + NULL, (xdrproc_t)xdr_gfx_ftruncate_req); + if (ret) { + gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); + } + + GF_FREE(req.xdata.pairs.pairs_val); + + return 0; +unwind: + CLIENT_STACK_UNWIND(ftruncate, frame, -1, op_errno, NULL, NULL, NULL); + GF_FREE(req.xdata.pairs.pairs_val); + + return 0; +} + +int32_t +client4_0_access(call_frame_t *frame, xlator_t *this, void *data) +{ + clnt_conf_t *conf = NULL; + clnt_args_t *args = NULL; + gfx_access_req req = { + { + 0, + }, + }; + int ret = 0; + int op_errno = ESTALE; + + if (!frame || !this || !data) + goto unwind; + + args = data; + + conf = this->private; + + ret = client_pre_access_v2(this, &req, args->loc, args->mask, args->xdata); + if (ret) { + op_errno = -ret; + goto unwind; + } + ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_ACCESS, + client4_0_access_cbk, NULL, + (xdrproc_t)xdr_gfx_access_req); + if (ret) { + gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); + } + + GF_FREE(req.xdata.pairs.pairs_val); + + return 0; +unwind: + CLIENT_STACK_UNWIND(access, frame, -1, op_errno, NULL); + GF_FREE(req.xdata.pairs.pairs_val); + + return 0; +} + +int32_t +client4_0_readlink(call_frame_t *frame, xlator_t *this, void *data) +{ + clnt_conf_t *conf = NULL; + clnt_args_t *args = NULL; + gfx_readlink_req req = { + { + 0, + }, + }; + int ret = 0; + int op_errno = ESTALE; + clnt_local_t *local = NULL; + + if (!frame || !this || !data) + goto unwind; + + args = data; + + conf = this->private; + + local = mem_get0(this->local_pool); + if (!local) { + op_errno = ENOMEM; + goto unwind; + } + + frame->local = local; + + ret = client_pre_readlink_v2(this, &req, args->loc, args->size, + args->xdata); + if (ret) { + op_errno = -ret; + goto unwind; + } + + ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_READLINK, + client4_0_readlink_cbk, NULL, + (xdrproc_t)xdr_gfx_readlink_req); + if (ret) { + gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); + } + + GF_FREE(req.xdata.pairs.pairs_val); + + return 0; +unwind: + + CLIENT_STACK_UNWIND(readlink, frame, -1, op_errno, NULL, NULL, NULL); + GF_FREE(req.xdata.pairs.pairs_val); + + return 0; +} + +int32_t +client4_0_unlink(call_frame_t *frame, xlator_t *this, void *data) +{ + clnt_conf_t *conf = NULL; + clnt_args_t *args = NULL; + gfx_unlink_req req = { + { + 0, + }, + }; + int ret = 0; + int op_errno = 0; + + if (!frame || !this || !data) + goto unwind; + + args = data; + conf = this->private; + + ret = client_pre_unlink_v2(this, &req, args->loc, args->flags, args->xdata); + if (ret) { + op_errno = -ret; + goto unwind; + } + ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_UNLINK, + client4_0_unlink_cbk, NULL, + (xdrproc_t)xdr_gfx_unlink_req); + if (ret) { + gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); + } + + GF_FREE(req.xdata.pairs.pairs_val); + + return 0; +unwind: + CLIENT_STACK_UNWIND(unlink, frame, -1, op_errno, NULL, NULL, NULL); + GF_FREE(req.xdata.pairs.pairs_val); + + return 0; +} + +int32_t +client4_0_rmdir(call_frame_t *frame, xlator_t *this, void *data) +{ + clnt_conf_t *conf = NULL; + clnt_args_t *args = NULL; + gfx_rmdir_req req = { + { + 0, + }, + }; + int ret = 0; + int op_errno = ESTALE; + + if (!frame || !this || !data) + goto unwind; + + args = data; + conf = this->private; + + ret = client_pre_rmdir_v2(this, &req, args->loc, args->flags, args->xdata); + + if (ret) { + op_errno = -ret; + goto unwind; + } + ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_RMDIR, + client4_0_rmdir_cbk, NULL, + (xdrproc_t)xdr_gfx_rmdir_req); + if (ret) { + gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); + } + GF_FREE(req.xdata.pairs.pairs_val); + + return 0; +unwind: + CLIENT_STACK_UNWIND(rmdir, frame, -1, op_errno, NULL, NULL, NULL); + GF_FREE(req.xdata.pairs.pairs_val); + + return 0; +} + +int32_t +client4_0_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; + gfx_symlink_req req = { + { + 0, + }, + }; + int ret = 0; + int op_errno = ESTALE; + + if (!frame || !this || !data) + goto unwind; + + args = data; + conf = this->private; + + 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); + + local->loc2.path = gf_strdup(args->linkname); + + ret = client_pre_symlink_v2(this, &req, args->loc, args->linkname, + args->umask, args->xdata); + if (ret) { + op_errno = -ret; + goto unwind; + } + ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_SYMLINK, + client4_0_symlink_cbk, NULL, + (xdrproc_t)xdr_gfx_symlink_req); + if (ret) { + gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); + } + + GF_FREE(req.xdata.pairs.pairs_val); + + return 0; +unwind: + + CLIENT_STACK_UNWIND(symlink, frame, -1, op_errno, NULL, NULL, NULL, NULL, + NULL); + + GF_FREE(req.xdata.pairs.pairs_val); + + return 0; +} + +int32_t +client4_0_rename(call_frame_t *frame, xlator_t *this, void *data) +{ + clnt_conf_t *conf = NULL; + clnt_args_t *args = NULL; + gfx_rename_req req = { + { + 0, + }, + }; + int ret = 0; + int op_errno = ESTALE; + + if (!frame || !this || !data) + goto unwind; + + args = data; + conf = this->private; + + ret = client_pre_rename_v2(this, &req, args->oldloc, args->newloc, + args->xdata); + if (ret) { + op_errno = -ret; + goto unwind; + } + ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_RENAME, + client4_0_rename_cbk, NULL, + (xdrproc_t)xdr_gfx_rename_req); + if (ret) { + gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); + } + + GF_FREE(req.xdata.pairs.pairs_val); + + return 0; +unwind: + CLIENT_STACK_UNWIND(rename, frame, -1, op_errno, NULL, NULL, NULL, NULL, + NULL, NULL); + + GF_FREE(req.xdata.pairs.pairs_val); + + return 0; +} + +int32_t +client4_0_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; + gfx_link_req req = { + { + 0, + }, + }; + int ret = 0; + int op_errno = ESTALE; + + if (!frame || !this || !data) + goto unwind; + + args = data; + conf = this->private; + + local = mem_get0(this->local_pool); + if (!local) { + op_errno = ENOMEM; + goto unwind; + } + + frame->local = local; + + ret = client_pre_link_v2(this, &req, args->oldloc, args->newloc, + args->xdata); + if (ret) { + op_errno = -ret; + goto unwind; + } + + loc_copy(&local->loc, args->oldloc); + loc_path(&local->loc, NULL); + loc_copy(&local->loc2, args->newloc); + loc_path(&local->loc2, NULL); + + ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_LINK, + client4_0_link_cbk, NULL, + (xdrproc_t)xdr_gfx_link_req); + if (ret) { + gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); + } + + GF_FREE(req.xdata.pairs.pairs_val); + + return 0; +unwind: + CLIENT_STACK_UNWIND(link, frame, -1, op_errno, NULL, NULL, NULL, NULL, + NULL); + GF_FREE(req.xdata.pairs.pairs_val); + + return 0; +} + +int32_t +client4_0_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; + gfx_mknod_req req = { + { + 0, + }, + }; + int ret = 0; + int op_errno = ESTALE; + + if (!frame || !this || !data) + goto unwind; + + args = data; + conf = this->private; + + local = mem_get0(this->local_pool); + if (!local) { + op_errno = ENOMEM; + goto unwind; + } + frame->local = local; + + loc_copy(&local->loc, args->loc); + loc_path(&local->loc, NULL); + + ret = client_pre_mknod_v2(this, &req, args->loc, args->mode, args->rdev, + args->umask, args->xdata); + if (ret) { + op_errno = -ret; + goto unwind; + } + ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_MKNOD, + client4_0_mknod_cbk, NULL, + (xdrproc_t)xdr_gfx_mknod_req); + if (ret) { + gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); + } + GF_FREE(req.xdata.pairs.pairs_val); + + return 0; +unwind: + CLIENT_STACK_UNWIND(mknod, frame, -1, op_errno, NULL, NULL, NULL, NULL, + NULL); + + GF_FREE(req.xdata.pairs.pairs_val); + + return 0; +} + +int32_t +client4_0_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; + gfx_mkdir_req req = { + { + 0, + }, + }; + int ret = 0; + int op_errno = ESTALE; + + if (!frame || !this || !data) + goto unwind; + + args = data; + conf = this->private; + + if (!args->xdata || !dict_get_sizen(args->xdata, "gfid-req")) { + op_errno = EPERM; + gf_msg_callingfn(this->name, GF_LOG_WARNING, op_errno, PC_MSG_GFID_NULL, + "mkdir: %s is received " + "without gfid-req %p", + args->loc->path, args->xdata); + goto unwind; + } + + 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); + + ret = client_pre_mkdir_v2(this, &req, args->loc, args->mode, args->umask, + args->xdata); + if (ret) { + op_errno = -ret; + goto unwind; + } + ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_MKDIR, + client4_0_mkdir_cbk, NULL, + (xdrproc_t)xdr_gfx_mkdir_req); + if (ret) { + gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); + } + GF_FREE(req.xdata.pairs.pairs_val); + + return 0; +unwind: + CLIENT_STACK_UNWIND(mkdir, frame, -1, op_errno, NULL, NULL, NULL, NULL, + NULL); + + GF_FREE(req.xdata.pairs.pairs_val); + + return 0; +} + +int32_t +client4_0_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; + gfx_create_req req = { + { + 0, + }, + }; + int ret = 0; + int op_errno = ESTALE; + + if (!frame || !this || !data) + goto unwind; + + args = data; + conf = this->private; + + local = mem_get0(this->local_pool); + if (!local) { + op_errno = ENOMEM; + goto unwind; + } + frame->local = local; + + local->fd = fd_ref(args->fd); + local->flags = args->flags; + + loc_copy(&local->loc, args->loc); + loc_path(&local->loc, NULL); + + ret = client_pre_create_v2(this, &req, args->loc, args->fd, args->mode, + args->flags, args->umask, args->xdata); + if (ret) { + op_errno = -ret; + goto unwind; + } + ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_CREATE, + client4_0_create_cbk, NULL, + (xdrproc_t)xdr_gfx_create_req); + if (ret) { + gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); + } + + GF_FREE(req.xdata.pairs.pairs_val); + + return 0; +unwind: + CLIENT_STACK_UNWIND(create, frame, -1, op_errno, NULL, NULL, NULL, NULL, + NULL, NULL); + + GF_FREE(req.xdata.pairs.pairs_val); + + return 0; +} + +int32_t +client4_0_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; + gfx_open_req req = { + { + 0, + }, + }; + int ret = 0; + int op_errno = ESTALE; + + if (!frame || !this || !data) + goto unwind; + + args = data; + + conf = this->private; + + local = mem_get0(this->local_pool); + if (!local) { + op_errno = ENOMEM; + goto unwind; + } + frame->local = local; + + local->flags = args->flags; + + local->fd = fd_ref(args->fd); + loc_copy(&local->loc, args->loc); + loc_path(&local->loc, NULL); + + ret = client_pre_open_v2(this, &req, args->loc, args->fd, args->flags, + args->xdata); + + if (ret) { + op_errno = -ret; + goto unwind; + } + ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_OPEN, + client4_0_open_cbk, NULL, + (xdrproc_t)xdr_gfx_open_req); + if (ret) { + gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); + } + + GF_FREE(req.xdata.pairs.pairs_val); + + return 0; +unwind: + CLIENT_STACK_UNWIND(open, frame, -1, op_errno, NULL, NULL); + + GF_FREE(req.xdata.pairs.pairs_val); + + return 0; +} + +int32_t +client4_0_readv(call_frame_t *frame, xlator_t *this, void *data) +{ + clnt_args_t *args = NULL; + clnt_conf_t *conf = NULL; + clnt_local_t *local = NULL; + int op_errno = ESTALE; + gfx_read_req req = { + { + 0, + }, + }; + int ret = 0; + struct iovec rsp_vec = { + 0, + }; + struct iobuf *rsp_iobuf = NULL; + struct iobref *rsp_iobref = NULL; + client_payload_t cp; + + if (!frame || !this || !data) + goto unwind; + + args = data; + conf = this->private; + + ret = client_pre_readv_v2(this, &req, args->fd, args->size, args->offset, + args->flags, args->xdata); + if (ret) { + op_errno = -ret; + goto unwind; + } + + ret = client_fd_fop_prepare_local(frame, args->fd, req.fd); + if (ret) { + op_errno = -ret; + goto unwind; + } + local = frame->local; + + 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); + rsp_vec.iov_base = iobuf_ptr(rsp_iobuf); + rsp_vec.iov_len = iobuf_pagesize(rsp_iobuf); + local->iobref = rsp_iobref; + iobuf_unref(rsp_iobuf); + rsp_iobref = NULL; + rsp_iobuf = NULL; + + if (args->size > rsp_vec.iov_len) { + gf_smsg(this->name, GF_LOG_WARNING, ENOMEM, PC_MSG_BIGGER_SIZE, + "read-size=%lu", (unsigned long)args->size, "iobuf-size=%lu", + (unsigned long)rsp_vec.iov_len, NULL); + op_errno = EINVAL; + goto unwind; + } + + memset(&cp, 0, sizeof(client_payload_t)); + + cp.rsp_payload = &rsp_vec; + cp.rsp_payload_cnt = 1; + cp.rsp_iobref = local->iobref; + ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_READ, + client4_0_readv_cbk, &cp, + (xdrproc_t)xdr_gfx_read_req); + if (ret) { + gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); + } + + GF_FREE(req.xdata.pairs.pairs_val); + + return 0; +unwind: + if (rsp_iobuf) + iobuf_unref(rsp_iobuf); + + CLIENT_STACK_UNWIND(readv, frame, -1, op_errno, NULL, 0, NULL, NULL, NULL); + GF_FREE(req.xdata.pairs.pairs_val); + + return 0; +} + +int32_t +client4_0_writev(call_frame_t *frame, xlator_t *this, void *data) +{ + clnt_args_t *args = NULL; + clnt_conf_t *conf = NULL; + gfx_write_req req = { + { + 0, + }, + }; + int op_errno = ESTALE; + int ret = 0; + client_payload_t cp; + + if (!frame || !this || !data) + goto unwind; + + args = data; + conf = this->private; + + ret = client_pre_writev_v2(this, &req, args->fd, args->size, args->offset, + args->flags, &args->xdata); + + if (ret) { + op_errno = -ret; + goto unwind; + } + + ret = client_fd_fop_prepare_local(frame, args->fd, req.fd); + if (ret) { + op_errno = -ret; + goto unwind; + } + + memset(&cp, 0, sizeof(client_payload_t)); + + cp.iobref = args->iobref; + cp.payload = args->vector; + cp.payload_cnt = args->count; + ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_WRITE, + client4_0_writev_cbk, &cp, + (xdrproc_t)xdr_gfx_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_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); + } + + GF_FREE(req.xdata.pairs.pairs_val); + + return 0; + +unwind: + CLIENT_STACK_UNWIND(writev, frame, -1, op_errno, NULL, NULL, NULL); + GF_FREE(req.xdata.pairs.pairs_val); + + return 0; +} + +int32_t +client4_0_flush(call_frame_t *frame, xlator_t *this, void *data) +{ + clnt_args_t *args = NULL; + gfx_flush_req req = { + { + 0, + }, + }; + 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; + + local = mem_get0(this->local_pool); + if (!local) { + op_errno = ENOMEM; + goto unwind; + } + + frame->local = local; + + local->fd = fd_ref(args->fd); + local->owner = frame->root->lk_owner; + ret = client_pre_flush_v2(this, &req, args->fd, args->xdata); + if (ret) { + op_errno = -ret; + if (op_errno == EBADF) { + ret = delete_granted_locks_owner(local->fd, &local->owner); + gf_msg_trace(this->name, 0, + "deleting locks of owner (%s) returned %d", + lkowner_utoa(&local->owner), ret); + } + + goto unwind; + } + ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_FLUSH, + client4_0_flush_cbk, NULL, + (xdrproc_t)xdr_gfx_flush_req); + if (ret) { + gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); + } + + GF_FREE(req.xdata.pairs.pairs_val); + + return 0; + +unwind: + CLIENT_STACK_UNWIND(flush, frame, -1, op_errno, NULL); + GF_FREE(req.xdata.pairs.pairs_val); + + return 0; +} + +int32_t +client4_0_fsync(call_frame_t *frame, xlator_t *this, void *data) +{ + clnt_args_t *args = NULL; + gfx_fsync_req req = { + { + 0, + }, + }; + clnt_conf_t *conf = NULL; + int op_errno = 0; + int ret = 0; + + if (!frame || !this || !data) + goto unwind; + + args = data; + conf = this->private; + + ret = client_pre_fsync_v2(this, &req, args->fd, args->flags, args->xdata); + if (ret) { + op_errno = -ret; + goto unwind; + } + ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_FSYNC, + client4_0_fsync_cbk, NULL, + (xdrproc_t)xdr_gfx_fsync_req); + if (ret) { + gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); + } + + GF_FREE(req.xdata.pairs.pairs_val); + + return 0; + +unwind: + CLIENT_STACK_UNWIND(fsync, frame, -1, op_errno, NULL, NULL, NULL); + GF_FREE(req.xdata.pairs.pairs_val); + + return 0; +} + +int32_t +client4_0_fstat(call_frame_t *frame, xlator_t *this, void *data) +{ + clnt_args_t *args = NULL; + gfx_fstat_req req = { + { + 0, + }, + }; + clnt_conf_t *conf = NULL; + int op_errno = ESTALE; + int ret = 0; + + if (!frame || !this || !data) + goto unwind; + + args = data; + conf = this->private; + + ret = client_pre_fstat_v2(this, &req, args->fd, args->xdata); + + if (ret) { + op_errno = -ret; + goto unwind; + } + + ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_FSTAT, + client4_0_fstat_cbk, NULL, + (xdrproc_t)xdr_gfx_fstat_req); + if (ret) { + gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); + } + + GF_FREE(req.xdata.pairs.pairs_val); + + return 0; + +unwind: + CLIENT_STACK_UNWIND(fstat, frame, -1, op_errno, NULL, NULL); + GF_FREE(req.xdata.pairs.pairs_val); + + return 0; +} + +int32_t +client4_0_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; + gfx_opendir_req req = { + { + 0, + }, + }; + int ret = 0; + int op_errno = ESTALE; + + if (!frame || !this || !data) + goto unwind; + + args = data; + conf = this->private; + + local = mem_get0(this->local_pool); + if (!local) { + op_errno = ENOMEM; + goto unwind; + } + frame->local = local; + + local->fd = fd_ref(args->fd); + loc_copy(&local->loc, args->loc); + loc_path(&local->loc, NULL); + + ret = client_pre_opendir_v2(this, &req, args->loc, args->fd, args->xdata); + if (ret) { + op_errno = -ret; + goto unwind; + } + ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_OPENDIR, + client4_0_opendir_cbk, NULL, + (xdrproc_t)xdr_gfx_opendir_req); + if (ret) { + gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); + } + + GF_FREE(req.xdata.pairs.pairs_val); + + return 0; + +unwind: + CLIENT_STACK_UNWIND(opendir, frame, -1, op_errno, NULL, NULL); + + GF_FREE(req.xdata.pairs.pairs_val); + + return 0; +} + +int32_t +client4_0_fsyncdir(call_frame_t *frame, xlator_t *this, void *data) +{ + clnt_args_t *args = NULL; + clnt_conf_t *conf = NULL; + gfx_fsyncdir_req req = { + { + 0, + }, + }; + int ret = 0; + int32_t op_errno = ESTALE; + + if (!frame || !this || !data) + goto unwind; + + args = data; + conf = this->private; + + ret = client_pre_fsyncdir_v2(this, &req, args->fd, args->flags, + args->xdata); + if (ret) { + op_errno = -ret; + goto unwind; + } + ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_FSYNCDIR, + client4_0_fsyncdir_cbk, NULL, + (xdrproc_t)xdr_gfx_fsyncdir_req); + if (ret) { + gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); + } + + GF_FREE(req.xdata.pairs.pairs_val); + + return 0; + +unwind: + CLIENT_STACK_UNWIND(fsyncdir, frame, -1, op_errno, NULL); + GF_FREE(req.xdata.pairs.pairs_val); + + return 0; +} + +int32_t +client4_0_statfs(call_frame_t *frame, xlator_t *this, void *data) +{ + clnt_conf_t *conf = NULL; + clnt_args_t *args = NULL; + gfx_statfs_req req = { + { + 0, + }, + }; + int ret = 0; + int op_errno = ESTALE; + + if (!frame || !this || !data) + goto unwind; + + args = data; + + conf = this->private; + + ret = client_pre_statfs_v2(this, &req, args->loc, args->xdata); + if (ret) { + op_errno = -ret; + goto unwind; + } + ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_STATFS, + client4_0_statfs_cbk, NULL, + (xdrproc_t)xdr_gfx_statfs_req); + if (ret) { + gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); + } + + GF_FREE(req.xdata.pairs.pairs_val); + + return 0; + +unwind: + CLIENT_STACK_UNWIND(statfs, frame, -1, op_errno, NULL, NULL); + GF_FREE(req.xdata.pairs.pairs_val); + + return 0; +} + +int32_t +client4_0_setxattr(call_frame_t *frame, xlator_t *this, void *data) +{ + clnt_conf_t *conf = NULL; + clnt_args_t *args = NULL; + gfx_setxattr_req req = { + { + 0, + }, + }; + int ret = 0; + int op_errno = ESTALE; + + if (!frame || !this || !data) + goto unwind; + + args = data; + conf = this->private; + + ret = client_pre_setxattr_v2(this, &req, args->loc, args->xattr, + args->flags, args->xdata); + if (ret) { + op_errno = -ret; + goto unwind; + } + ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_SETXATTR, + client4_0_setxattr_cbk, NULL, + (xdrproc_t)xdr_gfx_setxattr_req); + if (ret) { + gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); + } + GF_FREE(req.dict.pairs.pairs_val); + + GF_FREE(req.xdata.pairs.pairs_val); + + return 0; +unwind: + CLIENT_STACK_UNWIND(setxattr, frame, -1, op_errno, NULL); + GF_FREE(req.dict.pairs.pairs_val); + + GF_FREE(req.xdata.pairs.pairs_val); + + return 0; +} + +int32_t +client4_0_fsetxattr(call_frame_t *frame, xlator_t *this, void *data) +{ + clnt_args_t *args = NULL; + clnt_conf_t *conf = NULL; + gfx_fsetxattr_req req = { + { + 0, + }, + }; + int op_errno = ESTALE; + int ret = 0; + + if (!frame || !this || !data) + goto unwind; + + args = data; + conf = this->private; + + ret = client_pre_fsetxattr_v2(this, &req, args->fd, args->flags, + args->xattr, args->xdata); + if (ret) { + op_errno = -ret; + goto unwind; + } + ret = client_submit_request(this, &req, frame, conf->fops, + GFS3_OP_FSETXATTR, client4_0_fsetxattr_cbk, + NULL, (xdrproc_t)xdr_gfx_fsetxattr_req); + if (ret) { + gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); + } + + GF_FREE(req.dict.pairs.pairs_val); + GF_FREE(req.xdata.pairs.pairs_val); + + return 0; +unwind: + CLIENT_STACK_UNWIND(fsetxattr, frame, -1, op_errno, NULL); + GF_FREE(req.dict.pairs.pairs_val); + GF_FREE(req.xdata.pairs.pairs_val); + + return 0; +} + +int32_t +client4_0_fgetxattr(call_frame_t *frame, xlator_t *this, void *data) +{ + clnt_args_t *args = NULL; + clnt_conf_t *conf = NULL; + gfx_fgetxattr_req req = { + { + 0, + }, + }; + int op_errno = ESTALE; + int ret = 0; + clnt_local_t *local = NULL; + + if (!frame || !this || !data) + goto unwind; + + args = data; + conf = this->private; + + local = mem_get0(this->local_pool); + if (!local) { + op_errno = ENOMEM; + goto unwind; + } + frame->local = local; + + ret = client_pre_fgetxattr_v2(this, &req, args->fd, args->name, + args->xdata); + if (ret) { + op_errno = -ret; + goto unwind; + } + ret = client_submit_request(this, &req, frame, conf->fops, + GFS3_OP_FGETXATTR, client4_0_fgetxattr_cbk, + NULL, (xdrproc_t)xdr_gfx_fgetxattr_req); + if (ret) { + gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); + } + + GF_FREE(req.xdata.pairs.pairs_val); + + return 0; +unwind: + CLIENT_STACK_UNWIND(fgetxattr, frame, -1, op_errno, NULL, NULL); + + GF_FREE(req.xdata.pairs.pairs_val); + + return 0; +} + +int32_t +client4_0_getxattr(call_frame_t *frame, xlator_t *this, void *data) +{ + clnt_conf_t *conf = NULL; + clnt_args_t *args = NULL; + gfx_getxattr_req req = { + { + 0, + }, + }; + dict_t *dict = NULL; + int ret = 0; + int32_t op_ret = -1; + int op_errno = ESTALE; + clnt_local_t *local = NULL; + + if (!frame || !this || !data) { + op_errno = 0; + goto unwind; + } + args = data; + + local = mem_get0(this->local_pool); + if (!local) { + op_errno = ENOMEM; + goto unwind; + } + + frame->local = local; + + loc_copy(&local->loc, args->loc); + loc_path(&local->loc, NULL); + + if (args->name) + local->name = gf_strdup(args->name); + + conf = this->private; + + if (args && args->name) { + if (is_client_dump_locks_cmd((char *)args->name)) { + dict = dict_new(); + + if (!dict) { + op_errno = ENOMEM; + goto unwind; + } + + ret = client_dump_locks((char *)args->name, args->loc->inode, dict); + if (ret) { + gf_smsg(this->name, GF_LOG_WARNING, EINVAL, + PC_MSG_CLIENT_DUMP_LOCKS_FAILED, NULL); + op_errno = ENOMEM; + goto unwind; + } + + GF_ASSERT(dict); + op_ret = 0; + op_errno = 0; + goto unwind; + } + } + + ret = client_pre_getxattr_v2(this, &req, args->loc, args->name, + args->xdata); + if (ret) { + op_errno = -ret; + goto unwind; + } + ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_GETXATTR, + client4_0_getxattr_cbk, NULL, + (xdrproc_t)xdr_gfx_getxattr_req); + if (ret) { + gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); + } + + GF_FREE(req.xdata.pairs.pairs_val); + + return 0; +unwind: + CLIENT_STACK_UNWIND(getxattr, frame, op_ret, op_errno, dict, NULL); + + if (dict) { + dict_unref(dict); + } + + GF_FREE(req.xdata.pairs.pairs_val); + + return 0; +} + +int32_t +client4_0_xattrop(call_frame_t *frame, xlator_t *this, void *data) +{ + clnt_conf_t *conf = NULL; + clnt_args_t *args = NULL; + gfx_xattrop_req req = { + { + 0, + }, + }; + int ret = 0; + int op_errno = ESTALE; + clnt_local_t *local = NULL; + + 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; + + loc_copy(&local->loc, args->loc); + loc_path(&local->loc, NULL); + conf = this->private; + + ret = client_pre_xattrop_v2(this, &req, args->loc, args->xattr, args->flags, + args->xdata); + if (ret) { + op_errno = -ret; + goto unwind; + } + ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_XATTROP, + client4_0_xattrop_cbk, NULL, + (xdrproc_t)xdr_gfx_xattrop_req); + if (ret) { + gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); + } + + GF_FREE(req.dict.pairs.pairs_val); + GF_FREE(req.xdata.pairs.pairs_val); + + return 0; +unwind: + CLIENT_STACK_UNWIND(xattrop, frame, -1, op_errno, NULL, NULL); + + GF_FREE(req.dict.pairs.pairs_val); + GF_FREE(req.xdata.pairs.pairs_val); + + return 0; +} + +int32_t +client4_0_fxattrop(call_frame_t *frame, xlator_t *this, void *data) +{ + clnt_args_t *args = NULL; + clnt_conf_t *conf = NULL; + gfx_fxattrop_req req = { + { + 0, + }, + }; + int op_errno = ESTALE; + int ret = 0; + + if (!frame || !this || !data) + goto unwind; + + args = data; + conf = this->private; + + ret = client_pre_fxattrop_v2(this, &req, args->fd, args->xattr, args->flags, + args->xdata); + if (ret) { + op_errno = -ret; + goto unwind; + } + ret = client_fd_fop_prepare_local(frame, args->fd, req.fd); + if (ret) { + op_errno = -ret; + goto unwind; + } + + ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_FXATTROP, + client4_0_fxattrop_cbk, NULL, + (xdrproc_t)xdr_gfx_fxattrop_req); + if (ret) { + gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); + } + + GF_FREE(req.dict.pairs.pairs_val); + GF_FREE(req.xdata.pairs.pairs_val); + + return 0; +unwind: + CLIENT_STACK_UNWIND(fxattrop, frame, -1, op_errno, NULL, NULL); + + GF_FREE(req.dict.pairs.pairs_val); + GF_FREE(req.xdata.pairs.pairs_val); + + return 0; +} + +int32_t +client4_0_removexattr(call_frame_t *frame, xlator_t *this, void *data) +{ + clnt_conf_t *conf = NULL; + clnt_args_t *args = NULL; + gfx_removexattr_req req = { + { + 0, + }, + }; + int ret = 0; + int op_errno = ESTALE; + + if (!frame || !this || !data) + goto unwind; + + args = data; + conf = this->private; + + ret = client_pre_removexattr_v2(this, &req, args->loc, args->name, + args->xdata); + if (ret) { + op_errno = -ret; + goto unwind; + } + ret = client_submit_request(this, &req, frame, conf->fops, + GFS3_OP_REMOVEXATTR, client4_0_removexattr_cbk, + NULL, (xdrproc_t)xdr_gfx_removexattr_req); + if (ret) { + gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); + } + + GF_FREE(req.xdata.pairs.pairs_val); + + return 0; +unwind: + CLIENT_STACK_UNWIND(removexattr, frame, -1, op_errno, NULL); + GF_FREE(req.xdata.pairs.pairs_val); + + return 0; +} + +int32_t +client4_0_fremovexattr(call_frame_t *frame, xlator_t *this, void *data) +{ + clnt_conf_t *conf = NULL; + clnt_args_t *args = NULL; + gfx_fremovexattr_req req = { + { + 0, + }, + }; + int ret = 0; + int op_errno = ESTALE; + + if (!frame || !this || !data) + goto unwind; + + args = data; + + conf = this->private; + + ret = client_pre_fremovexattr_v2(this, &req, args->fd, args->name, + args->xdata); + if (ret) { + op_errno = -ret; + goto unwind; + } + ret = client_submit_request( + this, &req, frame, conf->fops, GFS3_OP_FREMOVEXATTR, + client4_0_fremovexattr_cbk, NULL, (xdrproc_t)xdr_gfx_fremovexattr_req); + if (ret) { + gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); + } + + GF_FREE(req.xdata.pairs.pairs_val); + + return 0; +unwind: + CLIENT_STACK_UNWIND(fremovexattr, frame, -1, op_errno, NULL); + GF_FREE(req.xdata.pairs.pairs_val); + + return 0; +} + +int32_t +client4_0_lease(call_frame_t *frame, xlator_t *this, void *data) +{ + clnt_args_t *args = NULL; + gfx_lease_req req = { + { + 0, + }, + }; + clnt_conf_t *conf = NULL; + int op_errno = ESTALE; + int ret = 0; + + GF_VALIDATE_OR_GOTO("client", this, unwind); + GF_VALIDATE_OR_GOTO(this->name, frame, unwind); + GF_VALIDATE_OR_GOTO(this->name, data, unwind); + + args = data; + conf = this->private; + + ret = client_pre_lease_v2(this, &req, args->loc, args->lease, args->xdata); + if (ret < 0) { + op_errno = -ret; + goto unwind; + } + ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_LEASE, + client4_0_lease_cbk, NULL, + (xdrproc_t)xdr_gfx_lease_req); + if (ret) { + gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); + } + + GF_FREE(req.xdata.pairs.pairs_val); + + return 0; +unwind: + CLIENT_STACK_UNWIND(lease, frame, -1, op_errno, NULL, NULL); + GF_FREE(req.xdata.pairs.pairs_val); + + return 0; +} + +int32_t +client4_0_lk(call_frame_t *frame, xlator_t *this, void *data) +{ + clnt_args_t *args = NULL; + gfx_lk_req req = { + { + 0, + }, + }; + int32_t gf_cmd = 0; + 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; + } + frame->local = local; + + ret = client_cmd_to_gf_cmd(args->cmd, &gf_cmd); + if (ret) { + op_errno = EINVAL; + gf_smsg(this->name, GF_LOG_WARNING, EINVAL, PC_MSG_UNKNOWN_CMD, + "gf_cmd=%d", gf_cmd, NULL); + goto unwind; + } + + local->owner = frame->root->lk_owner; + local->cmd = args->cmd; + local->fd = fd_ref(args->fd); + + ret = client_pre_lk_v2(this, &req, args->cmd, args->flock, args->fd, + args->xdata); + if (ret) { + op_errno = -ret; + + if ((op_errno == EBADF) && (args->flock->l_type == F_UNLCK) && + client_is_setlk(local->cmd)) { + client_add_lock_for_recovery(local->fd, args->flock, &local->owner, + local->cmd); + } + + goto unwind; + } + + ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_LK, + client4_0_lk_cbk, NULL, + (xdrproc_t)xdr_gfx_lk_req); + if (ret) { + gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); + } + + GF_FREE(req.xdata.pairs.pairs_val); + + return 0; +unwind: + CLIENT_STACK_UNWIND(lk, frame, -1, op_errno, NULL, NULL); + GF_FREE(req.xdata.pairs.pairs_val); + + return 0; +} + +int32_t +client4_0_inodelk(call_frame_t *frame, xlator_t *this, void *data) +{ + clnt_conf_t *conf = NULL; + clnt_args_t *args = NULL; + gfx_inodelk_req req = { + { + 0, + }, + }; + int ret = 0; + int op_errno = ESTALE; + + if (!frame || !this || !data) + goto unwind; + + args = data; + conf = this->private; + + ret = client_pre_inodelk_v2(this, &req, args->loc, args->cmd, args->flock, + args->volume, args->xdata); + if (ret) { + op_errno = -ret; + goto unwind; + } + ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_INODELK, + client4_0_inodelk_cbk, NULL, + (xdrproc_t)xdr_gfx_inodelk_req); + if (ret) { + gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); + } + + GF_FREE(req.xdata.pairs.pairs_val); + + return 0; +unwind: + CLIENT_STACK_UNWIND(inodelk, frame, -1, op_errno, NULL); + GF_FREE(req.xdata.pairs.pairs_val); + + return 0; +} + +int32_t +client4_0_finodelk(call_frame_t *frame, xlator_t *this, void *data) +{ + clnt_args_t *args = NULL; + gfx_finodelk_req req = { + { + 0, + }, + }; + clnt_conf_t *conf = NULL; + int op_errno = ESTALE; + int ret = 0; + + if (!frame || !this || !data) + goto unwind; + + args = data; + conf = this->private; + + ret = client_pre_finodelk_v2(this, &req, args->fd, args->cmd, args->flock, + args->volume, args->xdata); + if (ret) { + op_errno = -ret; + goto unwind; + } + + ret = client_fd_fop_prepare_local(frame, args->fd, req.fd); + if (ret) { + op_errno = -ret; + goto unwind; + } + + ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_FINODELK, + client4_0_finodelk_cbk, NULL, + (xdrproc_t)xdr_gfx_finodelk_req); + if (ret) { + gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); + } + + GF_FREE(req.xdata.pairs.pairs_val); + return 0; +unwind: + CLIENT_STACK_UNWIND(finodelk, frame, -1, op_errno, NULL); + GF_FREE(req.xdata.pairs.pairs_val); + + return 0; +} + +int32_t +client4_0_entrylk(call_frame_t *frame, xlator_t *this, void *data) +{ + clnt_conf_t *conf = NULL; + clnt_args_t *args = NULL; + gfx_entrylk_req req = { + { + 0, + }, + }; + int ret = 0; + int op_errno = ESTALE; + + if (!frame || !this || !data) + goto unwind; + + args = data; + + conf = this->private; + + ret = client_pre_entrylk_v2(this, &req, args->loc, args->cmd_entrylk, + args->type, args->volume, args->basename, + args->xdata); + if (ret) { + op_errno = -ret; + goto unwind; + } + + ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_ENTRYLK, + client4_0_entrylk_cbk, NULL, + (xdrproc_t)xdr_gfx_entrylk_req); + if (ret) { + gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); + } + + GF_FREE(req.xdata.pairs.pairs_val); + + return 0; +unwind: + CLIENT_STACK_UNWIND(entrylk, frame, -1, op_errno, NULL); + GF_FREE(req.xdata.pairs.pairs_val); + + return 0; +} + +int32_t +client4_0_fentrylk(call_frame_t *frame, xlator_t *this, void *data) +{ + clnt_args_t *args = NULL; + gfx_fentrylk_req req = { + { + 0, + }, + }; + clnt_conf_t *conf = NULL; + int op_errno = ESTALE; + int ret = 0; + + if (!frame || !this || !data) + goto unwind; + + args = data; + conf = this->private; + + ret = client_pre_fentrylk_v2(this, &req, args->fd, args->cmd_entrylk, + args->type, args->volume, args->basename, + args->xdata); + if (ret) { + op_errno = -ret; + goto unwind; + } + ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_FENTRYLK, + client4_0_fentrylk_cbk, NULL, + (xdrproc_t)xdr_gfx_fentrylk_req); + if (ret) { + gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); + } + + GF_FREE(req.xdata.pairs.pairs_val); + + return 0; +unwind: + CLIENT_STACK_UNWIND(fentrylk, frame, -1, op_errno, NULL); + GF_FREE(req.xdata.pairs.pairs_val); + + return 0; +} + +int32_t +client4_0_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; + gfx_readdir_req req = { + { + 0, + }, + }; + gfx_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; + client_payload_t cp; + + if (!frame || !this || !data) + goto unwind; + + args = data; + conf = this->private; + + readdir_rsp_size = xdr_sizeof((xdrproc_t)xdr_gfx_readdir_rsp, &rsp) + + args->size; + + local = mem_get0(this->local_pool); + if (!local) { + op_errno = ENOMEM; + goto unwind; + } + frame->local = local; + + local->cmd = remote_fd; + + if ((readdir_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); + + rsphdr = &vector[0]; + rsphdr->iov_base = iobuf_ptr(rsp_iobuf); + rsphdr->iov_len = iobuf_pagesize(rsp_iobuf); + count = 1; + local->iobref = rsp_iobref; + iobuf_unref(rsp_iobuf); + rsp_iobuf = NULL; + rsp_iobref = NULL; + } + + ret = client_pre_readdir_v2(this, &req, args->fd, args->size, args->offset, + args->xdata); + if (ret) { + op_errno = -ret; + goto unwind; + } + + memset(&cp, 0, sizeof(client_payload_t)); + + cp.rsphdr = rsphdr; + cp.rsphdr_cnt = count; + cp.rsp_iobref = rsp_iobref; + ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_READDIR, + client4_0_readdir_cbk, &cp, + (xdrproc_t)xdr_gfx_readdir_req); + + if (ret) { + gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); + } + + GF_FREE(req.xdata.pairs.pairs_val); + + return 0; + +unwind: + if (rsp_iobref) + iobref_unref(rsp_iobref); + + CLIENT_STACK_UNWIND(readdir, frame, -1, op_errno, NULL, NULL); + GF_FREE(req.xdata.pairs.pairs_val); + + return 0; +} + +int32_t +client4_0_readdirp(call_frame_t *frame, xlator_t *this, void *data) +{ + clnt_args_t *args = NULL; + gfx_readdirp_req req = { + { + 0, + }, + }; + gfx_readdirp_rsp rsp = { + 0, + }; + 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; + client_payload_t cp; + + if (!frame || !this || !data) + goto unwind; + + args = data; + conf = this->private; + + local = mem_get0(this->local_pool); + if (!local) { + op_errno = ENOMEM; + goto unwind; + } + frame->local = local; + + ret = client_pre_readdirp_v2(this, &req, args->fd, args->size, args->offset, + args->xdata); + + if (ret) { + op_errno = -ret; + goto unwind; + } + + readdirp_rsp_size = xdr_sizeof((xdrproc_t)xdr_gfx_readdirp_rsp, &rsp) + + args->size; + + 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; + } + + rsphdr = &vector[0]; + rsphdr->iov_base = iobuf_ptr(rsp_iobuf); + rsphdr->iov_len = iobuf_pagesize(rsp_iobuf); + count = 1; + local->iobref = rsp_iobref; + iobref_add(rsp_iobref, rsp_iobuf); + iobuf_unref(rsp_iobuf); + rsp_iobuf = NULL; + rsp_iobref = NULL; + } + + local->fd = fd_ref(args->fd); + + memset(&cp, 0, sizeof(client_payload_t)); + + cp.rsphdr = rsphdr; + cp.rsphdr_cnt = count; + cp.rsp_iobref = rsp_iobref; + ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_READDIRP, + client4_0_readdirp_cbk, &cp, + (xdrproc_t)xdr_gfx_readdirp_req); + if (ret) { + gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); + } + + GF_FREE(req.xdata.pairs.pairs_val); + + return 0; +unwind: + if (rsp_iobref) + iobref_unref(rsp_iobref); + + GF_FREE(req.xdata.pairs.pairs_val); + + CLIENT_STACK_UNWIND(readdirp, frame, -1, op_errno, NULL, NULL); + return 0; +} + +int32_t +client4_0_setattr(call_frame_t *frame, xlator_t *this, void *data) +{ + clnt_conf_t *conf = NULL; + clnt_args_t *args = NULL; + gfx_setattr_req req = { + { + 0, + }, + }; + int ret = 0; + int op_errno = ESTALE; + + if (!frame || !this || !data) + goto unwind; + + args = data; + conf = this->private; + + ret = client_pre_setattr_v2(this, &req, args->loc, args->valid, args->stbuf, + args->xdata); + + if (ret) { + op_errno = -ret; + goto unwind; + } + + ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_SETATTR, + client4_0_setattr_cbk, NULL, + (xdrproc_t)xdr_gfx_setattr_req); + if (ret) { + gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); + } + + GF_FREE(req.xdata.pairs.pairs_val); + + return 0; +unwind: + CLIENT_STACK_UNWIND(setattr, frame, -1, op_errno, NULL, NULL, NULL); + GF_FREE(req.xdata.pairs.pairs_val); + + return 0; +} + +int32_t +client4_0_fallocate(call_frame_t *frame, xlator_t *this, void *data) +{ + clnt_args_t *args = NULL; + clnt_conf_t *conf = NULL; + gfx_fallocate_req req = { + {0}, + }; + int op_errno = ESTALE; + int ret = 0; + + if (!frame || !this || !data) + goto unwind; + + args = data; + conf = this->private; + + ret = client_pre_fallocate_v2(this, &req, args->fd, args->flags, + args->offset, args->size, args->xdata); + if (ret) { + op_errno = -ret; + goto unwind; + } + + ret = client_submit_request(this, &req, frame, conf->fops, + GFS3_OP_FALLOCATE, client4_0_fallocate_cbk, + NULL, (xdrproc_t)xdr_gfx_fallocate_req); + if (ret) { + gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); + } + + GF_FREE(req.xdata.pairs.pairs_val); + + return 0; +unwind: + CLIENT_STACK_UNWIND(fallocate, frame, -1, op_errno, NULL, NULL, NULL); + GF_FREE(req.xdata.pairs.pairs_val); + + return 0; +} + +int32_t +client4_0_discard(call_frame_t *frame, xlator_t *this, void *data) +{ + clnt_args_t *args = NULL; + clnt_conf_t *conf = NULL; + gfx_discard_req req = { + {0}, + }; + int op_errno = ESTALE; + int ret = 0; + + if (!frame || !this || !data) + goto unwind; + + args = data; + conf = this->private; + + ret = client_pre_discard_v2(this, &req, args->fd, args->offset, args->size, + args->xdata); + if (ret) { + op_errno = -ret; + goto unwind; + } + + ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_DISCARD, + client4_0_discard_cbk, NULL, + (xdrproc_t)xdr_gfx_discard_req); + if (ret) + gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); + + GF_FREE(req.xdata.pairs.pairs_val); + + return 0; +unwind: + CLIENT_STACK_UNWIND(discard, frame, -1, op_errno, NULL, NULL, NULL); + GF_FREE(req.xdata.pairs.pairs_val); + + return 0; +} + +int32_t +client4_0_zerofill(call_frame_t *frame, xlator_t *this, void *data) +{ + clnt_args_t *args = NULL; + clnt_conf_t *conf = NULL; + gfx_zerofill_req req = { + {0}, + }; + int op_errno = ESTALE; + int ret = 0; + + GF_ASSERT(frame); + + if (!this || !data) + goto unwind; + + args = data; + conf = this->private; + + ret = client_pre_zerofill_v2(this, &req, args->fd, args->offset, args->size, + args->xdata); + if (ret) { + op_errno = -ret; + goto unwind; + } + + ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_ZEROFILL, + client4_0_zerofill_cbk, NULL, + (xdrproc_t)xdr_gfx_zerofill_req); + if (ret) + gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); + + GF_FREE(req.xdata.pairs.pairs_val); + + return 0; +unwind: + CLIENT_STACK_UNWIND(zerofill, frame, -1, op_errno, NULL, NULL, NULL); + GF_FREE(req.xdata.pairs.pairs_val); + + return 0; +} + +int32_t +client4_0_ipc(call_frame_t *frame, xlator_t *this, void *data) +{ + clnt_args_t *args = NULL; + clnt_conf_t *conf = NULL; + gfx_ipc_req req = { + 0, + }; + int op_errno = ESTALE; + int ret = 0; + + GF_ASSERT(frame); + + if (!this || !data) + goto unwind; + + args = data; + conf = this->private; + + ret = client_pre_ipc_v2(this, &req, args->cmd, args->xdata); + + if (ret) { + op_errno = -ret; + goto unwind; + } + + ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_IPC, + client4_0_ipc_cbk, NULL, + (xdrproc_t)xdr_gfx_ipc_req); + if (ret) + gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); + + GF_FREE(req.xdata.pairs.pairs_val); + + return 0; +unwind: + CLIENT_STACK_UNWIND(ipc, frame, -1, op_errno, NULL); + GF_FREE(req.xdata.pairs.pairs_val); + + return 0; +} + +int32_t +client4_0_seek(call_frame_t *frame, xlator_t *this, void *data) +{ + clnt_args_t *args = NULL; + clnt_conf_t *conf = NULL; + struct gfx_seek_req req = { + { + 0, + }, + }; + int op_errno = ESTALE; + int ret = 0; + + GF_ASSERT(frame); + + if (!this || !data) + goto unwind; + + args = data; + conf = this->private; + + ret = client_pre_seek_v2(this, &req, args->fd, args->offset, args->what, + args->xdata); + if (ret) { + op_errno = -ret; + goto unwind; + } + + ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_SEEK, + client4_0_seek_cbk, NULL, + (xdrproc_t)xdr_gfx_seek_req); + if (ret) + gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); + + GF_FREE(req.xdata.pairs.pairs_val); + + return 0; +unwind: + CLIENT_STACK_UNWIND(ipc, frame, -1, op_errno, NULL); + GF_FREE(req.xdata.pairs.pairs_val); + + return 0; +} + +int32_t +client4_0_getactivelk(call_frame_t *frame, xlator_t *this, void *data) +{ + clnt_conf_t *conf = NULL; + clnt_args_t *args = NULL; + gfx_getactivelk_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 (!gf_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, + !gf_uuid_is_null(*((uuid_t *)req.gfid)), + unwind, op_errno, EINVAL); + conf = this->private; + + dict_to_xdr(args->xdata, &req.xdata); + + ret = client_submit_request(this, &req, frame, conf->fops, + GFS3_OP_GETACTIVELK, client4_0_getactivelk_cbk, + NULL, (xdrproc_t)xdr_gfx_getactivelk_req); + if (ret) { + gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); + } + + GF_FREE(req.xdata.pairs.pairs_val); + + return 0; +unwind: + CLIENT_STACK_UNWIND(getactivelk, frame, -1, op_errno, NULL, NULL); + + GF_FREE(req.xdata.pairs.pairs_val); + + return 0; +} + +int32_t +client4_0_setactivelk(call_frame_t *frame, xlator_t *this, void *data) +{ + clnt_conf_t *conf = NULL; + clnt_args_t *args = NULL; + gfx_setactivelk_req req = { + { + 0, + }, + }; + int ret = 0; + int op_errno = ESTALE; + + if (!frame || !this || !data) + goto unwind; + + args = data; + if (!(args->loc && args->loc->inode && args->locklist)) + goto unwind; + + if (!gf_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, + !gf_uuid_is_null(*((uuid_t *)req.gfid)), + unwind, op_errno, EINVAL); + conf = this->private; + + dict_to_xdr(args->xdata, &req.xdata); + ret = serialize_req_locklist_v2(args->locklist, &req); + + if (ret) + goto unwind; + + ret = client_submit_request(this, &req, frame, conf->fops, + GFS3_OP_SETACTIVELK, client4_0_setactivelk_cbk, + NULL, (xdrproc_t)xdr_gfx_setactivelk_req); + if (ret) { + gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); + } + + clnt_setactivelk_req_cleanup_v2(&req); + + GF_FREE(req.xdata.pairs.pairs_val); + + return 0; + +unwind: + + CLIENT_STACK_UNWIND(setactivelk, frame, -1, op_errno, NULL); + + GF_FREE(req.xdata.pairs.pairs_val); + + clnt_setactivelk_req_cleanup_v2(&req); + + return 0; +} + +int +client4_rchecksum_cbk(struct rpc_req *req, struct iovec *iov, int count, + void *myframe) +{ + call_frame_t *frame = NULL; + gfx_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_gfx_rchecksum_rsp); + if (ret < 0) { + gf_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, + NULL); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; + } + + xdr_to_dict(&rsp.xdata, &xdata); +out: + if (rsp.op_ret == -1) { + gf_smsg(this->name, GF_LOG_WARNING, gf_error_to_errno(rsp.op_errno), + PC_MSG_REMOTE_OP_FAILED, NULL); + } + + 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); + } + + if (xdata) + dict_unref(xdata); + + return 0; +} + +int32_t +client4_namelink_cbk(struct rpc_req *req, struct iovec *iov, int count, + void *myframe) +{ + int32_t ret = 0; + struct iatt prebuf = { + 0, + }; + struct iatt postbuf = { + 0, + }; + dict_t *xdata = NULL; + call_frame_t *frame = NULL; + gfx_common_2iatt_rsp rsp = { + 0, + }; + + frame = myframe; + + if (req->rpc_status == -1) { + rsp.op_ret = -1; + rsp.op_errno = ENOTCONN; + goto out; + } + + ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gfx_common_2iatt_rsp); + if (ret < 0) { + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; + } + + if (rsp.op_ret != -1) { + gfx_stat_to_iattx(&rsp.prestat, &prebuf); + gfx_stat_to_iattx(&rsp.poststat, &postbuf); + } + + xdr_to_dict(&rsp.xdata, &xdata); +out: + CLIENT_STACK_UNWIND(namelink, frame, rsp.op_ret, + gf_error_to_errno(rsp.op_errno), &prebuf, &postbuf, + xdata); + if (xdata) + dict_unref(xdata); + return 0; +} + +int32_t +client4_icreate_cbk(struct rpc_req *req, struct iovec *iov, int count, + void *myframe) +{ + int32_t ret = 0; + inode_t *inode = NULL; + clnt_local_t *local = NULL; + struct iatt stbuf = { + 0, + }; + dict_t *xdata = NULL; + call_frame_t *frame = NULL; + gfx_common_iatt_rsp rsp = { + 0, + }; + + frame = myframe; + local = frame->local; + + inode = local->loc.inode; + + if (req->rpc_status == -1) { + rsp.op_ret = -1; + rsp.op_errno = ENOTCONN; + goto out; + } + + ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gfx_common_iatt_rsp); + if (ret < 0) { + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; + } + + if (rsp.op_ret != -1) + gfx_stat_to_iattx(&rsp.stat, &stbuf); + + xdr_to_dict(&rsp.xdata, &xdata); +out: + CLIENT_STACK_UNWIND(icreate, frame, rsp.op_ret, + gf_error_to_errno(rsp.op_errno), inode, &stbuf, xdata); + if (xdata) + dict_unref(xdata); + return 0; +} + +int +client4_0_put_cbk(struct rpc_req *req, struct iovec *iov, int count, + void *myframe) +{ + gfx_common_3iatt_rsp rsp = { + 0, + }; + call_frame_t *frame = NULL; + int ret = 0; + xlator_t *this = NULL; + dict_t *xdata = NULL; + clnt_local_t *local = NULL; + struct iatt stbuf = { + 0, + }; + struct iatt preparent = { + 0, + }; + struct iatt postparent = { + 0, + }; + inode_t *inode = 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_gfx_common_3iatt_rsp); + if (ret < 0) { + gf_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_XDR_DECODING_FAILED, + NULL); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; + } + + if (-1 != rsp.op_ret) { + ret = client_post_common_3iatt(this, &rsp, &stbuf, &preparent, + &postparent, &xdata); + if (ret < 0) + goto out; + } +out: + if (rsp.op_ret == -1) { + gf_smsg(this->name, GF_LOG_WARNING, gf_error_to_errno(rsp.op_errno), + PC_MSG_REMOTE_OP_FAILED, NULL); + } + + CLIENT_STACK_UNWIND(put, frame, rsp.op_ret, gf_error_to_errno(rsp.op_errno), + inode, &stbuf, &preparent, &postparent, xdata); + + if (xdata) + dict_unref(xdata); + + return 0; +} + +int32_t +client4_0_namelink(call_frame_t *frame, xlator_t *this, void *data) +{ + int32_t ret = 0; + int32_t op_errno = EINVAL; + clnt_conf_t *conf = NULL; + clnt_args_t *args = NULL; + gfx_namelink_req req = { + { + 0, + }, + }; + + GF_ASSERT(frame); + + args = data; + conf = this->private; + + if (!(args->loc && args->loc->parent)) + goto unwind; + + if (!gf_uuid_is_null(args->loc->parent->gfid)) + memcpy(req.pargfid, args->loc->parent->gfid, sizeof(uuid_t)); + else + memcpy(req.pargfid, args->loc->pargfid, sizeof(uuid_t)); + + GF_ASSERT_AND_GOTO_WITH_ERROR(this->name, + !gf_uuid_is_null(*((uuid_t *)req.pargfid)), + unwind, op_errno, EINVAL); + + req.bname = (char *)args->loc->name; + + dict_to_xdr(args->xdata, &req.xdata); + ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_NAMELINK, + client4_namelink_cbk, NULL, + (xdrproc_t)xdr_gfx_namelink_req); + if (ret) { + gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); + } + + GF_FREE(req.xdata.pairs.pairs_val); + return 0; + +unwind: + CLIENT_STACK_UNWIND(namelink, frame, -1, op_errno, NULL, NULL, NULL); + return 0; +} + +int32_t +client4_0_icreate(call_frame_t *frame, xlator_t *this, void *data) +{ + int32_t ret = 0; + int32_t op_errno = EINVAL; + clnt_conf_t *conf = NULL; + clnt_args_t *args = NULL; + clnt_local_t *local = NULL; + gfx_icreate_req req = { + { + 0, + }, + }; + + GF_ASSERT(frame); + + args = data; + conf = this->private; + + if (!(args->loc && args->loc->inode)) + goto unwind; + + local = mem_get0(this->local_pool); + if (!local) { + op_errno = ENOMEM; + goto unwind; + } + frame->local = local; + + loc_copy(&local->loc, args->loc); + + req.mode = args->mode; + memcpy(req.gfid, args->loc->gfid, sizeof(uuid_t)); + + op_errno = ESTALE; + dict_to_xdr(args->xdata, &req.xdata); + ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_ICREATE, + client4_icreate_cbk, NULL, + (xdrproc_t)xdr_gfx_icreate_req); + if (ret) + goto free_reqdata; + GF_FREE(req.xdata.pairs.pairs_val); + return 0; + +free_reqdata: + GF_FREE(req.xdata.pairs.pairs_val); +unwind: + CLIENT_STACK_UNWIND(icreate, frame, -1, op_errno, NULL, NULL, NULL); + return 0; +} + +int32_t +client4_0_put(call_frame_t *frame, xlator_t *this, void *data) +{ + clnt_args_t *args = NULL; + clnt_conf_t *conf = NULL; + gfx_put_req req = { + { + 0, + }, + }; + int op_errno = ESTALE; + int ret = 0; + clnt_local_t *local = NULL; + client_payload_t cp; + + if (!frame || !this || !data) + goto unwind; + + args = data; + conf = this->private; + + local = mem_get0(this->local_pool); + if (!local) { + op_errno = ENOMEM; + goto unwind; + } + frame->local = local; + + loc_copy(&local->loc, args->loc); + loc_path(&local->loc, NULL); + + ret = client_pre_put_v2(this, &req, args->loc, args->mode, args->umask, + args->flags, args->size, args->offset, args->xattr, + args->xdata); + + if (ret) { + op_errno = -ret; + goto unwind; + } + + memset(&cp, 0, sizeof(client_payload_t)); + + cp.iobref = args->iobref; + cp.payload = args->vector; + cp.payload_cnt = args->count; + ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_PUT, + client4_0_put_cbk, &cp, + (xdrproc_t)xdr_gfx_put_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_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); + } + + return 0; + +unwind: + CLIENT_STACK_UNWIND(put, frame, -1, op_errno, NULL, NULL, NULL, NULL, NULL); + return 0; +} + +int32_t +client4_0_copy_file_range(call_frame_t *frame, xlator_t *this, void *data) +{ + clnt_args_t *args = NULL; + clnt_conf_t *conf = NULL; + clnt_local_t *local = NULL; + gfx_copy_file_range_req req = { + { + 0, + }, + }; + int op_errno = ESTALE; + int ret = 0; + + if (!frame || !this || !data) + goto unwind; + + args = data; + conf = this->private; + + ret = client_pre_copy_file_range_v2(this, &req, args->fd, args->off_in, + args->fd_out, args->off_out, args->size, + args->flags, &args->xdata); + + if (ret) { + op_errno = -ret; + goto unwind; + } + + ret = client_fd_fop_prepare_local(frame, args->fd, req.fd_in); + if (ret) { + op_errno = -ret; + goto unwind; + } + + /* + * Since frame->local is allocated in above function call + * itself, better to use it (with the assumption that it + * has been allocated) directly instead of again calling + * client_fd_fop_prepare_local or modifying it, as doing + * so requires changes in other places as well. + */ + + local = frame->local; + local->fd_out = fd_ref(args->fd_out); + local->attempt_reopen_out = client_is_reopen_needed(args->fd_out, this, + req.fd_out); + + ret = client_submit_request(this, &req, frame, conf->fops, + GFS3_OP_COPY_FILE_RANGE, + client4_0_copy_file_range_cbk, NULL, + (xdrproc_t)xdr_gfx_copy_file_range_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_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); + } + + GF_FREE(req.xdata.pairs.pairs_val); + + return 0; + +unwind: + CLIENT_STACK_UNWIND(copy_file_range, frame, -1, op_errno, NULL, NULL, NULL, + NULL); + GF_FREE(req.xdata.pairs.pairs_val); + + return 0; +} + +int32_t +client4_0_fsetattr(call_frame_t *frame, xlator_t *this, void *data) +{ + clnt_args_t *args = NULL; + clnt_conf_t *conf = NULL; + gfx_fsetattr_req req = { + {0}, + }; + int op_errno = ESTALE; + int ret = 0; + + if (!frame || !this || !data) + goto unwind; + + args = data; + conf = this->private; + + ret = client_pre_fsetattr_v2(this, &req, args->fd, args->valid, args->stbuf, + args->xdata); + if (ret) { + op_errno = -ret; + goto unwind; + } + ret = client_submit_request(this, &req, frame, conf->fops, GFS3_OP_FSETATTR, + client4_0_fsetattr_cbk, NULL, + (xdrproc_t)xdr_gfx_fsetattr_req); + if (ret) { + gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); + } + + GF_FREE(req.xdata.pairs.pairs_val); + + return 0; +unwind: + CLIENT_STACK_UNWIND(fsetattr, frame, -1, op_errno, NULL, NULL, NULL); + GF_FREE(req.xdata.pairs.pairs_val); + + return 0; +} + +int32_t +client4_0_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; + gfx_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; + memcpy(req.gfid, args->fd->inode->gfid, 16); + + dict_to_xdr(args->xdata, &req.xdata); + + ret = client_submit_request(this, &req, frame, conf->fops, + GFS3_OP_RCHECKSUM, client4_rchecksum_cbk, NULL, + (xdrproc_t)xdr_gfx_rchecksum_req); + if (ret) { + gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, NULL); + } + + GF_FREE(req.xdata.pairs.pairs_val); + + return 0; +unwind: + CLIENT_STACK_UNWIND(rchecksum, frame, -1, op_errno, 0, NULL, NULL); + GF_FREE(req.xdata.pairs.pairs_val); + + return 0; +} + +/* Used From RPC-CLNT library to log proper name of procedure based on number */ +char *clnt4_0_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", + [GFS3_OP_IPC] = "IPC", + [GFS3_OP_SEEK] = "SEEK", + [GFS3_OP_LEASE] = "LEASE", + [GFS3_OP_GETACTIVELK] = "GETACTIVELK", + [GFS3_OP_SETACTIVELK] = "SETACTIVELK", + [GFS3_OP_COMPOUND] = "COMPOUND", + [GFS3_OP_ICREATE] = "ICREATE", + [GFS3_OP_NAMELINK] = "NAMELINK", +}; + +rpc_clnt_procedure_t clnt4_0_fop_actors[GF_FOP_MAXVALUE] = { + [GF_FOP_NULL] = {"NULL", NULL}, + [GF_FOP_STAT] = {"STAT", client4_0_stat}, + [GF_FOP_READLINK] = {"READLINK", client4_0_readlink}, + [GF_FOP_MKNOD] = {"MKNOD", client4_0_mknod}, + [GF_FOP_MKDIR] = {"MKDIR", client4_0_mkdir}, + [GF_FOP_UNLINK] = {"UNLINK", client4_0_unlink}, + [GF_FOP_RMDIR] = {"RMDIR", client4_0_rmdir}, + [GF_FOP_SYMLINK] = {"SYMLINK", client4_0_symlink}, + [GF_FOP_RENAME] = {"RENAME", client4_0_rename}, + [GF_FOP_LINK] = {"LINK", client4_0_link}, + [GF_FOP_TRUNCATE] = {"TRUNCATE", client4_0_truncate}, + [GF_FOP_OPEN] = {"OPEN", client4_0_open}, + [GF_FOP_READ] = {"READ", client4_0_readv}, + [GF_FOP_WRITE] = {"WRITE", client4_0_writev}, + [GF_FOP_STATFS] = {"STATFS", client4_0_statfs}, + [GF_FOP_FLUSH] = {"FLUSH", client4_0_flush}, + [GF_FOP_FSYNC] = {"FSYNC", client4_0_fsync}, + [GF_FOP_GETXATTR] = {"GETXATTR", client4_0_getxattr}, + [GF_FOP_SETXATTR] = {"SETXATTR", client4_0_setxattr}, + [GF_FOP_REMOVEXATTR] = {"REMOVEXATTR", client4_0_removexattr}, + [GF_FOP_OPENDIR] = {"OPENDIR", client4_0_opendir}, + [GF_FOP_FSYNCDIR] = {"FSYNCDIR", client4_0_fsyncdir}, + [GF_FOP_ACCESS] = {"ACCESS", client4_0_access}, + [GF_FOP_CREATE] = {"CREATE", client4_0_create}, + [GF_FOP_FTRUNCATE] = {"FTRUNCATE", client4_0_ftruncate}, + [GF_FOP_FSTAT] = {"FSTAT", client4_0_fstat}, + [GF_FOP_LK] = {"LK", client4_0_lk}, + [GF_FOP_LOOKUP] = {"LOOKUP", client4_0_lookup}, + [GF_FOP_READDIR] = {"READDIR", client4_0_readdir}, + [GF_FOP_INODELK] = {"INODELK", client4_0_inodelk}, + [GF_FOP_FINODELK] = {"FINODELK", client4_0_finodelk}, + [GF_FOP_ENTRYLK] = {"ENTRYLK", client4_0_entrylk}, + [GF_FOP_FENTRYLK] = {"FENTRYLK", client4_0_fentrylk}, + [GF_FOP_XATTROP] = {"XATTROP", client4_0_xattrop}, + [GF_FOP_FXATTROP] = {"FXATTROP", client4_0_fxattrop}, + [GF_FOP_FGETXATTR] = {"FGETXATTR", client4_0_fgetxattr}, + [GF_FOP_FSETXATTR] = {"FSETXATTR", client4_0_fsetxattr}, + [GF_FOP_RCHECKSUM] = {"RCHECKSUM", client4_0_rchecksum}, + [GF_FOP_SETATTR] = {"SETATTR", client4_0_setattr}, + [GF_FOP_FSETATTR] = {"FSETATTR", client4_0_fsetattr}, + [GF_FOP_READDIRP] = {"READDIRP", client4_0_readdirp}, + [GF_FOP_FALLOCATE] = {"FALLOCATE", client4_0_fallocate}, + [GF_FOP_DISCARD] = {"DISCARD", client4_0_discard}, + [GF_FOP_ZEROFILL] = {"ZEROFILL", client4_0_zerofill}, + [GF_FOP_RELEASE] = {"RELEASE", client4_0_release}, + [GF_FOP_RELEASEDIR] = {"RELEASEDIR", client4_0_releasedir}, + [GF_FOP_GETSPEC] = {"GETSPEC", client3_getspec}, + [GF_FOP_FREMOVEXATTR] = {"FREMOVEXATTR", client4_0_fremovexattr}, + [GF_FOP_IPC] = {"IPC", client4_0_ipc}, + [GF_FOP_SEEK] = {"SEEK", client4_0_seek}, + [GF_FOP_LEASE] = {"LEASE", client4_0_lease}, + [GF_FOP_GETACTIVELK] = {"GETACTIVELK", client4_0_getactivelk}, + [GF_FOP_SETACTIVELK] = {"SETACTIVELK", client4_0_setactivelk}, + [GF_FOP_COMPOUND] = {"COMPOUND", NULL}, + [GF_FOP_ICREATE] = {"ICREATE", client4_0_icreate}, + [GF_FOP_NAMELINK] = {"NAMELINK", client4_0_namelink}, + [GF_FOP_COPY_FILE_RANGE] = {"COPY-FILE-RANGE", client4_0_copy_file_range}, +}; + +rpc_clnt_prog_t clnt4_0_fop_prog = { + .progname = "GlusterFS 4.x v1", + .prognum = GLUSTER_FOP_PROGRAM, + .progver = GLUSTER_FOP_VERSION_v2, + .numproc = GLUSTER_FOP_PROCCNT, + .proctable = clnt4_0_fop_actors, + .procnames = clnt4_0_fop_names, +}; diff --git a/xlators/protocol/client/src/client.c b/xlators/protocol/client/src/client.c index 87a4603c191..0f31fea9511 100644 --- a/xlators/protocol/client/src/client.c +++ b/xlators/protocol/client/src/client.c @@ -1,2377 +1,2997 @@ /* - Copyright (c) 2010-2011 Gluster, Inc. <http://www.gluster.com> + Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com> This file is part of GlusterFS. - GlusterFS is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 3 of the License, - or (at your option) any later version. - - GlusterFS is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see - <http://www.gnu.org/licenses/>. + This file is licensed to you under your choice of the GNU Lesser + General Public License, version 3 or any later version (LGPLv3 or + later), or the GNU General Public License, version 2 (GPLv2), in all + cases as published by the Free Software Foundation. */ - -#ifndef _CONFIG_H -#define _CONFIG_H -#include "config.h" -#endif - #include "client.h" -#include "xlator.h" -#include "defaults.h" -#include "glusterfs.h" -#include "statedump.h" -#include "compat-errno.h" - +#include <glusterfs/xlator.h> +#include <glusterfs/defaults.h> +#include <glusterfs/glusterfs.h> +#include <glusterfs/statedump.h> +#include <glusterfs/compat-errno.h> +#include <glusterfs/gf-event.h> + +#include "xdr-rpc.h" #include "glusterfs3.h" +#include "client-messages.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_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_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; - - 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; - } +client_handshake(xlator_t *this, struct rpc_clnt *rpc); +static int +client_destroy_rpc(xlator_t *this); - 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"); - } - } +static void +client_filter_o_direct(clnt_conf_t *conf, int32_t *flags) +{ + if (conf->filter_o_direct) + *flags = (*flags & ~O_DIRECT); +} - ret = iobref_add (new_iobref, iobuf); - if (ret != 0) { - gf_log (this->name, GF_LOG_WARNING, - "cannot add iobuf into iobref"); - goto out; - } +static int +client_fini_complete(xlator_t *this) +{ + GF_VALIDATE_OR_GOTO(this->name, this->private, 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; - } + clnt_conf_t *conf = this->private; + if (!conf->destroy) + return 0; + + pthread_mutex_lock(&conf->lock); + { + conf->fini_completed = _gf_true; + pthread_cond_broadcast(&conf->fini_complete_cond); + } + pthread_mutex_unlock(&conf->lock); + +out: + return 0; +} + +static int +client_is_last_child_down(xlator_t *this, int32_t event, struct rpc_clnt *rpc) +{ + rpc_clnt_connection_t *conn = NULL; + clnt_conf_t *conf = NULL; + int ret = 0; - /* Send the msg */ - ret = rpc_clnt_submit (conf->rpc, prog, procnum, cbk, &iov, count, NULL, - 0, new_iobref, frame, rsphdr, rsphdr_count, - rsp_payload, rsp_payload_count, rsp_iobref); + if (!this || !rpc) + goto out; - if (ret < 0) { - gf_log (this->name, GF_LOG_DEBUG, "rpc_clnt_submit failed"); + conf = this->private; + if (!conf) + goto out; + + if (!conf->parent_down) + goto out; + + if (event != GF_EVENT_CHILD_DOWN) + goto out; + + conn = &rpc->conn; + pthread_mutex_lock(&conn->lock); + { + if (!conn->reconnect && rpc->disabled) { + ret = 1; } + } + pthread_mutex_unlock(&conn->lock); +out: + return ret; +} - if (ret == 0) { - pthread_mutex_lock (&conf->rpc->conn.lock); - { - if (!conf->rpc->conn.ping_started) { - start_ping = 1; - } +int +client_notify_dispatch_uniq(xlator_t *this, int32_t event, void *data, ...) +{ + clnt_conf_t *conf = this->private; + glusterfs_ctx_t *ctx = this->ctx; + glusterfs_graph_t *graph = this->graph; + + pthread_mutex_lock(&ctx->notify_lock); + { + while (ctx->notifying) + pthread_cond_wait(&ctx->notify_cond, &ctx->notify_lock); + + if (client_is_last_child_down(this, event, data) && graph) { + pthread_mutex_lock(&graph->mutex); + { + graph->parent_down++; + if (graph->parent_down == graph_total_client_xlator(graph)) { + graph->used = 0; + pthread_cond_broadcast(&graph->child_down_cond); } - pthread_mutex_unlock (&conf->rpc->conn.lock); + } + pthread_mutex_unlock(&graph->mutex); } + } + pthread_mutex_unlock(&ctx->notify_lock); - if (start_ping) - client_start_ping ((void *) this); - - ret = 0; -out: - if (new_iobref != NULL) - iobref_unref (new_iobref); + if (conf->last_sent_event == event) + return 0; - if (iobuf) - iobuf_unref (iobuf); + return client_notify_dispatch(this, event, data); - return ret; + /* Please avoid any code that access xlator object here + * Because for a child down event, once we do the signal + * we will start cleanup. + */ } - -int32_t -client_forget (xlator_t *this, inode_t *inode) +int +client_notify_dispatch(xlator_t *this, int32_t event, void *data, ...) { - /* Nothing here */ - return 0; + int ret = -1; + glusterfs_ctx_t *ctx = this->ctx; + + clnt_conf_t *conf = this->private; + + pthread_mutex_lock(&ctx->notify_lock); + { + while (ctx->notifying) + pthread_cond_wait(&ctx->notify_cond, &ctx->notify_lock); + ctx->notifying = 1; + } + pthread_mutex_unlock(&ctx->notify_lock); + + /* We assume that all translators in the graph handle notification + * events in sequence. + * */ + + ret = default_notify(this, event, data); + + /* NB (Even) with MT-epoll and EPOLLET|EPOLLONESHOT we are guaranteed + * that there would be atmost one poller thread executing this + * notification function. This allows us to update last_sent_event + * without explicit synchronization. See epoll(7). + */ + conf->last_sent_event = event; + + pthread_mutex_lock(&ctx->notify_lock); + { + ctx->notifying = 0; + pthread_cond_signal(&ctx->notify_cond); + } + pthread_mutex_unlock(&ctx->notify_lock); + + /* Please avoid any code that access xlator object here + * Because for a child down event, once we do the signal + * we will start cleanup. + */ + + return ret; } -int32_t -client_releasedir (xlator_t *this, fd_t *fd) +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, + client_payload_t *cp, xdrproc_t xdrproc) { - int ret = -1; - clnt_conf_t *conf = NULL; - rpc_clnt_procedure_t *proc = NULL; - clnt_args_t args = {0,}; - call_frame_t *frame = NULL; + int ret = -1; + clnt_conf_t *conf = NULL; + struct iovec iov = { + 0, + }; + struct iobuf *iobuf = NULL; + int count = 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_msg_debug(this->name, 0, "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 (cp && cp->iobref != NULL) { + ret = iobref_merge(new_iobref, cp->iobref); + if (ret != 0) { + gf_smsg(this->name, GF_LOG_WARNING, ENOMEM, + PC_MSG_MERGE_IOBREF_FAILED, NULL); + } + } + + ret = iobref_add(new_iobref, iobuf); + if (ret != 0) { + gf_smsg(this->name, GF_LOG_WARNING, ENOMEM, PC_MSG_ADD_IOBUF_FAILED, + NULL); + 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; + } + + /* do not send all groups if they are resolved server-side */ + if (!conf->send_gids) { + if (frame->root->ngrps <= SMALL_GROUP_COUNT) { + frame->root->groups_small[0] = frame->root->gid; + frame->root->groups = frame->root->groups_small; + } + frame->root->ngrps = 1; + } + + /* Send the msg */ + if (cp) { + ret = rpc_clnt_submit(conf->rpc, prog, procnum, cbkfn, &iov, count, + cp->payload, cp->payload_cnt, new_iobref, frame, + cp->rsphdr, cp->rsphdr_cnt, cp->rsp_payload, + cp->rsp_payload_cnt, cp->rsp_iobref); + } else { + ret = rpc_clnt_submit(conf->rpc, prog, procnum, cbkfn, &iov, count, + NULL, 0, new_iobref, frame, NULL, 0, NULL, 0, + NULL); + } + + if (ret < 0) { + gf_msg_debug(this->name, 0, "rpc_clnt_submit failed"); + } + + ret = 0; + + if (new_iobref) + iobref_unref(new_iobref); + + if (iobuf) + iobuf_unref(iobuf); + + return ret; - conf = this->private; - if (!conf || !conf->fops) - goto out; +out: + rpcreq.rpc_status = -1; - args.fd = fd; + cbkfn(&rpcreq, NULL, 0, frame); - 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) { - frame = create_frame (this, this->ctx->pool); - if (!frame) { - goto out; - } - ret = proc->fn (frame, this, &args); - } -out: - if (ret) - gf_log (this->name, GF_LOG_WARNING, - "releasedir fop failed"); - return 0; + if (new_iobref) + iobref_unref(new_iobref); + + if (iobuf) + iobuf_unref(iobuf); + + return ret; } -int32_t -client_release (xlator_t *this, fd_t *fd) +static int32_t +client_forget(xlator_t *this, inode_t *inode) { - 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 || !conf->fops) - goto out; + /* Nothing here */ + return 0; +} +static 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; + + proc = &conf->fops->proctable[GF_FOP_RELEASEDIR]; + if (proc->fn) { 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) { - frame = create_frame (this, this->ctx->pool); - if (!frame) { - goto out; - } - ret = proc->fn (frame, this, &args); - } + ret = proc->fn(NULL, this, &args); + } out: - if (ret) - gf_log (this->name, GF_LOG_WARNING, - "release fop failed"); - return 0; + if (ret) + gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_RELEASE_DIR_OP_FAILED, + NULL); + return 0; } - -int32_t -client_lookup (call_frame_t *frame, xlator_t *this, loc_t *loc, - dict_t *xattr_req) +static 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; + 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; + + proc = &conf->fops->proctable[GF_FOP_RELEASE]; + if (proc->fn) { + args.fd = fd; + ret = proc->fn(NULL, this, &args); + } +out: + if (ret) + gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_FILE_OP_FAILED, NULL); + return 0; +} +static 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; + + proc = &conf->fops->proctable[GF_FOP_LOOKUP]; + if (proc->fn) { args.loc = loc; - args.dict = xattr_req; - - 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); + args.xdata = xdata; + 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); + /* think of avoiding a missing frame */ + if (ret) + STACK_UNWIND_STRICT(lookup, frame, -1, ENOTCONN, NULL, NULL, NULL, + NULL); - return 0; + return 0; } - -int32_t -client_stat (call_frame_t *frame, xlator_t *this, loc_t *loc) +static 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; - + 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; + + proc = &conf->fops->proctable[GF_FOP_STAT]; + if (proc->fn) { args.loc = loc; - - 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); + args.xdata = xdata; + ret = proc->fn(frame, this, &args); + } out: - if (ret) - STACK_UNWIND_STRICT (stat, frame, -1, ENOTCONN, NULL); + if (ret) + STACK_UNWIND_STRICT(stat, frame, -1, ENOTCONN, NULL, NULL); - return 0; + return 0; } - -int32_t -client_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset) +static 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; + 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; + + proc = &conf->fops->proctable[GF_FOP_TRUNCATE]; + if (proc->fn) { + args.loc = loc; args.offset = offset; - - 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); + args.xdata = xdata; + ret = proc->fn(frame, this, &args); + } out: - if (ret) - STACK_UNWIND_STRICT (truncate, frame, -1, ENOTCONN, NULL, NULL); + if (ret) + STACK_UNWIND_STRICT(truncate, frame, -1, ENOTCONN, NULL, NULL, NULL); - - return 0; + return 0; } - -int32_t -client_ftruncate (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset) +static 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; + 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; + + proc = &conf->fops->proctable[GF_FOP_FTRUNCATE]; + if (proc->fn) { + args.fd = fd; args.offset = offset; - - 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); + args.xdata = xdata; + ret = proc->fn(frame, this, &args); + } out: - if (ret) - STACK_UNWIND_STRICT (ftruncate, frame, -1, ENOTCONN, NULL, NULL); + if (ret) + STACK_UNWIND_STRICT(ftruncate, frame, -1, ENOTCONN, NULL, NULL, NULL); - return 0; + return 0; } - - -int32_t -client_access (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t mask) +static 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; + 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; + + proc = &conf->fops->proctable[GF_FOP_ACCESS]; + if (proc->fn) { + args.loc = loc; args.mask = mask; - - 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); + args.xdata = xdata; + ret = proc->fn(frame, this, &args); + } out: - if (ret) - STACK_UNWIND_STRICT (access, frame, -1, ENOTCONN); + if (ret) + STACK_UNWIND_STRICT(access, frame, -1, ENOTCONN, NULL); - return 0; + return 0; } - - - -int32_t -client_readlink (call_frame_t *frame, xlator_t *this, loc_t *loc, size_t size) +static 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; + 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; + + proc = &conf->fops->proctable[GF_FOP_READLINK]; + if (proc->fn) { + args.loc = loc; args.size = size; - - 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); + args.xdata = xdata; + ret = proc->fn(frame, this, &args); + } out: - if (ret) - STACK_UNWIND_STRICT (readlink, frame, -1, ENOTCONN, NULL, NULL); + if (ret) + STACK_UNWIND_STRICT(readlink, frame, -1, ENOTCONN, NULL, NULL, NULL); - return 0; + return 0; } - -int -client_mknod (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode, - dev_t rdev, dict_t *params) +static 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; + 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; + + proc = &conf->fops->proctable[GF_FOP_MKNOD]; + if (proc->fn) { + args.loc = loc; args.mode = mode; args.rdev = rdev; - args.dict = params; - - 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); + args.umask = umask; + args.xdata = xdata; + ret = proc->fn(frame, this, &args); + } out: - if (ret) - STACK_UNWIND_STRICT (mknod, frame, -1, ENOTCONN, - NULL, NULL, NULL, NULL); + if (ret) + STACK_UNWIND_STRICT(mknod, frame, -1, ENOTCONN, NULL, NULL, NULL, NULL, + NULL); - return 0; + return 0; } - -int -client_mkdir (call_frame_t *frame, xlator_t *this, loc_t *loc, - mode_t mode, dict_t *params) +static 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; + 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; + + proc = &conf->fops->proctable[GF_FOP_MKDIR]; + if (proc->fn) { + args.loc = loc; args.mode = mode; - args.dict = params; - - 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); + args.umask = umask; + args.xdata = xdata; + ret = proc->fn(frame, this, &args); + } out: - if (ret) - STACK_UNWIND_STRICT (mkdir, frame, -1, ENOTCONN, - NULL, NULL, NULL, NULL); + if (ret) + STACK_UNWIND_STRICT(mkdir, frame, -1, ENOTCONN, NULL, NULL, NULL, NULL, + NULL); - return 0; + return 0; } - - -int32_t -client_unlink (call_frame_t *frame, xlator_t *this, loc_t *loc) +static 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; - + 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; + + proc = &conf->fops->proctable[GF_FOP_UNLINK]; + if (proc->fn) { args.loc = loc; - - 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); + args.xdata = xdata; + args.flags = xflag; + ret = proc->fn(frame, this, &args); + } out: - if (ret) - STACK_UNWIND_STRICT (unlink, frame, -1, ENOTCONN, - NULL, NULL); + if (ret) + STACK_UNWIND_STRICT(unlink, frame, -1, ENOTCONN, NULL, NULL, NULL); - return 0; + return 0; } -int32_t -client_rmdir (call_frame_t *frame, xlator_t *this, loc_t *loc, int flags) +static 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; - + 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; + + proc = &conf->fops->proctable[GF_FOP_RMDIR]; + if (proc->fn) { args.loc = loc; args.flags = flags; - - 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); + args.xdata = xdata; + ret = proc->fn(frame, this, &args); + } out: - /* think of avoiding a missing frame */ - if (ret) - STACK_UNWIND_STRICT (rmdir, frame, -1, ENOTCONN, - NULL, NULL); + /* think of avoiding a missing frame */ + if (ret) + STACK_UNWIND_STRICT(rmdir, frame, -1, ENOTCONN, NULL, NULL, NULL); - return 0; + return 0; } - -int -client_symlink (call_frame_t *frame, xlator_t *this, const char *linkpath, - loc_t *loc, dict_t *params) +static 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; - + 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; + + proc = &conf->fops->proctable[GF_FOP_SYMLINK]; + if (proc->fn) { args.linkname = linkpath; - args.loc = loc; - args.dict = params; - - 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); + args.loc = loc; + args.umask = umask; + args.xdata = xdata; + ret = proc->fn(frame, this, &args); + } out: - if (ret) - STACK_UNWIND_STRICT (symlink, frame, -1, ENOTCONN, - NULL, NULL, NULL, NULL); + if (ret) + STACK_UNWIND_STRICT(symlink, frame, -1, ENOTCONN, NULL, NULL, NULL, + NULL, NULL); - return 0; + return 0; } - - -int32_t -client_rename (call_frame_t *frame, xlator_t *this, loc_t *oldloc, - loc_t *newloc) +static 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; - + 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; + + proc = &conf->fops->proctable[GF_FOP_RENAME]; + if (proc->fn) { args.oldloc = oldloc; args.newloc = newloc; - 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); + args.xdata = xdata; + ret = proc->fn(frame, this, &args); + } out: - if (ret) - STACK_UNWIND_STRICT (rename, frame, -1, ENOTCONN, - NULL, NULL, NULL, NULL, NULL); + if (ret) + STACK_UNWIND_STRICT(rename, frame, -1, ENOTCONN, NULL, NULL, NULL, NULL, + NULL, NULL); - return 0; + return 0; } - - -int32_t -client_link (call_frame_t *frame, xlator_t *this, loc_t *oldloc, - loc_t *newloc) +static 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; - + 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; + + proc = &conf->fops->proctable[GF_FOP_LINK]; + if (proc->fn) { args.oldloc = oldloc; args.newloc = newloc; - - 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); + args.xdata = xdata; + ret = proc->fn(frame, this, &args); + } out: - if (ret) - STACK_UNWIND_STRICT (link, frame, -1, ENOTCONN, - NULL, NULL, NULL, NULL); + if (ret) + STACK_UNWIND_STRICT(link, frame, -1, ENOTCONN, NULL, NULL, NULL, NULL, + NULL); - return 0; + 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, dict_t *params) +static 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; - + 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; + + proc = &conf->fops->proctable[GF_FOP_CREATE]; + if (proc->fn) { args.loc = loc; - args.flags = flags; args.mode = mode; args.fd = fd; - args.dict = params; - - 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); + args.umask = umask; + args.xdata = xdata; + args.flags = flags; + client_filter_o_direct(conf, &args.flags); + ret = proc->fn(frame, this, &args); + } out: - if (ret) - STACK_UNWIND_STRICT (create, frame, -1, ENOTCONN, - NULL, NULL, NULL, NULL, NULL); + if (ret) + STACK_UNWIND_STRICT(create, frame, -1, ENOTCONN, NULL, NULL, NULL, NULL, + NULL, NULL); - return 0; + 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) +static 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; - + 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; + + proc = &conf->fops->proctable[GF_FOP_OPEN]; + if (proc->fn) { args.loc = loc; - args.flags = flags; args.fd = fd; - args.wbflags = wbflags; - - 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); - + args.xdata = xdata; + args.flags = flags; + client_filter_o_direct(conf, &args.flags); + ret = proc->fn(frame, this, &args); + } out: - if (ret) - STACK_UNWIND_STRICT (open, frame, -1, ENOTCONN, NULL); + if (ret) + STACK_UNWIND_STRICT(open, frame, -1, ENOTCONN, NULL, NULL); - return 0; + return 0; } - - -int32_t -client_readv (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, - off_t offset) +static 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; + 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; + + proc = &conf->fops->proctable[GF_FOP_READ]; + if (proc->fn) { + args.fd = fd; + args.size = size; args.offset = offset; + args.flags = flags; + args.xdata = xdata; + client_filter_o_direct(conf, &args.flags); - 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); - + ret = proc->fn(frame, this, &args); + } out: - if (ret) - STACK_UNWIND_STRICT (readv, frame, -1, ENOTCONN, - NULL, 0, NULL, NULL); + if (ret) + STACK_UNWIND_STRICT(readv, frame, -1, ENOTCONN, NULL, 0, NULL, NULL, + NULL); - return 0; + 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) +static 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; + 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; + + proc = &conf->fops->proctable[GF_FOP_WRITE]; + if (proc->fn) { + args.fd = fd; args.vector = vector; - args.count = count; + args.count = count; args.offset = off; + args.size = iov_length(vector, count); + args.flags = flags; args.iobref = iobref; - - 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); + args.xdata = xdata; + client_filter_o_direct(conf, &args.flags); + ret = proc->fn(frame, this, &args); + } out: - if (ret) - STACK_UNWIND_STRICT (writev, frame, -1, ENOTCONN, NULL, NULL); + if (ret) + STACK_UNWIND_STRICT(writev, frame, -1, ENOTCONN, NULL, NULL, NULL); - return 0; + return 0; } - - -int32_t -client_flush (call_frame_t *frame, xlator_t *this, fd_t *fd) +static 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; - + 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; + + proc = &conf->fops->proctable[GF_FOP_FLUSH]; + if (proc->fn) { args.fd = fd; - - 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); + args.xdata = xdata; + ret = proc->fn(frame, this, &args); + } out: - if (ret) - STACK_UNWIND_STRICT (flush, frame, -1, ENOTCONN); + if (ret) + STACK_UNWIND_STRICT(flush, frame, -1, ENOTCONN, NULL); - return 0; + return 0; } - - -int32_t -client_fsync (call_frame_t *frame, xlator_t *this, fd_t *fd, - int32_t flags) +static 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; + 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; + + proc = &conf->fops->proctable[GF_FOP_FSYNC]; + if (proc->fn) { + args.fd = fd; args.flags = flags; - - 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); + args.xdata = xdata; + ret = proc->fn(frame, this, &args); + } out: - if (ret) - STACK_UNWIND_STRICT (fsync, frame, -1, ENOTCONN, NULL, NULL); + if (ret) + STACK_UNWIND_STRICT(fsync, frame, -1, ENOTCONN, NULL, NULL, NULL); - return 0; + return 0; } - - -int32_t -client_fstat (call_frame_t *frame, xlator_t *this, fd_t *fd) +static 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; - + 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; + + proc = &conf->fops->proctable[GF_FOP_FSTAT]; + if (proc->fn) { args.fd = fd; - - 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); + args.xdata = xdata; + ret = proc->fn(frame, this, &args); + } out: - if (ret) - STACK_UNWIND_STRICT (fstat, frame, -1, ENOTCONN, NULL); + if (ret) + STACK_UNWIND_STRICT(fstat, frame, -1, ENOTCONN, NULL, NULL); - return 0; + return 0; } - - -int32_t -client_opendir (call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd) +static 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; - + 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; + + proc = &conf->fops->proctable[GF_FOP_OPENDIR]; + if (proc->fn) { args.loc = loc; - args.fd = fd; - - 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); + args.fd = fd; + args.xdata = xdata; + ret = proc->fn(frame, this, &args); + } out: - if (ret) - STACK_UNWIND_STRICT (opendir, frame, -1, ENOTCONN, NULL); + if (ret) + STACK_UNWIND_STRICT(opendir, frame, -1, ENOTCONN, NULL, NULL); - return 0; + return 0; } - - int32_t -client_fsyncdir (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t flags) +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; + 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; + + proc = &conf->fops->proctable[GF_FOP_FSYNCDIR]; + if (proc->fn) { + args.fd = fd; args.flags = flags; - - 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); + args.xdata = xdata; + ret = proc->fn(frame, this, &args); + } out: - if (ret) - STACK_UNWIND_STRICT (fsyncdir, frame, -1, ENOTCONN); + if (ret) + STACK_UNWIND_STRICT(fsyncdir, frame, -1, ENOTCONN, NULL); - return 0; + return 0; } - - -int32_t -client_statfs (call_frame_t *frame, xlator_t *this, loc_t *loc) +static 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; - + 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; + + proc = &conf->fops->proctable[GF_FOP_STATFS]; + if (proc->fn) { args.loc = loc; + args.xdata = xdata; + ret = proc->fn(frame, this, &args); + } +out: + if (ret) + STACK_UNWIND_STRICT(statfs, frame, -1, ENOTCONN, NULL, NULL); - 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); + return 0; +} + +static int32_t +client_copy_file_range(call_frame_t *frame, xlator_t *this, fd_t *fd_in, + off_t off_in, fd_t *fd_out, off_t off_out, size_t len, + 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; + + proc = &conf->fops->proctable[GF_FOP_COPY_FILE_RANGE]; + if (proc->fn) { + args.fd = fd_in; + args.fd_out = fd_out; + args.offset = off_in; + args.off_out = off_out; + args.size = len; + args.flags = flags; + args.xdata = xdata; + ret = proc->fn(frame, this, &args); + } out: - if (ret) - STACK_UNWIND_STRICT (statfs, frame, -1, ENOTCONN, NULL); + if (ret) + STACK_UNWIND_STRICT(copy_file_range, frame, -1, ENOTCONN, NULL, NULL, + NULL, NULL); - return 0; + return 0; } static gf_boolean_t -is_client_rpc_init_command (dict_t *dict, xlator_t *this, - char **value) +is_client_rpc_init_command(dict_t *dict, xlator_t *this, char **value) { - gf_boolean_t ret = _gf_false; - int dict_ret = -1; + gf_boolean_t ret = _gf_false; - 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; - } + int dict_ret = dict_get_str_sizen(dict, CLIENT_CMD_CONNECT, value); + if (dict_ret) { + gf_msg_trace(this->name, 0, "key %s not present", CLIENT_CMD_CONNECT); + goto out; + } - ret = _gf_true; + ret = _gf_true; out: - return ret; - + return ret; } static gf_boolean_t -is_client_rpc_destroy_command (dict_t *dict, xlator_t *this) +is_client_rpc_destroy_command(dict_t *dict, xlator_t *this) { - gf_boolean_t ret = _gf_false; - int dict_ret = -1; - char *dummy = NULL; + 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; - } + if (strncmp(this->name, "replace-brick", 13)) { + gf_msg_trace(this->name, 0, "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; - } + dict_ret = dict_get_str_sizen(dict, CLIENT_CMD_DISCONNECT, &dummy); + if (dict_ret) { + gf_msg_trace(this->name, 0, "key %s not present", + CLIENT_CMD_DISCONNECT); + goto out; + } - ret = _gf_true; + ret = _gf_true; out: - return ret; - + 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); +static int +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; + int ret = -1; + + dup_value = gf_strdup(value); + if (dup_value == NULL) { + goto out; + } + host = strtok_r(dup_value, ":", &tmp); + subvol = strtok_r(NULL, ":", &tmp); + remote_port_str = strtok_r(NULL, ":", &tmp); + + if (host) { + host_dup = gf_strdup(host); if (!host_dup) { - goto out; + goto out; } - - ret = dict_set_dynstr (this->options, "remote-host", host_dup); + ret = dict_set_dynstr_sizen(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; + gf_smsg(this->name, GF_LOG_WARNING, 0, + PC_MSG_REMOTE_HOST_SET_FAILED, "host=%s", host, NULL); + GF_FREE(host_dup); + goto out; } + } - subvol_dup = gf_strdup (subvol); + if (subvol) { + subvol_dup = gf_strdup(subvol); if (!subvol_dup) { - goto out; + goto out; } - ret = dict_set_dynstr (this->options, "remote-subvolume", subvol_dup); + ret = dict_set_dynstr_sizen(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; + gf_smsg(this->name, GF_LOG_WARNING, 0, + PC_MSG_REMOTE_HOST_SET_FAILED, "host=%s", host, NULL); + GF_FREE(subvol_dup); + goto out; } + } - remote_port = atoi (remote_port_str); - GF_ASSERT (remote_port); + if (remote_port_str) { + remote_port = atoi(remote_port_str); - ret = dict_set_int32 (this->options, "remote-port", - remote_port); + ret = dict_set_int32_sizen(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; + gf_smsg(this->name, GF_LOG_ERROR, 0, PC_MSG_REMOTE_PORT_SET_FAILED, + "remote-port=%d", remote_port, NULL); + goto out; } + } - ret = _gf_true; + ret = 0; out: - if (dup_value) - GF_FREE (dup_value); + GF_FREE(dup_value); - return ret; + return ret; } - -int32_t -client_setxattr (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *dict, - int32_t flags) -{ - 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.dict = dict; +static 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_smsg(this->name, GF_LOG_INFO, 0, PC_MSG_RPC_INIT, NULL); + ret = client_set_remote_options(value, 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_smsg(this->name, GF_LOG_INFO, 0, PC_MSG_RPC_DESTROY, NULL); + 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; + } + + proc = &conf->fops->proctable[GF_FOP_SETXATTR]; + if (proc->fn) { + args.loc = loc; + args.xattr = dict; args.flags = flags; - - 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; - } + args.xdata = xdata; + ret = proc->fn(frame, this, &args); + if (ret) { + need_unwind = 1; } + } out: - if (need_unwind) - STACK_UNWIND_STRICT (setxattr, frame, op_ret, op_errno); + if (need_unwind) + STACK_UNWIND_STRICT(setxattr, frame, op_ret, op_errno, NULL); - return 0; + return 0; } - - -int32_t -client_fsetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd, - dict_t *dict, int32_t flags) +static 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; - + 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; + + proc = &conf->fops->proctable[GF_FOP_FSETXATTR]; + if (proc->fn) { args.fd = fd; - args.dict = dict; + args.xattr = dict; args.flags = flags; - - 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); + args.xdata = xdata; + ret = proc->fn(frame, this, &args); + } out: - if (ret) - STACK_UNWIND_STRICT (fsetxattr, frame, -1, ENOTCONN); + if (ret) + STACK_UNWIND_STRICT(fsetxattr, frame, -1, ENOTCONN, NULL); - return 0; + return 0; } - - - -int32_t -client_fgetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd, - const char *name) +static 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; - + 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; + + proc = &conf->fops->proctable[GF_FOP_FGETXATTR]; + if (proc->fn) { args.fd = fd; args.name = name; - - 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); + args.xdata = xdata; + ret = proc->fn(frame, this, &args); + } out: - if (ret) - STACK_UNWIND_STRICT (fgetxattr, frame, -1, ENOTCONN, NULL); + if (ret) + STACK_UNWIND_STRICT(fgetxattr, frame, -1, ENOTCONN, NULL, NULL); - return 0; + return 0; } - - -int32_t -client_getxattr (call_frame_t *frame, xlator_t *this, loc_t *loc, - const char *name) +static 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; - + 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; + + proc = &conf->fops->proctable[GF_FOP_GETXATTR]; + if (proc->fn) { args.name = name; - args.loc = loc; - - 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); + args.loc = loc; + args.xdata = xdata; + ret = proc->fn(frame, this, &args); + } out: - if (ret) - STACK_UNWIND_STRICT (getxattr, frame, -1, ENOTCONN, NULL); + if (ret) + STACK_UNWIND_STRICT(getxattr, frame, -1, ENOTCONN, NULL, NULL); - return 0; + return 0; } - - -int32_t -client_xattrop (call_frame_t *frame, xlator_t *this, loc_t *loc, - gf_xattrop_flags_t flags, dict_t *dict) +static 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; - + 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; + + proc = &conf->fops->proctable[GF_FOP_XATTROP]; + if (proc->fn) { args.loc = loc; args.flags = flags; - args.dict = dict; - - 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); + args.xattr = dict; + args.xdata = xdata; + ret = proc->fn(frame, this, &args); + } out: - if (ret) - STACK_UNWIND_STRICT (xattrop, frame, -1, ENOTCONN, NULL); + if (ret) + STACK_UNWIND_STRICT(xattrop, frame, -1, ENOTCONN, NULL, NULL); - return 0; + return 0; } - - -int32_t -client_fxattrop (call_frame_t *frame, xlator_t *this, fd_t *fd, - gf_xattrop_flags_t flags, dict_t *dict) +static 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; - + 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; + + proc = &conf->fops->proctable[GF_FOP_FXATTROP]; + if (proc->fn) { args.fd = fd; args.flags = flags; - args.dict = dict; - - 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); + args.xattr = dict; + args.xdata = xdata; + ret = proc->fn(frame, this, &args); + } out: - if (ret) - STACK_UNWIND_STRICT (fxattrop, frame, -1, ENOTCONN, NULL); + if (ret) + STACK_UNWIND_STRICT(fxattrop, frame, -1, ENOTCONN, NULL, NULL); - return 0; + return 0; } - - -int32_t -client_removexattr (call_frame_t *frame, xlator_t *this, loc_t *loc, - const char *name) +static 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,}; + 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; + + proc = &conf->fops->proctable[GF_FOP_REMOVEXATTR]; + if (proc->fn) { + args.name = name; + args.loc = loc; + args.xdata = xdata; + ret = proc->fn(frame, this, &args); + } +out: + if (ret) + STACK_UNWIND_STRICT(removexattr, frame, -1, ENOTCONN, NULL); - conf = this->private; - if (!conf || !conf->fops) - goto out; + return 0; +} +static 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; + + proc = &conf->fops->proctable[GF_FOP_FREMOVEXATTR]; + if (proc->fn) { args.name = name; - args.loc = loc; - - 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); + args.fd = fd; + args.xdata = xdata; + ret = proc->fn(frame, this, &args); + } out: - if (ret) - STACK_UNWIND_STRICT (removexattr, frame, -1, ENOTCONN); + if (ret) + STACK_UNWIND_STRICT(fremovexattr, frame, -1, ENOTCONN, NULL); - return 0; + return 0; } - -int32_t -client_lk (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t cmd, - struct gf_flock *lock) +static int32_t +client_lease(call_frame_t *frame, xlator_t *this, loc_t *loc, + struct gf_lease *lease, dict_t *xdata) { - int ret = -1; - clnt_conf_t *conf = NULL; - rpc_clnt_procedure_t *proc = NULL; - clnt_args_t args = {0,}; + 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; + + proc = &conf->fops->proctable[GF_FOP_LEASE]; + if (proc->fn) { + args.loc = loc; + args.lease = lease; + args.xdata = xdata; + ret = proc->fn(frame, this, &args); + } +out: + if (ret) + STACK_UNWIND_STRICT(lk, frame, -1, ENOTCONN, NULL, NULL); - conf = this->private; - if (!conf || !conf->fops) - goto out; + return 0; +} - args.fd = fd; - args.cmd = cmd; +static 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; + + proc = &conf->fops->proctable[GF_FOP_LK]; + if (proc->fn) { + args.fd = fd; + args.cmd = cmd; args.flock = lock; - - 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); + args.xdata = xdata; + ret = proc->fn(frame, this, &args); + } out: - if (ret) - STACK_UNWIND_STRICT (lk, frame, -1, ENOTCONN, NULL); + if (ret) + STACK_UNWIND_STRICT(lk, frame, -1, ENOTCONN, NULL, NULL); - return 0; + 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) +static 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; + 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; + + proc = &conf->fops->proctable[GF_FOP_INODELK]; + if (proc->fn) { + args.loc = loc; + args.cmd = cmd; + args.flock = lock; args.volume = volume; - - 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); + args.xdata = xdata; + ret = proc->fn(frame, this, &args); + } out: - if (ret) - STACK_UNWIND_STRICT (inodelk, frame, -1, ENOTCONN); + if (ret) + STACK_UNWIND_STRICT(inodelk, frame, -1, ENOTCONN, NULL); - return 0; + 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) +static 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; + 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; + + proc = &conf->fops->proctable[GF_FOP_FINODELK]; + if (proc->fn) { + args.fd = fd; + args.cmd = cmd; + args.flock = lock; args.volume = volume; - - 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); + args.xdata = xdata; + ret = proc->fn(frame, this, &args); + } out: - if (ret) - STACK_UNWIND_STRICT (finodelk, frame, -1, ENOTCONN); + if (ret) + STACK_UNWIND_STRICT(finodelk, frame, -1, ENOTCONN, NULL); - return 0; + 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) +static 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; - - 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); + 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; + + proc = &conf->fops->proctable[GF_FOP_ENTRYLK]; + if (proc->fn) { + args.loc = loc; + args.basename = basename; + args.type = type; + args.volume = volume; + args.cmd_entrylk = cmd; + args.xdata = xdata; + ret = proc->fn(frame, this, &args); + } out: - if (ret) - STACK_UNWIND_STRICT (entrylk, frame, -1, ENOTCONN); + if (ret) + STACK_UNWIND_STRICT(entrylk, frame, -1, ENOTCONN, NULL); - return 0; + 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) +static 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; - - 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); + 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; + + proc = &conf->fops->proctable[GF_FOP_FENTRYLK]; + if (proc->fn) { + args.fd = fd; + args.basename = basename; + args.type = type; + args.volume = volume; + args.cmd_entrylk = cmd; + args.xdata = xdata; + ret = proc->fn(frame, this, &args); + } out: - if (ret) - STACK_UNWIND_STRICT (fentrylk, frame, -1, ENOTCONN); + if (ret) + STACK_UNWIND_STRICT(fentrylk, frame, -1, ENOTCONN, NULL); - return 0; + return 0; } - -int32_t -client_rchecksum (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, - int32_t len) +static 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; - + 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; + + proc = &conf->fops->proctable[GF_FOP_RCHECKSUM]; + if (proc->fn) { args.fd = fd; args.offset = offset; args.len = len; - - 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); + args.xdata = xdata; + ret = proc->fn(frame, this, &args); + } out: - if (ret) - STACK_UNWIND_STRICT (rchecksum, frame, -1, ENOTCONN, 0, NULL); + if (ret) + STACK_UNWIND_STRICT(rchecksum, frame, -1, ENOTCONN, 0, NULL, NULL); - return 0; + return 0; } int32_t -client_readdir (call_frame_t *frame, xlator_t *this, fd_t *fd, - size_t size, off_t off) +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; + 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; + + proc = &conf->fops->proctable[GF_FOP_READDIR]; + if (proc->fn) { + if (off != 0) + off = gf_dirent_orig_offset(this, off); args.fd = fd; args.size = size; args.offset = off; - - 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); + args.xdata = xdata; + ret = proc->fn(frame, this, &args); + } out: - if (ret) - STACK_UNWIND_STRICT (readdir, frame, -1, ENOTCONN, NULL); + if (ret) + STACK_UNWIND_STRICT(readdir, frame, -1, ENOTCONN, NULL, NULL); - return 0; + return 0; } - -int32_t -client_readdirp (call_frame_t *frame, xlator_t *this, fd_t *fd, - size_t size, off_t off) +static 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; + 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; + + proc = &conf->fops->proctable[GF_FOP_READDIRP]; + if (proc->fn) { + if (off != 0) + off = gf_dirent_orig_offset(this, off); args.fd = fd; args.size = size; args.offset = off; - - 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); + args.xdata = dict; + ret = proc->fn(frame, this, &args); + } out: - if (ret) - STACK_UNWIND_STRICT (readdirp, frame, -1, ENOTCONN, NULL); + if (ret) + STACK_UNWIND_STRICT(readdirp, frame, -1, ENOTCONN, NULL, NULL); - return 0; + return 0; } - -int32_t -client_setattr (call_frame_t *frame, xlator_t *this, loc_t *loc, - struct iatt *stbuf, int32_t valid) +static 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,}; + 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; + + proc = &conf->fops->proctable[GF_FOP_SETATTR]; + if (proc->fn) { + args.loc = loc; + args.stbuf = stbuf; + args.valid = valid; + args.xdata = xdata; + ret = proc->fn(frame, this, &args); + } +out: + if (ret) + STACK_UNWIND_STRICT(setattr, frame, -1, ENOTCONN, NULL, NULL, NULL); - conf = this->private; - if (!conf || !conf->fops) - goto out; + return 0; +} - args.loc = loc; +static 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; + + proc = &conf->fops->proctable[GF_FOP_FSETATTR]; + if (proc->fn) { + args.fd = fd; args.stbuf = stbuf; args.valid = valid; + args.xdata = xdata; + ret = proc->fn(frame, this, &args); + } +out: + if (ret) + STACK_UNWIND_STRICT(fsetattr, frame, -1, ENOTCONN, NULL, NULL, NULL); - 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); + return 0; +} + +static 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; + + proc = &conf->fops->proctable[GF_FOP_FALLOCATE]; + if (proc->fn) { + args.fd = fd; + args.flags = mode; + args.offset = offset; + args.size = len; + args.xdata = xdata; + ret = proc->fn(frame, this, &args); + } out: - if (ret) - STACK_UNWIND_STRICT (setattr, frame, -1, ENOTCONN, NULL, NULL); + if (ret) + STACK_UNWIND_STRICT(fallocate, frame, -1, ENOTCONN, NULL, NULL, NULL); - return 0; + return 0; } -int32_t -client_fsetattr (call_frame_t *frame, xlator_t *this, fd_t *fd, - struct iatt *stbuf, int32_t valid) +static 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,}; + 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; + + proc = &conf->fops->proctable[GF_FOP_DISCARD]; + if (proc->fn) { + args.fd = fd; + args.offset = offset; + args.size = len; + args.xdata = xdata; + ret = proc->fn(frame, this, &args); + } +out: + if (ret) + STACK_UNWIND_STRICT(discard, frame, -1, ENOTCONN, NULL, NULL, NULL); - conf = this->private; - if (!conf || !conf->fops) - goto out; + return 0; +} +static int32_t +client_zerofill(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, + off_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; + + proc = &conf->fops->proctable[GF_FOP_ZEROFILL]; + if (proc->fn) { args.fd = fd; - args.stbuf = stbuf; - args.valid = valid; + args.offset = offset; + args.size = len; + args.xdata = xdata; + ret = proc->fn(frame, this, &args); + } +out: + if (ret) + STACK_UNWIND_STRICT(zerofill, frame, -1, ENOTCONN, NULL, NULL, NULL); - 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); + return 0; +} + +static int32_t +client_ipc(call_frame_t *frame, xlator_t *this, int32_t op, 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; + + proc = &conf->fops->proctable[GF_FOP_IPC]; + if (proc->fn) { + args.cmd = op; + args.xdata = xdata; + ret = proc->fn(frame, this, &args); + } out: - if (ret) - STACK_UNWIND_STRICT (fsetattr, frame, -1, ENOTCONN, NULL, NULL); + if (ret) + STACK_UNWIND_STRICT(ipc, frame, -1, ENOTCONN, NULL); - return 0; + return 0; } +static int32_t +client_seek(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, + gf_seek_what_t what, 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; + + proc = &conf->fops->proctable[GF_FOP_SEEK]; + if (proc->fn) { + args.fd = fd; + args.offset = offset; + args.what = what; + args.xdata = xdata; + ret = proc->fn(frame, this, &args); + } +out: + if (ret) + STACK_UNWIND_STRICT(seek, frame, -1, ENOTCONN, 0, NULL); + + return 0; +} -int32_t -client_getspec (call_frame_t *frame, xlator_t *this, const char *key, - int32_t flags) +static int32_t +client_getactivelk(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,}; + 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; + + proc = &conf->fops->proctable[GF_FOP_GETACTIVELK]; + if (proc->fn) { + args.loc = loc; + args.xdata = xdata; + ret = proc->fn(frame, this, &args); + } +out: + if (ret) + STACK_UNWIND_STRICT(getactivelk, frame, -1, ENOTCONN, NULL, NULL); - conf = this->private; - if (!conf || !conf->fops || !conf->handshake) - goto out; + return 0; +} +static int32_t +client_setactivelk(call_frame_t *frame, xlator_t *this, loc_t *loc, + lock_migration_info_t *locklist, 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; + + proc = &conf->fops->proctable[GF_FOP_SETACTIVELK]; + if (proc->fn) { + args.loc = loc; + args.xdata = xdata; + args.locklist = locklist; + ret = proc->fn(frame, this, &args); + } +out: + if (ret) + STACK_UNWIND_STRICT(setactivelk, frame, -1, ENOTCONN, NULL); + + return 0; +} + +static 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; + + /* For all other xlators, getspec is an fop, hence its in fops table */ + proc = &conf->fops->proctable[GF_FOP_GETSPEC]; + if (proc->fn) { args.name = key; args.flags = flags; + /* But at protocol level, this is handshake */ + ret = proc->fn(frame, this, &args); + } +out: + if (ret) + STACK_UNWIND_STRICT(getspec, frame, -1, EINVAL, NULL); - /* 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); - } + return 0; +} + +static int32_t +client_compound(call_frame_t *frame, xlator_t *this, void *data, dict_t *xdata) +{ + int ret = -1; + clnt_conf_t *conf = NULL; + compound_args_t *args = data; + rpc_clnt_procedure_t *proc = NULL; + + conf = this->private; + if (!conf || !conf->fops) + goto out; + + proc = &conf->fops->proctable[GF_FOP_COMPOUND]; + if (proc->fn) { + args->xdata = xdata; + ret = proc->fn(frame, this, args); + } out: - if (ret) - STACK_UNWIND_STRICT (getspec, frame, -1, EINVAL, NULL); + if (ret) + STACK_UNWIND_STRICT(compound, frame, -1, ENOTCONN, NULL, NULL); - return 0; + return 0; } +int32_t +client_namelink(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) +{ + int32_t ret = -1; + clnt_conf_t *conf = NULL; + clnt_args_t args = { + 0, + }; + rpc_clnt_procedure_t *proc = NULL; + + conf = this->private; + if (!conf || !conf->fops || !conf->handshake) + goto out; + + proc = &conf->fops->proctable[GF_FOP_NAMELINK]; + if (proc->fn) { + args.loc = loc; + args.xdata = xdata; + ret = proc->fn(frame, this, &args); + } +out: + if (ret) + STACK_UNWIND_STRICT(namelink, frame, -1, EINVAL, NULL, NULL, NULL); + return 0; +} - int -client_mark_fd_bad (xlator_t *this) +static int32_t +client_icreate(call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode, + dict_t *xdata) { - clnt_conf_t *conf = NULL; - clnt_fd_ctx_t *tmp = NULL, *fdctx = NULL; + int32_t ret = -1; + clnt_conf_t *conf = NULL; + clnt_args_t args = { + 0, + }; + rpc_clnt_procedure_t *proc = NULL; + + conf = this->private; + if (!conf || !conf->fops || !conf->handshake) + goto out; + + proc = &conf->fops->proctable[GF_FOP_ICREATE]; + if (proc->fn) { + args.loc = loc; + args.mode = mode; + args.xdata = xdata; + ret = proc->fn(frame, this, &args); + } +out: + if (ret) + STACK_UNWIND_STRICT(icreate, frame, -1, EINVAL, NULL, NULL, NULL); + return 0; +} - conf = this->private; +static int32_t +client_put(call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode, + mode_t umask, uint32_t flags, struct iovec *vector, int32_t count, + off_t off, struct iobref *iobref, dict_t *xattr, 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; + + proc = &conf->fops->proctable[GF_FOP_PUT]; + if (proc->fn) { + args.loc = loc; + args.mode = mode; + args.umask = umask; + args.flags = flags; + args.vector = vector; + args.count = count; + args.offset = off; + args.size = iov_length(vector, count); + args.iobref = iobref; + args.xattr = xattr; + args.xdata = xdata; - 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); + client_filter_o_direct(conf, &args.flags); + ret = proc->fn(frame, this, &args); + } +out: + if (ret) + STACK_UNWIND_STRICT(put, frame, -1, ENOTCONN, NULL, NULL, NULL, NULL, + NULL); - return 0; + return 0; } +static void +client_mark_fd_bad(xlator_t *this) +{ + clnt_conf_t *conf = this->private; + clnt_fd_ctx_t *tmp = NULL, *fdctx = NULL; -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; + pthread_spin_lock(&conf->fd_lock); + { + list_for_each_entry_safe(fdctx, tmp, &conf->saved_fds, sfd_pos) + { + fdctx->remote_fd = -1; } + } + pthread_spin_unlock(&conf->fd_lock); +} - 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, conf->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; - } - } - break; +int +client_rpc_notify(struct rpc_clnt *rpc, void *mydata, rpc_clnt_event_t event, + void *data) +{ + xlator_t *this = NULL; + clnt_conf_t *conf = NULL; + gf_boolean_t is_parent_down = _gf_false; + int ret = 0; + + this = mydata; + if (!this || !this->private) { + gf_smsg("client", GF_LOG_ERROR, EINVAL, PC_MSG_XLATOR_NULL, + (this != NULL) ? "private structue" : "", NULL); + goto out; + } + + conf = this->private; + + switch (event) { + case RPC_CLNT_PING: { + if (conf->connection_to_brick) { + ret = default_notify(this, GF_EVENT_CHILD_PING, data); + if (ret) + gf_log(this->name, GF_LOG_INFO, "CHILD_PING notify failed"); + conf->last_sent_event = GF_EVENT_CHILD_PING; + } + break; + } + case RPC_CLNT_CONNECT: { + conf->can_log_disconnect = 1; + // connect happened, send 'get_supported_versions' mop + + gf_msg_debug(this->name, 0, "got RPC_CLNT_CONNECT"); + + ret = client_handshake(this, rpc); + if (ret) + gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_HANDSHAKE_RETURN, + "ret=%d", ret, NULL); + break; } case RPC_CLNT_DISCONNECT: - - client_mark_fd_bad (this); - - if (!conf->skip_notify) { - if (conf->connected) - gf_log (this->name, GF_LOG_INFO, - "disconnected"); - - /* 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)"); + gf_msg_debug(this->name, 0, "got RPC_CLNT_DISCONNECT"); + + client_mark_fd_bad(this); + + if (!conf->skip_notify) { + if (conf->can_log_disconnect) { + if (!conf->disconnect_err_logged) { + gf_smsg(this->name, GF_LOG_INFO, 0, + PC_MSG_CLIENT_DISCONNECTED, "conn-name=%s", + conf->rpc->conn.name, NULL); + } else { + gf_msg_debug(this->name, 0, + "disconnected from %s. " + "Client process will keep" + " trying to connect to " + "glusterd until brick's " + "port is available", + conf->rpc->conn.name); + } + if (conf->portmap_err_logged) + conf->disconnect_err_logged = 1; } - - conf->connected = 0; - conf->skip_notify = 0; - - break; + /* + * Once we complete the child down notification, + * There is a chance that the graph might get freed, + * So it is not safe to access any xlator contens + * So here we are checking whether the parent is down + * or not. + */ + pthread_mutex_lock(&conf->lock); + { + is_parent_down = conf->parent_down; + } + pthread_mutex_unlock(&conf->lock); + + /* 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 */ + ret = client_notify_dispatch_uniq(this, GF_EVENT_CHILD_DOWN, + rpc); + if (is_parent_down) { + /* If parent is down, then there should not be any + * operation after a child down. + */ + goto out; + } + if (ret) + gf_smsg(this->name, GF_LOG_INFO, 0, + PC_MSG_CHILD_DOWN_NOTIFY_FAILED, NULL); + + } else { + if (conf->can_log_disconnect) + gf_msg_debug(this->name, 0, + "disconnected (skipped notify)"); + } + + conf->connected = 0; + conf->can_log_disconnect = 0; + conf->skip_notify = 0; + + if (conf->quick_reconnect) { + conf->connection_to_brick = _gf_true; + conf->quick_reconnect = 0; + rpc_clnt_cleanup_and_start(rpc); + + } else { + rpc->conn.config.remote_port = 0; + conf->connection_to_brick = _gf_false; + } + break; + case RPC_CLNT_DESTROY: + ret = client_fini_complete(this); + break; default: - gf_log (this->name, GF_LOG_TRACE, - "got some other RPC event %d", event); + gf_msg_trace(this->name, 0, "got some other RPC event %d", event); - break; - } + break; + } out: - return 0; + return 0; } - int -notify (xlator_t *this, int32_t event, void *data, ...) +notify(xlator_t *this, int32_t event, void *data, ...) { - clnt_conf_t *conf = NULL; + clnt_conf_t *conf = NULL; + glusterfs_graph_t *graph = this->graph; + int ret = -1; - conf = this->private; - if (!conf) - return 0; + 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"); + switch (event) { + case GF_EVENT_PARENT_UP: { + gf_smsg(this->name, GF_LOG_INFO, 0, PC_MSG_PARENT_UP, NULL); - rpc_clnt_start (conf->rpc); + rpc_clnt_start(conf->rpc); + break; } - break; + + case GF_EVENT_PARENT_DOWN: + gf_smsg(this->name, GF_LOG_INFO, 0, PC_MSG_PARENT_DOWN, NULL); + + pthread_mutex_lock(&conf->lock); + { + conf->parent_down = 1; + } + pthread_mutex_unlock(&conf->lock); + + ret = rpc_clnt_disable(conf->rpc); + if (ret == -1 && graph) { + pthread_mutex_lock(&graph->mutex); + { + graph->parent_down++; + if (graph->parent_down == + graph_total_client_xlator(graph)) { + graph->used = 0; + pthread_cond_broadcast(&graph->child_down_cond); + } + } + pthread_mutex_unlock(&graph->mutex); + } + break; default: - gf_log (this->name, GF_LOG_DEBUG, - "got %d, calling default_notify ()", event); + gf_msg_debug(this->name, 0, "got %d, calling default_notify ()", + event); + + default_notify(this, event, data); + conf->last_sent_event = event; + break; + } + + return 0; +} + +static int +client_check_remote_host(xlator_t *this, dict_t *options) +{ + char *remote_host = NULL; + int ret = -1; - default_notify (this, event, data); - conf->last_sent_event = event; - break; + ret = dict_get_str_sizen(options, "remote-host", &remote_host); + if (ret < 0) { + gf_smsg(this->name, GF_LOG_INFO, EINVAL, PC_MSG_REMOTE_HOST_NOT_SET, + NULL); + + if (!this->ctx->cmd_args.volfile_server) { + gf_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_NOREMOTE_HOST, + NULL); + goto out; } - return 0; + ret = dict_set_str_sizen(options, "remote-host", + this->ctx->cmd_args.volfile_server); + if (ret == -1) { + gf_smsg(this->name, GF_LOG_ERROR, 0, PC_MSG_REMOTE_HOST_SET_FAILED, + NULL); + goto out; + } + } + + ret = 0; +out: + return ret; } -int -build_client_config (xlator_t *this, clnt_conf_t *conf) +static int +build_client_config(xlator_t *this, clnt_conf_t *conf) { - int ret = -1; + int ret = -1; - if (!conf) - goto out; + GF_OPTION_INIT("frame-timeout", conf->rpc_conf.rpc_timeout, int32, 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 ("remote-port", conf->rpc_conf.remote_port, - int32, out); + GF_OPTION_INIT("ping-timeout", conf->opt.ping_timeout, 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_smsg(this->name, GF_LOG_WARNING, EINVAL, + PC_MSG_REMOTE_SUBVOL_NOT_GIVEN, NULL); - 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; + GF_OPTION_INIT("send-gids", conf->send_gids, bool, out); + + GF_OPTION_INIT("testing.old-protocol", conf->old_protocol, bool, out); + GF_OPTION_INIT("strict-locks", conf->strict_locks, bool, out); + + conf->client_id = glusterfs_leaf_position(this); + + ret = client_check_remote_host(this, this->options); + if (ret) + goto out; + + ret = 0; out: - return ret; + return ret; } - int32_t -mem_acct_init (xlator_t *this) +mem_acct_init(xlator_t *this) { - int ret = -1; - - if (!this) - return ret; + int ret = -1; - ret = xlator_mem_acct_init (this, gf_client_mt_end + 1); + if (!this) + return ret; - if (ret != 0) { - gf_log (this->name, GF_LOG_ERROR, "Memory accounting init" - "failed"); - return ret; - } + ret = xlator_mem_acct_init(this, gf_client_mt_end + 1); + if (ret != 0) { + gf_smsg(this->name, GF_LOG_ERROR, ENOMEM, PC_MSG_NO_MEMORY, NULL); return ret; + } + + return ret; } -int -client_destroy_rpc (xlator_t *this) +static int +client_destroy_rpc(xlator_t *this) { - int ret = -1; - clnt_conf_t *conf = NULL; + int ret = -1; + clnt_conf_t *conf = NULL; - conf = this->private; - if (!conf) - goto out; + conf = this->private; + if (!conf) + goto out; - if (conf->rpc) { - conf->rpc = rpc_clnt_unref (conf->rpc); - ret = 0; - gf_log (this->name, GF_LOG_DEBUG, - "Client rpc conn destroyed"); - goto out; - } + if (conf->rpc) { + /* cleanup the saved-frames before last unref */ + rpc_clnt_connection_cleanup(&conf->rpc->conn); - gf_log (this->name, GF_LOG_WARNING, - "RPC destroy called on already destroyed " - "connection"); + conf->rpc = rpc_clnt_unref(conf->rpc); + ret = 0; + gf_msg_debug(this->name, 0, "Client rpc conn destroyed"); + goto out; + } + + gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_RPC_INVALID_CALL, NULL); out: - return ret; + return ret; } -int -client_init_rpc (xlator_t *this) +static int +client_init_rpc(xlator_t *this) { - int ret = -1; - clnt_conf_t *conf = NULL; + int ret = -1; + clnt_conf_t *conf = NULL; - conf = this->private; + conf = this->private; - if (conf->rpc) { - gf_log (this->name, GF_LOG_WARNING, - "client rpc already init'ed"); - ret = -1; - goto out; - } + if (conf->rpc) { + gf_smsg(this->name, GF_LOG_WARNING, 0, PC_MSG_RPC_INITED_ALREADY, NULL); + ret = -1; + goto out; + } - conf->rpc = rpc_clnt_new (this->options, this->ctx, this->name); - if (!conf->rpc) { - gf_log (this->name, GF_LOG_ERROR, "failed to initialize RPC"); - goto out; - } + conf->rpc = rpc_clnt_new(this->options, this, this->name, 0); + if (!conf->rpc) { + gf_smsg(this->name, GF_LOG_ERROR, 0, PC_MSG_RPC_INIT_FAILED, NULL); + 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; - } + ret = rpc_clnt_register_notify(conf->rpc, client_rpc_notify, this); + if (ret) { + gf_smsg(this->name, GF_LOG_ERROR, 0, PC_MSG_RPC_NOTIFY_FAILED, NULL); + goto out; + } - conf->handshake = &clnt_handshake_prog; - conf->dump = &clnt_dump_prog; + conf->handshake = &clnt_handshake_prog; + conf->dump = &clnt_dump_prog; - ret = rpcclnt_cbk_program_register (conf->rpc, &gluster_cbk_prog); - if (ret) { - gf_log (this->name, GF_LOG_ERROR, - "failed to register callback program"); - goto out; - } + ret = rpcclnt_cbk_program_register(conf->rpc, &gluster_cbk_prog, this); + if (ret) { + gf_smsg(this->name, GF_LOG_ERROR, 0, PC_MSG_RPC_CBK_FAILED, NULL); + goto out; + } - ret = 0; + ret = 0; - gf_log (this->name, GF_LOG_DEBUG, "client init successful"); + gf_msg_debug(this->name, 0, "client init successful"); out: - return ret; + return ret; } - -int -reconfigure (xlator_t *this, dict_t *options) +static int +client_check_event_threads(xlator_t *this, clnt_conf_t *conf, int32_t old, + int32_t new) { - 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); + if (old == new) + return 0; - subvol_ret = dict_get_str (this->options, "remote-host", - &old_remote_host); + conf->event_threads = new; + return gf_event_reconfigure_threads(this->ctx->event_pool, + conf->event_threads); +} +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; + int32_t new_nthread = 0; + struct rpc_clnt_config rpc_config = { + 0, + }; + + conf = this->private; + + GF_OPTION_RECONF("frame-timeout", conf->rpc_conf.rpc_timeout, options, + int32, out); + + GF_OPTION_RECONF("ping-timeout", rpc_config.ping_timeout, options, int32, + out); + + GF_OPTION_RECONF("event-threads", new_nthread, options, int32, out); + ret = client_check_event_threads(this, conf, conf->event_threads, + new_nthread); + if (ret) + goto out; + + ret = client_check_remote_host(this, options); + if (ret) + goto out; + + subvol_ret = dict_get_str_sizen(this->options, "remote-host", + &old_remote_host); + + if (subvol_ret == 0) { + subvol_ret = dict_get_str_sizen(options, "remote-host", + &new_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; - } - } + if (strcmp(old_remote_host, new_remote_host)) { + ret = 1; + goto out; + } } + } - subvol_ret = dict_get_str (this->options, "remote-subvolume", - &old_remote_subvol); + subvol_ret = dict_get_str_sizen(this->options, "remote-subvolume", + &old_remote_subvol); + if (subvol_ret == 0) { + subvol_ret = dict_get_str_sizen(options, "remote-subvolume", + &new_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; - } - } + if (strcmp(old_remote_subvol, new_remote_subvol)) { + ret = 1; + goto out; + } } + } - ret = 0; -out: - return ret; + /* Reconfiguring client xlator's @rpc with new frame-timeout + * and ping-timeout */ + rpc_clnt_reconfig(conf->rpc, &rpc_config); -} + GF_OPTION_RECONF("filter-O_DIRECT", conf->filter_o_direct, options, bool, + out); + GF_OPTION_RECONF("send-gids", conf->send_gids, options, bool, out); + GF_OPTION_RECONF("strict-locks", conf->strict_locks, options, bool, out); + + ret = 0; +out: + return ret; +} int -init (xlator_t *this) +init(xlator_t *this) { - int ret = -1; - clnt_conf_t *conf = NULL; + 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->children) { + gf_smsg(this->name, GF_LOG_ERROR, EINVAL, PC_MSG_FATAL_CLIENT_PROTOCOL, + NULL); + goto out; + } - if (!this->parents) { - gf_log (this->name, GF_LOG_WARNING, - "Volume is dangling. "); - } + if (!this->parents) { + gf_smsg(this->name, GF_LOG_WARNING, EINVAL, PC_MSG_VOL_DANGLING, NULL); + } - conf = GF_CALLOC (1, sizeof (*conf), gf_client_mt_clnt_conf_t); - if (!conf) - 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); + pthread_mutex_init(&conf->lock, NULL); + pthread_cond_init(&conf->fini_complete_cond, NULL); + pthread_spin_init(&conf->fd_lock, 0); + INIT_LIST_HEAD(&conf->saved_fds); - LOCK_INIT (&conf->rec_lock); + conf->child_up = _gf_false; - conf->last_sent_event = -1; /* To start with we don't have any events */ + /* Set event threads to the configured default */ + GF_OPTION_INIT("event-threads", conf->event_threads, int32, out); + ret = client_check_event_threads(this, conf, STARTING_EVENT_THREADS, + conf->event_threads); + if (ret) + goto out; - this->private = conf; + LOCK_INIT(&conf->rec_lock); - /* 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. - */ + conf->last_sent_event = -1; /* To start with we don't have any events */ - ret = build_client_config (this, conf); - if (ret == -1) - goto out; + this->private = conf; - if (ret) { - ret = 0; - goto out; - } + /* 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; - ret = client_init_rpc (this); + if (ret) { + ret = 0; + goto out; + } + + this->local_pool = mem_pool_new(clnt_local_t, 64); + if (!this->local_pool) { + ret = -1; + gf_smsg(this->name, GF_LOG_ERROR, ENOMEM, PC_MSG_CREATE_MEM_POOL_FAILED, + NULL); + goto out; + } + + ret = client_init_rpc(this); out: - if (ret) - this->fini (this); + if (ret) + this->fini(this); - return ret; + return ret; } void -fini (xlator_t *this) +fini(xlator_t *this) { - clnt_conf_t *conf = NULL; + clnt_conf_t *conf = NULL; - conf = this->private; - this->private = NULL; - - if (conf) { - if (conf->rpc) - rpc_clnt_unref (conf->rpc); - - /* Saved Fds */ - /* TODO: */ - - pthread_mutex_destroy (&conf->lock); - - GF_FREE (conf); - } + conf = this->private; + if (!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(this->name, 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); + conf->fini_completed = _gf_false; + conf->destroy = 1; + if (conf->rpc) { + /* cleanup the saved-frames before last unref */ + rpc_clnt_connection_cleanup(&conf->rpc->conn); + rpc_clnt_unref(conf->rpc); + } + + pthread_mutex_lock(&conf->lock); + { + while (!conf->fini_completed) + pthread_cond_wait(&conf->fini_complete_cond, &conf->lock); + } + pthread_mutex_unlock(&conf->lock); + + pthread_spin_destroy(&conf->fd_lock); + pthread_mutex_destroy(&conf->lock); + pthread_cond_destroy(&conf->fini_complete_cond); + GF_FREE(conf); + + /* Saved Fds */ + /* TODO: */ + + return; +} - gf_proc_dump_add_section(key_prefix); +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_ref(lk_ctx); + if (!lk_ctx_ref) + return; - 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); - } + ret = client_fd_lk_list_empty(lk_ctx_ref, (use_try_lock = _gf_true)); + if (ret != 0) + return; - gf_proc_dump_write("connecting", "%d", conf->connecting); - gf_proc_dump_write("last_sent", "%s", ctime(&conf->last_sent.tv_sec)); - gf_proc_dump_write("last_received", "%s", ctime(&conf->last_received.tv_sec)); + gf_proc_dump_write("------", "------"); - if (conf->rpc) { - gf_proc_dump_write("total_bytes_read", "%"PRIu64, - conf->rpc->conn.trans->total_bytes_read); + lock_no = 0; - gf_proc_dump_write("total_bytes_written", "%"PRIu64, - conf->rpc->conn.trans->total_bytes_write); - } - pthread_mutex_unlock(&conf->lock); + ret = TRY_LOCK(&lk_ctx_ref->lock); + if (ret) + return; - return 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); + } + UNLOCK(&lk_ctx_ref->lock); + + gf_proc_dump_write("------", "------"); + + fd_lk_ctx_unref(lk_ctx_ref); +} +static 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]; + rpc_clnt_connection_t *conn = NULL; + + if (!this) + return -1; + + conf = this->private; + if (!conf) + return -1; + + gf_proc_dump_build_key(key_prefix, "xlator.protocol.client", "%s.priv", + this->name); + + gf_proc_dump_add_section("%s", key_prefix); + + ret = pthread_mutex_trylock(&conf->lock); + if (ret) + return -1; + + pthread_spin_lock(&conf->fd_lock); + list_for_each_entry(tmp, &conf->saved_fds, sfd_pos) + { + sprintf(key, "fd.%d.remote_fd", i); + gf_proc_dump_write(key, "%" PRId64, tmp->remote_fd); + client_fd_lk_ctx_dump(this, tmp->lk_ctx, i); + i++; + } + pthread_spin_unlock(&conf->fd_lock); + + gf_proc_dump_write("connected", "%d", conf->connected); + + if (conf->rpc) { + conn = &conf->rpc->conn; + gf_proc_dump_write("total_bytes_read", "%" PRIu64, + conn->trans->total_bytes_read); + gf_proc_dump_write("ping_timeout", "%" PRIu32, conn->ping_timeout); + gf_proc_dump_write("total_bytes_written", "%" PRIu64, + conn->trans->total_bytes_write); + gf_proc_dump_write("ping_msgs_sent", "%" PRIu64, conn->pingcnt); + gf_proc_dump_write("msgs_sent", "%" PRIu64, conn->msgcnt); + } + pthread_mutex_unlock(&conf->lock); + + return 0; } int32_t -client_inodectx_dump (xlator_t *this, inode_t *inode) +client_inodectx_dump(xlator_t *this, inode_t *inode) { - if (!inode) - return -1; + if (!inode) + return -1; - if (!this) - return -1; + if (!this) + return -1; - /*TODO*/ + /*TODO*/ - return 0; + return 0; } - - - -struct xlator_cbks cbks = { - .forget = client_forget, - .release = client_release, - .releasedir = client_releasedir -}; +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, - .rchecksum = client_rchecksum, - .xattrop = client_xattrop, - .fxattrop = client_fxattrop, - .setattr = client_setattr, - .fsetattr = client_fsetattr, - .getspec = client_getspec, + .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, + .ipc = client_ipc, + .seek = client_seek, + .lease = client_lease, + .compound = client_compound, + .getactivelk = client_getactivelk, + .setactivelk = client_setactivelk, + .icreate = client_icreate, + .namelink = client_namelink, + .put = client_put, + .copy_file_range = client_copy_file_range, }; - struct xlator_dumpops dumpops = { - .priv = client_priv_dump, - .inodectx = client_inodectx_dump, + .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 = {NULL} }, + {.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, + .default_value = "tcp", + }, + {.key = {"remote-host"}, + .type = GF_OPTION_TYPE_INTERNET_ADDRESS, + .default_value = "{{ brick.hostname }}"}, + { + .key = {"remote-port"}, + .type = GF_OPTION_TYPE_INT, + }, + {.key = {"remote-subvolume"}, + .type = GF_OPTION_TYPE_ANY, + .default_value = "{{ brick.path }}"}, + {.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.", + .op_version = {1}, + .flags = OPT_FLAG_SETTABLE | OPT_FLAG_DOC}, + {.key = {"ping-timeout"}, + .type = GF_OPTION_TYPE_TIME, + .min = 0, + .max = 1013, + .default_value = TOSTRING(GF_NETWORK_TIMEOUT), + .description = "Time duration for which the client waits to " + "check if the server is responsive.", + .op_version = {1}, + .flags = OPT_FLAG_SETTABLE | OPT_FLAG_DOC}, + {.key = {"client-bind-insecure"}, .type = GF_OPTION_TYPE_BOOL}, + {.key = {"tcp-window-size"}, + .type = GF_OPTION_TYPE_SIZET, + .min = GF_MIN_SOCKET_WINDOW_SIZE, + .max = GF_MAX_SOCKET_WINDOW_SIZE, + .description = "Specifies the window size for tcp socket.", + .op_version = {1}, + .flags = OPT_FLAG_SETTABLE | OPT_FLAG_DOC}, + {.key = {"filter-O_DIRECT"}, + .type = GF_OPTION_TYPE_BOOL, + .default_value = "disable", + .description = + "If enabled, in open/creat/readv/writev fops, " + "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. Anon-fds can choose to readv/writev " + "using O_DIRECT", + .op_version = {2}, + .flags = OPT_FLAG_SETTABLE | OPT_FLAG_DOC}, + {.key = {"send-gids"}, + .type = GF_OPTION_TYPE_BOOL, + .default_value = "on", + .op_version = {GD_OP_VERSION_3_6_0}, + .flags = OPT_FLAG_SETTABLE}, + {.key = {"event-threads"}, + .type = GF_OPTION_TYPE_INT, + .min = 1, + .max = 32, + .default_value = "2", + .description = "Specifies the number of event threads to execute " + "in parallel. Larger values would help process" + " responses faster, depending on available processing" + " power. Range 1-32 threads.", + .op_version = {GD_OP_VERSION_3_7_0}, + .flags = OPT_FLAG_SETTABLE | OPT_FLAG_DOC}, + + /* This option is required for running code-coverage tests with + old protocol */ + { + .key = {"testing.old-protocol"}, + .type = GF_OPTION_TYPE_BOOL, + .default_value = "off", + .op_version = {GD_OP_VERSION_7_0}, + .flags = OPT_FLAG_SETTABLE, + }, + {.key = {"strict-locks"}, + .type = GF_OPTION_TYPE_BOOL, + .default_value = "off", + .op_version = {GD_OP_VERSION_7_0}, + .flags = OPT_FLAG_SETTABLE, + .description = "When set, doesn't reopen saved fds after reconnect " + "if POSIX locks are held on them. Hence subsequent " + "operations on these fds will fail. This is " + "necessary for stricter lock complaince as bricks " + "cleanup any granted locks when a client " + "disconnects."}, + {.key = {NULL}}, +}; + +xlator_api_t xlator_api = { + .init = init, + .fini = fini, + .notify = notify, + .reconfigure = reconfigure, + .mem_acct_init = mem_acct_init, + .op_version = {1}, /* Present from the initial version */ + .dumpops = &dumpops, + .fops = &fops, + .cbks = &cbks, + .options = options, + .identifier = "client", + .category = GF_MAINTAINED, }; diff --git a/xlators/protocol/client/src/client.h b/xlators/protocol/client/src/client.h index 69830db9dc1..ab799c41755 100644 --- a/xlators/protocol/client/src/client.h +++ b/xlators/protocol/client/src/client.h @@ -1,20 +1,11 @@ /* - Copyright (c) 2010-2011 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/>. + 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 @@ -24,184 +15,380 @@ #include <stdint.h> #include "rpc-clnt.h" -#include "list.h" -#include "inode.h" +#include <glusterfs/list.h> +#include <glusterfs/inode.h> #include "client-mem-types.h" #include "protocol-common.h" #include "glusterfs3.h" +#include "glusterfs3-xdr.h" +#include <glusterfs/fd-lk.h> +#include <glusterfs/defaults.h> +#include <glusterfs/default-args.h> +#include "client-messages.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 CLIENT_GET_REMOTE_FD(conf, fd, remote_fd, label) \ - do { \ - clnt_fd_ctx_t *fdctx = NULL; \ - pthread_mutex_lock (&conf->lock); \ - { \ - fdctx = this_fd_get_ctx (fd, THIS); \ - } \ - pthread_mutex_unlock (&conf->lock); \ - if (!fdctx) { \ - remote_fd = -2; \ - } else { \ - remote_fd = fdctx->remote_fd; \ - } \ - } while (0); +#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 { + DEFAULT_REMOTE_FD = 0, + FALLBACK_TO_ANON_FD = 1 +} clnt_remote_fd_flags_t; + +#define CLIENT_POST_FOP(fop, this_rsp_u, this_args_cbk, params...) \ + do { \ + gf_common_rsp *_this_rsp = &CPD_RSP_FIELD(this_rsp_u, fop); \ + \ + int _op_ret = _this_rsp->op_ret; \ + int _op_errno = gf_error_to_errno(_this_rsp->op_errno); \ + args_##fop##_cbk_store(this_args_cbk, _op_ret, _op_errno, params); \ + } while (0) + +#define CLIENT_POST_FOP_TYPE(fop, this_rsp_u, this_args_cbk, params...) \ + do { \ + gfs3_##fop##_rsp *_this_rsp = &CPD_RSP_FIELD(this_rsp_u, fop); \ + \ + int _op_ret = _this_rsp->op_ret; \ + int _op_errno = gf_error_to_errno(_this_rsp->op_errno); \ + args_##fop##_cbk_store(this_args_cbk, _op_ret, _op_errno, params); \ + } while (0) + +#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_smsg(xl->name, GF_LOG_WARNING, EBADFD, PC_MSG_BAD_FD, \ + "gfid=%s", uuid_utoa(fd->inode->gfid), NULL); \ + op_errno = EBADFD; \ + goto label; \ + } \ + } while (0) + +#define CLIENT_STACK_UNWIND(op, frame, params...) \ + do { \ + if (!frame) \ + break; \ + 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; + 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; - struct timeval last_sent; - struct timeval last_received; - - 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 need_different_port; /* flag used to change the - portmap path in case of - 'tcp,rdma' on server */ + struct rpc_clnt *rpc; + struct clnt_options opt; + struct rpc_clnt_config rpc_conf; + struct list_head saved_fds; + pthread_spinlock_t fd_lock; /* protects saved_fds list + * and all fdctx */ + pthread_mutex_t lock; + int connected; + + rpc_clnt_prog_t *fops; + rpc_clnt_prog_t *mgmt; + rpc_clnt_prog_t *handshake; + rpc_clnt_prog_t *dump; + + int client_id; + 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 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() */ + /* set volume is the op which results in creating/re-using + * the conn-id and is called once per connection, this remembers + * how manytimes set_volume is called + */ + uint64_t setvol_count; + + gf_boolean_t send_gids; /* let the server resolve gids */ + + int event_threads; /* # of event threads + * configured */ + + gf_boolean_t destroy; /* if enabled implies fini was called + * on @this xlator instance */ + + gf_boolean_t child_up; /* Set to true, when child is up, and + * false, when child is down */ + + gf_boolean_t can_log_disconnect; /* socket level connection is + * up, disconnects can be + * logged + */ + + gf_boolean_t old_protocol; /* used only for old-protocol testing */ + pthread_cond_t fini_complete_cond; /* Used to wait till we finsh the fini + compltely, ie client_fini_complete + to return*/ + gf_boolean_t fini_completed; + gf_boolean_t strict_locks; /* When set, doesn't reopen saved fds after + reconnect if POSIX locks are held on them. + Hence subsequent operations on these fds will + fail. This is necessary for stricter lock + complaince as bricks cleanup any granted + locks when a client disconnects. + */ + + gf_boolean_t connection_to_brick; /*True from attempt to connect to brick + till disconnection to brick*/ } 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; - inode_t *inode; - uint64_t ino; - uint64_t gen; - char is_dir; - char released; - int32_t flags; - int32_t wbflags; - - pthread_mutex_t mutex; - struct list_head lock_list; /* List of all granted locks on this fd */ + 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; + uuid_t gfid; + void (*reopen_done)(struct _client_fd_ctx *, int64_t rfd, 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 */ - uint64_t owner; /* lock owner from fuse */ + fd_t *fd; /* The fd on which the lk operation was made */ - struct list_head list; /* reference used to add to the fdctx list of locks */ + 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; - uint32_t wbflags; - struct iobref *iobref; - - client_posix_lock_t *client_lock; - uint64_t owner; - int32_t cmd; - struct list_head lock_list; - pthread_mutex_t mutex; + loc_t loc; + loc_t loc2; + fd_t *fd; + fd_t *fd_out; /* used in copy_file_range */ + 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; + /* + * The below boolean variable is used + * only for copy_file_range fop + */ + gf_boolean_t attempt_reopen_out; } clnt_local_t; typedef struct client_args { - loc_t *loc; - fd_t *fd; - dict_t *xattr_req; - const char *linkname; - struct iobref *iobref; - struct iovec *vector; - dict_t *xattr; - struct iatt *stbuf; - dict_t *dict; - 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 wbflags; - int32_t count; - int32_t datasync; - entrylk_cmd cmd_entrylk; - entrylk_type type; - gf_xattrop_flags_t optype; - int32_t valid; - int32_t len; + loc_t *loc; + /* + * This is the source fd for copy_file_range and + * the default fd for any other fd based fop which + * requires only one fd (i.e. opetates on one fd) + */ + fd_t *fd; + fd_t *fd_out; /* this is the destination fd for copy_file_range */ + 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; + /* + * According to the man page of copy_file_range, + * the offsets for source and destination file + * are of type loff_t. But the type loff_t is + * linux specific and is actual a typedef of + * off64_t. + */ + off64_t off_in; /* used in copy_file_range for source fd */ + off64_t off_out; /* used in copy_file_range for dst fd */ + 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; + gf_seek_what_t what; + struct gf_lease *lease; + + mode_t umask; + dict_t *xdata; + lock_migration_info_t *locklist; } 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 protocol_client_reopendir (xlator_t *this, clnt_fd_ctx_t *fdctx); -int protocol_client_reopen (xlator_t *this, clnt_fd_ctx_t *fdctx); - -int unserialize_rsp_dirent (struct gfs3_readdir_rsp *rsp, gf_dirent_t *entries); -int unserialize_rsp_direntp (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, uint64_t owner); -int client_add_lock_for_recovery (fd_t *fd, struct gf_flock *flock, uint64_t owner, - int32_t cmd); -uint64_t decrement_reopen_fd_count (xlator_t *this, clnt_conf_t *conf); -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); +typedef struct client_payload { + struct iobref *iobref; + struct iovec *payload; + struct iovec *rsphdr; + struct iovec *rsp_payload; + struct iobref *rsp_iobref; + int payload_cnt; + int rsphdr_cnt; + int rsp_payload_cnt; +} client_payload_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, + client_payload_t *cp, xdrproc_t xdrproc); + +int +unserialize_rsp_dirent(xlator_t *this, 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); +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); +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); + +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, int64_t rfd, 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); +int +client_notify_dispatch(xlator_t *this, int32_t event, void *data, ...); +int +client_notify_dispatch_uniq(xlator_t *this, int32_t event, void *data, ...); + +gf_boolean_t +client_is_reopen_needed(fd_t *fd, xlator_t *this, int64_t remote_fd); + +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 +clnt_unserialize_rsp_locklist(xlator_t *this, struct gfs3_getactivelk_rsp *rsp, + lock_migration_info_t *lmi); +void +clnt_getactivelk_rsp_cleanup(gfs3_getactivelk_rsp *rsp); + +void +clnt_setactivelk_req_cleanup(gfs3_setactivelk_req *req); + +int +serialize_req_locklist(lock_migration_info_t *locklist, + gfs3_setactivelk_req *req); + +void +clnt_getactivelk_rsp_cleanup_v2(gfx_getactivelk_rsp *rsp); + +void +clnt_setactivelk_req_cleanup_v2(gfx_setactivelk_req *req); + +int +serialize_req_locklist_v2(lock_migration_info_t *locklist, + gfx_setactivelk_req *req); + +int +clnt_unserialize_rsp_locklist_v2(xlator_t *this, + struct gfx_getactivelk_rsp *rsp, + lock_migration_info_t *lmi); + +int +unserialize_rsp_dirent_v2(xlator_t *this, struct gfx_readdir_rsp *rsp, + gf_dirent_t *entries); +int +unserialize_rsp_direntp_v2(xlator_t *this, fd_t *fd, + struct gfx_readdirp_rsp *rsp, gf_dirent_t *entries); + +int +clnt_readdir_rsp_cleanup_v2(gfx_readdir_rsp *rsp); +int +clnt_readdirp_rsp_cleanup_v2(gfx_readdirp_rsp *rsp); + +int +client_add_lock_for_recovery(fd_t *fd, struct gf_flock *flock, + gf_lkowner_t *owner, int32_t cmd); + +int +client_is_setlk(int32_t cmd); #endif /* !_CLIENT_H */ diff --git a/xlators/protocol/client/src/client3_1-fops.c b/xlators/protocol/client/src/client3_1-fops.c deleted file mode 100644 index 6300b264fb1..00000000000 --- a/xlators/protocol/client/src/client3_1-fops.c +++ /dev/null @@ -1,5352 +0,0 @@ -/* - Copyright (c) 2010-2011 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 "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_1_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 cbk, - 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; - - 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 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) { - gf_log_callingfn ("", GF_LOG_WARNING, - "XDR function failed"); - goto out; - } - - iov.iov_len = ret; - count = 1; - } - - /* Send the msg */ - ret = rpc_clnt_submit (conf->rpc, prog, procnum, cbk, &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); - -out: - if (new_iobref != NULL) { - iobref_unref (new_iobref); - } - - iobuf_unref (iobuf); - - return ret; -} - -/* CBK */ - -int -client3_1_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; - - this = THIS; - - frame = myframe; - - local = frame->local; - frame->local = NULL; - 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); - } - -out: - frame->local = NULL; - 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) ? local->loc.path : "--"); - } - STACK_UNWIND_STRICT (symlink, frame, rsp.op_ret, - gf_error_to_errno (rsp.op_errno), inode, &stbuf, - &preparent, &postparent); - - client_local_wipe (local); - - return 0; -} - - -int -client3_1_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; - - this = THIS; - - frame = myframe; - - local = frame->local; - frame->local = NULL; - 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); - } - -out: - frame->local = NULL; - 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) ? local->loc.path : "--"); - } - STACK_UNWIND_STRICT (mknod, frame, rsp.op_ret, - gf_error_to_errno (rsp.op_errno), inode, - &stbuf, &preparent, &postparent); - - client_local_wipe (local); - - return 0; -} - -int -client3_1_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; - - 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); - } - -out: - frame->local = NULL; - 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) ? local->loc.path : "--"); - } - STACK_UNWIND_STRICT (mkdir, frame, rsp.op_ret, - gf_error_to_errno (rsp.op_errno), inode, - &stbuf, &preparent, &postparent); - - client_local_wipe (local); - - return 0; -} - -int -client3_1_open_cbk (struct rpc_req *req, struct iovec *iov, int count, - void *myframe) -{ - clnt_local_t *local = NULL; - clnt_conf_t *conf = NULL; - clnt_fd_ctx_t *fdctx = NULL; - call_frame_t *frame = NULL; - fd_t *fd = NULL; - int ret = 0; - gfs3_open_rsp rsp = {0,}; - xlator_t *this = NULL; - - this = THIS; - - frame = myframe; - local = frame->local; - - frame->local = NULL; - 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) { - fdctx = GF_CALLOC (1, sizeof (*fdctx), - gf_client_mt_clnt_fdctx_t); - if (!fdctx) { - rsp.op_ret = -1; - rsp.op_errno = ENOMEM; - goto out; - } - - fdctx->remote_fd = rsp.fd; - fdctx->inode = inode_ref (fd->inode); - fdctx->flags = local->flags; - fdctx->wbflags = local->wbflags; - - INIT_LIST_HEAD (&fdctx->sfd_pos); - INIT_LIST_HEAD (&fdctx->lock_list); - - this_fd_set_ctx (fd, frame->this, &local->loc, fdctx); - - pthread_mutex_lock (&conf->lock); - { - list_add_tail (&fdctx->sfd_pos, &conf->saved_fds); - } - pthread_mutex_unlock (&conf->lock); - } - -out: - frame->local = NULL; - 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) ? local->loc.path : "--"); - } - STACK_UNWIND_STRICT (open, frame, rsp.op_ret, - gf_error_to_errno (rsp.op_errno), fd); - - client_local_wipe (local); - - return 0; -} - - -int -client3_1_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; - - 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); - } - -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))); - } - STACK_UNWIND_STRICT (stat, frame, rsp.op_ret, - gf_error_to_errno (rsp.op_errno), &iatt); - - return 0; -} - -int -client3_1_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; - - 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); - } - -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))); - } - STACK_UNWIND_STRICT (readlink, frame, rsp.op_ret, - gf_error_to_errno (rsp.op_errno), rsp.path, &iatt); - - /* This is allocated by the libc while decoding RPC msg */ - /* Hence no 'GF_FREE', but just 'free' */ - if (rsp.path) - free (rsp.path); - - return 0; -} - -int -client3_1_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; - - 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); - } - -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))); - } - STACK_UNWIND_STRICT (unlink, frame, rsp.op_ret, - gf_error_to_errno (rsp.op_errno), &preparent, - &postparent); - - return 0; -} - -int -client3_1_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; - - 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); - } - -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))); - } - STACK_UNWIND_STRICT (rmdir, frame, rsp.op_ret, - gf_error_to_errno (rsp.op_errno), &preparent, - &postparent); - - return 0; -} - - -int -client3_1_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; - - 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); - } - -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))); - } - STACK_UNWIND_STRICT (truncate, frame, rsp.op_ret, - gf_error_to_errno (rsp.op_errno), &prestat, - &poststat); - - return 0; -} - - -int -client3_1_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; - - 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); - } - -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))); - } - STACK_UNWIND_STRICT (statfs, frame, rsp.op_ret, - gf_error_to_errno (rsp.op_errno), &statfs); - - return 0; -} - - -int -client3_1_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; - - 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); - } - -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))); - } - STACK_UNWIND_STRICT (writev, frame, rsp.op_ret, - gf_error_to_errno (rsp.op_errno), &prestat, - &poststat); - - return 0; -} - -int -client3_1_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; - 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) { - /* 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 (%llu) returned %d", - (long long unsigned) local->owner, ret); - } - -out: - frame->local = NULL; - if (rsp.op_ret == -1) { - gf_log (this->name, GF_LOG_WARNING, - "remote operation failed: %s", - strerror (gf_error_to_errno (rsp.op_errno))); - } - STACK_UNWIND_STRICT (flush, frame, rsp.op_ret, - gf_error_to_errno (rsp.op_errno)); - - client_local_wipe (local); - - return 0; -} - -int -client3_1_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; - - 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); - } - -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))); - } - STACK_UNWIND_STRICT (fsync, frame, rsp.op_ret, - gf_error_to_errno (rsp.op_errno), &prestat, - &poststat); - - return 0; -} - -int -client3_1_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; - - 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; - } - -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))); - } - STACK_UNWIND_STRICT (setxattr, frame, rsp.op_ret, - gf_error_to_errno (rsp.op_errno)); - - return 0; -} - -int -client3_1_getxattr_cbk (struct rpc_req *req, struct iovec *iov, int count, - void *myframe) -{ - call_frame_t *frame = NULL; - dict_t *dict = NULL; - char *buf = NULL; - int dict_len = 0; - int op_ret = 0; - int op_errno = EINVAL; - gfs3_getxattr_rsp rsp = {0,}; - int ret = 0; - clnt_local_t *local = NULL; - xlator_t *this = NULL; - - this = THIS; - - frame = myframe; - local = frame->local; - frame->local = NULL; - - if (-1 == req->rpc_status) { - 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"); - op_ret = -1; - op_errno = EINVAL; - goto out; - } - - op_errno = gf_error_to_errno (rsp.op_errno); - op_ret = rsp.op_ret; - if (-1 != op_ret) { - op_ret = -1; - dict_len = rsp.dict.dict_len; - - if (dict_len > 0) { - dict = dict_new(); - buf = memdup (rsp.dict.dict_val, rsp.dict.dict_len); - - GF_VALIDATE_OR_GOTO (frame->this->name, dict, out); - GF_VALIDATE_OR_GOTO (frame->this->name, buf, out); - - ret = dict_unserialize (buf, dict_len, &dict); - if (ret < 0) { - gf_log (frame->this->name, GF_LOG_WARNING, - "failed to unserialize xattr dict"); - op_errno = EINVAL; - goto out; - } - dict->extra_free = buf; - buf = NULL; - } - op_ret = 0; - } - -out: - if (rsp.op_ret == -1) { - gf_log (this->name, GF_LOG_WARNING, - "remote operation failed: %s. Path: %s", - strerror (op_errno), - (local) ? local->loc.path : "--"); - } - STACK_UNWIND_STRICT (getxattr, frame, op_ret, op_errno, dict); - - if (rsp.dict.dict_val) { - /* don't use GF_FREE, this memory was allocated by libc - */ - free (rsp.dict.dict_val); - rsp.dict.dict_val = NULL; - } - - if (buf) - GF_FREE (buf); - - if (dict) - dict_unref (dict); - - client_local_wipe (local); - - return 0; -} - -int -client3_1_fgetxattr_cbk (struct rpc_req *req, struct iovec *iov, int count, - void *myframe) -{ - call_frame_t *frame = NULL; - char *buf = NULL; - dict_t *dict = NULL; - gfs3_fgetxattr_rsp rsp = {0,}; - int ret = 0; - int dict_len = 0; - int op_ret = 0; - int op_errno = EINVAL; - clnt_local_t *local = NULL; - xlator_t *this = NULL; - - this = THIS; - - frame = myframe; - local = frame->local; - frame->local = NULL; - - if (-1 == req->rpc_status) { - 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"); - op_ret = -1; - op_errno = EINVAL; - goto out; - } - - op_errno = gf_error_to_errno (rsp.op_errno); - op_ret = rsp.op_ret; - if (-1 != op_ret) { - op_ret = -1; - dict_len = rsp.dict.dict_len; - - if (dict_len > 0) { - dict = dict_new(); - GF_VALIDATE_OR_GOTO (frame->this->name, dict, out); - buf = memdup (rsp.dict.dict_val, rsp.dict.dict_len); - GF_VALIDATE_OR_GOTO (frame->this->name, buf, out); - - ret = dict_unserialize (buf, dict_len, &dict); - if (ret < 0) { - gf_log (frame->this->name, GF_LOG_WARNING, - "failed to unserialize xattr dict"); - op_errno = EINVAL; - goto out; - } - dict->extra_free = buf; - buf = NULL; - } - op_ret = 0; - } -out: - if (rsp.op_ret == -1) { - gf_log (this->name, GF_LOG_WARNING, - "remote operation failed: %s", - strerror (op_errno)); - } - STACK_UNWIND_STRICT (fgetxattr, frame, op_ret, op_errno, dict); - if (rsp.dict.dict_val) { - /* don't use GF_FREE, this memory was allocated by libc - */ - free (rsp.dict.dict_val); - rsp.dict.dict_val = NULL; - } - - if (buf) - GF_FREE (buf); - - if (dict) - dict_unref (dict); - - client_local_wipe (local); - - return 0; -} - -int -client3_1_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; - - 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; - } - -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))); - } - STACK_UNWIND_STRICT (removexattr, frame, rsp.op_ret, - gf_error_to_errno (rsp.op_errno)); - - return 0; -} - -int -client3_1_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; - - 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; - } - -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))); - } - STACK_UNWIND_STRICT (fsyncdir, frame, rsp.op_ret, - gf_error_to_errno (rsp.op_errno)); - - return 0; -} - -int -client3_1_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; - - 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; - } - -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))); - } - STACK_UNWIND_STRICT (access, frame, rsp.op_ret, - gf_error_to_errno (rsp.op_errno)); - - return 0; -} - - -int -client3_1_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; - - 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); - } - -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))); - } - STACK_UNWIND_STRICT (ftruncate, frame, rsp.op_ret, - gf_error_to_errno (rsp.op_errno), &prestat, - &poststat); - - return 0; -} - -int -client3_1_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; - - 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); - } - -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))); - } - STACK_UNWIND_STRICT (fstat, frame, rsp.op_ret, - gf_error_to_errno (rsp.op_errno), &stat); - - return 0; -} - - -int -client3_1_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; - - 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; - } - -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))); - } - STACK_UNWIND_STRICT (inodelk, frame, rsp.op_ret, - gf_error_to_errno (rsp.op_errno)); - - return 0; -} - -int -client3_1_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; - - 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; - } - -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))); - } - STACK_UNWIND_STRICT (finodelk, frame, rsp.op_ret, - gf_error_to_errno (rsp.op_errno)); - - return 0; -} - -int -client3_1_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; - - 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; - } - -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))); - } - STACK_UNWIND_STRICT (entrylk, frame, rsp.op_ret, - gf_error_to_errno (rsp.op_errno)); - - return 0; -} - -int -client3_1_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; - - 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; - } - -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))); - } - STACK_UNWIND_STRICT (fentrylk, frame, rsp.op_ret, - gf_error_to_errno (rsp.op_errno)); - - return 0; -} - -int -client3_1_xattrop_cbk (struct rpc_req *req, struct iovec *iov, int count, - void *myframe) -{ - call_frame_t *frame = NULL; - dict_t *dict = NULL; - char *buf = NULL; - gfs3_xattrop_rsp rsp = {0,}; - int ret = 0; - int op_ret = 0; - int dict_len = 0; - int op_errno = EINVAL; - clnt_local_t *local = NULL; - xlator_t *this = NULL; - - this = THIS; - - frame = myframe; - local = frame->local; - frame->local = NULL; - - if (-1 == req->rpc_status) { - 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"); - op_ret = -1; - op_errno = EINVAL; - goto out; - } - - op_errno = rsp.op_errno; - op_ret = rsp.op_ret; - if (-1 != op_ret) { - op_ret = -1; - dict_len = rsp.dict.dict_len; - - if (dict_len > 0) { - dict = dict_new(); - GF_VALIDATE_OR_GOTO (frame->this->name, dict, out); - - buf = memdup (rsp.dict.dict_val, rsp.dict.dict_len); - GF_VALIDATE_OR_GOTO (frame->this->name, buf, out); - op_ret = dict_unserialize (buf, dict_len, &dict); - if (op_ret < 0) { - gf_log (frame->this->name, GF_LOG_WARNING, - "failed to unserialize xattr dict"); - op_errno = EINVAL; - goto out; - } - dict->extra_free = buf; - buf = NULL; - } - op_ret = 0; - } - -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) ? local->loc.path : "--"); - } - STACK_UNWIND_STRICT (xattrop, frame, op_ret, - gf_error_to_errno (op_errno), dict); - - if (rsp.dict.dict_val) { - /* don't use GF_FREE, this memory was allocated by libc - */ - free (rsp.dict.dict_val); - rsp.dict.dict_val = NULL; - } - - if (buf) - GF_FREE (buf); - - if (dict) - dict_unref (dict); - - client_local_wipe (local); - - return 0; -} - -int -client3_1_fxattrop_cbk (struct rpc_req *req, struct iovec *iov, int count, - void *myframe) -{ - call_frame_t *frame = NULL; - dict_t *dict = NULL; - char *buf = NULL; - gfs3_fxattrop_rsp rsp = {0,}; - int ret = 0; - int op_ret = 0; - int dict_len = 0; - int op_errno = 0; - clnt_local_t *local = NULL; - xlator_t *this = NULL; - - this = THIS; - - frame = myframe; - local = frame->local; - frame->local = NULL; - - if (-1 == req->rpc_status) { - op_ret = -1; - op_errno = ENOTCONN; - goto out; - } - - ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gfs3_fxattrop_rsp); - if (ret < 0) { - op_ret = -1; - op_errno = EINVAL; - gf_log (this->name, GF_LOG_ERROR, "XDR decoding failed"); - goto out; - } - op_errno = rsp.op_errno; - op_ret = rsp.op_ret; - if (-1 != op_ret) { - op_ret = -1; - dict_len = rsp.dict.dict_len; - - if (dict_len > 0) { - dict = dict_new(); - GF_VALIDATE_OR_GOTO (frame->this->name, dict, out); - - buf = memdup (rsp.dict.dict_val, rsp.dict.dict_len); - GF_VALIDATE_OR_GOTO (frame->this->name, buf, out); - op_ret = dict_unserialize (buf, dict_len, &dict); - if (op_ret < 0) { - gf_log (frame->this->name, GF_LOG_WARNING, - "failed to unserialize xattr dict"); - op_errno = EINVAL; - goto out; - } - dict->extra_free = buf; - buf = NULL; - } - op_ret = 0; - } - -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))); - } - STACK_UNWIND_STRICT (fxattrop, frame, op_ret, - gf_error_to_errno (op_errno), dict); - - if (rsp.dict.dict_val) { - /* don't use GF_FREE, this memory was allocated by libc - */ - free (rsp.dict.dict_val); - rsp.dict.dict_val = NULL; - } - - if (buf) - GF_FREE (buf); - - if (dict) - dict_unref (dict); - - client_local_wipe (local); - return 0; -} - -int -client3_1_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; - - 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; - } - -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))); - } - STACK_UNWIND_STRICT (fsetxattr, frame, rsp.op_ret, - gf_error_to_errno (rsp.op_errno)); - - return 0; -} - -int -client3_1_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; - - 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); - } - -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))); - } - STACK_UNWIND_STRICT (fsetattr, frame, rsp.op_ret, - gf_error_to_errno (rsp.op_errno), &prestat, - &poststat); - - return 0; -} - - -int -client3_1_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; - - 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); - } - -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))); - } - STACK_UNWIND_STRICT (setattr, frame, rsp.op_ret, - gf_error_to_errno (rsp.op_errno), &prestat, - &poststat); - - return 0; -} - -int -client3_1_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; - clnt_conf_t *conf = NULL; - clnt_fd_ctx_t *fdctx = NULL; - gfs3_create_rsp rsp = {0,}; - xlator_t *this = NULL; - - this = THIS; - - frame = myframe; - local = frame->local; frame->local = NULL; - conf = frame->this->private; - 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); - - fdctx = GF_CALLOC (1, sizeof (*fdctx), - gf_client_mt_clnt_fdctx_t); - if (!fdctx) { - rsp.op_ret = -1; - rsp.op_errno = ENOMEM; - goto out; - } - - fdctx->remote_fd = rsp.fd; - fdctx->inode = inode_ref (inode); - fdctx->flags = local->flags; - - INIT_LIST_HEAD (&fdctx->sfd_pos); - INIT_LIST_HEAD (&fdctx->lock_list); - - this_fd_set_ctx (fd, frame->this, &local->loc, fdctx); - - pthread_mutex_lock (&conf->lock); - { - list_add_tail (&fdctx->sfd_pos, &conf->saved_fds); - } - pthread_mutex_unlock (&conf->lock); - } - -out: - frame->local = NULL; - 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) ? local->loc.path : "--"); - } - STACK_UNWIND_STRICT (create, frame, rsp.op_ret, - gf_error_to_errno (rsp.op_errno), fd, inode, - &stbuf, &preparent, &postparent); - - client_local_wipe (local); - return 0; -} - - -int -client3_1_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; - - 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; - } - -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))); - } - STACK_UNWIND_STRICT (rchecksum, frame, rsp.op_ret, - gf_error_to_errno (rsp.op_errno), - rsp.weak_checksum, - (uint8_t *)rsp.strong_checksum.strong_checksum_val); - - 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); - } - - return 0; -} - -int -client3_1_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; - - 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; - } - } - */ - -out: - frame->local = NULL; - 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))); - } - STACK_UNWIND_STRICT (lk, frame, rsp.op_ret, - gf_error_to_errno (rsp.op_errno), &lock); - - client_local_wipe (local); - return 0; -} - -int -client3_1_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; - - this = THIS; - - frame = myframe; - local = frame->local; - frame->local = NULL; - - 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); - } - -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))); - } - STACK_UNWIND_STRICT (readdir, frame, rsp.op_ret, - gf_error_to_errno (rsp.op_errno), &entries); - - client_local_wipe (local); - - if (rsp.op_ret != -1) { - gf_dirent_free (&entries); - } - - clnt_readdir_rsp_cleanup (&rsp); - - return 0; -} - - -int -client3_1_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; - - this = THIS; - - frame = myframe; - local = frame->local; - frame->local = NULL; - - 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 (&rsp, &entries); - } - -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))); - } - STACK_UNWIND_STRICT (readdirp, frame, rsp.op_ret, - gf_error_to_errno (rsp.op_errno), &entries); - - client_local_wipe (local); - - if (rsp.op_ret != -1) { - gf_dirent_free (&entries); - } - - clnt_readdirp_rsp_cleanup (&rsp); - - return 0; -} - - -int -client3_1_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; - - 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); - } - -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))); - } - STACK_UNWIND_STRICT (rename, frame, rsp.op_ret, - gf_error_to_errno (rsp.op_errno), - &stbuf, &preoldparent, &postoldparent, - &prenewparent, &postnewparent); - - return 0; -} - -int -client3_1_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; - - this = THIS; - - frame = myframe; - - local = frame->local; - frame->local = NULL; - 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); - } - -out: - frame->local = NULL; - 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) ? local->loc.path : "--"); - } - STACK_UNWIND_STRICT (link, frame, rsp.op_ret, - gf_error_to_errno (rsp.op_errno), inode, - &stbuf, &preparent, &postparent); - - client_local_wipe (local); - return 0; -} - - -int -client3_1_opendir_cbk (struct rpc_req *req, struct iovec *iov, int count, - void *myframe) -{ - clnt_local_t *local = NULL; - clnt_conf_t *conf = NULL; - clnt_fd_ctx_t *fdctx = NULL; - call_frame_t *frame = NULL; - fd_t *fd = NULL; - int ret = 0; - gfs3_opendir_rsp rsp = {0,}; - xlator_t *this = NULL; - - this = THIS; - - frame = myframe; - local = frame->local; - - frame->local = NULL; - 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) { - fdctx = GF_CALLOC (1, sizeof (*fdctx), - gf_client_mt_clnt_fdctx_t); - if (!fdctx) { - rsp.op_ret = -1; - rsp.op_errno = ENOMEM; - goto out; - } - - fdctx->remote_fd = rsp.fd; - fdctx->inode = inode_ref (fd->inode); - fdctx->is_dir = 1; - - INIT_LIST_HEAD (&fdctx->sfd_pos); - INIT_LIST_HEAD (&fdctx->lock_list); - - this_fd_set_ctx (fd, frame->this, &local->loc, fdctx); - - pthread_mutex_lock (&conf->lock); - { - list_add_tail (&fdctx->sfd_pos, &conf->saved_fds); - } - pthread_mutex_unlock (&conf->lock); - } - -out: - frame->local = NULL; - 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) ? local->loc.path : "--"); - } - STACK_UNWIND_STRICT (opendir, frame, rsp.op_ret, - gf_error_to_errno (rsp.op_errno), fd); - - client_local_wipe (local); - - return 0; -} - - -int -client3_1_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 *xattr = NULL; - inode_t *inode = NULL; - char *buf = NULL; - xlator_t *this = NULL; - - this = THIS; - - frame = myframe; - local = frame->local; - inode = local->loc.inode; - frame->local = NULL; - - 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); - - if (rsp.dict.dict_len > 0) { - xattr = dict_new(); - GF_VALIDATE_OR_GOTO (frame->this->name, xattr, out); - - buf = memdup (rsp.dict.dict_val, rsp.dict.dict_len); - GF_VALIDATE_OR_GOTO (frame->this->name, buf, out); - - ret = dict_unserialize (buf, rsp.dict.dict_len, &xattr); - if (ret < 0) { - gf_log (frame->this->name, GF_LOG_WARNING, - "%s (%s): failed to unserialize dictionary", - local->loc.path, uuid_utoa (inode->gfid)); - op_errno = EINVAL; - goto out; - } - - xattr->extra_free = buf; - buf = NULL; - } - - 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; - frame->local = NULL; - 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", - strerror (rsp.op_errno), - (local) ? local->loc.path : "--"); - else - gf_log (this->name, GF_LOG_TRACE, "not found on remote node"); - - } - STACK_UNWIND_STRICT (lookup, frame, rsp.op_ret, rsp.op_errno, inode, - &stbuf, xattr, &postparent); - - client_local_wipe (local); - - if (xattr) - dict_unref (xattr); - - if (rsp.dict.dict_val) { - /* don't use GF_FREE, this memory was allocated by libc - */ - free (rsp.dict.dict_val); - rsp.dict.dict_val = NULL; - } - - if (buf) { - GF_FREE (buf); - } - - return 0; -} - -int -client3_1_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; - - this = THIS; - - memset (vector, 0, sizeof (vector)); - - frame = myframe; - local = frame->local; - frame->local = NULL; - - 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; - } -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))); - } - STACK_UNWIND_STRICT (readv, frame, rsp.op_ret, - gf_error_to_errno (rsp.op_errno), vector, rspcount, - &stat, iobref); - - client_local_wipe (local); - - return 0; -} - -int -client3_1_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_1_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) -{ - call_frame_t *fr = NULL; - int32_t ret = -1; - - if (!fdctx) - goto out; - - if (fdctx->remote_fd == -1) { - gf_log (this->name, GF_LOG_DEBUG, "not a valid fd"); - goto out; - } - - fr = create_frame (this, this->ctx->pool); - - if (fdctx->is_dir) { - gfs3_releasedir_req req = {{0,},}; - req.fd = fdctx->remote_fd; - gf_log (this->name, GF_LOG_INFO, "sending releasedir on fd"); - ret = client_submit_request (this, &req, fr, &clnt3_1_fop_prog, - GFS3_OP_RELEASEDIR, - client3_1_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_INFO, "sending release on fd"); - ret = client_submit_request (this, &req, fr, &clnt3_1_fop_prog, - GFS3_OP_RELEASE, - client3_1_release_cbk, NULL, - NULL, 0, NULL, 0, NULL, - (xdrproc_t)xdr_gfs3_release_req); - } - -out: - if (!ret && fdctx) { - fdctx->remote_fd = -1; - inode_unref (fdctx->inode); - GF_FREE (fdctx); - } - - if (ret && fr) - STACK_DESTROY (fr->root); - - return ret; -} - -int32_t -client3_1_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; - gfs3_releasedir_req req = {{0,},}; - int64_t remote_fd = -1; - int ret = 0; - - if (!frame || !this || !data) - goto unwind; - - 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) { - req.fd = remote_fd; - ret = client_submit_request (this, &req, frame, conf->fops, - GFS3_OP_RELEASEDIR, - client3_1_releasedir_cbk, - NULL, NULL, 0, NULL, 0, NULL, - (xdrproc_t)xdr_gfs3_releasedir_req); - inode_unref (fdctx->inode); - GF_FREE (fdctx); - } - -unwind: - if (ret) - STACK_DESTROY (frame->root); - - return 0; -} - -int32_t -client3_1_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; - gfs3_release_req req = {{0,},}; - int ret = 0; - - if (!frame || !this || !data) - goto unwind; - - 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) { - req.fd = remote_fd; - - delete_granted_locks_fd (fdctx); - - ret = client_submit_request (this, &req, frame, conf->fops, - GFS3_OP_RELEASE, - client3_1_release_cbk, NULL, NULL, - 0, NULL, 0, NULL, - (xdrproc_t)xdr_gfs3_release_req); - inode_unref (fdctx->inode); - GF_FREE (fdctx); - } -unwind: - if (ret) - STACK_DESTROY (frame->root); - - return 0; -} - - -int32_t -client3_1_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; - size_t dict_len = 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 = GF_CALLOC (1, sizeof (*local), gf_client_mt_clnt_local_t); - if (!local) { - op_errno = ENOMEM; - goto unwind; - } - - if (!(args->loc && args->loc->inode)) - goto unwind; - - loc_copy (&local->loc, args->loc); - 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->dict) { - content = dict_get (args->dict, GF_CONTENT_KEY); - if (content != NULL) { - rsp_iobref = iobref_new (); - if (rsp_iobref == NULL) { - goto unwind; - } - - /* TODO: what is the size we should send ? */ - 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; - rsp_iobuf = NULL; - local->iobref = rsp_iobref; - rsp_iobref = NULL; - } - - ret = dict_allocate_and_serialize (args->dict, - &req.dict.dict_val, - &dict_len); - if (ret < 0) { - gf_log (this->name, GF_LOG_WARNING, - "failed to get serialized length of dict"); - op_errno = EINVAL; - goto unwind; - } - } - - req.path = (char *)args->loc->path; - if (args->loc->name) - req.bname = (char *)args->loc->name; - else - req.bname = ""; - req.dict.dict_len = dict_len; - - ret = client_submit_request (this, &req, frame, conf->fops, - GFS3_OP_LOOKUP, client3_1_lookup_cbk, - NULL, rsphdr, count, - NULL, 0, local->iobref, - (xdrproc_t)xdr_gfs3_lookup_req); - - if (ret) { - op_errno = ENOTCONN; - goto unwind; - } - - if (req.dict.dict_val) { - GF_FREE (req.dict.dict_val); - } - - if (rsp_iobref != NULL) { - iobref_unref (rsp_iobref); - } - - return 0; - -unwind: - gf_log (this->name, GF_LOG_WARNING, "failed to send the fop: %s", strerror (op_errno)); - - if (frame) - frame->local = NULL; - - STACK_UNWIND_STRICT (lookup, frame, -1, op_errno, NULL, NULL, NULL, - NULL); - - client_local_wipe (local); - - if (req.dict.dict_val) - GF_FREE (req.dict.dict_val); - - if (rsp_iobref != NULL) { - iobref_unref (rsp_iobref); - } - - if (rsp_iobuf != NULL) { - iobuf_unref (rsp_iobuf); - } - - return 0; -} - - - -int32_t -client3_1_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); - req.path = (char *)args->loc->path; - conf = this->private; - - ret = client_submit_request (this, &req, frame, conf->fops, - GFS3_OP_STAT, client3_1_stat_cbk, NULL, - NULL, 0, NULL, 0, NULL, - (xdrproc_t)xdr_gfs3_stat_req); - if (ret) { - op_errno = ENOTCONN; - goto unwind; - } - - return 0; -unwind: - gf_log (this->name, GF_LOG_WARNING, "failed to send the fop %s", - strerror (op_errno)); - STACK_UNWIND_STRICT (stat, frame, -1, op_errno, NULL); - return 0; -} - - -int32_t -client3_1_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.path = (char *)args->loc->path; - req.offset = args->offset; - - conf = this->private; - - ret = client_submit_request (this, &req, frame, conf->fops, - GFS3_OP_TRUNCATE, - client3_1_truncate_cbk, NULL, - NULL, 0, NULL, 0, - NULL, (xdrproc_t)xdr_gfs3_truncate_req); - if (ret) { - op_errno = ENOTCONN; - goto unwind; - } - return 0; -unwind: - gf_log (this->name, GF_LOG_WARNING, "failed to send the fop %s", strerror (op_errno)); - STACK_UNWIND_STRICT (truncate, frame, -1, op_errno, NULL, NULL); - return 0; -} - - -int32_t -client3_1_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(conf, args->fd, remote_fd, unwind); - - req.offset = args->offset; - req.fd = remote_fd; - memcpy (req.gfid, args->fd->inode->gfid, 16); - - ret = client_submit_request (this, &req, frame, conf->fops, - GFS3_OP_FTRUNCATE, - client3_1_ftruncate_cbk, NULL, - NULL, 0, NULL, 0, - NULL, (xdrproc_t)xdr_gfs3_ftruncate_req); - if (ret) { - op_errno = ENOTCONN; - goto unwind; - } - return 0; -unwind: - gf_log (this->name, GF_LOG_WARNING, "failed to send the fop: %s", strerror (op_errno)); - STACK_UNWIND_STRICT (ftruncate, frame, -1, op_errno, NULL, NULL); - return 0; -} - - - -int32_t -client3_1_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.path = (char *)args->loc->path; - req.mask = args->mask; - - conf = this->private; - - ret = client_submit_request (this, &req, frame, conf->fops, - GFS3_OP_ACCESS, - client3_1_access_cbk, NULL, - NULL, 0, NULL, 0, - NULL, (xdrproc_t)xdr_gfs3_access_req); - if (ret) { - op_errno = ENOTCONN; - goto unwind; - } - - return 0; -unwind: - gf_log (this->name, GF_LOG_WARNING, "failed to send the fop: %s", strerror (op_errno)); - STACK_UNWIND_STRICT (access, frame, -1, op_errno); - return 0; -} - -int32_t -client3_1_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; - - 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.path = (char *)args->loc->path; - req.size = args->size; - conf = this->private; - - ret = client_submit_request (this, &req, frame, conf->fops, - GFS3_OP_READLINK, - client3_1_readlink_cbk, NULL, - NULL, 0, NULL, 0, - NULL, (xdrproc_t)xdr_gfs3_readlink_req); - if (ret) { - op_errno = ENOTCONN; - goto unwind; - } - - return 0; -unwind: - gf_log (this->name, GF_LOG_WARNING, "failed to send the fop: %s", strerror (op_errno)); - STACK_UNWIND_STRICT (readlink, frame, -1, op_errno, NULL, NULL); - return 0; -} - - - - -int32_t -client3_1_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.path = (char *)args->loc->path; - req.bname = (char *)args->loc->name; - conf = this->private; - - ret = client_submit_request (this, &req, frame, conf->fops, - GFS3_OP_UNLINK, - client3_1_unlink_cbk, NULL, - NULL, 0, NULL, 0, - NULL, (xdrproc_t)xdr_gfs3_unlink_req); - if (ret) { - op_errno = ENOTCONN; - goto unwind; - } - return 0; -unwind: - gf_log (this->name, GF_LOG_WARNING, "failed to send the fop: %s", strerror (op_errno)); - STACK_UNWIND_STRICT (unlink, frame, -1, op_errno, NULL, NULL); - return 0; -} - - - -int32_t -client3_1_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.path = (char *)args->loc->path; - req.bname = (char *)args->loc->name; - req.flags = args->flags; - conf = this->private; - - ret = client_submit_request (this, &req, frame, conf->fops, - GFS3_OP_RMDIR, client3_1_rmdir_cbk, NULL, - NULL, 0, NULL, 0, - NULL, (xdrproc_t)xdr_gfs3_rmdir_req); - if (ret) { - op_errno = ENOTCONN; - goto unwind; - } - return 0; -unwind: - gf_log (this->name, GF_LOG_WARNING, "failed to send the fop: %s", strerror (op_errno)); - STACK_UNWIND_STRICT (rmdir, frame, -1, op_errno, NULL, NULL); - return 0; -} - - - -int32_t -client3_1_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,},}; - size_t dict_len = 0; - int ret = 0; - int op_errno = ESTALE; - - if (!frame || !this || !data) - goto unwind; - - args = data; - local = GF_CALLOC (1, sizeof (*local), gf_client_mt_clnt_local_t); - if (!local) { - op_errno = ENOMEM; - goto unwind; - } - - if (!(args->loc && args->loc->parent)) - goto unwind; - - loc_copy (&local->loc, args->loc); - 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.path = (char *)args->loc->path; - req.linkname = (char *)args->linkname; - req.bname = (char *)args->loc->name; - if (args->dict) { - ret = dict_allocate_and_serialize (args->dict, - &req.dict.dict_val, - &dict_len); - if (ret < 0) { - gf_log (this->name, GF_LOG_WARNING, - "failed to get serialized length of dict"); - op_errno = EINVAL; - goto unwind; - } - } - req.dict.dict_len = dict_len; - - conf = this->private; - - ret = client_submit_request (this, &req, frame, conf->fops, - GFS3_OP_SYMLINK, client3_1_symlink_cbk, - NULL, NULL, 0, NULL, - 0, NULL, (xdrproc_t)xdr_gfs3_symlink_req); - if (ret) { - op_errno = ENOTCONN; - goto unwind; - } - if (req.dict.dict_val) { - GF_FREE (req.dict.dict_val); - } - return 0; -unwind: - gf_log (this->name, GF_LOG_WARNING, "failed to send the fop: %s", strerror (op_errno)); - if (frame) - frame->local = NULL; - - STACK_UNWIND_STRICT (symlink, frame, -1, op_errno, NULL, NULL, NULL, NULL); - - client_local_wipe (local); - if (req.dict.dict_val) { - GF_FREE (req.dict.dict_val); - } - return 0; -} - - - -int32_t -client3_1_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.oldpath = (char *)args->oldloc->path; - req.oldbname = (char *)args->oldloc->name; - req.newpath = (char *)args->newloc->path; - req.newbname = (char *)args->newloc->name; - conf = this->private; - - ret = client_submit_request (this, &req, frame, conf->fops, - GFS3_OP_RENAME, client3_1_rename_cbk, NULL, - NULL, 0, NULL, 0, - NULL, (xdrproc_t)xdr_gfs3_rename_req); - if (ret) { - op_errno = ENOTCONN; - goto unwind; - } - return 0; -unwind: - gf_log (this->name, GF_LOG_WARNING, "failed to send the fop: %s", strerror (op_errno)); - STACK_UNWIND_STRICT (rename, frame, -1, op_errno, NULL, NULL, NULL, NULL, NULL); - return 0; -} - - - -int32_t -client3_1_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 = GF_CALLOC (1, sizeof (*local), gf_client_mt_clnt_local_t); - if (!local) { - op_errno = ENOMEM; - goto unwind; - } - - loc_copy (&local->loc, args->oldloc); - frame->local = local; - - req.oldpath = (char *)args->oldloc->path; - req.newpath = (char *)args->newloc->path; - req.newbname = (char *)args->newloc->name; - conf = this->private; - - ret = client_submit_request (this, &req, frame, conf->fops, - GFS3_OP_LINK, client3_1_link_cbk, NULL, - NULL, 0, NULL, 0, NULL, - (xdrproc_t)xdr_gfs3_link_req); - if (ret) { - op_errno = ENOTCONN; - goto unwind; - } - return 0; -unwind: - gf_log (this->name, GF_LOG_WARNING, "failed to send the fop: %s", strerror (op_errno)); - STACK_UNWIND_STRICT (link, frame, -1, op_errno, NULL, NULL, NULL, NULL); - return 0; -} - - - -int32_t -client3_1_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,},}; - size_t dict_len = 0; - int ret = 0; - int op_errno = ESTALE; - - if (!frame || !this || !data) - goto unwind; - - args = data; - - local = GF_CALLOC (1, sizeof (*local), gf_client_mt_clnt_local_t); - if (!local) { - op_errno = ENOMEM; - goto unwind; - } - - if (!(args->loc && args->loc->parent)) - goto unwind; - - loc_copy (&local->loc, args->loc); - 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.path = (char *)args->loc->path; - req.bname = (char *)args->loc->name; - req.mode = args->mode; - req.dev = args->rdev; - if (args->dict) { - ret = dict_allocate_and_serialize (args->dict, - &req.dict.dict_val, - &dict_len); - if (ret < 0) { - gf_log (this->name, GF_LOG_WARNING, - "failed to get serialized length of dict"); - op_errno = EINVAL; - goto unwind; - } - } - req.dict.dict_len = dict_len; - - conf = this->private; - - ret = client_submit_request (this, &req, frame, conf->fops, - GFS3_OP_MKNOD, client3_1_mknod_cbk, NULL, - NULL, 0, NULL, 0, - NULL, (xdrproc_t)xdr_gfs3_mknod_req); - if (ret) { - op_errno = ENOTCONN; - goto unwind; - } - if (req.dict.dict_val) { - GF_FREE (req.dict.dict_val); - } - return 0; -unwind: - gf_log (this->name, GF_LOG_WARNING, "failed to send the fop: %s", strerror (op_errno)); - if (frame) - frame->local = NULL; - - STACK_UNWIND_STRICT (mknod, frame, -1, op_errno, NULL, NULL, NULL, NULL); - - client_local_wipe (local); - if (req.dict.dict_val) { - GF_FREE (req.dict.dict_val); - } - return 0; -} - - - -int32_t -client3_1_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,},}; - size_t dict_len = 0; - int ret = 0; - int op_errno = ESTALE; - - if (!frame || !this || !data) - goto unwind; - - args = data; - - local = GF_CALLOC (1, sizeof (*local), gf_client_mt_clnt_local_t); - if (!local) { - op_errno = ENOMEM; - goto unwind; - } - - if (!(args->loc && args->loc->parent)) - goto unwind; - - loc_copy (&local->loc, args->loc); - 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.path = (char *)args->loc->path; - req.bname = (char *)args->loc->name; - req.mode = args->mode; - if (args->dict) { - ret = dict_allocate_and_serialize (args->dict, - &req.dict.dict_val, - &dict_len); - if (ret < 0) { - gf_log (this->name, GF_LOG_WARNING, - "failed to get serialized length of dict"); - op_errno = EINVAL; - goto unwind; - } - } - req.dict.dict_len = dict_len; - - conf = this->private; - - ret = client_submit_request (this, &req, frame, conf->fops, - GFS3_OP_MKDIR, client3_1_mkdir_cbk, NULL, - NULL, 0, NULL, 0, - NULL, (xdrproc_t)xdr_gfs3_mkdir_req); - if (ret) { - op_errno = ENOTCONN; - goto unwind; - } - if (req.dict.dict_val) { - GF_FREE (req.dict.dict_val); - } - return 0; -unwind: - gf_log (this->name, GF_LOG_WARNING, "failed to send the fop: %s", strerror (op_errno)); - if (frame) - frame->local = NULL; - - STACK_UNWIND_STRICT (mkdir, frame, -1, op_errno, NULL, NULL, NULL, NULL); - - client_local_wipe (local); - if (req.dict.dict_val) { - GF_FREE (req.dict.dict_val); - } - return 0; -} - - -int32_t -client3_1_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,},}; - size_t dict_len = 0; - int ret = 0; - int op_errno = ESTALE; - - if (!frame || !this || !data) - goto unwind; - - args = data; - - local = GF_CALLOC (1, sizeof (*local), gf_client_mt_clnt_local_t); - 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); - 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.path = (char *)args->loc->path; - req.bname = (char *)args->loc->name; - req.mode = args->mode; - req.flags = gf_flags_from_flags (args->flags); - if (args->dict) { - ret = dict_allocate_and_serialize (args->dict, - &req.dict.dict_val, - &dict_len); - if (ret < 0) { - gf_log (this->name, GF_LOG_WARNING, - "failed to get serialized length of dict"); - op_errno = EINVAL; - goto unwind; - } - } - req.dict.dict_len = dict_len; - - conf = this->private; - - ret = client_submit_request (this, &req, frame, conf->fops, - GFS3_OP_CREATE, client3_1_create_cbk, NULL, - NULL, 0, NULL, 0, - NULL, (xdrproc_t)xdr_gfs3_create_req); - if (ret) { - op_errno = ENOTCONN; - goto unwind; - } - if (req.dict.dict_val) { - GF_FREE (req.dict.dict_val); - } - return 0; -unwind: - gf_log (this->name, GF_LOG_WARNING, "failed to send the fop: %s", strerror (op_errno)); - if (frame) - frame->local = NULL; - - STACK_UNWIND_STRICT (create, frame, -1, op_errno, NULL, NULL, NULL, - NULL, NULL); - client_local_wipe (local); - if (req.dict.dict_val) { - GF_FREE (req.dict.dict_val); - } - return 0; -} - - - -int32_t -client3_1_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 = GF_CALLOC (1, sizeof (*local), gf_client_mt_clnt_local_t); - 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; - local->wbflags = args->wbflags; - loc_copy (&local->loc, args->loc); - 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); - req.wbflags = args->wbflags; - req.path = (char *)args->loc->path; - - conf = this->private; - - ret = client_submit_request (this, &req, frame, conf->fops, - GFS3_OP_OPEN, client3_1_open_cbk, NULL, - NULL, 0, NULL, 0, NULL, - (xdrproc_t)xdr_gfs3_open_req); - if (ret) { - op_errno = ENOTCONN; - goto unwind; - } - return 0; -unwind: - gf_log (this->name, GF_LOG_WARNING, "failed to send the fop: %s", strerror (op_errno)); - if (frame) - frame->local = NULL; - - STACK_UNWIND_STRICT (open, frame, -1, op_errno, NULL); - - client_local_wipe (local); - return 0; -} - - - -int32_t -client3_1_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; - 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; - clnt_local_t *local = NULL; - - if (!frame || !this || !data) - goto unwind; - - args = data; - conf = this->private; - - CLIENT_GET_REMOTE_FD(conf, args->fd, remote_fd, unwind); - - req.size = args->size; - req.offset = args->offset; - req.fd = remote_fd; - memcpy (req.gfid, args->fd->inode->gfid, 16); - - /* TODO: what is the size we should send ? */ - rsp_iobuf = iobuf_get (this->ctx->iobuf_pool); - 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 = GF_CALLOC (1, sizeof (*local), gf_client_mt_clnt_local_t); - if (local == NULL) { - op_errno = ENOMEM; - goto unwind; - } - - local->iobref = rsp_iobref; - rsp_iobref = NULL; - frame->local = local; - - ret = client_submit_request (this, &req, frame, conf->fops, - GFS3_OP_READ, client3_1_readv_cbk, NULL, - NULL, 0, &rsp_vec, 1, - local->iobref, - (xdrproc_t)xdr_gfs3_read_req); - if (ret) { - op_errno = ENOTCONN; - goto unwind; - } - - return 0; -unwind: - gf_log (this->name, GF_LOG_WARNING, "failed to send the fop: %s", strerror (op_errno)); - if (rsp_iobuf) { - iobuf_unref (rsp_iobuf); - } - - if (rsp_iobref) { - iobref_unref (rsp_iobref); - } - - STACK_UNWIND_STRICT (readv, frame, -1, op_errno, NULL, 0, NULL, NULL); - return 0; -} - - -int32_t -client3_1_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(conf, args->fd, remote_fd, unwind); - - req.size = args->size; - req.offset = args->offset; - req.fd = remote_fd; - memcpy (req.gfid, args->fd->inode->gfid, 16); - - ret = client_submit_vec_request (this, &req, frame, conf->fops, GFS3_OP_WRITE, - client3_1_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: %s", strerror (op_errno)); - } - - return 0; - -unwind: - STACK_UNWIND_STRICT (writev, frame, -1, op_errno, NULL, NULL); - return 0; -} - - -int32_t -client3_1_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(conf, args->fd, remote_fd, unwind); - - conf = this->private; - - local = GF_CALLOC (1, sizeof (*local), gf_client_mt_clnt_local_t); - if (!local) { - STACK_UNWIND (frame, -1, ENOMEM); - return 0; - - } - - 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); - - ret = client_submit_request (this, &req, frame, conf->fops, - GFS3_OP_FLUSH, client3_1_flush_cbk, NULL, - NULL, 0, NULL, 0, - NULL, (xdrproc_t)xdr_gfs3_flush_req); - if (ret) { - op_errno = ENOTCONN; - goto unwind; - } - return 0; -unwind: - gf_log (this->name, GF_LOG_WARNING, "failed to send the fop: %s", strerror (op_errno)); - STACK_UNWIND_STRICT (flush, frame, -1, op_errno); - return 0; -} - - - -int32_t -client3_1_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(conf, args->fd, remote_fd, unwind); - - req.fd = remote_fd; - req.data = args->flags; - memcpy (req.gfid, args->fd->inode->gfid, 16); - - ret = client_submit_request (this, &req, frame, conf->fops, - GFS3_OP_FSYNC, client3_1_fsync_cbk, NULL, - NULL, 0, NULL, 0, - NULL, (xdrproc_t)xdr_gfs3_fsync_req); - if (ret) { - op_errno = ENOTCONN; - goto unwind; - } - return 0; -unwind: - gf_log (this->name, GF_LOG_WARNING, "failed to send the fop: %s", strerror (op_errno)); - STACK_UNWIND_STRICT (fsync, frame, -1, op_errno, NULL, NULL); - return 0; -} - - - -int32_t -client3_1_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(conf, args->fd, remote_fd, unwind); - - req.fd = remote_fd; - memcpy (req.gfid, args->fd->inode->gfid, 16); - - ret = client_submit_request (this, &req, frame, conf->fops, - GFS3_OP_FSTAT, client3_1_fstat_cbk, NULL, - NULL, 0, NULL, 0, - NULL, (xdrproc_t)xdr_gfs3_fstat_req); - if (ret) { - op_errno = ENOTCONN; - goto unwind; - } - return 0; -unwind: - gf_log (this->name, GF_LOG_WARNING, "failed to send the fop: %s", strerror (op_errno)); - STACK_UNWIND_STRICT (fstat, frame, -1, op_errno, NULL); - return 0; -} - - - -int32_t -client3_1_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 = GF_CALLOC (1, sizeof (*local), gf_client_mt_clnt_local_t); - 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); - 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.path = (char *)args->loc->path; - - conf = this->private; - - ret = client_submit_request (this, &req, frame, conf->fops, - GFS3_OP_OPENDIR, client3_1_opendir_cbk, - NULL, NULL, 0, NULL, 0, NULL, - (xdrproc_t)xdr_gfs3_opendir_req); - if (ret) { - op_errno = ENOTCONN; - goto unwind; - } - return 0; -unwind: - gf_log (this->name, GF_LOG_WARNING, "failed to send the fop: %s", strerror (op_errno)); - if (frame) - frame->local = NULL; - STACK_UNWIND_STRICT (opendir, frame, -1, op_errno, NULL); - client_local_wipe (local); - return 0; -} - - - -int32_t -client3_1_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; - int op_errno = ESTALE; - gfs3_fsyncdir_req req = {{0,},}; - int ret = 0; - - if (!frame || !this || !data) - goto unwind; - - args = data; - conf = this->private; - - CLIENT_GET_REMOTE_FD(conf, args->fd, remote_fd, unwind); - - req.fd = remote_fd; - req.data = args->flags; - memcpy (req.gfid, args->fd->inode->gfid, 16); - - conf = this->private; - - ret = client_submit_request (this, &req, frame, conf->fops, - GFS3_OP_FSYNCDIR, client3_1_fsyncdir_cbk, - NULL, NULL, 0, - NULL, 0, NULL, - (xdrproc_t)xdr_gfs3_fsyncdir_req); - if (ret) { - op_errno = ENOTCONN; - goto unwind; - } - return 0; -unwind: - gf_log (this->name, GF_LOG_WARNING, "failed to send the fop: %s", strerror (op_errno)); - STACK_UNWIND_STRICT (fsyncdir, frame, -1, op_errno); - return 0; -} - - - -int32_t -client3_1_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); - req.path = (char *)args->loc->path; - - conf = this->private; - - ret = client_submit_request (this, &req, frame, conf->fops, - GFS3_OP_STATFS, client3_1_statfs_cbk, NULL, - NULL, 0, NULL, 0, - NULL, (xdrproc_t)xdr_gfs3_statfs_req); - if (ret) { - op_errno = ENOTCONN; - goto unwind; - } - return 0; -unwind: - gf_log (this->name, GF_LOG_WARNING, "failed to send the fop: %s", strerror (op_errno)); - STACK_UNWIND_STRICT (statfs, frame, -1, op_errno, NULL); - return 0; -} - - - -int32_t -client3_1_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; - size_t dict_len = 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->dict) { - ret = dict_allocate_and_serialize (args->dict, - &req.dict.dict_val, - &dict_len); - if (ret < 0) { - gf_log (this->name, GF_LOG_WARNING, - "failed to get serialized dict"); - op_errno = EINVAL; - goto unwind; - } - req.dict.dict_len = dict_len; - } - req.flags = args->flags; - req.path = (char *)args->loc->path; - - conf = this->private; - - ret = client_submit_request (this, &req, frame, conf->fops, - GFS3_OP_SETXATTR, client3_1_setxattr_cbk, - NULL, NULL, 0, NULL, 0, NULL, - (xdrproc_t)xdr_gfs3_setxattr_req); - if (ret) { - op_errno = ENOTCONN; - goto unwind; - } - if (req.dict.dict_val) { - GF_FREE (req.dict.dict_val); - } - - return 0; -unwind: - gf_log (this->name, GF_LOG_WARNING, "failed to send the fop: %s", strerror (op_errno)); - STACK_UNWIND_STRICT (setxattr, frame, -1, op_errno); - if (req.dict.dict_val) { - GF_FREE (req.dict.dict_val); - } - return 0; -} - - - -int32_t -client3_1_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; - size_t dict_len = 0; - - if (!frame || !this || !data) - goto unwind; - - args = data; - conf = this->private; - - CLIENT_GET_REMOTE_FD(conf, args->fd, remote_fd, unwind); - - req.fd = remote_fd; - req.flags = args->flags; - memcpy (req.gfid, args->fd->inode->gfid, 16); - - if (args->dict) { - ret = dict_allocate_and_serialize (args->dict, - &req.dict.dict_val, - &dict_len); - if (ret < 0) { - gf_log (this->name, GF_LOG_WARNING, - "failed to get serialized dict"); - goto unwind; - } - req.dict.dict_len = dict_len; - } - - ret = client_submit_request (this, &req, frame, conf->fops, - GFS3_OP_FSETXATTR, client3_1_fsetxattr_cbk, - NULL, NULL, 0, NULL, 0, NULL, - (xdrproc_t)xdr_gfs3_fsetxattr_req); - if (ret) { - op_errno = ENOTCONN; - goto unwind; - } - - if (req.dict.dict_val) { - GF_FREE (req.dict.dict_val); - } - - return 0; -unwind: - gf_log (this->name, GF_LOG_WARNING, "failed to send the fop: %s", strerror (op_errno)); - STACK_UNWIND_STRICT (fsetxattr, frame, -1, op_errno); - if (req.dict.dict_val) { - GF_FREE (req.dict.dict_val); - } - return 0; -} - - - - -int32_t -client3_1_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(conf, args->fd, remote_fd, unwind); - - local = GF_CALLOC (1, sizeof (*local), - gf_client_mt_clnt_local_t); - 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_get (this->ctx->iobuf_pool); - 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; - rsp_iobuf = NULL; - local->iobref = rsp_iobref; - 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); - - ret = client_submit_request (this, &req, frame, conf->fops, - GFS3_OP_FGETXATTR, - client3_1_fgetxattr_cbk, NULL, - rsphdr, count, - NULL, 0, local->iobref, - (xdrproc_t)xdr_gfs3_fgetxattr_req); - if (ret) { - op_errno = ENOTCONN; - goto unwind; - } - - return 0; -unwind: - gf_log (this->name, GF_LOG_WARNING, "failed to send the fop: %s", strerror (op_errno)); - local = frame->local; - frame->local = NULL; - - STACK_UNWIND_STRICT (fgetxattr, frame, -1, op_errno, NULL); - - client_local_wipe (local); - - if (rsp_iobuf) { - iobuf_unref (rsp_iobuf); - } - - if (rsp_iobref) { - iobref_unref (rsp_iobref); - } - - return 0; -} - - - -int32_t -client3_1_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 = 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) { - op_ret = -1; - op_errno = 0; - goto unwind; - } - args = data; - - if (!(args->loc && args->loc->inode)) { - op_ret = -1; - op_errno = EINVAL; - goto unwind; - } - - local = GF_CALLOC (1, sizeof (*local), - gf_client_mt_clnt_local_t); - if (!local) { - op_ret = -1; - op_errno = ENOMEM; - goto unwind; - } - frame->local = local; - - rsp_iobref = iobref_new (); - if (rsp_iobref == NULL) { - op_ret = -1; - op_errno = ENOMEM; - goto unwind; - } - - /* TODO: what is the size we should send ? */ - rsp_iobuf = iobuf_get (this->ctx->iobuf_pool); - if (rsp_iobuf == NULL) { - op_ret = -1; - 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; - rsp_iobuf = NULL; - local->iobref = rsp_iobref; - 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); - - 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.path = (char *)args->loc->path; - 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_ret = -1; - op_errno = EINVAL; - } - - GF_ASSERT (dict); - op_ret = 0; - op_errno = 0; - goto unwind; - } - } - - ret = client_submit_request (this, &req, frame, conf->fops, - GFS3_OP_GETXATTR, - client3_1_getxattr_cbk, NULL, - rsphdr, count, - NULL, 0, local->iobref, - (xdrproc_t)xdr_gfs3_getxattr_req); - if (ret) { - op_ret = -1; - op_errno = ENOTCONN; - goto unwind; - } - - return 0; -unwind: - gf_log (this->name, GF_LOG_WARNING, "failed to send the fop: %s", strerror (op_errno)); - local = frame->local; - frame->local = NULL; - client_local_wipe (local); - - if (rsp_iobuf) { - iobuf_unref (rsp_iobuf); - } - - if (rsp_iobref) { - iobref_unref (rsp_iobref); - } - - STACK_UNWIND_STRICT (getxattr, frame, op_ret, op_errno, dict); - - return 0; -} - - - -int32_t -client3_1_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; - size_t dict_len = 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 = GF_CALLOC (1, sizeof (*local), - gf_client_mt_clnt_local_t); - 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_get (this->ctx->iobuf_pool); - 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; - rsp_iobuf = NULL; - local->iobref = rsp_iobref; - 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); - - GF_ASSERT_AND_GOTO_WITH_ERROR (this->name, - !uuid_is_null (*((uuid_t*)req.gfid)), - unwind, op_errno, EINVAL); - if (args->dict) { - ret = dict_allocate_and_serialize (args->dict, - &req.dict.dict_val, - &dict_len); - if (ret < 0) { - gf_log (this->name, GF_LOG_WARNING, - "failed to get serialized dict"); - op_errno = EINVAL; - goto unwind; - } - req.dict.dict_len = dict_len; - } - req.flags = args->flags; - req.path = (char *)args->loc->path; - - conf = this->private; - - ret = client_submit_request (this, &req, frame, conf->fops, - GFS3_OP_XATTROP, - client3_1_xattrop_cbk, NULL, - rsphdr, count, - NULL, 0, local->iobref, - (xdrproc_t)xdr_gfs3_xattrop_req); - if (ret) { - op_errno = ENOTCONN; - goto unwind; - } - - if (req.dict.dict_val) { - GF_FREE (req.dict.dict_val); - } - return 0; -unwind: - gf_log (this->name, GF_LOG_WARNING, "failed to send the fop: %s", strerror (op_errno)); - local = frame->local; - frame->local = NULL; - - STACK_UNWIND_STRICT (xattrop, frame, -1, op_errno, NULL); - - if (req.dict.dict_val) { - GF_FREE (req.dict.dict_val); - } - - client_local_wipe (local); - - if (rsp_iobuf) { - iobuf_unref (rsp_iobuf); - } - - if (rsp_iobref) { - iobref_unref (rsp_iobref); - } - - return 0; -} - - - -int32_t -client3_1_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; - gfs3_fxattrop_req req = {{0,},}; - int op_errno = ESTALE; - int ret = 0; - size_t dict_len = 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(conf, args->fd, remote_fd, unwind); - - req.fd = remote_fd; - req.flags = args->flags; - memcpy (req.gfid, args->fd->inode->gfid, 16); - - local = GF_CALLOC (1, sizeof (*local), - gf_client_mt_clnt_local_t); - 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_get (this->ctx->iobuf_pool); - 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; - rsp_iobuf = NULL; - local->iobref = rsp_iobref; - rsp_iobref = NULL; - - if (args->dict) { - ret = dict_allocate_and_serialize (args->dict, - &req.dict.dict_val, - &dict_len); - if (ret < 0) { - gf_log (this->name, GF_LOG_WARNING, - "failed to get serialized dict"); - goto unwind; - } - req.dict.dict_len = dict_len; - } - - ret = client_submit_request (this, &req, frame, conf->fops, - GFS3_OP_FXATTROP, - client3_1_fxattrop_cbk, NULL, - rsphdr, count, - NULL, 0, local->iobref, - (xdrproc_t)xdr_gfs3_fxattrop_req); - if (ret) { - op_errno = ENOTCONN; - goto unwind; - } - - if (req.dict.dict_val) { - GF_FREE (req.dict.dict_val); - } - - return 0; -unwind: - gf_log (this->name, GF_LOG_WARNING, "failed to send the fop: %s", strerror (op_errno)); - local = frame->local; - frame->local = NULL; - - STACK_UNWIND_STRICT (fxattrop, frame, -1, op_errno, NULL); - - if (req.dict.dict_val) { - GF_FREE (req.dict.dict_val); - } - - client_local_wipe (local); - - if (rsp_iobref) { - iobref_unref (rsp_iobref); - } - - if (rsp_iobuf) { - iobuf_unref (rsp_iobuf); - } - - return 0; -} - - - -int32_t -client3_1_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.path = (char *)args->loc->path; - req.name = (char *)args->name; - - conf = this->private; - - ret = client_submit_request (this, &req, frame, conf->fops, - GFS3_OP_REMOVEXATTR, - client3_1_removexattr_cbk, NULL, - NULL, 0, NULL, 0, NULL, - (xdrproc_t)xdr_gfs3_removexattr_req); - if (ret) { - op_errno = ENOTCONN; - goto unwind; - } - - return 0; -unwind: - gf_log (this->name, GF_LOG_WARNING, "failed to send the fop: %s", strerror (op_errno)); - STACK_UNWIND_STRICT (removexattr, frame, -1, op_errno); - return 0; -} - - -int32_t -client3_1_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 = GF_CALLOC (1, sizeof (*local), gf_client_mt_clnt_local_t); - if (!local) { - op_errno = ENOMEM; - goto unwind; - } - - CLIENT_GET_REMOTE_FD(conf, args->fd, remote_fd, 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); - - ret = client_submit_request (this, &req, frame, conf->fops, GFS3_OP_LK, - client3_1_lk_cbk, NULL, - NULL, 0, NULL, 0, NULL, - (xdrproc_t)xdr_gfs3_lk_req); - if (ret) { - op_errno = ENOTCONN; - goto unwind; - } - - return 0; -unwind: - gf_log (this->name, GF_LOG_WARNING, "failed to send the fop: %s", strerror (op_errno)); - STACK_UNWIND_STRICT (lk, frame, -1, op_errno, NULL); - return 0; -} - - -int32_t -client3_1_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.path = (char *)args->loc->path; - 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; - - ret = client_submit_request (this, &req, frame, conf->fops, - GFS3_OP_INODELK, - client3_1_inodelk_cbk, NULL, - NULL, 0, NULL, 0, - NULL, (xdrproc_t)xdr_gfs3_inodelk_req); - if (ret) { - op_errno = ENOTCONN; - goto unwind; - } - - return 0; -unwind: - gf_log (this->name, GF_LOG_WARNING, "failed to send the fop: %s", strerror (op_errno)); - STACK_UNWIND_STRICT (inodelk, frame, -1, op_errno); - return 0; -} - - - -int32_t -client3_1_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(conf, args->fd, remote_fd, 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); - - ret = client_submit_request (this, &req, frame, conf->fops, - GFS3_OP_FINODELK, - client3_1_finodelk_cbk, NULL, - NULL, 0, NULL, 0, - NULL, (xdrproc_t)xdr_gfs3_finodelk_req); - if (ret) { - op_errno = ENOTCONN; - goto unwind; - } - - return 0; -unwind: - gf_log (this->name, GF_LOG_WARNING, "failed to send the fop: %s", strerror (op_errno)); - STACK_UNWIND_STRICT (finodelk, frame, -1, op_errno); - return 0; -} - - -int32_t -client3_1_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.path = (char *)args->loc->path; - 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; - - ret = client_submit_request (this, &req, frame, conf->fops, - GFS3_OP_ENTRYLK, - client3_1_entrylk_cbk, NULL, - NULL, 0, NULL, 0, - NULL, (xdrproc_t)xdr_gfs3_entrylk_req); - if (ret) { - op_errno = ENOTCONN; - goto unwind; - } - - return 0; -unwind: - gf_log (this->name, GF_LOG_WARNING, "failed to send the fop: %s", strerror (op_errno)); - STACK_UNWIND_STRICT (entrylk, frame, -1, op_errno); - return 0; -} - - - -int32_t -client3_1_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(conf, args->fd, remote_fd, 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); - - ret = client_submit_request (this, &req, frame, conf->fops, - GFS3_OP_FENTRYLK, - client3_1_fentrylk_cbk, NULL, - NULL, 0, NULL, 0, - NULL, (xdrproc_t)xdr_gfs3_fentrylk_req); - if (ret) { - op_errno = ENOTCONN; - goto unwind; - } - - return 0; -unwind: - gf_log (this->name, GF_LOG_WARNING, "failed to send the fop: %s", strerror (op_errno)); - STACK_UNWIND_STRICT (fentrylk, frame, -1, op_errno); - return 0; -} - - -int32_t -client3_1_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(conf, args->fd, remote_fd, unwind); - - req.len = args->len; - req.offset = args->offset; - req.fd = remote_fd; - - ret = client_submit_request (this, &req, frame, conf->fops, - GFS3_OP_RCHECKSUM, - client3_1_rchecksum_cbk, NULL, - NULL, 0, NULL, - 0, NULL, (xdrproc_t)xdr_gfs3_rchecksum_req); - if (ret) { - op_errno = ENOTCONN; - goto unwind; - } - - return 0; -unwind: - gf_log (this->name, GF_LOG_WARNING, "failed to send the fop: %s", strerror (op_errno)); - STACK_UNWIND_STRICT (rchecksum, frame, -1, op_errno, 0, NULL); - return 0; -} - - - -int32_t -client3_1_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(conf, args->fd, remote_fd, 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 = GF_CALLOC (1, sizeof (*local), - gf_client_mt_clnt_local_t); - 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 ? */ - 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; - rsp_iobuf = NULL; - local->iobref = rsp_iobref; - } - - req.size = args->size; - req.offset = args->offset; - req.fd = remote_fd; - memcpy (req.gfid, args->fd->inode->gfid, 16); - - ret = client_submit_request (this, &req, frame, conf->fops, - GFS3_OP_READDIR, - client3_1_readdir_cbk, NULL, - rsphdr, count, - NULL, 0, rsp_iobref, - (xdrproc_t)xdr_gfs3_readdir_req); - rsp_iobref = NULL; - - if (ret) { - op_errno = ENOTCONN; - goto unwind; - } - - return 0; - -unwind: - gf_log (this->name, GF_LOG_WARNING, "failed to send the fop: %s", strerror (op_errno)); - local = frame->local; - frame->local = NULL; - client_local_wipe (local); - - if (rsp_iobref != NULL) { - iobref_unref (rsp_iobref); - } - - if (rsp_iobuf != NULL) { - iobuf_unref (rsp_iobuf); - } - - STACK_UNWIND_STRICT (readdir, frame, -1, op_errno, NULL); - return 0; -} - - -int32_t -client3_1_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(conf, args->fd, remote_fd, unwind); - - readdirp_rsp_size = xdr_sizeof ((xdrproc_t) xdr_gfs3_readdirp_rsp, &rsp) - + args->size; - - if ((readdirp_rsp_size + GLUSTERFS_RPC_REPLY_SIZE - + GLUSTERFS_RDMA_MAX_HEADER_SIZE) - > (GLUSTERFS_RDMA_INLINE_THRESHOLD)) { - local = GF_CALLOC (1, sizeof (*local), - gf_client_mt_clnt_local_t); - 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 ? */ - 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; - rsp_iobuf = NULL; - local->iobref = rsp_iobref; - rsp_iobref = NULL; - } - - req.size = args->size; - req.offset = args->offset; - req.fd = remote_fd; - memcpy (req.gfid, args->fd->inode->gfid, 16); - - ret = client_submit_request (this, &req, frame, conf->fops, - GFS3_OP_READDIRP, - client3_1_readdirp_cbk, NULL, - rsphdr, count, NULL, - 0, rsp_iobref, - (xdrproc_t)xdr_gfs3_readdirp_req); - if (ret) { - op_errno = ENOTCONN; - goto unwind; - } - - return 0; -unwind: - gf_log (this->name, GF_LOG_WARNING, "failed to send the fop: %s", strerror (op_errno)); - local = frame->local; - frame->local = NULL; - client_local_wipe (local); - - if (rsp_iobref) { - iobref_unref (rsp_iobref); - } - - if (rsp_iobuf) { - iobuf_unref (rsp_iobuf); - } - - STACK_UNWIND_STRICT (readdirp, frame, -1, op_errno, NULL); - return 0; -} - - -int32_t -client3_1_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.path = (char *)args->loc->path; - req.valid = args->valid; - gf_stat_from_iatt (&req.stbuf, args->stbuf); - - conf = this->private; - - ret = client_submit_request (this, &req, frame, conf->fops, - GFS3_OP_SETATTR, - client3_1_setattr_cbk, NULL, - NULL, 0, NULL, 0, - NULL, (xdrproc_t)xdr_gfs3_setattr_req); - if (ret) { - op_errno = ENOTCONN; - goto unwind; - } - - return 0; -unwind: - gf_log (this->name, GF_LOG_WARNING, "failed to send the fop: %s", strerror (op_errno)); - STACK_UNWIND_STRICT (setattr, frame, -1, op_errno, NULL, NULL); - return 0; -} - -int32_t -client3_1_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(conf, args->fd, remote_fd, unwind); - - req.fd = remote_fd; - req.valid = args->valid; - gf_stat_from_iatt (&req.stbuf, args->stbuf); - - ret = client_submit_request (this, &req, frame, conf->fops, - GFS3_OP_FSETATTR, - client3_1_fsetattr_cbk, NULL, - NULL, 0, NULL, 0, - NULL, (xdrproc_t)xdr_gfs3_fsetattr_req); - if (ret) { - op_errno = ENOTCONN; - goto unwind; - } - - return 0; -unwind: - gf_log (this->name, GF_LOG_WARNING, "failed to send the fop: %s", strerror (op_errno)); - STACK_UNWIND_STRICT (fsetattr, frame, -1, op_errno, NULL, NULL); - return 0; -} - - - -/* Table Specific to FOPS */ - - -rpc_clnt_procedure_t clnt3_1_fop_actors[GF_FOP_MAXVALUE] = { - [GF_FOP_NULL] = { "NULL", NULL}, - [GF_FOP_STAT] = { "STAT", client3_1_stat }, - [GF_FOP_READLINK] = { "READLINK", client3_1_readlink }, - [GF_FOP_MKNOD] = { "MKNOD", client3_1_mknod }, - [GF_FOP_MKDIR] = { "MKDIR", client3_1_mkdir }, - [GF_FOP_UNLINK] = { "UNLINK", client3_1_unlink }, - [GF_FOP_RMDIR] = { "RMDIR", client3_1_rmdir }, - [GF_FOP_SYMLINK] = { "SYMLINK", client3_1_symlink }, - [GF_FOP_RENAME] = { "RENAME", client3_1_rename }, - [GF_FOP_LINK] = { "LINK", client3_1_link }, - [GF_FOP_TRUNCATE] = { "TRUNCATE", client3_1_truncate }, - [GF_FOP_OPEN] = { "OPEN", client3_1_open }, - [GF_FOP_READ] = { "READ", client3_1_readv }, - [GF_FOP_WRITE] = { "WRITE", client3_1_writev }, - [GF_FOP_STATFS] = { "STATFS", client3_1_statfs }, - [GF_FOP_FLUSH] = { "FLUSH", client3_1_flush }, - [GF_FOP_FSYNC] = { "FSYNC", client3_1_fsync }, - [GF_FOP_SETXATTR] = { "SETXATTR", client3_1_setxattr }, - [GF_FOP_GETXATTR] = { "GETXATTR", client3_1_getxattr }, - [GF_FOP_REMOVEXATTR] = { "REMOVEXATTR", client3_1_removexattr }, - [GF_FOP_OPENDIR] = { "OPENDIR", client3_1_opendir }, - [GF_FOP_FSYNCDIR] = { "FSYNCDIR", client3_1_fsyncdir }, - [GF_FOP_ACCESS] = { "ACCESS", client3_1_access }, - [GF_FOP_CREATE] = { "CREATE", client3_1_create }, - [GF_FOP_FTRUNCATE] = { "FTRUNCATE", client3_1_ftruncate }, - [GF_FOP_FSTAT] = { "FSTAT", client3_1_fstat }, - [GF_FOP_LK] = { "LK", client3_1_lk }, - [GF_FOP_LOOKUP] = { "LOOKUP", client3_1_lookup }, - [GF_FOP_READDIR] = { "READDIR", client3_1_readdir }, - [GF_FOP_INODELK] = { "INODELK", client3_1_inodelk }, - [GF_FOP_FINODELK] = { "FINODELK", client3_1_finodelk }, - [GF_FOP_ENTRYLK] = { "ENTRYLK", client3_1_entrylk }, - [GF_FOP_FENTRYLK] = { "FENTRYLK", client3_1_fentrylk }, - [GF_FOP_XATTROP] = { "XATTROP", client3_1_xattrop }, - [GF_FOP_FXATTROP] = { "FXATTROP", client3_1_fxattrop }, - [GF_FOP_FGETXATTR] = { "FGETXATTR", client3_1_fgetxattr }, - [GF_FOP_FSETXATTR] = { "FSETXATTR", client3_1_fsetxattr }, - [GF_FOP_RCHECKSUM] = { "RCHECKSUM", client3_1_rchecksum }, - [GF_FOP_SETATTR] = { "SETATTR", client3_1_setattr }, - [GF_FOP_FSETATTR] = { "FSETATTR", client3_1_fsetattr }, - [GF_FOP_READDIRP] = { "READDIRP", client3_1_readdirp }, - [GF_FOP_RELEASE] = { "RELEASE", client3_1_release }, - [GF_FOP_RELEASEDIR] = { "RELEASEDIR", client3_1_releasedir }, - [GF_FOP_GETSPEC] = { "GETSPEC", client3_getspec }, -}; - -/* Used From RPC-CLNT library to log proper name of procedure based on number */ -char *clnt3_1_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", -}; - -rpc_clnt_prog_t clnt3_1_fop_prog = { - .progname = "GlusterFS 3.1", - .prognum = GLUSTER3_1_FOP_PROGRAM, - .progver = GLUSTER3_1_FOP_VERSION, - .numproc = GLUSTER3_1_FOP_PROCCNT, - .proctable = clnt3_1_fop_actors, - .procnames = clnt3_1_fop_names, -}; |
