diff options
Diffstat (limited to 'xlators/protocol')
62 files changed, 4554 insertions, 27918 deletions
diff --git a/xlators/protocol/auth/addr/src/Makefile.am b/xlators/protocol/auth/addr/src/Makefile.am index f09d1c502..426e7c2fb 100644 --- a/xlators/protocol/auth/addr/src/Makefile.am +++ b/xlators/protocol/auth/addr/src/Makefile.am @@ -1,12 +1,14 @@ auth_LTLIBRARIES = addr.la authdir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/auth -addr_la_LDFLAGS = -module -avoidversion +addr_la_LDFLAGS = -module -avoid-version addr_la_SOURCES = addr.c addr_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la -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) \ +AM_CPPFLAGS = $(GF_CPPFLAGS) \ + -I$(top_srcdir)/libglusterfs/src \ -I$(top_srcdir)/xlators/protocol/server/src \ -I$(top_srcdir)/rpc/rpc-lib/src/ + +AM_CFLAGS = -Wall $(GF_CFLAGS) diff --git a/xlators/protocol/auth/addr/src/addr.c b/xlators/protocol/auth/addr/src/addr.c index 3551ec760..64e8d0fc6 100644 --- a/xlators/protocol/auth/addr/src/addr.c +++ b/xlators/protocol/auth/addr/src/addr.c @@ -2,19 +2,10 @@ 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. */ @@ -218,8 +209,7 @@ gf_auth (dict_t *input_params, dict_t *config_params) } out: - if (addr_cpy) - GF_FREE (addr_cpy); + GF_FREE (addr_cpy); return result; } diff --git a/xlators/protocol/auth/login/src/Makefile.am b/xlators/protocol/auth/login/src/Makefile.am index b4719d1a7..d84db91c4 100644 --- a/xlators/protocol/auth/login/src/Makefile.am +++ b/xlators/protocol/auth/login/src/Makefile.am @@ -1,11 +1,12 @@ auth_LTLIBRARIES = login.la authdir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/auth -login_la_LDFLAGS = -module -avoidversion +login_la_LDFLAGS = -module -avoid-version login_la_SOURCES = login.c login_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la -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) \ +AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \ -I$(top_srcdir)/xlators/protocol/server/src + +AM_CFLAGS = -Wall $(GF_CFLAGS) diff --git a/xlators/protocol/auth/login/src/login.c b/xlators/protocol/auth/login/src/login.c index 838cb4262..c2f0bf0d0 100644 --- a/xlators/protocol/auth/login/src/login.c +++ b/xlators/protocol/auth/login/src/login.c @@ -2,19 +2,10 @@ 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 @@ -121,8 +112,7 @@ auth_result_t gf_auth (dict_t *input_params, dict_t *config_params) } out: - if (username_cpy) - GF_FREE (username_cpy); + GF_FREE (username_cpy); return result; } diff --git a/xlators/protocol/client/src/Makefile.am b/xlators/protocol/client/src/Makefile.am index 29c6e9dde..cf89d42da 100644 --- a/xlators/protocol/client/src/Makefile.am +++ b/xlators/protocol/client/src/Makefile.am @@ -2,16 +2,19 @@ xlator_LTLIBRARIES = client.la xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/protocol -client_la_LDFLAGS = -module -avoidversion +client_la_LDFLAGS = -module -avoid-version client_la_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_la_SOURCES = client.c client-helpers.c client-rpc-fops.c \ client-handshake.c client-callback.c client-lk.c + noinst_HEADERS = client.h client-mem-types.h -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 +AM_CPPFLAGS = $(GF_CPPFLAGS) \ + -I$(top_srcdir)/libglusterfs/src \ + -I$(top_srcdir)/rpc/xdr/src -I$(top_srcdir)/rpc/rpc-lib/src/ + +AM_CFLAGS = -Wall $(GF_CFLAGS) diff --git a/xlators/protocol/client/src/client-callback.c b/xlators/protocol/client/src/client-callback.c index b8bda96ce..d886862f7 100644 --- a/xlators/protocol/client/src/client-callback.c +++ b/xlators/protocol/client/src/client-callback.c @@ -17,7 +17,7 @@ #include "rpc-clnt.h" int -client_cbk_null (void *data) +client_cbk_null (struct rpc_clnt *rpc, void *mydata, void *data) { gf_log (THIS->name, GF_LOG_WARNING, "this function should not be called"); @@ -25,7 +25,7 @@ client_cbk_null (void *data) } int -client_cbk_fetchspec (void *data) +client_cbk_fetchspec (struct rpc_clnt *rpc, void *mydata, void *data) { gf_log (THIS->name, GF_LOG_WARNING, "this function should not be called"); @@ -33,7 +33,7 @@ client_cbk_fetchspec (void *data) } int -client_cbk_ino_flush (void *data) +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"); diff --git a/xlators/protocol/client/src/client-handshake.c b/xlators/protocol/client/src/client-handshake.c index 64e0c356d..5668fea53 100644 --- a/xlators/protocol/client/src/client-handshake.c +++ b/xlators/protocol/client/src/client-handshake.c @@ -25,7 +25,8 @@ #include "portmap-xdr.h" #include "rpc-common-xdr.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 clnt_pmap_prog; int client_ping_cbk (struct rpc_req *req, struct iovec *iov, int count, @@ -52,7 +53,7 @@ rpc_client_ping_timer_expired (void *data) rpc_clnt_connection_t *conn = NULL; int disconnect = 0; int transport_activity = 0; - struct timeval timeout = {0, }; + struct timespec timeout = {0, }; struct timeval current = {0, }; struct rpc_clnt *clnt = NULL; xlator_t *this = NULL; @@ -100,7 +101,7 @@ rpc_client_ping_timer_expired (void *data) "ping timer expired but transport activity " "detected - not bailing transport"); timeout.tv_sec = conf->opt.ping_timeout; - timeout.tv_usec = 0; + timeout.tv_nsec = 0; conn->ping_timer = gf_timer_call_after (this->ctx, timeout, @@ -139,7 +140,7 @@ client_start_ping (void *data) clnt_conf_t *conf = NULL; rpc_clnt_connection_t *conn = NULL; int32_t ret = -1; - struct timeval timeout = {0, }; + struct timespec timeout = {0, }; call_frame_t *frame = NULL; int frame_count = 0; @@ -195,7 +196,7 @@ client_start_ping (void *data) } timeout.tv_sec = conf->opt.ping_timeout; - timeout.tv_usec = 0; + timeout.tv_nsec = 0; conn->ping_timer = gf_timer_call_after (this->ctx, timeout, @@ -240,7 +241,7 @@ client_ping_cbk (struct rpc_req *req, struct iovec *iov, int count, { xlator_t *this = NULL; rpc_clnt_connection_t *conn = NULL; - struct timeval timeout = {0, }; + struct timespec timeout = {0, }; call_frame_t *frame = NULL; clnt_conf_t *conf = NULL; @@ -280,7 +281,7 @@ client_ping_cbk (struct rpc_req *req, struct iovec *iov, int count, timeout.tv_sec = conf->opt.ping_timeout; - timeout.tv_usec = 0; + timeout.tv_nsec = 0; gf_timer_call_cancel (this->ctx, conn->ping_timer); @@ -347,8 +348,7 @@ out: rsp.spec); /* Don't use 'GF_FREE', this is allocated by libc */ - if (rsp.spec) - free (rsp.spec); + free (rsp.spec); return 0; } @@ -416,9 +416,6 @@ clnt_fd_lk_reacquire_failed (xlator_t *this, clnt_fd_ctx_t *fdctx, { fdctx->remote_fd = -1; fdctx->lk_heal_state = GF_LK_HEAL_DONE; - - list_add_tail (&fdctx->sfd_pos, - &conf->saved_fds); } pthread_mutex_unlock (&conf->lock); @@ -604,7 +601,7 @@ clnt_release_reopen_fd_cbk (struct rpc_req *req, struct iovec *iov, clnt_fd_lk_reacquire_failed (this, fdctx, conf); - decrement_reopen_fd_count (this, conf); + fdctx->reopen_done (fdctx, this); frame->local = NULL; STACK_DESTROY (frame->root); @@ -634,10 +631,11 @@ clnt_release_reopen_fd (xlator_t *this, clnt_fd_ctx_t *fdctx) clnt_release_reopen_fd_cbk, NULL, NULL, 0, NULL, 0, NULL, (xdrproc_t)xdr_gfs3_releasedir_req); + return 0; out: if (ret) { - decrement_reopen_fd_count (this, conf); clnt_fd_lk_reacquire_failed (this, fdctx, conf); + fdctx->reopen_done (fdctx, this); if (frame) { frame->local = NULL; STACK_DESTROY (frame->root); @@ -747,21 +745,18 @@ client_reacquire_lock_cbk (struct rpc_req *req, struct iovec *iov, gf_log (this->name, GF_LOG_DEBUG, "%s type lock reacquired on file " "with gfid %s from %"PRIu64 " to %"PRIu64, - get_lk_type (lock.l_type), uuid_utoa (fdctx->inode->gfid), + get_lk_type (lock.l_type), uuid_utoa (fdctx->gfid), lock.l_start, lock.l_start + lock.l_len); - if (clnt_fd_lk_local_unref (this, local) == 0 && - !clnt_fd_lk_local_error_status (this, local)) { + if (!clnt_fd_lk_local_error_status (this, local) && + clnt_fd_lk_local_unref (this, local) == 0) { pthread_mutex_lock (&conf->lock); { fdctx->lk_heal_state = GF_LK_HEAL_DONE; - - list_add_tail (&fdctx->sfd_pos, - &conf->saved_fds); } pthread_mutex_unlock (&conf->lock); - decrement_reopen_fd_count (this, conf); + fdctx->reopen_done (fdctx, this); } ret = 0; @@ -799,7 +794,7 @@ _client_reacquire_lock (xlator_t *this, clnt_fd_ctx_t *fdctx) if (!local) { gf_log (this->name, GF_LOG_WARNING, "clnt_fd_lk_local_create " "failed, aborting reacquring of locks on %s.", - uuid_utoa (fdctx->inode->gfid)); + uuid_utoa (fdctx->gfid)); clnt_reacquire_lock_error (this, fdctx, conf); goto out; } @@ -825,7 +820,7 @@ _client_reacquire_lock (xlator_t *this, clnt_fd_ctx_t *fdctx) (void) gf_proto_flock_from_flock (&req.flock, &flock); - memcpy (req.gfid, fdctx->inode->gfid, 16); + memcpy (req.gfid, fdctx->gfid, 16); frame = create_frame (this, this->ctx->pool); if (!frame) { @@ -844,7 +839,7 @@ _client_reacquire_lock (xlator_t *this, clnt_fd_ctx_t *fdctx) if (ret) { gf_log (this->name, GF_LOG_WARNING, "reacquiring locks failed on file with gfid %s", - uuid_utoa (fdctx->inode->gfid)); + uuid_utoa (fdctx->gfid)); break; } @@ -870,8 +865,7 @@ client_reacquire_lock (xlator_t *this, clnt_fd_ctx_t *fdctx) if (client_fd_lk_list_empty (fdctx->lk_ctx, _gf_false)) { gf_log (this->name, GF_LOG_DEBUG, "fd lock list is empty"); - decrement_reopen_fd_count (this, - (clnt_conf_t *)this->private); + fdctx->reopen_done (fdctx, this); } else { lk_ctx = fdctx->lk_ctx; @@ -886,14 +880,66 @@ out: return ret; } +void +client_default_reopen_done (clnt_fd_ctx_t *fdctx, xlator_t *this) +{ + gf_log_callingfn (this->name, GF_LOG_WARNING, + "This function should never be called"); +} + +void +client_reopen_done (clnt_fd_ctx_t *fdctx, xlator_t *this) +{ + clnt_conf_t *conf = NULL; + gf_boolean_t destroy = _gf_false; + + conf = this->private; + + pthread_mutex_lock (&conf->lock); + { + fdctx->reopen_attempts = 0; + if (!fdctx->released) + list_add_tail (&fdctx->sfd_pos, &conf->saved_fds); + else + destroy = _gf_true; + fdctx->reopen_done = client_default_reopen_done; + } + pthread_mutex_unlock (&conf->lock); + + if (destroy) + client_fdctx_destroy (this, fdctx); +} + +void +client_child_up_reopen_done (clnt_fd_ctx_t *fdctx, xlator_t *this) +{ + clnt_conf_t *conf = NULL; + uint64_t fd_count = 0; + + conf = this->private; + + LOCK (&conf->rec_lock); + { + fd_count = --(conf->reopen_fd_count); + } + UNLOCK (&conf->rec_lock); + + client_reopen_done (fdctx, this); + if (fd_count == 0) { + gf_log (this->name, GF_LOG_INFO, + "last fd open'd/lock-self-heal'd - notifying CHILD-UP"); + client_set_lk_version (this); + client_notify_parents_child_up (this); + } +} + int -client3_1_reopen_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) { int32_t ret = -1; gfs3_open_rsp rsp = {0,}; - int attempt_lock_recovery = _gf_false; - uint64_t fd_count = 0; + gf_boolean_t attempt_lock_recovery = _gf_false; clnt_local_t *local = NULL; clnt_conf_t *conf = NULL; clnt_fd_ctx_t *fdctx = NULL; @@ -901,12 +947,10 @@ client3_1_reopen_cbk (struct rpc_req *req, struct iovec *iov, int count, xlator_t *this = NULL; frame = myframe; - if (!frame || !frame->this) - goto out; - this = frame->this; + conf = this->private; local = frame->local; - conf = frame->this->private; + fdctx = local->fdctx; if (-1 == req->rpc_status) { gf_log (frame->this->name, GF_LOG_WARNING, @@ -939,32 +983,23 @@ client3_1_reopen_cbk (struct rpc_req *req, struct iovec *iov, int count, goto out; } - fdctx = local->fdctx; - if (!fdctx) { - gf_log (frame->this->name, GF_LOG_WARNING, "fdctx not found"); - ret = -1; - goto out; - } - pthread_mutex_lock (&conf->lock); { fdctx->remote_fd = rsp.fd; if (!fdctx->released) { - if (!client_fd_lk_list_empty (fdctx->lk_ctx, _gf_false)) { + if (conf->lk_heal && + !client_fd_lk_list_empty (fdctx->lk_ctx, + _gf_false)) { attempt_lock_recovery = _gf_true; fdctx->lk_heal_state = GF_LK_HEAL_IN_PROGRESS; - } else { - list_add_tail (&fdctx->sfd_pos, - &conf->saved_fds); } - fdctx = NULL; } } pthread_mutex_unlock (&conf->lock); ret = 0; - if (conf->lk_heal && attempt_lock_recovery) { + if (attempt_lock_recovery) { /* Delay decrementing the reopen fd count untill all the locks corresponding to this fd are acquired.*/ gf_log (this->name, GF_LOG_DEBUG, "acquiring locks " @@ -974,23 +1009,15 @@ client3_1_reopen_cbk (struct rpc_req *req, struct iovec *iov, int count, clnt_reacquire_lock_error (this, local->fdctx, conf); gf_log (this->name, GF_LOG_WARNING, "acquiring locks " "failed on %s", local->loc.path); - ret = 0; } - } else { - fd_count = decrement_reopen_fd_count (frame->this, conf); } out: - if (fdctx) { - clnt_release_reopen_fd (this, fdctx); - } else if ((ret < 0) && frame && frame->this && conf) { - decrement_reopen_fd_count (frame->this, conf); - } + if (!attempt_lock_recovery) + fdctx->reopen_done (fdctx, this); - if (frame) { - frame->local = NULL; - STACK_DESTROY (frame->root); - } + frame->local = NULL; + STACK_DESTROY (frame->root); client_local_wipe (local); @@ -998,7 +1025,7 @@ out: } int -client3_1_reopendir_cbk (struct rpc_req *req, struct iovec *iov, int count, +client3_3_reopendir_cbk (struct rpc_req *req, struct iovec *iov, int count, void *myframe) { int32_t ret = -1; @@ -1009,11 +1036,10 @@ client3_1_reopendir_cbk (struct rpc_req *req, struct iovec *iov, int count, call_frame_t *frame = NULL; frame = myframe; - if (!frame || !frame->this) - goto out; + local = frame->local; + fdctx = local->fdctx; + conf = frame->this->private; - local = frame->local; - conf = frame->this->private; if (-1 == req->rpc_status) { gf_log (frame->this->name, GF_LOG_WARNING, @@ -1046,78 +1072,44 @@ client3_1_reopendir_cbk (struct rpc_req *req, struct iovec *iov, int count, goto out; } - fdctx = local->fdctx; - if (!fdctx) { - gf_log (frame->this->name, GF_LOG_WARNING, "fdctx not found"); - ret = -1; - goto out; - } - pthread_mutex_lock (&conf->lock); { fdctx->remote_fd = rsp.fd; - - if (!fdctx->released) { - list_add_tail (&fdctx->sfd_pos, &conf->saved_fds); - fdctx = NULL; - } } pthread_mutex_unlock (&conf->lock); - decrement_reopen_fd_count (frame->this, conf); - ret = 0; - out: - if (fdctx) - client_fdctx_destroy (frame->this, fdctx); - - if ((ret < 0) && frame && frame->this && conf) - decrement_reopen_fd_count (frame->this, conf); - - if (frame) { - frame->local = NULL; - STACK_DESTROY (frame->root); - } + fdctx->reopen_done (fdctx, frame->this); + frame->local = NULL; + STACK_DESTROY (frame->root); client_local_wipe (local); return 0; } -int -protocol_client_reopendir (xlator_t *this, clnt_fd_ctx_t *fdctx) +static int +protocol_client_reopendir (clnt_fd_ctx_t *fdctx, xlator_t *this) { int ret = -1; gfs3_opendir_req req = {{0,},}; clnt_local_t *local = NULL; - 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 = mem_get0 (this->local_pool); if (!local) { ret = -1; goto out; } - local->fdctx = fdctx; - local->loc.path = path; - path = NULL; + + 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) { @@ -1125,24 +1117,24 @@ protocol_client_reopendir (xlator_t *this, clnt_fd_ctx_t *fdctx) goto out; } - memcpy (req.gfid, inode->gfid, 16); + memcpy (req.gfid, fdctx->gfid, 16); gf_log (frame->this->name, GF_LOG_DEBUG, "attempting reopen on %s", local->loc.path); - frame->local = local; local = NULL; + frame->local = local; ret = client_submit_request (this, &req, frame, conf->fops, GFS3_OP_OPENDIR, - client3_1_reopendir_cbk, NULL, + client3_3_reopendir_cbk, NULL, NULL, 0, NULL, 0, NULL, (xdrproc_t)xdr_gfs3_opendir_req); if (ret) { - gf_log (THIS->name, GF_LOG_ERROR, + gf_log (this->name, GF_LOG_ERROR, "failed to send the re-opendir request"); } - return ret; + return 0; out: if (frame) { @@ -1153,41 +1145,23 @@ out: if (local) client_local_wipe (local); - if (path) - GF_FREE (path); - if ((ret < 0) && this && conf) { - decrement_reopen_fd_count (this, conf); - } + fdctx->reopen_done (fdctx, this); return 0; } -int -protocol_client_reopen (xlator_t *this, clnt_fd_ctx_t *fdctx) +static int +protocol_client_reopenfile (clnt_fd_ctx_t *fdctx, xlator_t *this) { int ret = -1; gfs3_open_req req = {{0,},}; clnt_local_t *local = NULL; - 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; - } - frame = create_frame (this, this->ctx->pool); if (!frame) { ret = -1; @@ -1201,27 +1175,30 @@ protocol_client_reopen (xlator_t *this, clnt_fd_ctx_t *fdctx) } local->fdctx = fdctx; - local->loc.path = path; - path = NULL; + uuid_copy (local->loc.gfid, fdctx->gfid); + ret = loc_path (&local->loc, NULL); + if (ret < 0) + goto out; + frame->local = local; - memcpy (req.gfid, inode->gfid, 16); + memcpy (req.gfid, fdctx->gfid, 16); req.flags = gf_flags_from_flags (fdctx->flags); + req.flags = req.flags & (~(O_TRUNC|O_CREAT|O_EXCL)); gf_log (frame->this->name, GF_LOG_DEBUG, "attempting reopen on %s", local->loc.path); - local = NULL; ret = client_submit_request (this, &req, frame, conf->fops, - GFS3_OP_OPEN, client3_1_reopen_cbk, NULL, + GFS3_OP_OPEN, client3_3_reopen_cbk, NULL, NULL, 0, NULL, 0, NULL, (xdrproc_t)xdr_gfs3_open_req); if (ret) { - gf_log (THIS->name, GF_LOG_ERROR, + gf_log (this->name, GF_LOG_ERROR, "failed to send the re-open request"); } - return ret; + return 0; out: if (frame) { @@ -1232,17 +1209,65 @@ out: if (local) client_local_wipe (local); - if (path) - GF_FREE (path); - - if ((ret < 0) && this && conf) { - decrement_reopen_fd_count (this, conf); - } + fdctx->reopen_done (fdctx, this); return 0; } +static void +protocol_client_reopen (clnt_fd_ctx_t *fdctx, xlator_t *this) +{ + if (fdctx->is_dir) + protocol_client_reopendir (fdctx, this); + else + protocol_client_reopenfile (fdctx, this); +} + +gf_boolean_t +__is_fd_reopen_in_progress (clnt_fd_ctx_t *fdctx) +{ + if (fdctx->reopen_done == client_default_reopen_done) + return _gf_false; + return _gf_true; +} + +void +client_attempt_reopen (fd_t *fd, xlator_t *this) +{ + clnt_conf_t *conf = NULL; + clnt_fd_ctx_t *fdctx = NULL; + gf_boolean_t reopen = _gf_false; + + if (!fd || !this) + goto out; + + conf = this->private; + pthread_mutex_lock (&conf->lock); + { + fdctx = this_fd_get_ctx (fd, this); + if (!fdctx) + goto unlock; + if (__is_fd_reopen_in_progress (fdctx)) + goto unlock; + if (fdctx->remote_fd != -1) + goto unlock; + + if (fdctx->reopen_attempts == CLIENT_REOPEN_MAX_ATTEMPTS) { + reopen = _gf_true; + fdctx->reopen_done = client_reopen_done; + list_del_init (&fdctx->sfd_pos); + } else { + fdctx->reopen_attempts++; + } + } +unlock: + pthread_mutex_unlock (&conf->lock); + if (reopen) + protocol_client_reopen (fdctx, this); +out: + return; +} int client_post_handshake (call_frame_t *frame, xlator_t *this) @@ -1267,6 +1292,7 @@ client_post_handshake (call_frame_t *frame, xlator_t *this) if (fdctx->remote_fd != -1) continue; + fdctx->reopen_done = client_child_up_reopen_done; list_del_init (&fdctx->sfd_pos); list_add_tail (&fdctx->sfd_pos, &reopen_head); count++; @@ -1285,10 +1311,7 @@ client_post_handshake (call_frame_t *frame, xlator_t *this) 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); + protocol_client_reopen (fdctx, this); } } else { gf_log (this->name, GF_LOG_DEBUG, @@ -1481,8 +1504,7 @@ out: ret = 0; } - if (rsp.dict.dict_val) - free (rsp.dict.dict_val); + free (rsp.dict.dict_val); STACK_DESTROY (frame->root); @@ -1577,13 +1599,14 @@ client_setvolume (xlator_t *this, struct rpc_clnt *rpc) client_get_lk_ver (conf)); } - req.dict.dict_len = dict_serialized_length (options); - if (req.dict.dict_len < 0) { + ret = dict_serialized_length (options); + if (ret < 0) { gf_log (this->name, GF_LOG_ERROR, "failed to get serialized length of dict"); ret = -1; goto fail; } + req.dict.dict_len = ret; req.dict.dict_val = GF_CALLOC (1, req.dict.dict_len, gf_client_mt_clnt_req_buf_t); ret = dict_serialize (options, req.dict.dict_val); @@ -1603,8 +1626,7 @@ client_setvolume (xlator_t *this, struct rpc_clnt *rpc) (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; } @@ -1627,9 +1649,9 @@ select_server_supported_programs (xlator_t *this, gf_prog_detail *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; + if ((clnt3_3_fop_prog.prognum == trav->prognum) && + (clnt3_3_fop_prog.progver == trav->progver)) { + conf->fops = &clnt3_3_fop_prog; gf_log (this->name, GF_LOG_INFO, "Using Program %s, Num (%"PRId64"), " "Version (%"PRId64")", @@ -1714,16 +1736,21 @@ client_query_portmap_cbk (struct rpc_req *req, struct iovec *iov, int count, voi 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"); + "failed to get the port number for remote subvolume. " + "Please run 'gluster volume status' on server to see " + "if brick process is running."); conf->portmap_err_logged = 1; goto out; } conf->portmap_err_logged = 0; + conf->disconnect_err_logged = 0; config.remote_port = rsp.port; rpc_clnt_reconfig (conf->rpc, &config); + conf->skip_notify = 1; + conf->quick_reconnect = 1; out: if (frame) @@ -1733,7 +1760,6 @@ out: /* 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); } return ret; diff --git a/xlators/protocol/client/src/client-helpers.c b/xlators/protocol/client/src/client-helpers.c index a0a006123..5d9f00fdc 100644 --- a/xlators/protocol/client/src/client-helpers.c +++ b/xlators/protocol/client/src/client-helpers.c @@ -16,7 +16,6 @@ #include "client.h" #include "fd.h" - int client_fd_lk_list_empty (fd_lk_ctx_t *lk_ctx, gf_boolean_t try_lock) { @@ -133,9 +132,7 @@ client_local_wipe (clnt_local_t *local) iobref_unref (local->iobref); } - if (local->name) { - GF_FREE (local->name); - } + GF_FREE (local->name); mem_put (local); } @@ -278,3 +275,75 @@ clnt_readdir_rsp_cleanup (gfs3_readdir_rsp *rsp) return 0; } + +int +client_get_remote_fd (xlator_t *this, fd_t *fd, int flags, int64_t *remote_fd) +{ + clnt_fd_ctx_t *fdctx = NULL; + clnt_conf_t *conf = NULL; + + GF_VALIDATE_OR_GOTO (this->name, fd, out); + GF_VALIDATE_OR_GOTO (this->name, remote_fd, out); + + conf = this->private; + pthread_mutex_lock (&conf->lock); + { + fdctx = this_fd_get_ctx (fd, this); + if (!fdctx) + *remote_fd = GF_ANON_FD_NO; + else if (__is_fd_reopen_in_progress (fdctx)) + *remote_fd = -1; + else + *remote_fd = fdctx->remote_fd; + } + pthread_mutex_unlock (&conf->lock); + + if ((flags & FALLBACK_TO_ANON_FD) && (*remote_fd == -1)) + *remote_fd = GF_ANON_FD_NO; + + return 0; +out: + return -1; +} + +gf_boolean_t +client_is_reopen_needed (fd_t *fd, xlator_t *this, int64_t remote_fd) +{ + clnt_fd_ctx_t *fdctx = NULL; + + fdctx = this_fd_get_ctx (fd, this); + if (fdctx && (fdctx->remote_fd == -1) && + (remote_fd == GF_ANON_FD_NO)) + return _gf_true; + return _gf_false; +} + +int +client_fd_fop_prepare_local (call_frame_t *frame, fd_t *fd, int64_t remote_fd) +{ + xlator_t *this = NULL; + clnt_conf_t *conf = NULL; + clnt_local_t *local = NULL; + int ret = 0; + + this = frame->this; + conf = this->private; + + if (!frame || !fd) { + ret = -EINVAL; + goto out; + } + + frame->local = mem_get0 (this->local_pool); + if (frame->local == NULL) { + ret = -ENOMEM; + goto out; + } + + local = frame->local; + local->fd = fd_ref (fd); + local->attempt_reopen = client_is_reopen_needed (fd, this, remote_fd); + return 0; +out: + return ret; +} diff --git a/xlators/protocol/client/src/client-lk.c b/xlators/protocol/client/src/client-lk.c index 5611c7b83..1fd8f0d50 100644 --- a/xlators/protocol/client/src/client-lk.c +++ b/xlators/protocol/client/src/client-lk.c @@ -16,9 +16,6 @@ static void __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) { @@ -430,21 +427,6 @@ delete_granted_locks_fd (clnt_fd_ctx_t *fdctx) return ret; } -static void -client_mark_bad_fd (fd_t *fd, clnt_fd_ctx_t *fdctx) -{ - 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); -} - int32_t client_cmd_to_gf_cmd (int32_t cmd, int32_t *gf_cmd) { @@ -553,348 +535,6 @@ out: } -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); - - 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; - lock->l_owner = client_lock->owner; - - 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_set_lk_version (this); - client_notify_parents_child_up (this); - } - - return fd_count; -} - -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, dict_t *xdata) -{ - 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, NULL); -} - -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, dict_t *xdata) -{ - - clnt_local_t *local = NULL; - clnt_conf_t *conf = NULL; - - uint64_t fd_count = 0; - - local = frame->local; - conf = this->private; - - /* Got the reserve lock. Check if lock is grantable and proceed - with the real lk call */ - - 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, dict_t *xdata) -{ - 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, NULL); - goto out; - - } - -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); - -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), NULL); - - return 0; -} - -static int -client_lockrec_init (clnt_fd_ctx_t *fdctx, clnt_local_t *local) -{ - - 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; -} - - -int -client_attempt_lock_recovery (xlator_t *this, clnt_fd_ctx_t *fdctx) -{ - call_frame_t *frame = NULL; - clnt_local_t *local = NULL; - client_posix_lock_t *lock = NULL; - - struct gf_flock reserve_flock; - int ret = 0; - - local = mem_get0 (this->local_pool); - if (!local) { - ret = -ENOMEM; - goto out; - } - - client_lockrec_init (fdctx, local); - - 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; - } - - 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; - } - - construct_reserve_lock (lock, frame, &reserve_flock); - - frame->local = local; - local->fdctx = fdctx; - local->client_lock = lock; - - STACK_WIND (frame, client_reserve_lock_cbk, - this, this->fops->lk, - lock->fd, F_RESLK_LCK, &reserve_flock, NULL); - -out: - return ret; - - -} - int32_t client_dump_locks (char *name, inode_t *inode, dict_t *dict) diff --git a/xlators/protocol/client/src/client3_1-fops.c b/xlators/protocol/client/src/client-rpc-fops.c index 061bfcd7e..6355450c3 100644 --- a/xlators/protocol/client/src/client3_1-fops.c +++ b/xlators/protocol/client/src/client-rpc-fops.c @@ -20,7 +20,7 @@ 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; +rpc_clnt_prog_t clnt3_3_fop_prog; int @@ -132,7 +132,7 @@ unwind: /* CBK */ int -client3_1_symlink_cbk (struct rpc_req *req, struct iovec *iov, int count, +client3_3_symlink_cbk (struct rpc_req *req, struct iovec *iov, int count, void *myframe) { call_frame_t *frame = NULL; @@ -185,16 +185,14 @@ out: gf_log (this->name, GF_LOG_WARNING, "remote operation failed: %s. Path: (%s to %s)", strerror (gf_error_to_errno (rsp.op_errno)), - (local) ? local->loc.path : "--", - (local) ? local->loc2.path: "--"); + local->loc.path, local->loc2.path); } CLIENT_STACK_UNWIND (symlink, frame, rsp.op_ret, gf_error_to_errno (rsp.op_errno), inode, &stbuf, &preparent, &postparent, xdata); - if (rsp.xdata.xdata_val) - free (rsp.xdata.xdata_val); + free (rsp.xdata.xdata_val); if (xdata) dict_unref (xdata); @@ -204,7 +202,7 @@ out: int -client3_1_mknod_cbk (struct rpc_req *req, struct iovec *iov, int count, +client3_3_mknod_cbk (struct rpc_req *req, struct iovec *iov, int count, void *myframe) { call_frame_t *frame = NULL; @@ -253,19 +251,16 @@ client3_1_mknod_cbk (struct rpc_req *req, struct iovec *iov, int count, out: if (rsp.op_ret == -1) { gf_log (this->name, GF_LOG_WARNING, - "remote operation failed: %s. Path: %s (%s)", + "remote operation failed: %s. Path: %s", strerror (gf_error_to_errno (rsp.op_errno)), - (local) ? local->loc.path : "--", - (local && local->loc.inode) ? - uuid_utoa (local->loc.inode->gfid) : "--"); + local->loc.path); } CLIENT_STACK_UNWIND (mknod, frame, rsp.op_ret, gf_error_to_errno (rsp.op_errno), inode, &stbuf, &preparent, &postparent, xdata); - if (rsp.xdata.xdata_val) - free (rsp.xdata.xdata_val); + free (rsp.xdata.xdata_val); if (xdata) dict_unref (xdata); @@ -274,7 +269,7 @@ out: } int -client3_1_mkdir_cbk (struct rpc_req *req, struct iovec *iov, int count, +client3_3_mkdir_cbk (struct rpc_req *req, struct iovec *iov, int count, void *myframe) { call_frame_t *frame = NULL; @@ -322,19 +317,16 @@ client3_1_mkdir_cbk (struct rpc_req *req, struct iovec *iov, int count, out: if (rsp.op_ret == -1) { gf_log (this->name, GF_LOG_WARNING, - "remote operation failed: %s. Path: %s (%s)", + "remote operation failed: %s. Path: %s", strerror (gf_error_to_errno (rsp.op_errno)), - (local) ? local->loc.path : "--", - (local && local->loc.inode) ? - uuid_utoa (local->loc.inode->gfid) : "--"); + local->loc.path); } CLIENT_STACK_UNWIND (mkdir, frame, rsp.op_ret, gf_error_to_errno (rsp.op_errno), inode, &stbuf, &preparent, &postparent, xdata); - if (rsp.xdata.xdata_val) - free (rsp.xdata.xdata_val); + free (rsp.xdata.xdata_val); if (xdata) dict_unref (xdata); @@ -343,12 +335,84 @@ out: } int -client3_1_open_cbk (struct rpc_req *req, struct iovec *iov, int count, +_copy_gfid_from_inode_holders (uuid_t gfid, loc_t *loc, fd_t *fd) +{ + int ret = 0; + + if (fd && fd->inode && !uuid_is_null (fd->inode->gfid)) { + uuid_copy (gfid, fd->inode->gfid); + goto out; + } + + if (!loc) { + GF_ASSERT (0); + ret = -1; + goto out; + } + + if (loc->inode && !uuid_is_null (loc->inode->gfid)) { + uuid_copy (gfid, loc->inode->gfid); + } else if (!uuid_is_null (loc->gfid)) { + uuid_copy (gfid, loc->gfid); + } else { + GF_ASSERT (0); + ret = -1; + } +out: + return ret; +} + +int +client_add_fd_to_saved_fds (xlator_t *this, fd_t *fd, loc_t *loc, int32_t flags, + int64_t remote_fd, int is_dir) +{ + int ret = 0; + uuid_t gfid = {0}; + clnt_conf_t *conf = NULL; + clnt_fd_ctx_t *fdctx = NULL; + + conf = this->private; + ret = _copy_gfid_from_inode_holders (gfid, loc, fd); + if (ret) { + ret = -EINVAL; + goto out; + } + + fdctx = GF_CALLOC (1, sizeof (*fdctx), + gf_client_mt_clnt_fdctx_t); + if (!fdctx) { + ret = -ENOMEM; + goto out; + } + + uuid_copy (fdctx->gfid, gfid); + fdctx->is_dir = is_dir; + fdctx->remote_fd = remote_fd; + fdctx->flags = flags; + fdctx->lk_ctx = fd_lk_ctx_ref (fd->lk_ctx); + fdctx->lk_heal_state = GF_LK_HEAL_DONE; + fdctx->reopen_done = client_default_reopen_done; + + INIT_LIST_HEAD (&fdctx->sfd_pos); + INIT_LIST_HEAD (&fdctx->lock_list); + + this_fd_set_ctx (fd, this, loc, fdctx); + + pthread_mutex_lock (&conf->lock); + { + list_add_tail (&fdctx->sfd_pos, &conf->saved_fds); + } + pthread_mutex_unlock (&conf->lock); +out: + return ret; +} + +int +client3_3_open_cbk (struct rpc_req *req, struct iovec *iov, int count, void *myframe) { clnt_local_t *local = NULL; clnt_conf_t *conf = NULL; - clnt_fd_ctx_t *fdctx = NULL; call_frame_t *frame = NULL; fd_t *fd = NULL; int ret = 0; @@ -379,31 +443,13 @@ client3_1_open_cbk (struct rpc_req *req, struct iovec *iov, int count, } if (-1 != rsp.op_ret) { - fdctx = GF_CALLOC (1, sizeof (*fdctx), - gf_client_mt_clnt_fdctx_t); - if (!fdctx) { + 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 = ENOMEM; + rsp.op_errno = -ret; goto out; } - - fdctx->remote_fd = rsp.fd; - fdctx->inode = inode_ref (fd->inode); - fdctx->flags = local->flags; - fdctx->wbflags = local->wbflags; - fdctx->lk_ctx = fd_lk_ctx_ref (fd->lk_ctx); - fdctx->lk_heal_state = GF_LK_HEAL_DONE; - - 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); } GF_PROTOCOL_DICT_UNSERIALIZE (this, xdata, (rsp.xdata.xdata_val), @@ -415,16 +461,13 @@ out: gf_log (this->name, GF_LOG_WARNING, "remote operation failed: %s. Path: %s (%s)", strerror (gf_error_to_errno (rsp.op_errno)), - (local) ? local->loc.path : "--", - (local && local->loc.inode) ? - uuid_utoa (local->loc.inode->gfid) : "--"); + local->loc.path, loc_gfid_utoa (&local->loc)); } CLIENT_STACK_UNWIND (open, frame, rsp.op_ret, gf_error_to_errno (rsp.op_errno), fd, xdata); - if (rsp.xdata.xdata_val) - free (rsp.xdata.xdata_val); + free (rsp.xdata.xdata_val); if (xdata) dict_unref (xdata); @@ -434,7 +477,7 @@ out: int -client3_1_stat_cbk (struct rpc_req *req, struct iovec *iov, int count, +client3_3_stat_cbk (struct rpc_req *req, struct iovec *iov, int count, void *myframe) { gfs3_stat_rsp rsp = {0,}; @@ -479,8 +522,7 @@ out: CLIENT_STACK_UNWIND (stat, frame, rsp.op_ret, gf_error_to_errno (rsp.op_errno), &iatt, xdata); - if (rsp.xdata.xdata_val) - free (rsp.xdata.xdata_val); + free (rsp.xdata.xdata_val); if (xdata) dict_unref (xdata); @@ -489,7 +531,7 @@ out: } int -client3_1_readlink_cbk (struct rpc_req *req, struct iovec *iov, int count, +client3_3_readlink_cbk (struct rpc_req *req, struct iovec *iov, int count, void *myframe) { gfs3_readlink_rsp rsp = {0,}; @@ -527,8 +569,9 @@ client3_1_readlink_cbk (struct rpc_req *req, struct iovec *iov, int count, 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))); + gf_log (this->name, (gf_error_to_errno(rsp.op_errno) == ENOENT)? + GF_LOG_DEBUG:GF_LOG_WARNING, "remote operation failed:" + " %s", strerror (gf_error_to_errno (rsp.op_errno))); } CLIENT_STACK_UNWIND (readlink, frame, rsp.op_ret, @@ -537,11 +580,9 @@ out: /* This is allocated by the libc while decoding RPC msg */ /* Hence no 'GF_FREE', but just 'free' */ - if (rsp.path) - free (rsp.path); + free (rsp.path); - if (rsp.xdata.xdata_val) - free (rsp.xdata.xdata_val); + free (rsp.xdata.xdata_val); if (xdata) dict_unref (xdata); @@ -550,7 +591,7 @@ out: } int -client3_1_unlink_cbk (struct rpc_req *req, struct iovec *iov, int count, +client3_3_unlink_cbk (struct rpc_req *req, struct iovec *iov, int count, void *myframe) { call_frame_t *frame = NULL; @@ -590,15 +631,18 @@ client3_1_unlink_cbk (struct rpc_req *req, struct iovec *iov, int count, out: if (rsp.op_ret == -1) { - gf_log (this->name, GF_LOG_WARNING, "remote operation failed: %s", + gf_log (this->name, + ((gf_error_to_errno (rsp.op_errno) == ENOENT) + ? GF_LOG_DEBUG : GF_LOG_WARNING), + "remote operation failed: %s", strerror (gf_error_to_errno (rsp.op_errno))); } + CLIENT_STACK_UNWIND (unlink, frame, rsp.op_ret, gf_error_to_errno (rsp.op_errno), &preparent, &postparent, xdata); - if (rsp.xdata.xdata_val) - free (rsp.xdata.xdata_val); + free (rsp.xdata.xdata_val); if (xdata) dict_unref (xdata); @@ -607,7 +651,7 @@ out: } int -client3_1_rmdir_cbk (struct rpc_req *req, struct iovec *iov, int count, +client3_3_rmdir_cbk (struct rpc_req *req, struct iovec *iov, int count, void *myframe) { gfs3_rmdir_rsp rsp = {0,}; @@ -654,8 +698,7 @@ out: gf_error_to_errno (rsp.op_errno), &preparent, &postparent, xdata); - if (rsp.xdata.xdata_val) - free (rsp.xdata.xdata_val); + free (rsp.xdata.xdata_val); if (xdata) dict_unref (xdata); @@ -665,7 +708,7 @@ out: int -client3_1_truncate_cbk (struct rpc_req *req, struct iovec *iov, int count, +client3_3_truncate_cbk (struct rpc_req *req, struct iovec *iov, int count, void *myframe) { gfs3_truncate_rsp rsp = {0,}; @@ -712,8 +755,7 @@ out: gf_error_to_errno (rsp.op_errno), &prestat, &poststat, xdata); - if (rsp.xdata.xdata_val) - free (rsp.xdata.xdata_val); + free (rsp.xdata.xdata_val); if (xdata) dict_unref (xdata); @@ -723,7 +765,7 @@ out: int -client3_1_statfs_cbk (struct rpc_req *req, struct iovec *iov, int count, +client3_3_statfs_cbk (struct rpc_req *req, struct iovec *iov, int count, void *myframe) { gfs3_statfs_rsp rsp = {0,}; @@ -767,8 +809,7 @@ out: CLIENT_STACK_UNWIND (statfs, frame, rsp.op_ret, gf_error_to_errno (rsp.op_errno), &statfs, xdata); - if (rsp.xdata.xdata_val) - free (rsp.xdata.xdata_val); + free (rsp.xdata.xdata_val); if (xdata) dict_unref (xdata); @@ -778,7 +819,7 @@ out: int -client3_1_writev_cbk (struct rpc_req *req, struct iovec *iov, int count, +client3_3_writev_cbk (struct rpc_req *req, struct iovec *iov, int count, void *myframe) { gfs3_write_rsp rsp = {0,}; @@ -788,11 +829,13 @@ client3_1_writev_cbk (struct rpc_req *req, struct iovec *iov, int count, 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; @@ -821,13 +864,15 @@ out: if (rsp.op_ret == -1) { gf_log (this->name, GF_LOG_WARNING, "remote operation failed: %s", strerror (gf_error_to_errno (rsp.op_errno))); + } else if (rsp.op_ret >= 0) { + if (local->attempt_reopen) + client_attempt_reopen (local->fd, this); } CLIENT_STACK_UNWIND (writev, frame, rsp.op_ret, gf_error_to_errno (rsp.op_errno), &prestat, &poststat, xdata); - if (rsp.xdata.xdata_val) - free (rsp.xdata.xdata_val); + free (rsp.xdata.xdata_val); if (xdata) dict_unref (xdata); @@ -836,7 +881,7 @@ out: } int -client3_1_flush_cbk (struct rpc_req *req, struct iovec *iov, int count, +client3_3_flush_cbk (struct rpc_req *req, struct iovec *iov, int count, void *myframe) { call_frame_t *frame = NULL; @@ -885,8 +930,7 @@ out: CLIENT_STACK_UNWIND (flush, frame, rsp.op_ret, gf_error_to_errno (rsp.op_errno), xdata); - if (rsp.xdata.xdata_val) - free (rsp.xdata.xdata_val); + free (rsp.xdata.xdata_val); if (xdata) dict_unref (xdata); @@ -895,7 +939,7 @@ out: } int -client3_1_fsync_cbk (struct rpc_req *req, struct iovec *iov, int count, +client3_3_fsync_cbk (struct rpc_req *req, struct iovec *iov, int count, void *myframe) { gfs3_fsync_rsp rsp = {0,}; @@ -943,8 +987,7 @@ out: gf_error_to_errno (rsp.op_errno), &prestat, &poststat, xdata); - if (rsp.xdata.xdata_val) - free (rsp.xdata.xdata_val); + free (rsp.xdata.xdata_val); if (xdata) dict_unref (xdata); @@ -953,7 +996,7 @@ out: } int -client3_1_setxattr_cbk (struct rpc_req *req, struct iovec *iov, int count, +client3_3_setxattr_cbk (struct rpc_req *req, struct iovec *iov, int count, void *myframe) { call_frame_t *frame = NULL; @@ -995,8 +1038,7 @@ out: } CLIENT_STACK_UNWIND (setxattr, frame, rsp.op_ret, op_errno, xdata); - if (rsp.xdata.xdata_val) - free (rsp.xdata.xdata_val); + free (rsp.xdata.xdata_val); if (xdata) dict_unref (xdata); @@ -1005,7 +1047,7 @@ out: } int -client3_1_getxattr_cbk (struct rpc_req *req, struct iovec *iov, int count, +client3_3_getxattr_cbk (struct rpc_req *req, struct iovec *iov, int count, void *myframe) { call_frame_t *frame = NULL; @@ -1051,24 +1093,22 @@ client3_1_getxattr_cbk (struct rpc_req *req, struct iovec *iov, int count, out: if (rsp.op_ret == -1) { - gf_log (this->name, ((op_errno == ENOTSUP) ? + gf_log (this->name, (((op_errno == ENOTSUP) || + (op_errno == ENODATA) || + (op_errno == ENOENT)) ? GF_LOG_DEBUG : GF_LOG_WARNING), "remote operation failed: %s. Path: %s (%s). Key: %s", strerror (op_errno), - (local) ? local->loc.path : "--", - (local && local->loc.inode) ? - uuid_utoa (local->loc.inode->gfid) : "--", - (local) ? local->name : "(null)"); + local->loc.path, loc_gfid_utoa (&local->loc), + (local->name) ? local->name : "(null)"); } CLIENT_STACK_UNWIND (getxattr, frame, rsp.op_ret, op_errno, dict, xdata); /* don't use GF_FREE, this memory was allocated by libc */ - if (rsp.dict.dict_val) - free (rsp.dict.dict_val); + free (rsp.dict.dict_val); - if (rsp.xdata.xdata_val) - free (rsp.xdata.xdata_val); + free (rsp.xdata.xdata_val); if (xdata) dict_unref (xdata); @@ -1080,7 +1120,7 @@ out: } int -client3_1_fgetxattr_cbk (struct rpc_req *req, struct iovec *iov, int count, +client3_3_fgetxattr_cbk (struct rpc_req *req, struct iovec *iov, int count, void *myframe) { call_frame_t *frame = NULL; @@ -1132,11 +1172,9 @@ out: CLIENT_STACK_UNWIND (fgetxattr, frame, rsp.op_ret, op_errno, dict, xdata); - if (rsp.dict.dict_val) - free (rsp.dict.dict_val); + free (rsp.dict.dict_val); - if (rsp.xdata.xdata_val) - free (rsp.xdata.xdata_val); + free (rsp.xdata.xdata_val); if (xdata) dict_unref (xdata); @@ -1148,7 +1186,7 @@ out: } int -client3_1_removexattr_cbk (struct rpc_req *req, struct iovec *iov, int count, +client3_3_removexattr_cbk (struct rpc_req *req, struct iovec *iov, int count, void *myframe) { call_frame_t *frame = NULL; @@ -1188,8 +1226,7 @@ out: CLIENT_STACK_UNWIND (removexattr, frame, rsp.op_ret, gf_error_to_errno (rsp.op_errno), xdata); - if (rsp.xdata.xdata_val) - free (rsp.xdata.xdata_val); + free (rsp.xdata.xdata_val); if (xdata) dict_unref (xdata); @@ -1198,7 +1235,7 @@ out: } int -client3_1_fremovexattr_cbk (struct rpc_req *req, struct iovec *iov, int count, +client3_3_fremovexattr_cbk (struct rpc_req *req, struct iovec *iov, int count, void *myframe) { call_frame_t *frame = NULL; @@ -1238,8 +1275,7 @@ out: CLIENT_STACK_UNWIND (fremovexattr, frame, rsp.op_ret, gf_error_to_errno (rsp.op_errno), xdata); - if (rsp.xdata.xdata_val) - free (rsp.xdata.xdata_val); + free (rsp.xdata.xdata_val); if (xdata) dict_unref (xdata); @@ -1248,7 +1284,7 @@ out: } int -client3_1_fsyncdir_cbk (struct rpc_req *req, struct iovec *iov, int count, +client3_3_fsyncdir_cbk (struct rpc_req *req, struct iovec *iov, int count, void *myframe) { call_frame_t *frame = NULL; @@ -1287,8 +1323,7 @@ out: CLIENT_STACK_UNWIND (fsyncdir, frame, rsp.op_ret, gf_error_to_errno (rsp.op_errno), xdata); - if (rsp.xdata.xdata_val) - free (rsp.xdata.xdata_val); + free (rsp.xdata.xdata_val); if (xdata) dict_unref (xdata); @@ -1297,7 +1332,7 @@ out: } int -client3_1_access_cbk (struct rpc_req *req, struct iovec *iov, int count, +client3_3_access_cbk (struct rpc_req *req, struct iovec *iov, int count, void *myframe) { call_frame_t *frame = NULL; @@ -1336,8 +1371,7 @@ out: CLIENT_STACK_UNWIND (access, frame, rsp.op_ret, gf_error_to_errno (rsp.op_errno), xdata); - if (rsp.xdata.xdata_val) - free (rsp.xdata.xdata_val); + free (rsp.xdata.xdata_val); if (xdata) dict_unref (xdata); @@ -1347,7 +1381,7 @@ out: int -client3_1_ftruncate_cbk (struct rpc_req *req, struct iovec *iov, int count, +client3_3_ftruncate_cbk (struct rpc_req *req, struct iovec *iov, int count, void *myframe) { gfs3_ftruncate_rsp rsp = {0,}; @@ -1394,8 +1428,7 @@ out: gf_error_to_errno (rsp.op_errno), &prestat, &poststat, xdata); - if (rsp.xdata.xdata_val) - free (rsp.xdata.xdata_val); + free (rsp.xdata.xdata_val); if (xdata) dict_unref (xdata); @@ -1404,7 +1437,7 @@ out: } int -client3_1_fstat_cbk (struct rpc_req *req, struct iovec *iov, int count, +client3_3_fstat_cbk (struct rpc_req *req, struct iovec *iov, int count, void *myframe) { gfs3_fstat_rsp rsp = {0,}; @@ -1448,8 +1481,7 @@ out: CLIENT_STACK_UNWIND (fstat, frame, rsp.op_ret, gf_error_to_errno (rsp.op_errno), &stat, xdata); - if (rsp.xdata.xdata_val) - free (rsp.xdata.xdata_val); + free (rsp.xdata.xdata_val); if (xdata) dict_unref (xdata); @@ -1459,7 +1491,7 @@ out: int -client3_1_inodelk_cbk (struct rpc_req *req, struct iovec *iov, int count, +client3_3_inodelk_cbk (struct rpc_req *req, struct iovec *iov, int count, void *myframe) { call_frame_t *frame = NULL; @@ -1499,8 +1531,7 @@ out: CLIENT_STACK_UNWIND (inodelk, frame, rsp.op_ret, gf_error_to_errno (rsp.op_errno), xdata); - if (rsp.xdata.xdata_val) - free (rsp.xdata.xdata_val); + free (rsp.xdata.xdata_val); if (xdata) dict_unref (xdata); @@ -1509,19 +1540,20 @@ out: } int -client3_1_finodelk_cbk (struct rpc_req *req, struct iovec *iov, int count, +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; - + 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; - this = THIS; frame = myframe; + this = frame->this; + local = frame->local; if (-1 == req->rpc_status) { rsp.op_ret = -1; @@ -1545,12 +1577,14 @@ out: (EAGAIN != gf_error_to_errno (rsp.op_errno))) { gf_log (this->name, GF_LOG_WARNING, "remote operation failed: %s", strerror (gf_error_to_errno (rsp.op_errno))); + } else if (rsp.op_ret == 0) { + if (local->attempt_reopen) + client_attempt_reopen (local->fd, this); } CLIENT_STACK_UNWIND (finodelk, frame, rsp.op_ret, gf_error_to_errno (rsp.op_errno), xdata); - if (rsp.xdata.xdata_val) - free (rsp.xdata.xdata_val); + free (rsp.xdata.xdata_val); if (xdata) dict_unref (xdata); @@ -1559,7 +1593,7 @@ out: } int -client3_1_entrylk_cbk (struct rpc_req *req, struct iovec *iov, int count, +client3_3_entrylk_cbk (struct rpc_req *req, struct iovec *iov, int count, void *myframe) { call_frame_t *frame = NULL; @@ -1600,8 +1634,7 @@ out: CLIENT_STACK_UNWIND (entrylk, frame, rsp.op_ret, gf_error_to_errno (rsp.op_errno), xdata); - if (rsp.xdata.xdata_val) - free (rsp.xdata.xdata_val); + free (rsp.xdata.xdata_val); if (xdata) dict_unref (xdata); @@ -1610,7 +1643,7 @@ out: } int -client3_1_fentrylk_cbk (struct rpc_req *req, struct iovec *iov, int count, +client3_3_fentrylk_cbk (struct rpc_req *req, struct iovec *iov, int count, void *myframe) { call_frame_t *frame = NULL; @@ -1651,8 +1684,7 @@ out: CLIENT_STACK_UNWIND (fentrylk, frame, rsp.op_ret, gf_error_to_errno (rsp.op_errno), xdata); - if (rsp.xdata.xdata_val) - free (rsp.xdata.xdata_val); + free (rsp.xdata.xdata_val); if (xdata) dict_unref (xdata); @@ -1661,7 +1693,7 @@ out: } int -client3_1_xattrop_cbk (struct rpc_req *req, struct iovec *iov, int count, +client3_3_xattrop_cbk (struct rpc_req *req, struct iovec *iov, int count, void *myframe) { call_frame_t *frame = NULL; @@ -1709,19 +1741,15 @@ out: gf_log (this->name, GF_LOG_WARNING, "remote operation failed: %s. Path: %s (%s)", strerror (gf_error_to_errno (rsp.op_errno)), - (local) ? local->loc.path : "--", - (local && local->loc.inode) ? - uuid_utoa (local->loc.inode->gfid) : "--"); + local->loc.path, loc_gfid_utoa (&local->loc)); } CLIENT_STACK_UNWIND (xattrop, frame, rsp.op_ret, gf_error_to_errno (op_errno), dict, xdata); - if (rsp.dict.dict_val) - free (rsp.dict.dict_val); + free (rsp.dict.dict_val); - if (rsp.xdata.xdata_val) - free (rsp.xdata.xdata_val); + free (rsp.xdata.xdata_val); if (xdata) dict_unref (xdata); @@ -1733,7 +1761,7 @@ out: } int -client3_1_fxattrop_cbk (struct rpc_req *req, struct iovec *iov, int count, +client3_3_fxattrop_cbk (struct rpc_req *req, struct iovec *iov, int count, void *myframe) { call_frame_t *frame = NULL; @@ -1781,15 +1809,16 @@ out: gf_log (this->name, GF_LOG_WARNING, "remote operation failed: %s", strerror (gf_error_to_errno (op_errno))); + } else if (rsp.op_ret == 0) { + if (local->attempt_reopen) + client_attempt_reopen (local->fd, this); } CLIENT_STACK_UNWIND (fxattrop, frame, rsp.op_ret, gf_error_to_errno (op_errno), dict, xdata); - if (rsp.dict.dict_val) - free (rsp.dict.dict_val); + free (rsp.dict.dict_val); - if (rsp.xdata.xdata_val) - free (rsp.xdata.xdata_val); + free (rsp.xdata.xdata_val); if (xdata) dict_unref (xdata); @@ -1801,7 +1830,7 @@ out: } int -client3_1_fsetxattr_cbk (struct rpc_req *req, struct iovec *iov, int count, +client3_3_fsetxattr_cbk (struct rpc_req *req, struct iovec *iov, int count, void *myframe) { call_frame_t *frame = NULL; @@ -1843,8 +1872,7 @@ out: CLIENT_STACK_UNWIND (fsetxattr, frame, rsp.op_ret, op_errno, xdata); - if (rsp.xdata.xdata_val) - free (rsp.xdata.xdata_val); + free (rsp.xdata.xdata_val); if (xdata) dict_unref (xdata); @@ -1853,7 +1881,7 @@ out: } int -client3_1_fsetattr_cbk (struct rpc_req *req, struct iovec *iov, int count, +client3_3_fsetattr_cbk (struct rpc_req *req, struct iovec *iov, int count, void *myframe) { call_frame_t *frame = NULL; @@ -1900,8 +1928,118 @@ out: gf_error_to_errno (rsp.op_errno), &prestat, &poststat, xdata); - if (rsp.xdata.xdata_val) - free (rsp.xdata.xdata_val); + free (rsp.xdata.xdata_val); + + if (xdata) + dict_unref (xdata); + + return 0; +} + +int +client3_3_fallocate_cbk (struct rpc_req *req, struct iovec *iov, int count, + void *myframe) +{ + call_frame_t *frame = NULL; + gfs3_fallocate_rsp rsp = {0,}; + struct iatt prestat = {0,}; + struct iatt poststat = {0,}; + int ret = 0; + xlator_t *this = NULL; + dict_t *xdata = NULL; + + + this = THIS; + + frame = myframe; + + if (-1 == req->rpc_status) { + rsp.op_ret = -1; + rsp.op_errno = ENOTCONN; + goto out; + } + ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gfs3_fallocate_rsp); + if (ret < 0) { + gf_log (this->name, GF_LOG_ERROR, "XDR decoding failed"); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; + } + + if (-1 != rsp.op_ret) { + gf_stat_to_iatt (&rsp.statpre, &prestat); + gf_stat_to_iatt (&rsp.statpost, &poststat); + } + + GF_PROTOCOL_DICT_UNSERIALIZE (this, xdata, (rsp.xdata.xdata_val), + (rsp.xdata.xdata_len), ret, + rsp.op_errno, out); + +out: + if (rsp.op_ret == -1) { + gf_log (this->name, GF_LOG_WARNING, "remote operation failed: %s", + strerror (gf_error_to_errno (rsp.op_errno))); + } + CLIENT_STACK_UNWIND (fallocate, frame, rsp.op_ret, + gf_error_to_errno (rsp.op_errno), &prestat, + &poststat, xdata); + + free (rsp.xdata.xdata_val); + + if (xdata) + dict_unref (xdata); + + return 0; +} + +int +client3_3_discard_cbk(struct rpc_req *req, struct iovec *iov, int count, + void *myframe) +{ + call_frame_t *frame = NULL; + gfs3_discard_rsp rsp = {0,}; + struct iatt prestat = {0,}; + struct iatt poststat = {0,}; + int ret = 0; + xlator_t *this = NULL; + dict_t *xdata = NULL; + + this = THIS; + + frame = myframe; + + if (-1 == req->rpc_status) { + rsp.op_ret = -1; + rsp.op_errno = ENOTCONN; + goto out; + } + ret = xdr_to_generic(*iov, &rsp, (xdrproc_t) xdr_gfs3_discard_rsp); + if (ret < 0) { + gf_log (this->name, GF_LOG_ERROR, "XDR decoding failed"); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; + } + + if (-1 != rsp.op_ret) { + gf_stat_to_iatt (&rsp.statpre, &prestat); + gf_stat_to_iatt (&rsp.statpost, &poststat); + } + + GF_PROTOCOL_DICT_UNSERIALIZE (this, xdata, (rsp.xdata.xdata_val), + (rsp.xdata.xdata_len), ret, + rsp.op_errno, out); + +out: + if (rsp.op_ret == -1) { + gf_log (this->name, GF_LOG_WARNING, "remote operation failed: %s", + strerror (gf_error_to_errno (rsp.op_errno))); + } + CLIENT_STACK_UNWIND (discard, frame, rsp.op_ret, + gf_error_to_errno (rsp.op_errno), &prestat, + &poststat, xdata); + + free (rsp.xdata.xdata_val); if (xdata) dict_unref (xdata); @@ -1909,9 +2047,64 @@ out: return 0; } +int +client3_3_zerofill_cbk(struct rpc_req *req, struct iovec *iov, int count, + void *myframe) +{ + call_frame_t *frame = NULL; + gfs3_zerofill_rsp rsp = {0,}; + struct iatt prestat = {0,}; + struct iatt poststat = {0,}; + int ret = 0; + xlator_t *this = NULL; + dict_t *xdata = NULL; + + this = THIS; + + frame = myframe; + + if (-1 == req->rpc_status) { + rsp.op_ret = -1; + rsp.op_errno = ENOTCONN; + goto out; + } + ret = xdr_to_generic(*iov, &rsp, (xdrproc_t) xdr_gfs3_zerofill_rsp); + if (ret < 0) { + gf_log (this->name, GF_LOG_ERROR, "XDR decoding failed"); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; + } + + if (-1 != rsp.op_ret) { + gf_stat_to_iatt (&rsp.statpre, &prestat); + gf_stat_to_iatt (&rsp.statpost, &poststat); + } + + GF_PROTOCOL_DICT_UNSERIALIZE (this, xdata, (rsp.xdata.xdata_val), + (rsp.xdata.xdata_len), ret, + rsp.op_errno, out); + +out: + if (rsp.op_ret == -1) { + gf_log (this->name, GF_LOG_WARNING, + "remote operation failed: %s", + strerror (gf_error_to_errno (rsp.op_errno))); + } + CLIENT_STACK_UNWIND (zerofill, frame, rsp.op_ret, + gf_error_to_errno (rsp.op_errno), &prestat, + &poststat, xdata); + + free (rsp.xdata.xdata_val); + + if (xdata) + dict_unref (xdata); + + return 0; +} int -client3_1_setattr_cbk (struct rpc_req *req, struct iovec *iov, int count, +client3_3_setattr_cbk (struct rpc_req *req, struct iovec *iov, int count, void *myframe) { call_frame_t *frame = NULL; @@ -1959,8 +2152,7 @@ out: gf_error_to_errno (rsp.op_errno), &prestat, &poststat, xdata); - if (rsp.xdata.xdata_val) - free (rsp.xdata.xdata_val); + free (rsp.xdata.xdata_val); if (xdata) dict_unref (xdata); @@ -1969,7 +2161,7 @@ out: } int -client3_1_create_cbk (struct rpc_req *req, struct iovec *iov, int count, +client3_3_create_cbk (struct rpc_req *req, struct iovec *iov, int count, void *myframe) { call_frame_t *frame = NULL; @@ -1980,8 +2172,6 @@ client3_1_create_cbk (struct rpc_req *req, struct iovec *iov, int count, 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; dict_t *xdata = NULL; @@ -1990,7 +2180,6 @@ client3_1_create_cbk (struct rpc_req *req, struct iovec *iov, int count, frame = myframe; local = frame->local; - conf = frame->this->private; fd = local->fd; inode = local->loc.inode; @@ -2013,31 +2202,14 @@ client3_1_create_cbk (struct rpc_req *req, struct iovec *iov, int count, 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) { + uuid_copy (local->loc.gfid, stbuf.ia_gfid); + ret = client_add_fd_to_saved_fds (frame->this, fd, &local->loc, + local->flags, rsp.fd, 0); + if (ret) { rsp.op_ret = -1; - rsp.op_errno = ENOMEM; + rsp.op_errno = -ret; goto out; } - - fdctx->remote_fd = rsp.fd; - fdctx->inode = inode_ref (inode); - fdctx->flags = local->flags; - fdctx->lk_ctx = fd_lk_ctx_ref (fd->lk_ctx); - fdctx->lk_heal_state = GF_LK_HEAL_DONE; - - 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); } GF_PROTOCOL_DICT_UNSERIALIZE (this, xdata, (rsp.xdata.xdata_val), @@ -2047,19 +2219,16 @@ client3_1_create_cbk (struct rpc_req *req, struct iovec *iov, int count, out: if (rsp.op_ret == -1) { gf_log (this->name, GF_LOG_WARNING, - "remote operation failed: %s. Path: %s (%s)", + "remote operation failed: %s. Path: %s", strerror (gf_error_to_errno (rsp.op_errno)), - (local) ? local->loc.path : "--", - (local && local->loc.inode) ? - uuid_utoa (local->loc.inode->gfid) : "--"); + local->loc.path); } CLIENT_STACK_UNWIND (create, frame, rsp.op_ret, gf_error_to_errno (rsp.op_errno), fd, inode, &stbuf, &preparent, &postparent, xdata); - if (rsp.xdata.xdata_val) - free (rsp.xdata.xdata_val); + free (rsp.xdata.xdata_val); if (xdata) dict_unref (xdata); @@ -2069,7 +2238,7 @@ out: int -client3_1_rchecksum_cbk (struct rpc_req *req, struct iovec *iov, int count, +client3_3_rchecksum_cbk (struct rpc_req *req, struct iovec *iov, int count, void *myframe) { call_frame_t *frame = NULL; @@ -2118,8 +2287,7 @@ out: free (rsp.strong_checksum.strong_checksum_val); } - if (rsp.xdata.xdata_val) - free (rsp.xdata.xdata_val); + free (rsp.xdata.xdata_val); if (xdata) dict_unref (xdata); @@ -2128,7 +2296,7 @@ out: } int -client3_1_lk_cbk (struct rpc_req *req, struct iovec *iov, int count, +client3_3_lk_cbk (struct rpc_req *req, struct iovec *iov, int count, void *myframe) { call_frame_t *frame = NULL; @@ -2191,11 +2359,9 @@ out: CLIENT_STACK_UNWIND (lk, frame, rsp.op_ret, gf_error_to_errno (rsp.op_errno), &lock, xdata); - if (rsp.xdata.xdata_val) - free (rsp.xdata.xdata_val); + free (rsp.xdata.xdata_val); - if (rsp.flock.lk_owner.lk_owner_val) - free (rsp.flock.lk_owner.lk_owner_val); + free (rsp.flock.lk_owner.lk_owner_val); if (xdata) dict_unref (xdata); @@ -2204,7 +2370,7 @@ out: } int -client3_1_readdir_cbk (struct rpc_req *req, struct iovec *iov, int count, +client3_3_readdir_cbk (struct rpc_req *req, struct iovec *iov, int count, void *myframe) { call_frame_t *frame = NULL; @@ -2258,8 +2424,7 @@ out: gf_dirent_free (&entries); } - if (rsp.xdata.xdata_val) - free (rsp.xdata.xdata_val); + free (rsp.xdata.xdata_val); if (xdata) dict_unref (xdata); @@ -2271,7 +2436,7 @@ out: int -client3_1_readdirp_cbk (struct rpc_req *req, struct iovec *iov, int count, +client3_3_readdirp_cbk (struct rpc_req *req, struct iovec *iov, int count, void *myframe) { call_frame_t *frame = NULL; @@ -2322,8 +2487,7 @@ out: if (rsp.op_ret != -1) { gf_dirent_free (&entries); } - if (rsp.xdata.xdata_val) - free (rsp.xdata.xdata_val); + free (rsp.xdata.xdata_val); if (xdata) dict_unref (xdata); @@ -2335,7 +2499,7 @@ out: int -client3_1_rename_cbk (struct rpc_req *req, struct iovec *iov, int count, +client3_3_rename_cbk (struct rpc_req *req, struct iovec *iov, int count, void *myframe) { call_frame_t *frame = NULL; @@ -2391,8 +2555,7 @@ out: &stbuf, &preoldparent, &postoldparent, &prenewparent, &postnewparent, xdata); - if (rsp.xdata.xdata_val) - free (rsp.xdata.xdata_val); + free (rsp.xdata.xdata_val); if (xdata) dict_unref (xdata); @@ -2401,7 +2564,7 @@ out: } int -client3_1_link_cbk (struct rpc_req *req, struct iovec *iov, int count, +client3_3_link_cbk (struct rpc_req *req, struct iovec *iov, int count, void *myframe) { call_frame_t *frame = NULL; @@ -2453,18 +2616,14 @@ out: gf_log (this->name, GF_LOG_WARNING, "remote operation failed: %s (%s -> %s)", strerror (gf_error_to_errno (rsp.op_errno)), - (local) ? ((local->loc.path)? local->loc.path : - uuid_utoa (local->loc.inode->gfid)) : "--", - (local) ? ((local->loc2.path)? local->loc2.path : - local->loc2.name) : "--"); + local->loc.path, local->loc2.path); } CLIENT_STACK_UNWIND (link, frame, rsp.op_ret, gf_error_to_errno (rsp.op_errno), inode, &stbuf, &preparent, &postparent, xdata); - if (rsp.xdata.xdata_val) - free (rsp.xdata.xdata_val); + free (rsp.xdata.xdata_val); if (xdata) dict_unref (xdata); @@ -2474,14 +2633,13 @@ out: int -client3_1_opendir_cbk (struct rpc_req *req, struct iovec *iov, int count, +client3_3_opendir_cbk (struct rpc_req *req, struct iovec *iov, int count, void *myframe) { clnt_local_t *local = NULL; clnt_conf_t *conf = NULL; - clnt_fd_ctx_t *fdctx = NULL; - call_frame_t *frame = NULL; - fd_t *fd = NULL; + call_frame_t *frame = NULL; + fd_t *fd = NULL; int ret = 0; gfs3_opendir_rsp rsp = {0,}; xlator_t *this = NULL; @@ -2510,28 +2668,13 @@ client3_1_opendir_cbk (struct rpc_req *req, struct iovec *iov, int count, } if (-1 != rsp.op_ret) { - fdctx = GF_CALLOC (1, sizeof (*fdctx), - gf_client_mt_clnt_fdctx_t); - if (!fdctx) { + 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 = ENOMEM; + rsp.op_errno = -ret; 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); } GF_PROTOCOL_DICT_UNSERIALIZE (this, xdata, (rsp.xdata.xdata_val), @@ -2543,15 +2686,12 @@ out: gf_log (this->name, GF_LOG_WARNING, "remote operation failed: %s. Path: %s (%s)", strerror (gf_error_to_errno (rsp.op_errno)), - (local) ? local->loc.path : "--", - (local && local->loc.inode) ? - uuid_utoa (local->loc.inode->gfid) : "--"); + local->loc.path, loc_gfid_utoa (&local->loc)); } CLIENT_STACK_UNWIND (opendir, frame, rsp.op_ret, gf_error_to_errno (rsp.op_errno), fd, xdata); - if (rsp.xdata.xdata_val) - free (rsp.xdata.xdata_val); + free (rsp.xdata.xdata_val); if (xdata) dict_unref (xdata); @@ -2561,7 +2701,7 @@ out: int -client3_1_lookup_cbk (struct rpc_req *req, struct iovec *iov, int count, +client3_3_lookup_cbk (struct rpc_req *req, struct iovec *iov, int count, void *myframe) { clnt_local_t *local = NULL; @@ -2626,10 +2766,8 @@ out: if (rsp.op_errno != ENOENT) gf_log (this->name, GF_LOG_WARNING, "remote operation failed: %s. Path: %s (%s)", - strerror (rsp.op_errno), - (local) ? local->loc.path : "--", - (local && local->loc.inode) ? - uuid_utoa (local->loc.inode->gfid) : "--"); + strerror (rsp.op_errno), local->loc.path, + loc_gfid_utoa (&local->loc)); else gf_log (this->name, GF_LOG_TRACE, "not found on remote node"); @@ -2641,14 +2779,13 @@ out: if (xdata) dict_unref (xdata); - if (rsp.xdata.xdata_val) - free (rsp.xdata.xdata_val); + free (rsp.xdata.xdata_val); return 0; } int -client3_1_readv_cbk (struct rpc_req *req, struct iovec *iov, int count, +client3_3_readv_cbk (struct rpc_req *req, struct iovec *iov, int count, void *myframe) { call_frame_t *frame = NULL; @@ -2704,13 +2841,15 @@ out: gf_log (this->name, GF_LOG_WARNING, "remote operation failed: %s", strerror (gf_error_to_errno (rsp.op_errno))); + } else if (rsp.op_ret >= 0) { + if (local->attempt_reopen) + client_attempt_reopen (local->fd, this); } CLIENT_STACK_UNWIND (readv, frame, rsp.op_ret, gf_error_to_errno (rsp.op_errno), vector, rspcount, &stat, iobref, xdata); - if (rsp.xdata.xdata_val) - free (rsp.xdata.xdata_val); + free (rsp.xdata.xdata_val); if (xdata) dict_unref (xdata); @@ -2719,7 +2858,7 @@ out: } int -client3_1_release_cbk (struct rpc_req *req, struct iovec *iov, int count, +client3_3_release_cbk (struct rpc_req *req, struct iovec *iov, int count, void *myframe) { call_frame_t *frame = NULL; @@ -2729,7 +2868,7 @@ client3_1_release_cbk (struct rpc_req *req, struct iovec *iov, int count, return 0; } int -client3_1_releasedir_cbk (struct rpc_req *req, struct iovec *iov, int count, +client3_3_releasedir_cbk (struct rpc_req *req, struct iovec *iov, int count, void *myframe) { call_frame_t *frame = NULL; @@ -2784,19 +2923,19 @@ client_fdctx_destroy (xlator_t *this, clnt_fd_ctx_t *fdctx) if (fdctx->is_dir) { gfs3_releasedir_req req = {{0,},}; req.fd = fdctx->remote_fd; - gf_log (this->name, GF_LOG_DEBUG, "sending releasedir on fd"); - client_submit_request (this, &req, fr, &clnt3_1_fop_prog, + gf_log (this->name, GF_LOG_TRACE, "sending releasedir on fd"); + client_submit_request (this, &req, fr, &clnt3_3_fop_prog, GFS3_OP_RELEASEDIR, - client3_1_releasedir_cbk, + client3_3_releasedir_cbk, NULL, NULL, 0, NULL, 0, NULL, (xdrproc_t)xdr_gfs3_releasedir_req); } else { gfs3_release_req req = {{0,},}; req.fd = fdctx->remote_fd; - gf_log (this->name, GF_LOG_DEBUG, "sending release on fd"); - client_submit_request (this, &req, fr, &clnt3_1_fop_prog, + gf_log (this->name, GF_LOG_TRACE, "sending release on fd"); + client_submit_request (this, &req, fr, &clnt3_3_fop_prog, GFS3_OP_RELEASE, - client3_1_release_cbk, NULL, + client3_3_release_cbk, NULL, NULL, 0, NULL, 0, NULL, (xdrproc_t)xdr_gfs3_release_req); } @@ -2805,7 +2944,6 @@ client_fdctx_destroy (xlator_t *this, clnt_fd_ctx_t *fdctx) out: if (fdctx) { fdctx->remote_fd = -1; - inode_unref (fdctx->inode); GF_FREE (fdctx); } @@ -2816,7 +2954,7 @@ out: } int32_t -client3_1_releasedir (call_frame_t *frame, xlator_t *this, +client3_3_releasedir (call_frame_t *frame, xlator_t *this, void *data) { clnt_conf_t *conf = NULL; @@ -2857,7 +2995,7 @@ out: } int32_t -client3_1_release (call_frame_t *frame, xlator_t *this, +client3_3_release (call_frame_t *frame, xlator_t *this, void *data) { int64_t remote_fd = -1; @@ -2901,7 +3039,7 @@ out: int32_t -client3_1_lookup (call_frame_t *frame, xlator_t *this, +client3_3_lookup (call_frame_t *frame, xlator_t *this, void *data) { clnt_conf_t *conf = NULL; @@ -2934,6 +3072,7 @@ client3_1_lookup (call_frame_t *frame, xlator_t *this, goto unwind; loc_copy (&local->loc, args->loc); + loc_path (&local->loc, NULL); frame->local = local; if (args->loc->parent) { @@ -2987,7 +3126,7 @@ client3_1_lookup (call_frame_t *frame, xlator_t *this, req.bname = ""; ret = client_submit_request (this, &req, frame, conf->fops, - GFS3_OP_LOOKUP, client3_1_lookup_cbk, + GFS3_OP_LOOKUP, client3_3_lookup_cbk, NULL, rsphdr, count, NULL, 0, local->iobref, (xdrproc_t)xdr_gfs3_lookup_req); @@ -2996,8 +3135,7 @@ client3_1_lookup (call_frame_t *frame, xlator_t *this, gf_log (this->name, GF_LOG_WARNING, "failed to send the fop"); } - if (req.xdata.xdata_val) - GF_FREE (req.xdata.xdata_val); + GF_FREE (req.xdata.xdata_val); if (rsp_iobref) iobref_unref (rsp_iobref); @@ -3011,8 +3149,7 @@ unwind: CLIENT_STACK_UNWIND (lookup, frame, -1, op_errno, NULL, NULL, NULL, NULL); - if (req.xdata.xdata_val) - GF_FREE (req.xdata.xdata_val); + GF_FREE (req.xdata.xdata_val); if (rsp_iobref) iobref_unref (rsp_iobref); @@ -3024,7 +3161,7 @@ unwind: } int32_t -client3_1_stat (call_frame_t *frame, xlator_t *this, +client3_3_stat (call_frame_t *frame, xlator_t *this, void *data) { clnt_conf_t *conf = NULL; @@ -3054,29 +3191,27 @@ client3_1_stat (call_frame_t *frame, xlator_t *this, req.xdata.xdata_len, op_errno, unwind); ret = client_submit_request (this, &req, frame, conf->fops, - GFS3_OP_STAT, client3_1_stat_cbk, NULL, + GFS3_OP_STAT, client3_3_stat_cbk, NULL, NULL, 0, NULL, 0, NULL, (xdrproc_t)xdr_gfs3_stat_req); if (ret) { gf_log (this->name, GF_LOG_WARNING, "failed to send the fop"); } - if (req.xdata.xdata_val) - GF_FREE (req.xdata.xdata_val); + GF_FREE (req.xdata.xdata_val); return 0; unwind: CLIENT_STACK_UNWIND (stat, frame, -1, op_errno, NULL, NULL); - if (req.xdata.xdata_val) - GF_FREE (req.xdata.xdata_val); + GF_FREE (req.xdata.xdata_val); return 0; } int32_t -client3_1_truncate (call_frame_t *frame, xlator_t *this, +client3_3_truncate (call_frame_t *frame, xlator_t *this, void *data) { clnt_conf_t *conf = NULL; @@ -3110,28 +3245,26 @@ client3_1_truncate (call_frame_t *frame, xlator_t *this, ret = client_submit_request (this, &req, frame, conf->fops, GFS3_OP_TRUNCATE, - client3_1_truncate_cbk, NULL, + client3_3_truncate_cbk, NULL, NULL, 0, NULL, 0, NULL, (xdrproc_t)xdr_gfs3_truncate_req); if (ret) { gf_log (this->name, GF_LOG_WARNING, "failed to send the fop"); } - if (req.xdata.xdata_val) - GF_FREE (req.xdata.xdata_val); + GF_FREE (req.xdata.xdata_val); return 0; unwind: CLIENT_STACK_UNWIND (truncate, frame, -1, op_errno, NULL, NULL, NULL); - if (req.xdata.xdata_val) - GF_FREE (req.xdata.xdata_val); + GF_FREE (req.xdata.xdata_val); return 0; } int32_t -client3_1_ftruncate (call_frame_t *frame, xlator_t *this, +client3_3_ftruncate (call_frame_t *frame, xlator_t *this, void *data) { clnt_args_t *args = NULL; @@ -3148,7 +3281,8 @@ client3_1_ftruncate (call_frame_t *frame, xlator_t *this, conf = this->private; - CLIENT_GET_REMOTE_FD(conf, args->fd, remote_fd, op_errno, unwind); + CLIENT_GET_REMOTE_FD (this, args->fd, DEFAULT_REMOTE_FD, + remote_fd, op_errno, unwind); req.offset = args->offset; req.fd = remote_fd; @@ -3159,21 +3293,19 @@ client3_1_ftruncate (call_frame_t *frame, xlator_t *this, ret = client_submit_request (this, &req, frame, conf->fops, GFS3_OP_FTRUNCATE, - client3_1_ftruncate_cbk, NULL, + client3_3_ftruncate_cbk, NULL, NULL, 0, NULL, 0, NULL, (xdrproc_t)xdr_gfs3_ftruncate_req); if (ret) { gf_log (this->name, GF_LOG_WARNING, "failed to send the fop"); } - if (req.xdata.xdata_val) - GF_FREE (req.xdata.xdata_val); + GF_FREE (req.xdata.xdata_val); return 0; unwind: CLIENT_STACK_UNWIND (ftruncate, frame, -1, op_errno, NULL, NULL, NULL); - if (req.xdata.xdata_val) - GF_FREE (req.xdata.xdata_val); + GF_FREE (req.xdata.xdata_val); return 0; } @@ -3181,7 +3313,7 @@ unwind: int32_t -client3_1_access (call_frame_t *frame, xlator_t *this, +client3_3_access (call_frame_t *frame, xlator_t *this, void *data) { clnt_conf_t *conf = NULL; @@ -3215,34 +3347,38 @@ client3_1_access (call_frame_t *frame, xlator_t *this, ret = client_submit_request (this, &req, frame, conf->fops, GFS3_OP_ACCESS, - client3_1_access_cbk, NULL, + client3_3_access_cbk, NULL, NULL, 0, NULL, 0, NULL, (xdrproc_t)xdr_gfs3_access_req); if (ret) { gf_log (this->name, GF_LOG_WARNING, "failed to send the fop"); } - if (req.xdata.xdata_val) - GF_FREE (req.xdata.xdata_val); + GF_FREE (req.xdata.xdata_val); return 0; unwind: CLIENT_STACK_UNWIND (access, frame, -1, op_errno, NULL); - if (req.xdata.xdata_val) - GF_FREE (req.xdata.xdata_val); + GF_FREE (req.xdata.xdata_val); return 0; } int32_t -client3_1_readlink (call_frame_t *frame, xlator_t *this, +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_conf_t *conf = NULL; + clnt_args_t *args = NULL; + gfs3_readlink_req req = {{0,},}; + int ret = 0; + int op_errno = ESTALE; + clnt_local_t *local = NULL; + struct iobuf *rsp_iobuf = NULL; + struct iobref *rsp_iobref = NULL; + struct iovec *rsphdr = NULL; + int count = 0; + struct iovec vector[MAX_IOVEC] = {{0}, }; if (!frame || !this || !data) goto unwind; @@ -3263,26 +3399,57 @@ client3_1_readlink (call_frame_t *frame, xlator_t *this, req.size = args->size; conf = this->private; + local = mem_get0 (this->local_pool); + if (!local) { + op_errno = ENOMEM; + goto unwind; + } + + frame->local = local; + GF_PROTOCOL_DICT_SERIALIZE (this, args->xdata, (&req.xdata.xdata_val), req.xdata.xdata_len, op_errno, unwind); + rsp_iobref = iobref_new (); + if (rsp_iobref == NULL) { + goto unwind; + } + + rsp_iobuf = iobuf_get (this->ctx->iobuf_pool); + if (rsp_iobuf == NULL) { + goto unwind; + } + + iobref_add (rsp_iobref, rsp_iobuf); + iobuf_unref (rsp_iobuf); + rsphdr = &vector[0]; + rsphdr->iov_base = iobuf_ptr (rsp_iobuf); + rsphdr->iov_len = iobuf_pagesize (rsp_iobuf); + count = 1; + local->iobref = rsp_iobref; + rsp_iobuf = NULL; + rsp_iobref = NULL; + ret = client_submit_request (this, &req, frame, conf->fops, GFS3_OP_READLINK, - client3_1_readlink_cbk, NULL, - NULL, 0, NULL, 0, - NULL, (xdrproc_t)xdr_gfs3_readlink_req); + client3_3_readlink_cbk, NULL, + rsphdr, count, NULL, 0, + local->iobref, + (xdrproc_t)xdr_gfs3_readlink_req); if (ret) { gf_log (this->name, GF_LOG_WARNING, "failed to send the fop"); } - if (req.xdata.xdata_val) - GF_FREE (req.xdata.xdata_val); + 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); - if (req.xdata.xdata_val) - GF_FREE (req.xdata.xdata_val); + GF_FREE (req.xdata.xdata_val); return 0; } @@ -3291,7 +3458,7 @@ unwind: int32_t -client3_1_unlink (call_frame_t *frame, xlator_t *this, +client3_3_unlink (call_frame_t *frame, xlator_t *this, void *data) { clnt_conf_t *conf = NULL; @@ -3324,21 +3491,19 @@ client3_1_unlink (call_frame_t *frame, xlator_t *this, ret = client_submit_request (this, &req, frame, conf->fops, GFS3_OP_UNLINK, - client3_1_unlink_cbk, NULL, + client3_3_unlink_cbk, NULL, NULL, 0, NULL, 0, NULL, (xdrproc_t)xdr_gfs3_unlink_req); if (ret) { gf_log (this->name, GF_LOG_WARNING, "failed to send the fop"); } - if (req.xdata.xdata_val) - GF_FREE (req.xdata.xdata_val); + GF_FREE (req.xdata.xdata_val); return 0; unwind: CLIENT_STACK_UNWIND (unlink, frame, -1, op_errno, NULL, NULL, NULL); - if (req.xdata.xdata_val) - GF_FREE (req.xdata.xdata_val); + GF_FREE (req.xdata.xdata_val); return 0; } @@ -3346,7 +3511,7 @@ unwind: int32_t -client3_1_rmdir (call_frame_t *frame, xlator_t *this, +client3_3_rmdir (call_frame_t *frame, xlator_t *this, void *data) { clnt_conf_t *conf = NULL; @@ -3379,20 +3544,18 @@ client3_1_rmdir (call_frame_t *frame, xlator_t *this, req.xdata.xdata_len, op_errno, unwind); ret = client_submit_request (this, &req, frame, conf->fops, - GFS3_OP_RMDIR, client3_1_rmdir_cbk, NULL, + GFS3_OP_RMDIR, client3_3_rmdir_cbk, NULL, NULL, 0, NULL, 0, NULL, (xdrproc_t)xdr_gfs3_rmdir_req); if (ret) { gf_log (this->name, GF_LOG_WARNING, "failed to send the fop"); } - if (req.xdata.xdata_val) - GF_FREE (req.xdata.xdata_val); + GF_FREE (req.xdata.xdata_val); return 0; unwind: CLIENT_STACK_UNWIND (rmdir, frame, -1, op_errno, NULL, NULL, NULL); - if (req.xdata.xdata_val) - GF_FREE (req.xdata.xdata_val); + GF_FREE (req.xdata.xdata_val); return 0; } @@ -3400,7 +3563,7 @@ unwind: int32_t -client3_1_symlink (call_frame_t *frame, xlator_t *this, +client3_3_symlink (call_frame_t *frame, xlator_t *this, void *data) { clnt_local_t *local = NULL; @@ -3426,6 +3589,7 @@ client3_1_symlink (call_frame_t *frame, xlator_t *this, goto unwind; loc_copy (&local->loc, args->loc); + loc_path (&local->loc, NULL); if (!uuid_is_null (args->loc->parent->gfid)) memcpy (req.pargfid, args->loc->parent->gfid, 16); @@ -3446,15 +3610,14 @@ client3_1_symlink (call_frame_t *frame, xlator_t *this, req.xdata.xdata_len, op_errno, unwind); ret = client_submit_request (this, &req, frame, conf->fops, - GFS3_OP_SYMLINK, client3_1_symlink_cbk, + GFS3_OP_SYMLINK, client3_3_symlink_cbk, NULL, NULL, 0, NULL, 0, NULL, (xdrproc_t)xdr_gfs3_symlink_req); if (ret) { gf_log (this->name, GF_LOG_WARNING, "failed to send the fop"); } - if (req.xdata.xdata_val) - GF_FREE (req.xdata.xdata_val); + GF_FREE (req.xdata.xdata_val); return 0; unwind: @@ -3462,8 +3625,7 @@ unwind: CLIENT_STACK_UNWIND (symlink, frame, -1, op_errno, NULL, NULL, NULL, NULL, NULL); - if (req.xdata.xdata_val) - GF_FREE (req.xdata.xdata_val); + GF_FREE (req.xdata.xdata_val); return 0; } @@ -3471,7 +3633,7 @@ unwind: int32_t -client3_1_rename (call_frame_t *frame, xlator_t *this, +client3_3_rename (call_frame_t *frame, xlator_t *this, void *data) { clnt_conf_t *conf = NULL; @@ -3513,23 +3675,21 @@ client3_1_rename (call_frame_t *frame, xlator_t *this, req.xdata.xdata_len, op_errno, unwind); ret = client_submit_request (this, &req, frame, conf->fops, - GFS3_OP_RENAME, client3_1_rename_cbk, NULL, + GFS3_OP_RENAME, client3_3_rename_cbk, NULL, NULL, 0, NULL, 0, NULL, (xdrproc_t)xdr_gfs3_rename_req); if (ret) { gf_log (this->name, GF_LOG_WARNING, "failed to send the fop"); } - if (req.xdata.xdata_val) - GF_FREE (req.xdata.xdata_val); + GF_FREE (req.xdata.xdata_val); return 0; unwind: CLIENT_STACK_UNWIND (rename, frame, -1, op_errno, NULL, NULL, NULL, NULL, NULL, NULL); - if (req.xdata.xdata_val) - GF_FREE (req.xdata.xdata_val); + GF_FREE (req.xdata.xdata_val); return 0; } @@ -3537,7 +3697,7 @@ unwind: int32_t -client3_1_link (call_frame_t *frame, xlator_t *this, +client3_3_link (call_frame_t *frame, xlator_t *this, void *data) { clnt_local_t *local = NULL; @@ -3579,7 +3739,9 @@ client3_1_link (call_frame_t *frame, xlator_t *this, } loc_copy (&local->loc, args->oldloc); + loc_path (&local->loc, NULL); loc_copy (&local->loc2, args->newloc); + loc_path (&local->loc2, NULL); frame->local = local; req.newbname = (char *)args->newloc->name; @@ -3589,21 +3751,19 @@ client3_1_link (call_frame_t *frame, xlator_t *this, req.xdata.xdata_len, op_errno, unwind); ret = client_submit_request (this, &req, frame, conf->fops, - GFS3_OP_LINK, client3_1_link_cbk, NULL, + GFS3_OP_LINK, client3_3_link_cbk, NULL, NULL, 0, NULL, 0, NULL, (xdrproc_t)xdr_gfs3_link_req); if (ret) { gf_log (this->name, GF_LOG_WARNING, "failed to send the fop"); } - if (req.xdata.xdata_val) - GF_FREE (req.xdata.xdata_val); + GF_FREE (req.xdata.xdata_val); return 0; unwind: CLIENT_STACK_UNWIND (link, frame, -1, op_errno, NULL, NULL, NULL, NULL, NULL); - if (req.xdata.xdata_val) - GF_FREE (req.xdata.xdata_val); + GF_FREE (req.xdata.xdata_val); return 0; } @@ -3611,7 +3771,7 @@ unwind: int32_t -client3_1_mknod (call_frame_t *frame, xlator_t *this, +client3_3_mknod (call_frame_t *frame, xlator_t *this, void *data) { clnt_local_t *local = NULL; @@ -3636,6 +3796,7 @@ client3_1_mknod (call_frame_t *frame, xlator_t *this, goto unwind; loc_copy (&local->loc, args->loc); + loc_path (&local->loc, NULL); frame->local = local; if (!uuid_is_null (args->loc->parent->gfid)) @@ -3657,22 +3818,20 @@ client3_1_mknod (call_frame_t *frame, xlator_t *this, req.xdata.xdata_len, op_errno, unwind); ret = client_submit_request (this, &req, frame, conf->fops, - GFS3_OP_MKNOD, client3_1_mknod_cbk, NULL, + GFS3_OP_MKNOD, client3_3_mknod_cbk, NULL, NULL, 0, NULL, 0, NULL, (xdrproc_t)xdr_gfs3_mknod_req); if (ret) { gf_log (this->name, GF_LOG_WARNING, "failed to send the fop"); } - if (req.xdata.xdata_val) - GF_FREE (req.xdata.xdata_val); + GF_FREE (req.xdata.xdata_val); return 0; unwind: CLIENT_STACK_UNWIND (mknod, frame, -1, op_errno, NULL, NULL, NULL, NULL, NULL); - if (req.xdata.xdata_val) - GF_FREE (req.xdata.xdata_val); + GF_FREE (req.xdata.xdata_val); return 0; } @@ -3680,7 +3839,7 @@ unwind: int32_t -client3_1_mkdir (call_frame_t *frame, xlator_t *this, +client3_3_mkdir (call_frame_t *frame, xlator_t *this, void *data) { clnt_local_t *local = NULL; @@ -3705,6 +3864,7 @@ client3_1_mkdir (call_frame_t *frame, xlator_t *this, goto unwind; loc_copy (&local->loc, args->loc); + loc_path (&local->loc, NULL); frame->local = local; if (!uuid_is_null (args->loc->parent->gfid)) @@ -3726,29 +3886,27 @@ client3_1_mkdir (call_frame_t *frame, xlator_t *this, req.xdata.xdata_len, op_errno, unwind); ret = client_submit_request (this, &req, frame, conf->fops, - GFS3_OP_MKDIR, client3_1_mkdir_cbk, NULL, + GFS3_OP_MKDIR, client3_3_mkdir_cbk, NULL, NULL, 0, NULL, 0, NULL, (xdrproc_t)xdr_gfs3_mkdir_req); if (ret) { gf_log (this->name, GF_LOG_WARNING, "failed to send the fop"); } - if (req.xdata.xdata_val) - GF_FREE (req.xdata.xdata_val); + GF_FREE (req.xdata.xdata_val); return 0; unwind: CLIENT_STACK_UNWIND (mkdir, frame, -1, op_errno, NULL, NULL, NULL, NULL, NULL); - if (req.xdata.xdata_val) - GF_FREE (req.xdata.xdata_val); + GF_FREE (req.xdata.xdata_val); return 0; } int32_t -client3_1_create (call_frame_t *frame, xlator_t *this, +client3_3_create (call_frame_t *frame, xlator_t *this, void *data) { clnt_local_t *local = NULL; @@ -3775,6 +3933,7 @@ client3_1_create (call_frame_t *frame, xlator_t *this, local->flags = args->flags; loc_copy (&local->loc, args->loc); + loc_path (&local->loc, NULL); frame->local = local; if (!uuid_is_null (args->loc->parent->gfid)) @@ -3796,23 +3955,21 @@ client3_1_create (call_frame_t *frame, xlator_t *this, req.xdata.xdata_len, op_errno, unwind); ret = client_submit_request (this, &req, frame, conf->fops, - GFS3_OP_CREATE, client3_1_create_cbk, NULL, + GFS3_OP_CREATE, client3_3_create_cbk, NULL, NULL, 0, NULL, 0, NULL, (xdrproc_t)xdr_gfs3_create_req); if (ret) { gf_log (this->name, GF_LOG_WARNING, "failed to send the fop"); } - if (req.xdata.xdata_val) - GF_FREE (req.xdata.xdata_val); + GF_FREE (req.xdata.xdata_val); return 0; unwind: CLIENT_STACK_UNWIND (create, frame, -1, op_errno, NULL, NULL, NULL, NULL, NULL, NULL); - if (req.xdata.xdata_val) - GF_FREE (req.xdata.xdata_val); + GF_FREE (req.xdata.xdata_val); return 0; } @@ -3820,7 +3977,7 @@ unwind: int32_t -client3_1_open (call_frame_t *frame, xlator_t *this, +client3_3_open (call_frame_t *frame, xlator_t *this, void *data) { clnt_local_t *local = NULL; @@ -3846,6 +4003,7 @@ client3_1_open (call_frame_t *frame, xlator_t *this, local->fd = fd_ref (args->fd); local->flags = args->flags; loc_copy (&local->loc, args->loc); + loc_path (&local->loc, NULL); frame->local = local; if (!uuid_is_null (args->loc->inode->gfid)) @@ -3864,22 +4022,20 @@ client3_1_open (call_frame_t *frame, xlator_t *this, req.xdata.xdata_len, op_errno, unwind); ret = client_submit_request (this, &req, frame, conf->fops, - GFS3_OP_OPEN, client3_1_open_cbk, NULL, + GFS3_OP_OPEN, client3_3_open_cbk, NULL, NULL, 0, NULL, 0, NULL, (xdrproc_t)xdr_gfs3_open_req); if (ret) { gf_log (this->name, GF_LOG_WARNING, "failed to send the fop"); } - if (req.xdata.xdata_val) - GF_FREE (req.xdata.xdata_val); + GF_FREE (req.xdata.xdata_val); return 0; unwind: CLIENT_STACK_UNWIND (open, frame, -1, op_errno, NULL, NULL); - if (req.xdata.xdata_val) - GF_FREE (req.xdata.xdata_val); + GF_FREE (req.xdata.xdata_val); return 0; } @@ -3887,19 +4043,19 @@ unwind: int32_t -client3_1_readv (call_frame_t *frame, xlator_t *this, +client3_3_readv (call_frame_t *frame, xlator_t *this, void *data) { clnt_args_t *args = NULL; int64_t remote_fd = -1; clnt_conf_t *conf = NULL; + clnt_local_t *local = NULL; int op_errno = ESTALE; gfs3_read_req req = {{0,},}; int ret = 0; struct iovec rsp_vec = {0, }; struct iobuf *rsp_iobuf = NULL; struct iobref *rsp_iobref = NULL; - clnt_local_t *local = NULL; if (!frame || !this || !data) goto unwind; @@ -3907,7 +4063,14 @@ client3_1_readv (call_frame_t *frame, xlator_t *this, args = data; conf = this->private; - CLIENT_GET_REMOTE_FD(conf, args->fd, remote_fd, op_errno, unwind); + CLIENT_GET_REMOTE_FD (this, args->fd, FALLBACK_TO_ANON_FD, + remote_fd, op_errno, unwind); + ret = client_fd_fop_prepare_local (frame, args->fd, remote_fd); + if (ret) { + op_errno = -ret; + goto unwind; + } + local = frame->local; req.size = args->size; req.offset = args->offset; @@ -3945,36 +4108,23 @@ client3_1_readv (call_frame_t *frame, xlator_t *this, goto unwind; } - local = mem_get0 (this->local_pool); - if (local == NULL) { - op_errno = ENOMEM; - goto unwind; - } - local->iobref = rsp_iobref; rsp_iobref = NULL; - frame->local = local; GF_PROTOCOL_DICT_SERIALIZE (this, args->xdata, (&req.xdata.xdata_val), req.xdata.xdata_len, op_errno, unwind); ret = client_submit_request (this, &req, frame, conf->fops, - GFS3_OP_READ, client3_1_readv_cbk, NULL, + GFS3_OP_READ, client3_3_readv_cbk, NULL, NULL, 0, &rsp_vec, 1, local->iobref, (xdrproc_t)xdr_gfs3_read_req); if (ret) { + //unwind is done in the cbk gf_log (this->name, GF_LOG_WARNING, "failed to send the fop"); } - if (req.xdata.xdata_val) - GF_FREE (req.xdata.xdata_val); - - if (rsp_iobuf) - iobuf_unref (rsp_iobuf); - - if (rsp_iobref) - iobref_unref (rsp_iobref); + GF_FREE (req.xdata.xdata_val); return 0; unwind: @@ -3985,22 +4135,21 @@ unwind: iobref_unref (rsp_iobref); CLIENT_STACK_UNWIND (readv, frame, -1, op_errno, NULL, 0, NULL, NULL, NULL); - if (req.xdata.xdata_val) - GF_FREE (req.xdata.xdata_val); + GF_FREE (req.xdata.xdata_val); return 0; } int32_t -client3_1_writev (call_frame_t *frame, xlator_t *this, void *data) +client3_3_writev (call_frame_t *frame, xlator_t *this, void *data) { clnt_args_t *args = NULL; int64_t remote_fd = -1; clnt_conf_t *conf = NULL; gfs3_write_req req = {{0,},}; int op_errno = ESTALE; - int ret = 0; + int ret = 0; if (!frame || !this || !data) goto unwind; @@ -4008,7 +4157,13 @@ client3_1_writev (call_frame_t *frame, xlator_t *this, void *data) args = data; conf = this->private; - CLIENT_GET_REMOTE_FD(conf, args->fd, remote_fd, op_errno, unwind); + CLIENT_GET_REMOTE_FD (this, args->fd, FALLBACK_TO_ANON_FD, + remote_fd, op_errno, unwind); + ret = client_fd_fop_prepare_local (frame, args->fd, remote_fd); + if (ret) { + op_errno = -ret; + goto unwind; + } req.size = args->size; req.offset = args->offset; @@ -4029,7 +4184,7 @@ client3_1_writev (call_frame_t *frame, xlator_t *this, void *data) req.xdata.xdata_len, op_errno, unwind); ret = client_submit_vec_request (this, &req, frame, conf->fops, - GFS3_OP_WRITE, client3_1_writev_cbk, + GFS3_OP_WRITE, client3_3_writev_cbk, args->vector, args->count, args->iobref, (xdrproc_t)xdr_gfs3_write_req); @@ -4042,22 +4197,20 @@ client3_1_writev (call_frame_t *frame, xlator_t *this, void *data) gf_log (this->name, GF_LOG_WARNING, "failed to send the fop"); } - if (req.xdata.xdata_val) - GF_FREE (req.xdata.xdata_val); + GF_FREE (req.xdata.xdata_val); return 0; unwind: CLIENT_STACK_UNWIND (writev, frame, -1, op_errno, NULL, NULL, NULL); - if (req.xdata.xdata_val) - GF_FREE (req.xdata.xdata_val); + GF_FREE (req.xdata.xdata_val); return 0; } int32_t -client3_1_flush (call_frame_t *frame, xlator_t *this, +client3_3_flush (call_frame_t *frame, xlator_t *this, void *data) { clnt_args_t *args = NULL; @@ -4074,7 +4227,8 @@ client3_1_flush (call_frame_t *frame, xlator_t *this, args = data; conf = this->private; - CLIENT_GET_REMOTE_FD(conf, args->fd, remote_fd, op_errno, unwind); + CLIENT_GET_REMOTE_FD (this, args->fd, DEFAULT_REMOTE_FD, + remote_fd, op_errno, unwind); conf = this->private; @@ -4095,23 +4249,21 @@ client3_1_flush (call_frame_t *frame, xlator_t *this, req.xdata.xdata_len, op_errno, unwind); ret = client_submit_request (this, &req, frame, conf->fops, - GFS3_OP_FLUSH, client3_1_flush_cbk, NULL, + GFS3_OP_FLUSH, client3_3_flush_cbk, NULL, NULL, 0, NULL, 0, NULL, (xdrproc_t)xdr_gfs3_flush_req); if (ret) { gf_log (this->name, GF_LOG_WARNING, "failed to send the fop"); } - if (req.xdata.xdata_val) - GF_FREE (req.xdata.xdata_val); + GF_FREE (req.xdata.xdata_val); return 0; unwind: CLIENT_STACK_UNWIND (flush, frame, -1, op_errno, NULL); - if (req.xdata.xdata_val) - GF_FREE (req.xdata.xdata_val); + GF_FREE (req.xdata.xdata_val); return 0; } @@ -4119,7 +4271,7 @@ unwind: int32_t -client3_1_fsync (call_frame_t *frame, xlator_t *this, +client3_3_fsync (call_frame_t *frame, xlator_t *this, void *data) { clnt_args_t *args = NULL; @@ -4135,15 +4287,18 @@ client3_1_fsync (call_frame_t *frame, xlator_t *this, args = data; conf = this->private; - CLIENT_GET_REMOTE_FD(conf, args->fd, remote_fd, op_errno, unwind); + CLIENT_GET_REMOTE_FD (this, args->fd, DEFAULT_REMOTE_FD, + remote_fd, op_errno, unwind); req.fd = remote_fd; req.data = args->flags; memcpy (req.gfid, args->fd->inode->gfid, 16); + GF_PROTOCOL_DICT_SERIALIZE (this, args->xdata, (&req.xdata.xdata_val), + req.xdata.xdata_len, op_errno, unwind); ret = client_submit_request (this, &req, frame, conf->fops, - GFS3_OP_FSYNC, client3_1_fsync_cbk, NULL, + GFS3_OP_FSYNC, client3_3_fsync_cbk, NULL, NULL, 0, NULL, 0, NULL, (xdrproc_t)xdr_gfs3_fsync_req); if (ret) { @@ -4151,15 +4306,13 @@ client3_1_fsync (call_frame_t *frame, xlator_t *this, } - if (req.xdata.xdata_val) - GF_FREE (req.xdata.xdata_val); + GF_FREE (req.xdata.xdata_val); return 0; unwind: CLIENT_STACK_UNWIND (fsync, frame, -1, op_errno, NULL, NULL, NULL); - if (req.xdata.xdata_val) - GF_FREE (req.xdata.xdata_val); + GF_FREE (req.xdata.xdata_val); return 0; } @@ -4167,7 +4320,7 @@ unwind: int32_t -client3_1_fstat (call_frame_t *frame, xlator_t *this, +client3_3_fstat (call_frame_t *frame, xlator_t *this, void *data) { clnt_args_t *args = NULL; @@ -4183,7 +4336,8 @@ client3_1_fstat (call_frame_t *frame, xlator_t *this, args = data; conf = this->private; - CLIENT_GET_REMOTE_FD(conf, args->fd, remote_fd, op_errno, unwind); + CLIENT_GET_REMOTE_FD (this, args->fd, DEFAULT_REMOTE_FD, + remote_fd, op_errno, unwind); req.fd = remote_fd; memcpy (req.gfid, args->fd->inode->gfid, 16); @@ -4192,22 +4346,20 @@ client3_1_fstat (call_frame_t *frame, xlator_t *this, req.xdata.xdata_len, op_errno, unwind); ret = client_submit_request (this, &req, frame, conf->fops, - GFS3_OP_FSTAT, client3_1_fstat_cbk, NULL, + GFS3_OP_FSTAT, client3_3_fstat_cbk, NULL, NULL, 0, NULL, 0, NULL, (xdrproc_t)xdr_gfs3_fstat_req); if (ret) { gf_log (this->name, GF_LOG_WARNING, "failed to send the fop"); } - if (req.xdata.xdata_val) - GF_FREE (req.xdata.xdata_val); + GF_FREE (req.xdata.xdata_val); return 0; unwind: CLIENT_STACK_UNWIND (fstat, frame, -1, op_errno, NULL, NULL); - if (req.xdata.xdata_val) - GF_FREE (req.xdata.xdata_val); + GF_FREE (req.xdata.xdata_val); return 0; } @@ -4215,7 +4367,7 @@ unwind: int32_t -client3_1_opendir (call_frame_t *frame, xlator_t *this, +client3_3_opendir (call_frame_t *frame, xlator_t *this, void *data) { clnt_local_t *local = NULL; @@ -4240,6 +4392,7 @@ client3_1_opendir (call_frame_t *frame, xlator_t *this, local->fd = fd_ref (args->fd); loc_copy (&local->loc, args->loc); + loc_path (&local->loc, NULL); frame->local = local; if (!uuid_is_null (args->loc->inode->gfid)) @@ -4253,24 +4406,25 @@ client3_1_opendir (call_frame_t *frame, xlator_t *this, conf = this->private; + GF_PROTOCOL_DICT_SERIALIZE (this, args->xdata, (&req.xdata.xdata_val), + req.xdata.xdata_len, op_errno, unwind); + ret = client_submit_request (this, &req, frame, conf->fops, - GFS3_OP_OPENDIR, client3_1_opendir_cbk, + GFS3_OP_OPENDIR, client3_3_opendir_cbk, NULL, NULL, 0, NULL, 0, NULL, (xdrproc_t)xdr_gfs3_opendir_req); if (ret) { gf_log (this->name, GF_LOG_WARNING, "failed to send the fop"); } - if (req.xdata.xdata_val) - GF_FREE (req.xdata.xdata_val); + GF_FREE (req.xdata.xdata_val); return 0; unwind: CLIENT_STACK_UNWIND (opendir, frame, -1, op_errno, NULL, NULL); - if (req.xdata.xdata_val) - GF_FREE (req.xdata.xdata_val); + GF_FREE (req.xdata.xdata_val); return 0; } @@ -4278,7 +4432,7 @@ unwind: int32_t -client3_1_fsyncdir (call_frame_t *frame, xlator_t *this, void *data) +client3_3_fsyncdir (call_frame_t *frame, xlator_t *this, void *data) { clnt_args_t *args = NULL; int64_t remote_fd = -1; @@ -4293,7 +4447,8 @@ client3_1_fsyncdir (call_frame_t *frame, xlator_t *this, void *data) args = data; conf = this->private; - CLIENT_GET_REMOTE_FD(conf, args->fd, remote_fd, op_errno, unwind); + CLIENT_GET_REMOTE_FD (this, args->fd, DEFAULT_REMOTE_FD, + remote_fd, op_errno, unwind); req.fd = remote_fd; req.data = args->flags; @@ -4305,7 +4460,7 @@ client3_1_fsyncdir (call_frame_t *frame, xlator_t *this, void *data) req.xdata.xdata_len, op_errno, unwind); ret = client_submit_request (this, &req, frame, conf->fops, - GFS3_OP_FSYNCDIR, client3_1_fsyncdir_cbk, + GFS3_OP_FSYNCDIR, client3_3_fsyncdir_cbk, NULL, NULL, 0, NULL, 0, NULL, (xdrproc_t)xdr_gfs3_fsyncdir_req); @@ -4313,15 +4468,13 @@ client3_1_fsyncdir (call_frame_t *frame, xlator_t *this, void *data) gf_log (this->name, GF_LOG_WARNING, "failed to send the fop"); } - if (req.xdata.xdata_val) - GF_FREE (req.xdata.xdata_val); + GF_FREE (req.xdata.xdata_val); return 0; unwind: CLIENT_STACK_UNWIND (fsyncdir, frame, -1, op_errno, NULL); - if (req.xdata.xdata_val) - GF_FREE (req.xdata.xdata_val); + GF_FREE (req.xdata.xdata_val); return 0; } @@ -4329,7 +4482,7 @@ unwind: int32_t -client3_1_statfs (call_frame_t *frame, xlator_t *this, +client3_3_statfs (call_frame_t *frame, xlator_t *this, void *data) { clnt_conf_t *conf = NULL; @@ -4364,22 +4517,20 @@ client3_1_statfs (call_frame_t *frame, xlator_t *this, req.xdata.xdata_len, op_errno, unwind); ret = client_submit_request (this, &req, frame, conf->fops, - GFS3_OP_STATFS, client3_1_statfs_cbk, NULL, + GFS3_OP_STATFS, client3_3_statfs_cbk, NULL, NULL, 0, NULL, 0, NULL, (xdrproc_t)xdr_gfs3_statfs_req); if (ret) { gf_log (this->name, GF_LOG_WARNING, "failed to send the fop"); } - if (req.xdata.xdata_val) - GF_FREE (req.xdata.xdata_val); + GF_FREE (req.xdata.xdata_val); return 0; unwind: CLIENT_STACK_UNWIND (statfs, frame, -1, op_errno, NULL, NULL); - if (req.xdata.xdata_val) - GF_FREE (req.xdata.xdata_val); + GF_FREE (req.xdata.xdata_val); return 0; } @@ -4387,7 +4538,7 @@ unwind: int32_t -client3_1_setxattr (call_frame_t *frame, xlator_t *this, +client3_3_setxattr (call_frame_t *frame, xlator_t *this, void *data) { clnt_conf_t *conf = NULL; @@ -4427,26 +4578,22 @@ client3_1_setxattr (call_frame_t *frame, xlator_t *this, req.xdata.xdata_len, op_errno, unwind); ret = client_submit_request (this, &req, frame, conf->fops, - GFS3_OP_SETXATTR, client3_1_setxattr_cbk, + GFS3_OP_SETXATTR, client3_3_setxattr_cbk, NULL, NULL, 0, NULL, 0, NULL, (xdrproc_t)xdr_gfs3_setxattr_req); if (ret) { gf_log (this->name, GF_LOG_WARNING, "failed to send the fop"); } - if (req.dict.dict_val) - GF_FREE (req.dict.dict_val); + GF_FREE (req.dict.dict_val); - if (req.xdata.xdata_val) - GF_FREE (req.xdata.xdata_val); + GF_FREE (req.xdata.xdata_val); return 0; unwind: CLIENT_STACK_UNWIND (setxattr, frame, -1, op_errno, NULL); - if (req.dict.dict_val) - GF_FREE (req.dict.dict_val); + GF_FREE (req.dict.dict_val); - if (req.xdata.xdata_val) - GF_FREE (req.xdata.xdata_val); + GF_FREE (req.xdata.xdata_val); return 0; } @@ -4454,7 +4601,7 @@ unwind: int32_t -client3_1_fsetxattr (call_frame_t *frame, xlator_t *this, +client3_3_fsetxattr (call_frame_t *frame, xlator_t *this, void *data) { clnt_args_t *args = NULL; @@ -4470,7 +4617,8 @@ client3_1_fsetxattr (call_frame_t *frame, xlator_t *this, args = data; conf = this->private; - CLIENT_GET_REMOTE_FD(conf, args->fd, remote_fd, op_errno, unwind); + CLIENT_GET_REMOTE_FD (this, args->fd, DEFAULT_REMOTE_FD, + remote_fd, op_errno, unwind); req.fd = remote_fd; req.flags = args->flags; @@ -4487,27 +4635,23 @@ client3_1_fsetxattr (call_frame_t *frame, xlator_t *this, req.xdata.xdata_len, op_errno, unwind); ret = client_submit_request (this, &req, frame, conf->fops, - GFS3_OP_FSETXATTR, client3_1_fsetxattr_cbk, + GFS3_OP_FSETXATTR, client3_3_fsetxattr_cbk, NULL, NULL, 0, NULL, 0, NULL, (xdrproc_t)xdr_gfs3_fsetxattr_req); if (ret) { gf_log (this->name, GF_LOG_WARNING, "failed to send the fop"); } - if (req.dict.dict_val) - GF_FREE (req.dict.dict_val); + GF_FREE (req.dict.dict_val); - if (req.xdata.xdata_val) - GF_FREE (req.xdata.xdata_val); + GF_FREE (req.xdata.xdata_val); return 0; unwind: CLIENT_STACK_UNWIND (fsetxattr, frame, -1, op_errno, NULL); - if (req.dict.dict_val) - GF_FREE (req.dict.dict_val); + GF_FREE (req.dict.dict_val); - if (req.xdata.xdata_val) - GF_FREE (req.xdata.xdata_val); + GF_FREE (req.xdata.xdata_val); return 0; } @@ -4516,7 +4660,7 @@ unwind: int32_t -client3_1_fgetxattr (call_frame_t *frame, xlator_t *this, +client3_3_fgetxattr (call_frame_t *frame, xlator_t *this, void *data) { clnt_args_t *args = NULL; @@ -4538,7 +4682,8 @@ client3_1_fgetxattr (call_frame_t *frame, xlator_t *this, args = data; conf = this->private; - CLIENT_GET_REMOTE_FD(conf, args->fd, remote_fd, op_errno, unwind); + CLIENT_GET_REMOTE_FD (this, args->fd, DEFAULT_REMOTE_FD, + remote_fd, op_errno, unwind); local = mem_get0 (this->local_pool); if (!local) { @@ -4585,7 +4730,7 @@ client3_1_fgetxattr (call_frame_t *frame, xlator_t *this, ret = client_submit_request (this, &req, frame, conf->fops, GFS3_OP_FGETXATTR, - client3_1_fgetxattr_cbk, NULL, + client3_3_fgetxattr_cbk, NULL, rsphdr, count, NULL, 0, local->iobref, (xdrproc_t)xdr_gfs3_fgetxattr_req); @@ -4593,8 +4738,7 @@ client3_1_fgetxattr (call_frame_t *frame, xlator_t *this, gf_log (this->name, GF_LOG_WARNING, "failed to send the fop"); } - if (req.xdata.xdata_val) - GF_FREE (req.xdata.xdata_val); + GF_FREE (req.xdata.xdata_val); if (rsp_iobuf) iobuf_unref (rsp_iobuf); @@ -4612,8 +4756,7 @@ unwind: if (rsp_iobref) iobref_unref (rsp_iobref); - if (req.xdata.xdata_val) - GF_FREE (req.xdata.xdata_val); + GF_FREE (req.xdata.xdata_val); return 0; } @@ -4621,7 +4764,7 @@ unwind: int32_t -client3_1_getxattr (call_frame_t *frame, xlator_t *this, +client3_3_getxattr (call_frame_t *frame, xlator_t *this, void *data) { clnt_conf_t *conf = NULL; @@ -4644,7 +4787,7 @@ client3_1_getxattr (call_frame_t *frame, xlator_t *this, } args = data; - if (!(args->loc && args->loc->inode)) { + if (!args->loc) { op_errno = EINVAL; goto unwind; } @@ -4656,6 +4799,7 @@ client3_1_getxattr (call_frame_t *frame, xlator_t *this, } loc_copy (&local->loc, args->loc); + loc_path (&local->loc, NULL); if (args->name) local->name = gf_strdup (args->name); @@ -4685,7 +4829,7 @@ client3_1_getxattr (call_frame_t *frame, xlator_t *this, rsp_iobuf = NULL; rsp_iobref = NULL; - if (!uuid_is_null (args->loc->inode->gfid)) + if (args->loc->inode && !uuid_is_null (args->loc->inode->gfid)) memcpy (req.gfid, args->loc->inode->gfid, 16); else memcpy (req.gfid, args->loc->gfid, 16); @@ -4727,7 +4871,7 @@ client3_1_getxattr (call_frame_t *frame, xlator_t *this, ret = client_submit_request (this, &req, frame, conf->fops, GFS3_OP_GETXATTR, - client3_1_getxattr_cbk, NULL, + client3_3_getxattr_cbk, NULL, rsphdr, count, NULL, 0, local->iobref, (xdrproc_t)xdr_gfs3_getxattr_req); @@ -4735,8 +4879,7 @@ client3_1_getxattr (call_frame_t *frame, xlator_t *this, gf_log (this->name, GF_LOG_WARNING, "failed to send the fop"); } - if (req.xdata.xdata_val) - GF_FREE (req.xdata.xdata_val); + GF_FREE (req.xdata.xdata_val); if (rsp_iobuf) iobuf_unref (rsp_iobuf); @@ -4754,8 +4897,7 @@ unwind: CLIENT_STACK_UNWIND (getxattr, frame, op_ret, op_errno, dict, NULL); - if (req.xdata.xdata_val) - GF_FREE (req.xdata.xdata_val); + GF_FREE (req.xdata.xdata_val); return 0; } @@ -4763,7 +4905,7 @@ unwind: int32_t -client3_1_xattrop (call_frame_t *frame, xlator_t *this, +client3_3_xattrop (call_frame_t *frame, xlator_t *this, void *data) { clnt_conf_t *conf = NULL; @@ -4822,6 +4964,8 @@ client3_1_xattrop (call_frame_t *frame, xlator_t *this, else memcpy (req.gfid, args->loc->gfid, 16); + loc_copy (&local->loc, args->loc); + loc_path (&local->loc, NULL); GF_ASSERT_AND_GOTO_WITH_ERROR (this->name, !uuid_is_null (*((uuid_t*)req.gfid)), unwind, op_errno, EINVAL); @@ -4841,7 +4985,7 @@ client3_1_xattrop (call_frame_t *frame, xlator_t *this, ret = client_submit_request (this, &req, frame, conf->fops, GFS3_OP_XATTROP, - client3_1_xattrop_cbk, NULL, + client3_3_xattrop_cbk, NULL, rsphdr, count, NULL, 0, local->iobref, (xdrproc_t)xdr_gfs3_xattrop_req); @@ -4849,11 +4993,9 @@ client3_1_xattrop (call_frame_t *frame, xlator_t *this, gf_log (this->name, GF_LOG_WARNING, "failed to send the fop"); } - if (req.dict.dict_val) - GF_FREE (req.dict.dict_val); + GF_FREE (req.dict.dict_val); - if (req.xdata.xdata_val) - GF_FREE (req.xdata.xdata_val); + GF_FREE (req.xdata.xdata_val); if (rsp_iobuf) iobuf_unref (rsp_iobuf); @@ -4865,9 +5007,7 @@ client3_1_xattrop (call_frame_t *frame, xlator_t *this, unwind: CLIENT_STACK_UNWIND (xattrop, frame, -1, op_errno, NULL, NULL); - if (req.dict.dict_val) { - GF_FREE (req.dict.dict_val); - } + GF_FREE (req.dict.dict_val); if (rsp_iobuf) iobuf_unref (rsp_iobuf); @@ -4875,8 +5015,7 @@ unwind: if (rsp_iobref) iobref_unref (rsp_iobref); - if (req.xdata.xdata_val) - GF_FREE (req.xdata.xdata_val); + GF_FREE (req.xdata.xdata_val); return 0; } @@ -4884,17 +5023,17 @@ unwind: int32_t -client3_1_fxattrop (call_frame_t *frame, xlator_t *this, +client3_3_fxattrop (call_frame_t *frame, xlator_t *this, void *data) { clnt_args_t *args = NULL; int64_t remote_fd = -1; clnt_conf_t *conf = NULL; + clnt_local_t *local = NULL; gfs3_fxattrop_req req = {{0,},}; int op_errno = ESTALE; int ret = 0; int count = 0; - clnt_local_t *local = NULL; struct iobref *rsp_iobref = NULL; struct iobuf *rsp_iobuf = NULL; struct iovec *rsphdr = NULL; @@ -4906,19 +5045,20 @@ client3_1_fxattrop (call_frame_t *frame, xlator_t *this, args = data; conf = this->private; - CLIENT_GET_REMOTE_FD(conf, args->fd, remote_fd, op_errno, unwind); + CLIENT_GET_REMOTE_FD (this, args->fd, FALLBACK_TO_ANON_FD, + remote_fd, op_errno, unwind); + ret = client_fd_fop_prepare_local (frame, args->fd, remote_fd); + if (ret) { + op_errno = -ret; + goto unwind; + } + + local = frame->local; req.fd = remote_fd; req.flags = args->flags; memcpy (req.gfid, args->fd->inode->gfid, 16); - 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; @@ -4954,7 +5094,7 @@ client3_1_fxattrop (call_frame_t *frame, xlator_t *this, ret = client_submit_request (this, &req, frame, conf->fops, GFS3_OP_FXATTROP, - client3_1_fxattrop_cbk, NULL, + client3_3_fxattrop_cbk, NULL, rsphdr, count, NULL, 0, local->iobref, (xdrproc_t)xdr_gfs3_fxattrop_req); @@ -4962,24 +5102,15 @@ client3_1_fxattrop (call_frame_t *frame, xlator_t *this, gf_log (this->name, GF_LOG_WARNING, "failed to send the fop"); } - if (req.dict.dict_val) - GF_FREE (req.dict.dict_val); - - if (req.xdata.xdata_val) - GF_FREE (req.xdata.xdata_val); + GF_FREE (req.dict.dict_val); - if (rsp_iobuf) - iobuf_unref (rsp_iobuf); - - if (rsp_iobref) - iobref_unref (rsp_iobref); + GF_FREE (req.xdata.xdata_val); return 0; unwind: CLIENT_STACK_UNWIND (fxattrop, frame, -1, op_errno, NULL, NULL); - if (req.dict.dict_val) - GF_FREE (req.dict.dict_val); + GF_FREE (req.dict.dict_val); if (rsp_iobref) iobref_unref (rsp_iobref); @@ -4987,15 +5118,14 @@ unwind: if (rsp_iobuf) iobuf_unref (rsp_iobuf); - if (req.xdata.xdata_val) - GF_FREE (req.xdata.xdata_val); + GF_FREE (req.xdata.xdata_val); return 0; } int32_t -client3_1_removexattr (call_frame_t *frame, xlator_t *this, +client3_3_removexattr (call_frame_t *frame, xlator_t *this, void *data) { clnt_conf_t *conf = NULL; @@ -5029,27 +5159,25 @@ client3_1_removexattr (call_frame_t *frame, xlator_t *this, ret = client_submit_request (this, &req, frame, conf->fops, GFS3_OP_REMOVEXATTR, - client3_1_removexattr_cbk, NULL, + client3_3_removexattr_cbk, NULL, NULL, 0, NULL, 0, NULL, (xdrproc_t)xdr_gfs3_removexattr_req); if (ret) { gf_log (this->name, GF_LOG_WARNING, "failed to send the fop"); } - if (req.xdata.xdata_val) - GF_FREE (req.xdata.xdata_val); + GF_FREE (req.xdata.xdata_val); return 0; unwind: CLIENT_STACK_UNWIND (removexattr, frame, -1, op_errno, NULL); - if (req.xdata.xdata_val) - GF_FREE (req.xdata.xdata_val); + GF_FREE (req.xdata.xdata_val); return 0; } int32_t -client3_1_fremovexattr (call_frame_t *frame, xlator_t *this, +client3_3_fremovexattr (call_frame_t *frame, xlator_t *this, void *data) { clnt_conf_t *conf = NULL; @@ -5069,7 +5197,8 @@ client3_1_fremovexattr (call_frame_t *frame, xlator_t *this, conf = this->private; - CLIENT_GET_REMOTE_FD(conf, args->fd, remote_fd, op_errno, unwind); + CLIENT_GET_REMOTE_FD (this, args->fd, DEFAULT_REMOTE_FD, + remote_fd, op_errno, unwind); memcpy (req.gfid, args->fd->inode->gfid, 16); req.name = (char *)args->name; @@ -5080,27 +5209,25 @@ client3_1_fremovexattr (call_frame_t *frame, xlator_t *this, ret = client_submit_request (this, &req, frame, conf->fops, GFS3_OP_FREMOVEXATTR, - client3_1_fremovexattr_cbk, NULL, + client3_3_fremovexattr_cbk, NULL, NULL, 0, NULL, 0, NULL, (xdrproc_t)xdr_gfs3_fremovexattr_req); if (ret) { gf_log (this->name, GF_LOG_WARNING, "failed to send the fop"); } - if (req.xdata.xdata_val) - GF_FREE (req.xdata.xdata_val); + GF_FREE (req.xdata.xdata_val); return 0; unwind: CLIENT_STACK_UNWIND (fremovexattr, frame, -1, op_errno, NULL); - if (req.xdata.xdata_val) - GF_FREE (req.xdata.xdata_val); + GF_FREE (req.xdata.xdata_val); return 0; } int32_t -client3_1_lk (call_frame_t *frame, xlator_t *this, +client3_3_lk (call_frame_t *frame, xlator_t *this, void *data) { clnt_args_t *args = NULL; @@ -5124,7 +5251,8 @@ client3_1_lk (call_frame_t *frame, xlator_t *this, goto unwind; } - CLIENT_GET_REMOTE_FD(conf, args->fd, remote_fd, op_errno, unwind); + CLIENT_GET_REMOTE_FD (this, args->fd, DEFAULT_REMOTE_FD, + remote_fd, op_errno, unwind); ret = client_cmd_to_gf_cmd (args->cmd, &gf_cmd); if (ret) { @@ -5158,29 +5286,30 @@ client3_1_lk (call_frame_t *frame, xlator_t *this, memcpy (req.gfid, args->fd->inode->gfid, 16); + GF_PROTOCOL_DICT_SERIALIZE (this, args->xdata, (&req.xdata.xdata_val), + req.xdata.xdata_len, op_errno, unwind); + ret = client_submit_request (this, &req, frame, conf->fops, GFS3_OP_LK, - client3_1_lk_cbk, NULL, + client3_3_lk_cbk, NULL, NULL, 0, NULL, 0, NULL, (xdrproc_t)xdr_gfs3_lk_req); if (ret) { gf_log (this->name, GF_LOG_WARNING, "failed to send the fop"); } - if (req.xdata.xdata_val) - GF_FREE (req.xdata.xdata_val); + GF_FREE (req.xdata.xdata_val); return 0; unwind: CLIENT_STACK_UNWIND (lk, frame, -1, op_errno, NULL, NULL); - if (req.xdata.xdata_val) - GF_FREE (req.xdata.xdata_val); + GF_FREE (req.xdata.xdata_val); return 0; } int32_t -client3_1_inodelk (call_frame_t *frame, xlator_t *this, +client3_3_inodelk (call_frame_t *frame, xlator_t *this, void *data) { clnt_conf_t *conf = NULL; @@ -5243,21 +5372,19 @@ client3_1_inodelk (call_frame_t *frame, xlator_t *this, ret = client_submit_request (this, &req, frame, conf->fops, GFS3_OP_INODELK, - client3_1_inodelk_cbk, NULL, + client3_3_inodelk_cbk, NULL, NULL, 0, NULL, 0, NULL, (xdrproc_t)xdr_gfs3_inodelk_req); if (ret) { gf_log (this->name, GF_LOG_WARNING, "failed to send the fop"); } - if (req.xdata.xdata_val) - GF_FREE (req.xdata.xdata_val); + GF_FREE (req.xdata.xdata_val); return 0; unwind: CLIENT_STACK_UNWIND (inodelk, frame, -1, op_errno, NULL); - if (req.xdata.xdata_val) - GF_FREE (req.xdata.xdata_val); + GF_FREE (req.xdata.xdata_val); return 0; } @@ -5265,7 +5392,7 @@ unwind: int32_t -client3_1_finodelk (call_frame_t *frame, xlator_t *this, +client3_3_finodelk (call_frame_t *frame, xlator_t *this, void *data) { clnt_args_t *args = NULL; @@ -5275,15 +5402,20 @@ client3_1_finodelk (call_frame_t *frame, xlator_t *this, int64_t remote_fd = -1; clnt_conf_t *conf = NULL; int op_errno = ESTALE; - int ret = 0; + int ret = 0; if (!frame || !this || !data) goto unwind; args = data; conf = this->private; - - CLIENT_GET_REMOTE_FD(conf, args->fd, remote_fd, op_errno, unwind); + CLIENT_GET_REMOTE_FD (this, args->fd, FALLBACK_TO_ANON_FD, + remote_fd, op_errno, unwind); + ret = client_fd_fop_prepare_local (frame, args->fd, remote_fd); + if (ret) { + op_errno = -ret; + goto unwind; + } if (args->cmd == F_GETLK || args->cmd == F_GETLK64) gf_cmd = GF_LK_GETLK; @@ -5321,27 +5453,25 @@ client3_1_finodelk (call_frame_t *frame, xlator_t *this, ret = client_submit_request (this, &req, frame, conf->fops, GFS3_OP_FINODELK, - client3_1_finodelk_cbk, NULL, + client3_3_finodelk_cbk, NULL, NULL, 0, NULL, 0, NULL, (xdrproc_t)xdr_gfs3_finodelk_req); if (ret) { gf_log (this->name, GF_LOG_WARNING, "failed to send the fop"); } - if (req.xdata.xdata_val) - GF_FREE (req.xdata.xdata_val); + GF_FREE (req.xdata.xdata_val); return 0; unwind: CLIENT_STACK_UNWIND (finodelk, frame, -1, op_errno, NULL); - if (req.xdata.xdata_val) - GF_FREE (req.xdata.xdata_val); + GF_FREE (req.xdata.xdata_val); return 0; } int32_t -client3_1_entrylk (call_frame_t *frame, xlator_t *this, +client3_3_entrylk (call_frame_t *frame, xlator_t *this, void *data) { clnt_conf_t *conf = NULL; @@ -5382,21 +5512,19 @@ client3_1_entrylk (call_frame_t *frame, xlator_t *this, ret = client_submit_request (this, &req, frame, conf->fops, GFS3_OP_ENTRYLK, - client3_1_entrylk_cbk, NULL, + client3_3_entrylk_cbk, NULL, NULL, 0, NULL, 0, NULL, (xdrproc_t)xdr_gfs3_entrylk_req); if (ret) { gf_log (this->name, GF_LOG_WARNING, "failed to send the fop"); } - if (req.xdata.xdata_val) - GF_FREE (req.xdata.xdata_val); + GF_FREE (req.xdata.xdata_val); return 0; unwind: CLIENT_STACK_UNWIND (entrylk, frame, -1, op_errno, NULL); - if (req.xdata.xdata_val) - GF_FREE (req.xdata.xdata_val); + GF_FREE (req.xdata.xdata_val); return 0; } @@ -5404,7 +5532,7 @@ unwind: int32_t -client3_1_fentrylk (call_frame_t *frame, xlator_t *this, +client3_3_fentrylk (call_frame_t *frame, xlator_t *this, void *data) { clnt_args_t *args = NULL; @@ -5420,7 +5548,8 @@ client3_1_fentrylk (call_frame_t *frame, xlator_t *this, args = data; conf = this->private; - CLIENT_GET_REMOTE_FD(conf, args->fd, remote_fd, op_errno, unwind); + CLIENT_GET_REMOTE_FD (this, args->fd, DEFAULT_REMOTE_FD, + remote_fd, op_errno, unwind); req.fd = remote_fd; req.cmd = args->cmd_entrylk; @@ -5438,28 +5567,26 @@ client3_1_fentrylk (call_frame_t *frame, xlator_t *this, ret = client_submit_request (this, &req, frame, conf->fops, GFS3_OP_FENTRYLK, - client3_1_fentrylk_cbk, NULL, + client3_3_fentrylk_cbk, NULL, NULL, 0, NULL, 0, NULL, (xdrproc_t)xdr_gfs3_fentrylk_req); if (ret) { gf_log (this->name, GF_LOG_WARNING, "failed to send the fop"); } - if (req.xdata.xdata_val) - GF_FREE (req.xdata.xdata_val); + GF_FREE (req.xdata.xdata_val); return 0; unwind: CLIENT_STACK_UNWIND (fentrylk, frame, -1, op_errno, NULL); - if (req.xdata.xdata_val) - GF_FREE (req.xdata.xdata_val); + GF_FREE (req.xdata.xdata_val); return 0; } int32_t -client3_1_rchecksum (call_frame_t *frame, xlator_t *this, +client3_3_rchecksum (call_frame_t *frame, xlator_t *this, void *data) { clnt_args_t *args = NULL; @@ -5475,7 +5602,8 @@ client3_1_rchecksum (call_frame_t *frame, xlator_t *this, args = data; conf = this->private; - CLIENT_GET_REMOTE_FD(conf, args->fd, remote_fd, op_errno, unwind); + CLIENT_GET_REMOTE_FD (this, args->fd, DEFAULT_REMOTE_FD, + remote_fd, op_errno, unwind); req.len = args->len; req.offset = args->offset; @@ -5486,7 +5614,7 @@ client3_1_rchecksum (call_frame_t *frame, xlator_t *this, ret = client_submit_request (this, &req, frame, conf->fops, GFS3_OP_RCHECKSUM, - client3_1_rchecksum_cbk, NULL, + client3_3_rchecksum_cbk, NULL, NULL, 0, NULL, 0, NULL, (xdrproc_t)xdr_gfs3_rchecksum_req); @@ -5494,14 +5622,12 @@ client3_1_rchecksum (call_frame_t *frame, xlator_t *this, gf_log (this->name, GF_LOG_WARNING, "failed to send the fop"); } - if (req.xdata.xdata_val) - GF_FREE (req.xdata.xdata_val); + GF_FREE (req.xdata.xdata_val); return 0; unwind: CLIENT_STACK_UNWIND (rchecksum, frame, -1, op_errno, 0, NULL, NULL); - if (req.xdata.xdata_val) - GF_FREE (req.xdata.xdata_val); + GF_FREE (req.xdata.xdata_val); return 0; } @@ -5509,7 +5635,7 @@ unwind: int32_t -client3_1_readdir (call_frame_t *frame, xlator_t *this, +client3_3_readdir (call_frame_t *frame, xlator_t *this, void *data) { clnt_args_t *args = NULL; @@ -5533,7 +5659,8 @@ client3_1_readdir (call_frame_t *frame, xlator_t *this, args = data; conf = this->private; - CLIENT_GET_REMOTE_FD(conf, args->fd, remote_fd, op_errno, unwind); + CLIENT_GET_REMOTE_FD (this, args->fd, DEFAULT_REMOTE_FD, + remote_fd, op_errno, unwind); readdir_rsp_size = xdr_sizeof ((xdrproc_t) xdr_gfs3_readdir_rsp, &rsp) + args->size; @@ -5584,7 +5711,7 @@ client3_1_readdir (call_frame_t *frame, xlator_t *this, ret = client_submit_request (this, &req, frame, conf->fops, GFS3_OP_READDIR, - client3_1_readdir_cbk, NULL, + client3_3_readdir_cbk, NULL, rsphdr, count, NULL, 0, rsp_iobref, (xdrproc_t)xdr_gfs3_readdir_req); @@ -5593,8 +5720,7 @@ client3_1_readdir (call_frame_t *frame, xlator_t *this, gf_log (this->name, GF_LOG_WARNING, "failed to send the fop"); } - if (req.xdata.xdata_val) - GF_FREE (req.xdata.xdata_val); + GF_FREE (req.xdata.xdata_val); if (rsp_iobuf) iobuf_unref (rsp_iobuf); @@ -5612,15 +5738,14 @@ unwind: iobuf_unref (rsp_iobuf); CLIENT_STACK_UNWIND (readdir, frame, -1, op_errno, NULL, NULL); - if (req.xdata.xdata_val) - GF_FREE (req.xdata.xdata_val); + GF_FREE (req.xdata.xdata_val); return 0; } int32_t -client3_1_readdirp (call_frame_t *frame, xlator_t *this, +client3_3_readdirp (call_frame_t *frame, xlator_t *this, void *data) { clnt_args_t *args = NULL; @@ -5644,7 +5769,8 @@ client3_1_readdirp (call_frame_t *frame, xlator_t *this, args = data; conf = this->private; - CLIENT_GET_REMOTE_FD(conf, args->fd, remote_fd, op_errno, unwind); + CLIENT_GET_REMOTE_FD (this, args->fd, DEFAULT_REMOTE_FD, + remote_fd, op_errno, unwind); readdirp_rsp_size = xdr_sizeof ((xdrproc_t) xdr_gfs3_readdirp_rsp, &rsp) + args->size; @@ -5697,7 +5823,7 @@ client3_1_readdirp (call_frame_t *frame, xlator_t *this, ret = client_submit_request (this, &req, frame, conf->fops, GFS3_OP_READDIRP, - client3_1_readdirp_cbk, NULL, + client3_3_readdirp_cbk, NULL, rsphdr, count, NULL, 0, rsp_iobref, (xdrproc_t)xdr_gfs3_readdirp_req); @@ -5705,8 +5831,7 @@ client3_1_readdirp (call_frame_t *frame, xlator_t *this, gf_log (this->name, GF_LOG_WARNING, "failed to send the fop"); } - if (req.dict.dict_val) - GF_FREE (req.dict.dict_val); + GF_FREE (req.dict.dict_val); if (rsp_iobuf) iobuf_unref (rsp_iobuf); @@ -5722,8 +5847,7 @@ unwind: if (rsp_iobuf) iobuf_unref (rsp_iobuf); - if (req.dict.dict_val) - GF_FREE (req.dict.dict_val); + GF_FREE (req.dict.dict_val); CLIENT_STACK_UNWIND (readdirp, frame, -1, op_errno, NULL, NULL); return 0; @@ -5731,7 +5855,7 @@ unwind: int32_t -client3_1_setattr (call_frame_t *frame, xlator_t *this, +client3_3_setattr (call_frame_t *frame, xlator_t *this, void *data) { clnt_conf_t *conf = NULL; @@ -5766,27 +5890,25 @@ client3_1_setattr (call_frame_t *frame, xlator_t *this, ret = client_submit_request (this, &req, frame, conf->fops, GFS3_OP_SETATTR, - client3_1_setattr_cbk, NULL, + client3_3_setattr_cbk, NULL, NULL, 0, NULL, 0, NULL, (xdrproc_t)xdr_gfs3_setattr_req); if (ret) { gf_log (this->name, GF_LOG_WARNING, "failed to send the fop"); } - if (req.xdata.xdata_val) - GF_FREE (req.xdata.xdata_val); + GF_FREE (req.xdata.xdata_val); return 0; unwind: CLIENT_STACK_UNWIND (setattr, frame, -1, op_errno, NULL, NULL, NULL); - if (req.xdata.xdata_val) - GF_FREE (req.xdata.xdata_val); + GF_FREE (req.xdata.xdata_val); return 0; } int32_t -client3_1_fsetattr (call_frame_t *frame, xlator_t *this, void *data) +client3_3_fsetattr (call_frame_t *frame, xlator_t *this, void *data) { clnt_args_t *args = NULL; int64_t remote_fd = -1; @@ -5801,88 +5923,226 @@ client3_1_fsetattr (call_frame_t *frame, xlator_t *this, void *data) args = data; conf = this->private; - CLIENT_GET_REMOTE_FD(conf, args->fd, remote_fd, op_errno, unwind); + CLIENT_GET_REMOTE_FD (this, args->fd, DEFAULT_REMOTE_FD, + remote_fd, op_errno, unwind); req.fd = remote_fd; req.valid = args->valid; gf_stat_from_iatt (&req.stbuf, args->stbuf); + GF_PROTOCOL_DICT_SERIALIZE (this, args->xdata, (&req.xdata.xdata_val), + req.xdata.xdata_len, op_errno, unwind); + ret = client_submit_request (this, &req, frame, conf->fops, GFS3_OP_FSETATTR, - client3_1_fsetattr_cbk, NULL, + client3_3_fsetattr_cbk, NULL, NULL, 0, NULL, 0, NULL, (xdrproc_t)xdr_gfs3_fsetattr_req); if (ret) { gf_log (this->name, GF_LOG_WARNING, "failed to send the fop"); } - if (req.xdata.xdata_val) - GF_FREE (req.xdata.xdata_val); + GF_FREE (req.xdata.xdata_val); return 0; unwind: CLIENT_STACK_UNWIND (fsetattr, frame, -1, op_errno, NULL, NULL, NULL); - if (req.xdata.xdata_val) - GF_FREE (req.xdata.xdata_val); + GF_FREE (req.xdata.xdata_val); + + return 0; +} + +int32_t +client3_3_fallocate(call_frame_t *frame, xlator_t *this, void *data) +{ + clnt_args_t *args = NULL; + int64_t remote_fd = -1; + clnt_conf_t *conf = NULL; + gfs3_fallocate_req req = {{0},}; + int op_errno = ESTALE; + int ret = 0; + + if (!frame || !this || !data) + goto unwind; + + args = data; + conf = this->private; + + CLIENT_GET_REMOTE_FD (this, args->fd, DEFAULT_REMOTE_FD, + remote_fd, op_errno, unwind); + + req.fd = remote_fd; + req.flags = args->flags; + req.offset = args->offset; + req.size = args->size; + memcpy(req.gfid, args->fd->inode->gfid, 16); + + GF_PROTOCOL_DICT_SERIALIZE (this, args->xdata, (&req.xdata.xdata_val), + req.xdata.xdata_len, op_errno, unwind); + + ret = client_submit_request (this, &req, frame, conf->fops, + GFS3_OP_FALLOCATE, + client3_3_fallocate_cbk, NULL, + NULL, 0, NULL, 0, + NULL, (xdrproc_t)xdr_gfs3_fallocate_req); + if (ret) { + gf_log (this->name, GF_LOG_WARNING, "failed to send the fop"); + } + + GF_FREE (req.xdata.xdata_val); + + return 0; +unwind: + CLIENT_STACK_UNWIND (fallocate, frame, -1, op_errno, NULL, NULL, NULL); + GF_FREE (req.xdata.xdata_val); + + return 0; +} + +int32_t +client3_3_discard(call_frame_t *frame, xlator_t *this, void *data) +{ + clnt_args_t *args = NULL; + int64_t remote_fd = -1; + clnt_conf_t *conf = NULL; + gfs3_discard_req req = {{0},}; + int op_errno = ESTALE; + int ret = 0; + + if (!frame || !this || !data) + goto unwind; + + args = data; + conf = this->private; + + CLIENT_GET_REMOTE_FD (this, args->fd, DEFAULT_REMOTE_FD, + remote_fd, op_errno, unwind); + + req.fd = remote_fd; + req.offset = args->offset; + req.size = args->size; + memcpy(req.gfid, args->fd->inode->gfid, 16); + + GF_PROTOCOL_DICT_SERIALIZE (this, args->xdata, (&req.xdata.xdata_val), + req.xdata.xdata_len, op_errno, unwind); + + ret = client_submit_request(this, &req, frame, conf->fops, + GFS3_OP_DISCARD, client3_3_discard_cbk, + NULL, NULL, 0, NULL, 0, NULL, + (xdrproc_t) xdr_gfs3_discard_req); + if (ret) + gf_log (this->name, GF_LOG_WARNING, "failed to send the fop"); + + GF_FREE (req.xdata.xdata_val); + + return 0; +unwind: + CLIENT_STACK_UNWIND(discard, frame, -1, op_errno, NULL, NULL, NULL); + GF_FREE (req.xdata.xdata_val); return 0; } +int32_t +client3_3_zerofill(call_frame_t *frame, xlator_t *this, void *data) +{ + clnt_args_t *args = NULL; + int64_t remote_fd = -1; + clnt_conf_t *conf = NULL; + gfs3_zerofill_req req = {{0},}; + int op_errno = ESTALE; + int ret = 0; + + if (!frame || !this || !data) + goto unwind; + + args = data; + conf = this->private; + + CLIENT_GET_REMOTE_FD (this, args->fd, DEFAULT_REMOTE_FD, + remote_fd, op_errno, unwind); + + req.fd = remote_fd; + req.offset = args->offset; + req.size = args->size; + memcpy(req.gfid, args->fd->inode->gfid, 16); + + GF_PROTOCOL_DICT_SERIALIZE (this, args->xdata, (&req.xdata.xdata_val), + req.xdata.xdata_len, op_errno, unwind); + ret = client_submit_request(this, &req, frame, conf->fops, + GFS3_OP_ZEROFILL, client3_3_zerofill_cbk, + NULL, NULL, 0, NULL, 0, NULL, + (xdrproc_t) xdr_gfs3_zerofill_req); + if (ret) + gf_log (this->name, GF_LOG_WARNING, "failed to send the fop"); + + GF_FREE (req.xdata.xdata_val); + + return 0; +unwind: + CLIENT_STACK_UNWIND(zerofill, frame, -1, op_errno, NULL, NULL, NULL); + GF_FREE (req.xdata.xdata_val); + + return 0; +} /* Table Specific to FOPS */ -rpc_clnt_procedure_t clnt3_1_fop_actors[GF_FOP_MAXVALUE] = { +rpc_clnt_procedure_t clnt3_3_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_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_1_fremovexattr }, + [GF_FOP_FREMOVEXATTR] = { "FREMOVEXATTR", client3_3_fremovexattr }, }; /* Used From RPC-CLNT library to log proper name of procedure based on number */ -char *clnt3_1_fop_names[GFS3_OP_MAXVALUE] = { +char *clnt3_3_fop_names[GFS3_OP_MAXVALUE] = { [GFS3_OP_NULL] = "NULL", [GFS3_OP_STAT] = "STAT", [GFS3_OP_READLINK] = "READLINK", @@ -5927,13 +6187,17 @@ char *clnt3_1_fop_names[GFS3_OP_MAXVALUE] = { [GFS3_OP_RELEASE] = "RELEASE", [GFS3_OP_RELEASEDIR] = "RELEASEDIR", [GFS3_OP_FREMOVEXATTR] = "FREMOVEXATTR", + [GFS3_OP_FALLOCATE] = "FALLOCATE", + [GFS3_OP_DISCARD] = "DISCARD", + [GFS3_OP_ZEROFILL] = "ZEROFILL", + }; -rpc_clnt_prog_t clnt3_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, +rpc_clnt_prog_t clnt3_3_fop_prog = { + .progname = "GlusterFS 3.3", + .prognum = GLUSTER_FOP_PROGRAM, + .progver = GLUSTER_FOP_VERSION, + .numproc = GLUSTER_FOP_PROCCNT, + .proctable = clnt3_3_fop_actors, + .procnames = clnt3_3_fop_names, }; diff --git a/xlators/protocol/client/src/client.c b/xlators/protocol/client/src/client.c index 65df70f06..1f7d13ea4 100644 --- a/xlators/protocol/client/src/client.c +++ b/xlators/protocol/client/src/client.c @@ -130,7 +130,7 @@ client_register_grace_timer (xlator_t *this, clnt_conf_t *conf) conf->grace_timer = gf_timer_call_after (this->ctx, - conf->grace_tv, + conf->grace_ts, client_grace_timeout, conf->rpc); } @@ -815,12 +815,16 @@ client_create (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags, goto out; args.loc = loc; - args.flags = flags; args.mode = mode; args.fd = fd; args.umask = umask; args.xdata = xdata; + if (!conf->filter_o_direct) + args.flags = flags; + else + args.flags = (flags & ~O_DIRECT); + proc = &conf->fops->proctable[GF_FOP_CREATE]; if (!proc) { gf_log (this->name, GF_LOG_ERROR, @@ -854,10 +858,14 @@ client_open (call_frame_t *frame, xlator_t *this, loc_t *loc, goto out; args.loc = loc; - args.flags = flags; args.fd = fd; args.xdata = xdata; + if (!conf->filter_o_direct) + args.flags = flags; + else + args.flags = (flags & ~O_DIRECT); + proc = &conf->fops->proctable[GF_FOP_OPEN]; if (!proc) { gf_log (this->name, GF_LOG_ERROR, @@ -1269,8 +1277,7 @@ client_set_remote_options (char *value, xlator_t *this) ret = _gf_true; out: - if (dup_value) - GF_FREE (dup_value); + GF_FREE (dup_value); return ret; } @@ -1954,6 +1961,110 @@ out: return 0; } +int32_t +client_fallocate(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t mode, + off_t offset, size_t len, dict_t *xdata) +{ + int ret = -1; + clnt_conf_t *conf = NULL; + rpc_clnt_procedure_t *proc = NULL; + clnt_args_t args = {0,}; + + conf = this->private; + if (!conf || !conf->fops) + goto out; + + args.fd = fd; + args.flags = mode; + args.offset = offset; + args.size = len; + args.xdata = xdata; + + proc = &conf->fops->proctable[GF_FOP_FALLOCATE]; + if (!proc) { + gf_log (this->name, GF_LOG_ERROR, + "rpc procedure not found for %s", + gf_fop_list[GF_FOP_FALLOCATE]); + goto out; + } + if (proc->fn) + ret = proc->fn (frame, this, &args); +out: + if (ret) + STACK_UNWIND_STRICT (fallocate, frame, -1, ENOTCONN, NULL, NULL, NULL); + + return 0; +} + +int32_t +client_discard(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, + size_t len, dict_t *xdata) +{ + int ret = -1; + clnt_conf_t *conf = NULL; + rpc_clnt_procedure_t *proc = NULL; + clnt_args_t args = {0,}; + + conf = this->private; + if (!conf || !conf->fops) + goto out; + + args.fd = fd; + args.offset = offset; + args.size = len; + args.xdata = xdata; + + proc = &conf->fops->proctable[GF_FOP_DISCARD]; + if (!proc) { + gf_log (this->name, GF_LOG_ERROR, + "rpc procedure not found for %s", + gf_fop_list[GF_FOP_DISCARD]); + goto out; + } + if (proc->fn) + ret = proc->fn (frame, this, &args); +out: + if (ret) + STACK_UNWIND_STRICT(discard, frame, -1, ENOTCONN, NULL, NULL, NULL); + + return 0; +} + +int32_t +client_zerofill(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, + size_t len, dict_t *xdata) +{ + int ret = -1; + clnt_conf_t *conf = NULL; + rpc_clnt_procedure_t *proc = NULL; + clnt_args_t args = {0,}; + + conf = this->private; + if (!conf || !conf->fops) + goto out; + + args.fd = fd; + args.offset = offset; + args.size = len; + args.xdata = xdata; + + proc = &conf->fops->proctable[GF_FOP_ZEROFILL]; + if (!proc) { + gf_log (this->name, GF_LOG_ERROR, + "rpc procedure not found for %s", + gf_fop_list[GF_FOP_ZEROFILL]); + goto out; + } + if (proc->fn) + ret = proc->fn (frame, this, &args); +out: + if (ret) + STACK_UNWIND_STRICT(zerofill, frame, -1, ENOTCONN, + NULL, NULL, NULL); + + return 0; +} + int32_t client_getspec (call_frame_t *frame, xlator_t *this, const char *key, @@ -2043,7 +2154,7 @@ client_rpc_notify (struct rpc_clnt *rpc, void *mydata, rpc_clnt_event_t event, gf_log (this->name, GF_LOG_DEBUG, "got RPC_CLNT_CONNECT"); if ((ret < 0) || (strcasecmp (handshake, "on"))) { - ret = client_handshake (this, conf->rpc); + ret = client_handshake (this, rpc); if (ret) gf_log (this->name, GF_LOG_WARNING, "handshake msg returned %d", ret); @@ -2085,9 +2196,19 @@ client_rpc_notify (struct rpc_clnt *rpc, void *mydata, rpc_clnt_event_t event, client_register_grace_timer (this, conf); if (!conf->skip_notify) { - if (conf->connected) - gf_log (this->name, GF_LOG_INFO, - "disconnected"); + if (conf->connected) { + gf_log (this->name, + ((!conf->disconnect_err_logged) + ? GF_LOG_INFO : GF_LOG_DEBUG), + "disconnected from %s. Client process " + "will keep trying to connect to " + "glusterd until brick's port is " + "available", + conf->rpc->conn.trans->peerinfo.identifier); + + if (conf->portmap_err_logged) + conf->disconnect_err_logged = 1; + } /* If the CHILD_DOWN event goes to parent xlator multiple times, the logic of parent xlator notify @@ -2111,6 +2232,15 @@ client_rpc_notify (struct rpc_clnt *rpc, void *mydata, rpc_clnt_event_t event, conf->connected = 0; conf->skip_notify = 0; + if (conf->quick_reconnect) { + conf->quick_reconnect = 0; + rpc_clnt_start (rpc); + + } else { + rpc->conn.config.remote_port = 0; + + } + break; default: @@ -2194,6 +2324,9 @@ build_client_config (xlator_t *this, clnt_conf_t *conf) gf_log (this->name, GF_LOG_WARNING, "option 'remote-subvolume' not given"); + GF_OPTION_INIT ("filter-O_DIRECT", conf->filter_o_direct, + bool, out); + ret = 0; out: return ret; @@ -2278,7 +2411,8 @@ client_init_rpc (xlator_t *this) conf->handshake = &clnt_handshake_prog; conf->dump = &clnt_dump_prog; - ret = rpcclnt_cbk_program_register (conf->rpc, &gluster_cbk_prog); + ret = rpcclnt_cbk_program_register (conf->rpc, &gluster_cbk_prog, + this); if (ret) { gf_log (this->name, GF_LOG_ERROR, "failed to register callback program"); @@ -2316,14 +2450,14 @@ client_init_grace_timer (xlator_t *this, dict_t *options, ret = dict_get_int32 (options, "grace-timeout", &grace_timeout); if (!ret) - conf->grace_tv.tv_sec = grace_timeout; + conf->grace_ts.tv_sec = grace_timeout; else - conf->grace_tv.tv_sec = 10; + conf->grace_ts.tv_sec = 10; - conf->grace_tv.tv_usec = 0; + conf->grace_ts.tv_nsec = 0; gf_log (this->name, GF_LOG_DEBUG, "Client grace timeout " - "value = %"PRIu64, conf->grace_tv.tv_sec); + "value = %"PRIu64, conf->grace_ts.tv_sec); ret = 0; out: @@ -2377,6 +2511,9 @@ reconfigure (xlator_t *this, dict_t *options) } } + GF_OPTION_RECONF ("filter-O_DIRECT", conf->filter_o_direct, + options, bool, out); + ret = client_init_grace_timer (this, options, conf); if (ret) goto out; @@ -2646,6 +2783,9 @@ struct xlator_fops fops = { .fxattrop = client_fxattrop, .setattr = client_setattr, .fsetattr = client_fsetattr, + .fallocate = client_fallocate, + .discard = client_discard, + .zerofill = client_zerofill, .getspec = client_getspec, }; @@ -2701,16 +2841,27 @@ struct volume_options options[] = { { .key = {"lk-heal"}, .type = GF_OPTION_TYPE_BOOL, .default_value = "off", + .description = "Enables or disables the lock heal." }, { .key = {"grace-timeout"}, .type = GF_OPTION_TYPE_INT, .min = 10, - .max = 1800 + .max = 1800, + .description = "Sets the grace-timeout value. Valid range 10-1800." }, {.key = {"tcp-window-size"}, .type = GF_OPTION_TYPE_SIZET, .min = GF_MIN_SOCKET_WINDOW_SIZE, - .max = GF_MAX_SOCKET_WINDOW_SIZE + .max = GF_MAX_SOCKET_WINDOW_SIZE, + .description = "Specifies the window size for tcp socket." + }, + { .key = {"filter-O_DIRECT"}, + .type = GF_OPTION_TYPE_BOOL, + .default_value = "disable", + .description = "If enabled, in open() and creat() calls, O_DIRECT " + "flag will be filtered at the client protocol level so server will " + "still continue to cache the file. This works similar to NFS's " + "behavior of O_DIRECT", }, { .key = {NULL} }, }; diff --git a/xlators/protocol/client/src/client.h b/xlators/protocol/client/src/client.h index 64066dd0a..afab2d74f 100644 --- a/xlators/protocol/client/src/client.h +++ b/xlators/protocol/client/src/client.h @@ -34,27 +34,27 @@ typedef enum { GF_LK_HEAL_DONE, } lk_heal_state_t; -#define CLIENT_GET_REMOTE_FD(conf, fd, remote_fd, op_errno, label) \ +typedef enum { + DEFAULT_REMOTE_FD = 0, + FALLBACK_TO_ANON_FD = 1 +} clnt_remote_fd_flags_t; + +#define CLIENT_GET_REMOTE_FD(xl, fd, flags, remote_fd, op_errno, label) \ do { \ - 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; \ + int _ret = 0; \ + _ret = client_get_remote_fd (xl, fd, flags, &remote_fd);\ + if (_ret < 0) { \ + op_errno = errno; \ + goto label; \ } \ if (remote_fd == -1) { \ - gf_log (THIS->name, GF_LOG_WARNING, " (%s) " \ + gf_log (xl->name, GF_LOG_WARNING, " (%s) " \ "remote_fd is -1. EBADFD", \ uuid_utoa (fd->inode->gfid)); \ op_errno = EBADFD; \ goto label; \ } \ - } while (0); + } while (0) #define CLIENT_STACK_UNWIND(op, frame, params ...) do { \ clnt_local_t *__local = frame->local; \ @@ -93,6 +93,10 @@ typedef struct clnt_conf { which was sent earlier */ char portmap_err_logged; /* flag used to prevent excessive logging */ + char disconnect_err_logged; /* flag used to prevent + excessive disconnect + logging */ + char need_different_port; /* flag used to change the portmap path in case of 'tcp,rdma' on server */ @@ -100,7 +104,7 @@ typedef struct clnt_conf { uint16_t lk_version; /* this variable is used to distinguish client-server transaction while performing lock healing */ - struct timeval grace_tv; + struct timespec grace_ts; gf_timer_t *grace_timer; gf_boolean_t grace_timer_needed; /* The state of this flag will be used to decide whether @@ -109,6 +113,13 @@ typedef struct clnt_conf { means dont register, true means register */ char parent_down; + gf_boolean_t quick_reconnect; /* When reconnecting after + portmap query, do not let + the reconnection happen after + the usual 3-second wait + */ + gf_boolean_t filter_o_direct; /* if set, filter O_DIRECT from + the flags list of open() */ } clnt_conf_t; typedef struct _client_fd_ctx { @@ -116,17 +127,16 @@ typedef struct _client_fd_ctx { 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; fd_lk_ctx_t *lk_ctx; pthread_mutex_t mutex; lk_heal_state_t lk_heal_state; + uuid_t gfid; + void (*reopen_done) (struct _client_fd_ctx*, xlator_t *); struct list_head lock_list; /* List of all granted locks on this fd */ + int32_t reopen_attempts; } clnt_fd_ctx_t; typedef struct _client_posix_lock { @@ -147,7 +157,6 @@ typedef struct client_local { fd_t *fd; clnt_fd_ctx_t *fdctx; uint32_t flags; - uint32_t wbflags; struct iobref *iobref; client_posix_lock_t *client_lock; @@ -155,7 +164,8 @@ typedef struct client_local { int32_t cmd; struct list_head lock_list; pthread_mutex_t mutex; - char *name; + char *name; + gf_boolean_t attempt_reopen; } clnt_local_t; typedef struct client_args { @@ -207,9 +217,6 @@ int client_submit_request (xlator_t *this, void *req, 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 (xlator_t *this, fd_t *fd, struct gfs3_readdirp_rsp *rsp, gf_dirent_t *entries); @@ -220,7 +227,6 @@ int client_attempt_lock_recovery (xlator_t *this, clnt_fd_ctx_t *fdctx); int32_t delete_granted_locks_owner (fd_t *fd, gf_lkowner_t *owner); int client_add_lock_for_recovery (fd_t *fd, struct gf_flock *flock, gf_lkowner_t *owner, int32_t cmd); -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); @@ -240,4 +246,12 @@ int client_mark_fd_bad (xlator_t *this); int client_set_lk_version (xlator_t *this); int client_fd_lk_list_empty (fd_lk_ctx_t *lk_ctx, gf_boolean_t use_try_lock); +void client_default_reopen_done (clnt_fd_ctx_t *fdctx, xlator_t *this); +void client_attempt_reopen (fd_t *fd, xlator_t *this); +int client_get_remote_fd (xlator_t *this, fd_t *fd, int flags, + int64_t *remote_fd); +int client_fd_fop_prepare_local (call_frame_t *frame, fd_t *fd, + int64_t remote_fd); +gf_boolean_t +__is_fd_reopen_in_progress (clnt_fd_ctx_t *fdctx); #endif /* !_CLIENT_H */ diff --git a/xlators/protocol/legacy/Makefile.am b/xlators/protocol/legacy/Makefile.am deleted file mode 100644 index 991486302..000000000 --- a/xlators/protocol/legacy/Makefile.am +++ /dev/null @@ -1,3 +0,0 @@ -SUBDIRS = lib transport client server - -CLEANFILES = diff --git a/xlators/protocol/legacy/client/Makefile.am b/xlators/protocol/legacy/client/Makefile.am deleted file mode 100644 index d471a3f92..000000000 --- a/xlators/protocol/legacy/client/Makefile.am +++ /dev/null @@ -1,3 +0,0 @@ -SUBDIRS = src - -CLEANFILES = diff --git a/xlators/protocol/legacy/client/src/Makefile.am b/xlators/protocol/legacy/client/src/Makefile.am deleted file mode 100644 index 2ae64ebd0..000000000 --- a/xlators/protocol/legacy/client/src/Makefile.am +++ /dev/null @@ -1,21 +0,0 @@ - -xlator_LTLIBRARIES = client-old.la -xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/legacy/protocol - -client_old_la_LDFLAGS = -module -avoidversion - -client_old_la_SOURCES = client-protocol.c saved-frames.c - -client_old_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la \ - $(top_builddir)/xlators/protocol/legacy/lib/src/libgfproto.la - -noinst_HEADERS = client-protocol.h saved-frames.h client-mem-types.h - -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)/xlators/protocol/legacy/lib/src - -CLEANFILES = - -install-data-hook: - ln -sf client-old.so $(DESTDIR)$(xlatordir)/client.so diff --git a/xlators/protocol/legacy/client/src/client-mem-types.h b/xlators/protocol/legacy/client/src/client-mem-types.h deleted file mode 100644 index d2e2878c3..000000000 --- a/xlators/protocol/legacy/client/src/client-mem-types.h +++ /dev/null @@ -1,43 +0,0 @@ - -/* - Copyright (c) 2008-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 __CLIENT_MEM_TYPES_H__ -#define __CLIENT_MEM_TYPES_H__ - -#include "mem-types.h" - -enum gf_client_mem_types_ { - gf_client_mt_dir_entry_t = gf_common_mt_end + 1, - gf_client_mt_volfile_ctx, - gf_client_mt_client_state_t, - gf_client_mt_client_conf_t, - gf_client_mt_locker, - gf_client_mt_lock_table, - gf_client_mt_char, - gf_client_mt_client_connection_t, - gf_client_mt_client_fd_ctx_t, - gf_client_mt_client_local_t, - gf_client_mt_saved_frames, - gf_client_mt_saved_frame, - gf_client_mt_end -}; -#endif - diff --git a/xlators/protocol/legacy/client/src/client-protocol.c b/xlators/protocol/legacy/client/src/client-protocol.c deleted file mode 100644 index 804b93a5c..000000000 --- a/xlators/protocol/legacy/client/src/client-protocol.c +++ /dev/null @@ -1,6683 +0,0 @@ -/* - Copyright (c) 2006-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 <inttypes.h> - - -#include "glusterfs.h" -#include "client-protocol.h" -#include "compat.h" -#include "dict.h" -#include "protocol.h" -#include "transport.h" -#include "xlator.h" -#include "logging.h" -#include "timer.h" -#include "defaults.h" -#include "compat.h" -#include "compat-errno.h" -#include "statedump.h" -#include "client-mem-types.h" - -#include <sys/resource.h> -#include <inttypes.h> - -/* for default_*_cbk functions */ -#include "defaults.c" -#include "saved-frames.h" -#include "common-utils.h" - -int protocol_client_cleanup (transport_t *trans); -int protocol_client_interpret (xlator_t *this, transport_t *trans, - char *hdr_p, size_t hdrlen, - struct iobuf *iobuf); -int -protocol_client_xfer (call_frame_t *frame, xlator_t *this, transport_t *trans, - int type, int op, - gf_hdr_common_t *hdr, size_t hdrlen, - struct iovec *vector, int count, - struct iobref *iobref); - -int -protocol_client_post_handshake (call_frame_t *frame, xlator_t *this); - -static gf_op_t gf_fops[GF_PROTO_FOP_MAXVALUE]; -static gf_op_t gf_mops[GF_MOP_MAXVALUE]; -static gf_op_t gf_cbks[GF_CBK_MAXVALUE]; - - -transport_t * -client_channel (xlator_t *this, int id) -{ - transport_t *trans = NULL; - client_conf_t *conf = NULL; - int i = 0; - struct client_connection *conn = NULL; - - conf = this->private; - - trans = conf->transport[id]; - conn = trans->xl_private; - - if (conn->connected == 1) - goto ret; - - for (i = 0; i < CHANNEL_MAX; i++) { - trans = conf->transport[i]; - conn = trans->xl_private; - if (conn->connected == 1) - break; - } - -ret: - return trans; -} - - -client_fd_ctx_t * -this_fd_del_ctx (fd_t *file, xlator_t *this) -{ - int dict_ret = -1; - uint64_t ctxaddr = 0; - - GF_VALIDATE_OR_GOTO ("client", this, out); - GF_VALIDATE_OR_GOTO (this->name, file, out); - - dict_ret = fd_ctx_del (file, this, &ctxaddr); - - if (dict_ret < 0) { - ctxaddr = 0; - } - -out: - return (client_fd_ctx_t *)(unsigned long)ctxaddr; -} - - -client_fd_ctx_t * -this_fd_get_ctx (fd_t *file, xlator_t *this) -{ - int dict_ret = -1; - uint64_t ctxaddr = 0; - - GF_VALIDATE_OR_GOTO ("client", this, out); - GF_VALIDATE_OR_GOTO (this->name, file, out); - - dict_ret = fd_ctx_get (file, this, &ctxaddr); - - if (dict_ret < 0) { - ctxaddr = 0; - } - -out: - return (client_fd_ctx_t *)(unsigned long)ctxaddr; -} - - -static void -this_fd_set_ctx (fd_t *file, xlator_t *this, loc_t *loc, client_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_DEBUG, - "%s (%"PRId64"): trying duplicate remote fd set. ", - loc->path, loc->inode->ino); - else - gf_log (this->name, GF_LOG_DEBUG, - "%p: trying duplicate remote fd set. ", - file); - } - - ret = fd_ctx_set (file, this, (uint64_t)(unsigned long)ctx); - if (ret < 0) { - if (loc) - gf_log (this->name, GF_LOG_DEBUG, - "%s (%"PRId64"): failed to set remote fd", - loc->path, loc->inode->ino); - else - gf_log (this->name, GF_LOG_DEBUG, - "%p: failed to set remote fd", - file); - } -out: - return; -} - - -static int -client_local_wipe (client_local_t *local) -{ - if (local) { - loc_wipe (&local->loc); - - if (local->fd) - fd_unref (local->fd); - - mem_put (local); - } - - return 0; -} - -/* - * lookup_frame - lookup call frame corresponding to a given callid - * @trans: transport object - * @callid: call id of the frame - * - * not for external reference - */ - -static call_frame_t * -lookup_frame (transport_t *trans, int32_t op, int8_t type, int64_t callid) -{ - client_connection_t *conn = NULL; - call_frame_t *frame = NULL; - - conn = trans->xl_private; - - pthread_mutex_lock (&conn->lock); - { - frame = saved_frames_get (conn->saved_frames, - op, type, callid); - } - pthread_mutex_unlock (&conn->lock); - - return frame; -} - - -static void -call_bail (void *data) -{ - client_connection_t *conn = NULL; - struct timeval current; - transport_t *trans = NULL; - struct list_head list; - struct saved_frame *saved_frame = NULL; - struct saved_frame *trav = NULL; - struct saved_frame *tmp = NULL; - call_frame_t *frame = NULL; - gf_hdr_common_t hdr = {0, }; - char **gf_op_list = NULL; - gf_op_t *gf_ops = NULL; - struct tm frame_sent_tm; - char frame_sent[32] = {0,}; - struct timeval timeout = {0,}; - gf_timer_cbk_t timer_cbk = NULL; - - GF_VALIDATE_OR_GOTO ("client", data, out); - trans = data; - - conn = trans->xl_private; - - gettimeofday (¤t, NULL); - INIT_LIST_HEAD (&list); - - pthread_mutex_lock (&conn->lock); - { - /* Chaining to get call-always functionality from - call-once timer */ - if (conn->timer) { - timer_cbk = conn->timer->callbk; - - timeout.tv_sec = 10; - timeout.tv_usec = 0; - - gf_timer_call_cancel (trans->xl->ctx, conn->timer); - conn->timer = gf_timer_call_after (trans->xl->ctx, - timeout, - timer_cbk, - trans); - if (conn->timer == NULL) { - gf_log (trans->xl->name, GF_LOG_DEBUG, - "Cannot create bailout timer"); - } - } - - do { - saved_frame = - saved_frames_get_timedout (conn->saved_frames, - GF_OP_TYPE_MOP_REQUEST, - conn->frame_timeout, - ¤t); - if (saved_frame) - list_add (&saved_frame->list, &list); - - } while (saved_frame); - - do { - saved_frame = - saved_frames_get_timedout (conn->saved_frames, - GF_OP_TYPE_FOP_REQUEST, - conn->frame_timeout, - ¤t); - if (saved_frame) - list_add (&saved_frame->list, &list); - } while (saved_frame); - - do { - saved_frame = - saved_frames_get_timedout (conn->saved_frames, - GF_OP_TYPE_CBK_REQUEST, - conn->frame_timeout, - ¤t); - if (saved_frame) - list_add (&saved_frame->list, &list); - } while (saved_frame); - } - pthread_mutex_unlock (&conn->lock); - - hdr.rsp.op_ret = hton32 (-1); - hdr.rsp.op_errno = hton32 (ENOTCONN); - - list_for_each_entry_safe (trav, tmp, &list, list) { - switch (trav->type) - { - case GF_OP_TYPE_FOP_REQUEST: - gf_ops = gf_fops; - gf_op_list = gf_fop_list; - break; - case GF_OP_TYPE_MOP_REQUEST: - gf_ops = gf_mops; - gf_op_list = gf_mop_list; - break; - case GF_OP_TYPE_CBK_REQUEST: - gf_ops = gf_cbks; - gf_op_list = gf_cbk_list; - break; - default: - goto out; - } - - localtime_r (&trav->saved_at.tv_sec, &frame_sent_tm); - strftime (frame_sent, 32, "%Y-%m-%d %H:%M:%S", &frame_sent_tm); - - gf_log (trans->xl->name, GF_LOG_ERROR, - "bailing out frame %s(%d) " - "frame sent = %s. frame-timeout = %d", - gf_op_list[trav->op], trav->op, - frame_sent, conn->frame_timeout); - - hdr.type = hton32 (trav->type); - hdr.op = hton32 (trav->op); - - frame = trav->frame; - - gf_ops[trav->op] (frame, &hdr, sizeof (hdr), NULL); - - list_del_init (&trav->list); - GF_FREE (trav); - } -out: - return; -} - - -void -save_frame (transport_t *trans, call_frame_t *frame, - int32_t op, int8_t type, uint64_t callid) -{ - client_connection_t *conn = NULL; - struct timeval timeout = {0, }; - - - conn = trans->xl_private; - - saved_frames_put (conn->saved_frames, frame, op, type, callid); - - if (conn->timer == NULL && conn->frame_timeout) { - timeout.tv_sec = 10; - timeout.tv_usec = 0; - conn->timer = gf_timer_call_after (trans->xl->ctx, timeout, - call_bail, (void *) trans); - } -} - - - -void -client_ping_timer_expired (void *data) -{ - xlator_t *this = NULL; - transport_t *trans = NULL; - client_conf_t *conf = NULL; - client_connection_t *conn = NULL; - int disconnect = 0; - int transport_activity = 0; - struct timeval timeout = {0, }; - struct timeval current = {0, }; - - trans = data; - this = trans->xl; - conf = this->private; - conn = trans->xl_private; - - pthread_mutex_lock (&conn->lock); - { - if (conn->ping_timer) - gf_timer_call_cancel (trans->xl->ctx, - conn->ping_timer); - gettimeofday (¤t, NULL); - - pthread_mutex_lock (&conf->mutex); - { - if (((current.tv_sec - conf->last_received.tv_sec) < - conn->ping_timeout) - || ((current.tv_sec - conf->last_sent.tv_sec) < - conn->ping_timeout)) { - transport_activity = 1; - } - } - pthread_mutex_unlock (&conf->mutex); - - if (transport_activity) { - gf_log (this->name, GF_LOG_TRACE, - "ping timer expired but transport activity " - "detected - not bailing transport"); - conn->transport_activity = 0; - timeout.tv_sec = conn->ping_timeout; - timeout.tv_usec = 0; - - conn->ping_timer = - gf_timer_call_after (trans->xl->ctx, timeout, - client_ping_timer_expired, - (void *) trans); - if (conn->ping_timer == NULL) - gf_log (this->name, GF_LOG_DEBUG, - "unable to setup timer"); - - } else { - conn->ping_started = 0; - conn->ping_timer = NULL; - disconnect = 1; - } - } - pthread_mutex_unlock (&conn->lock); - if (disconnect) { - gf_log (this->name, GF_LOG_ERROR, - "Server %s has not responded in the last %d " - "seconds, disconnecting.", - conf->transport[0]->peerinfo.identifier, - conn->ping_timeout); - - transport_disconnect (conf->transport[0]); - transport_disconnect (conf->transport[1]); - } -} - - -void -client_start_ping (void *data) -{ - xlator_t *this = NULL; - transport_t *trans = NULL; - client_conf_t *conf = NULL; - client_connection_t *conn = NULL; - int32_t ret = -1; - gf_hdr_common_t *hdr = NULL; - struct timeval timeout = {0, }; - call_frame_t *dummy_frame = NULL; - size_t hdrlen = -1; - gf_mop_ping_req_t *req = NULL; - int frame_count = 0; - - - trans = data; - this = trans->xl; - conf = this->private; - conn = trans->xl_private; - - if (!conn->ping_timeout) - return; - - pthread_mutex_lock (&conn->lock); - { - if (conn->ping_timer) - gf_timer_call_cancel (trans->xl->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 */ - pthread_mutex_unlock (&conn->lock); - return; - } - - if (frame_count < 0) { - gf_log (this->name, GF_LOG_TRACE, - "saved_frames->count is %"PRId64, - conn->saved_frames->count); - conn->saved_frames->count = 0; - } - - timeout.tv_sec = conn->ping_timeout; - timeout.tv_usec = 0; - - conn->ping_timer = - gf_timer_call_after (trans->xl->ctx, timeout, - client_ping_timer_expired, - (void *) trans); - - if (conn->ping_timer == NULL) { - gf_log (this->name, GF_LOG_DEBUG, - "unable to setup timer"); - } else { - conn->ping_started = 1; - } - } - pthread_mutex_unlock (&conn->lock); - - hdrlen = gf_hdr_len (req, 0); - hdr = gf_hdr_new (req, 0); - if (!hdr) - goto err; - - dummy_frame = create_frame (this, this->ctx->pool); - - if (!dummy_frame) - goto err; - - dummy_frame->local = trans; - - ret = protocol_client_xfer (dummy_frame, this, trans, - GF_OP_TYPE_MOP_REQUEST, GF_MOP_PING, - hdr, hdrlen, NULL, 0, NULL); - return; -err: - if (hdr) - GF_FREE (hdr); - - if (dummy_frame) - STACK_DESTROY (dummy_frame->root); - - return; -} - - -int -client_ping_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen, - struct iobuf *iobuf) -{ - xlator_t *this = NULL; - transport_t *trans = NULL; - client_connection_t *conn = NULL; - struct timeval timeout = {0, }; - int op_ret = 0; - - trans = frame->local; frame->local = NULL; - this = trans->xl; - conn = trans->xl_private; - - op_ret = ntoh32 (hdr->rsp.op_ret); - - if (op_ret == -1) { - /* timer expired and transport bailed out */ - gf_log (this->name, GF_LOG_DEBUG, "timer must have expired"); - goto out; - } - - pthread_mutex_lock (&conn->lock); - { - timeout.tv_sec = conn->ping_timeout; - timeout.tv_usec = 0; - - gf_timer_call_cancel (trans->xl->ctx, - conn->ping_timer); - - conn->ping_timer = - gf_timer_call_after (trans->xl->ctx, timeout, - client_start_ping, (void *)trans); - if (conn->ping_timer == NULL) - gf_log (this->name, GF_LOG_DEBUG, - "gf_timer_call_after() returned NULL"); - } - pthread_mutex_unlock (&conn->lock); -out: - STACK_DESTROY (frame->root); - return 0; -} - -int -client_encode_groups (call_frame_t *frame, gf_hdr_common_t *hdr) -{ - int i = 0; - if ((!frame) || (!hdr)) - return -1; - - hdr->req.ngrps = hton32 (frame->root->ngrps); - if (frame->root->ngrps == 0) - return 0; - - for (; i < frame->root->ngrps; ++i) - hdr->req.groups[i] = hton32 (frame->root->groups[i]); - - return 0; -} - - -int -protocol_client_xfer (call_frame_t *frame, xlator_t *this, transport_t *trans, - int type, int op, - gf_hdr_common_t *hdr, size_t hdrlen, - struct iovec *vector, int count, - struct iobref *iobref) -{ - client_conf_t *conf = NULL; - client_connection_t *conn = NULL; - uint64_t callid = 0; - int32_t ret = -1; - int start_ping = 0; - gf_hdr_common_t rsphdr = {0, }; - - conf = this->private; - - if (!trans) { - /* default to bulk op since it is 'safer' */ - trans = conf->transport[CHANNEL_BULK]; - } - conn = trans->xl_private; - - pthread_mutex_lock (&conn->lock); - { - callid = ++conn->callid; - - hdr->callid = hton64 (callid); - hdr->op = hton32 (op); - hdr->type = hton32 (type); - - if (frame) { - hdr->req.uid = hton32 (frame->root->uid); - hdr->req.gid = hton32 (frame->root->gid); - hdr->req.pid = hton32 (frame->root->pid); - hdr->req.lk_owner = hton64 (frame->root->lk_owner); - client_encode_groups (frame, hdr); - } - - if (conn->connected == 0) - transport_connect (trans); - - ret = -1; - - if (conn->connected || - ((type == GF_OP_TYPE_MOP_REQUEST) && - (op == GF_MOP_SETVOLUME))) { - ret = transport_submit (trans, (char *)hdr, hdrlen, - vector, count, iobref); - } - - if ((ret >= 0) && frame) { - pthread_mutex_lock (&conf->mutex); - { - gettimeofday (&conf->last_sent, NULL); - } - pthread_mutex_unlock (&conf->mutex); - save_frame (trans, frame, op, type, callid); - } - - if (!conn->ping_started && (ret >= 0)) { - start_ping = 1; - } - } - pthread_mutex_unlock (&conn->lock); - - if (start_ping) - client_start_ping ((void *) trans); - - if (frame && (ret < 0)) { - rsphdr.op = op; - rsphdr.rsp.op_ret = hton32 (-1); - rsphdr.rsp.op_errno = hton32 (ENOTCONN); - - if (type == GF_OP_TYPE_FOP_REQUEST) { - rsphdr.type = GF_OP_TYPE_FOP_REPLY; - gf_fops[op] (frame, &rsphdr, sizeof (rsphdr), NULL); - } else if (type == GF_OP_TYPE_MOP_REQUEST) { - rsphdr.type = GF_OP_TYPE_MOP_REPLY; - gf_mops[op] (frame, &rsphdr, sizeof (rsphdr), NULL); - } else { - rsphdr.type = GF_OP_TYPE_CBK_REPLY; - gf_cbks[op] (frame, &rsphdr, sizeof (rsphdr), NULL); - } - - GF_FREE (hdr); - } - - return ret; -} - - - -/** - * client_create - create function for client protocol - * @frame: call frame - * @this: this translator structure - * @path: complete path to file - * @flags: create flags - * @mode: create mode - * - * external reference through client_protocol_xlator->fops->create - */ - -int -client_create (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags, - mode_t mode, fd_t *fd, dict_t *params) -{ - gf_hdr_common_t *hdr = NULL; - gf_fop_create_req_t *req = NULL; - size_t hdrlen = 0; - size_t pathlen = 0; - size_t baselen = 0; - int32_t ret = -1; - ino_t par = 0; - uint64_t gen = 0; - client_local_t *local = NULL; - - - local = GF_CALLOC (1, sizeof (*local), gf_client_mt_client_local_t); - GF_VALIDATE_OR_GOTO (this->name, local, unwind); - - local->fd = fd_ref (fd); - loc_copy (&local->loc, loc); - local->flags = flags; - - frame->local = local; - - pathlen = STRLEN_0 (loc->path); - baselen = STRLEN_0 (loc->name); - - ret = inode_ctx_get2 (loc->parent, this, &par, &gen); - if (loc->parent->ino && ret < 0) { - gf_log (this->name, GF_LOG_DEBUG, - "CREATE %"PRId64"/%s (%s): failed to get remote inode " - "number for parent inode", - loc->parent->ino, loc->name, loc->path); - goto unwind; - } - - hdrlen = gf_hdr_len (req, pathlen + baselen); - hdr = gf_hdr_new (req, pathlen + baselen); - GF_VALIDATE_OR_GOTO (this->name, hdr, unwind); - - req = gf_param (hdr); - - req->flags = hton32 (gf_flags_from_flags (flags)); - req->mode = hton32 (mode); - req->par = hton64 (par); - req->gen = hton64 (gen); - strcpy (req->path, loc->path); - strcpy (req->bname + pathlen, loc->name); - - ret = protocol_client_xfer (frame, this, - CLIENT_CHANNEL (this, CHANNEL_LOWLAT), - GF_OP_TYPE_FOP_REQUEST, GF_PROTO_FOP_CREATE, - hdr, hdrlen, NULL, 0, NULL); - return ret; -unwind: - if (hdr) - GF_FREE (hdr); - STACK_UNWIND (frame, -1, EINVAL, fd, NULL, NULL); - return 0; - -} - -/** - * client_open - open function for client protocol - * @frame: call frame - * @this: this translator structure - * @loc: location of file - * @flags: open flags - * @mode: open modes - * - * external reference through client_protocol_xlator->fops->open - */ - -int -client_open (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags, - fd_t *fd, int32_t wbflags) -{ - int ret = -1; - gf_hdr_common_t *hdr = NULL; - size_t hdrlen = 0; - gf_fop_open_req_t *req = NULL; - size_t pathlen = 0; - ino_t ino = 0; - uint64_t gen = 0; - client_local_t *local = NULL; - - local = GF_CALLOC (1, sizeof (*local), gf_client_mt_client_local_t); - GF_VALIDATE_OR_GOTO (this->name, local, unwind); - - local->fd = fd_ref (fd); - loc_copy (&local->loc, loc); - local->flags = flags; - local->wbflags = wbflags; - - frame->local = local; - - pathlen = STRLEN_0 (loc->path); - - ret = inode_ctx_get2 (loc->inode, this, &ino, &gen); - if (loc->inode->ino && ret < 0) { - gf_log (this->name, GF_LOG_DEBUG, - "OPEN %"PRId64" (%s): " - "failed to get remote inode number", - loc->inode->ino, loc->path); - goto unwind; - } - - hdrlen = gf_hdr_len (req, pathlen); - hdr = gf_hdr_new (req, pathlen); - GF_VALIDATE_OR_GOTO (this->name, hdr, unwind); - - req = gf_param (hdr); - - req->ino = hton64 (ino); - req->gen = hton64 (gen); - req->flags = hton32 (gf_flags_from_flags (flags)); - req->wbflags = hton32 (wbflags); - strcpy (req->path, loc->path); - - ret = protocol_client_xfer (frame, this, - CLIENT_CHANNEL (this, CHANNEL_LOWLAT), - GF_OP_TYPE_FOP_REQUEST, GF_PROTO_FOP_OPEN, - hdr, hdrlen, NULL, 0, NULL); - - return ret; -unwind: - if (hdr) - GF_FREE (hdr); - STACK_UNWIND (frame, -1, EINVAL, fd); - return 0; - -} - - -/** - * client_stat - stat function for client protocol - * @frame: call frame - * @this: this translator structure - * @loc: location - * - * external reference through client_protocol_xlator->fops->stat - */ - -int -client_stat (call_frame_t *frame, xlator_t *this, loc_t *loc) -{ - gf_hdr_common_t *hdr = NULL; - gf_fop_stat_req_t *req = NULL; - size_t hdrlen = -1; - int32_t ret = -1; - size_t pathlen = 0; - ino_t ino = 0; - ino_t gen = 0; - - pathlen = STRLEN_0 (loc->path); - - ret = inode_ctx_get2 (loc->inode, this, &ino, &gen); - if (loc->inode->ino && ret < 0) { - gf_log (this->name, GF_LOG_TRACE, - "STAT %"PRId64" (%s): " - "failed to get remote inode number", - loc->inode->ino, loc->path); - goto unwind; - } - - hdrlen = gf_hdr_len (req, pathlen); - hdr = gf_hdr_new (req, pathlen); - GF_VALIDATE_OR_GOTO (this->name, hdr, unwind); - - req = gf_param (hdr); - - req->ino = hton64 (ino); - req->gen = hton64 (gen); - strcpy (req->path, loc->path); - - ret = protocol_client_xfer (frame, this, - CLIENT_CHANNEL (this, CHANNEL_LOWLAT), - GF_OP_TYPE_FOP_REQUEST, GF_PROTO_FOP_STAT, - hdr, hdrlen, NULL, 0, NULL); - - return ret; -unwind: - if (hdr) - GF_FREE (hdr); - STACK_UNWIND (frame, -1, EINVAL, NULL); - return 0; - -} - - -/** - * client_readlink - readlink function for client protocol - * @frame: call frame - * @this: this translator structure - * @loc: location - * @size: - * - * external reference through client_protocol_xlator->fops->readlink - */ -int -client_readlink (call_frame_t *frame, xlator_t *this, loc_t *loc, size_t size) -{ - gf_hdr_common_t *hdr = NULL; - gf_fop_readlink_req_t *req = NULL; - size_t hdrlen = -1; - int ret = -1; - size_t pathlen = 0; - ino_t ino = 0; - uint64_t gen = 0; - - pathlen = STRLEN_0 (loc->path); - - ret = inode_ctx_get2 (loc->inode, this, &ino, &gen); - if (loc->inode->ino && ret < 0) { - gf_log (this->name, GF_LOG_DEBUG, - "READLINK %"PRId64" (%s): " - "failed to get remote inode number", - loc->inode->ino, loc->path); - goto unwind; - } - - hdrlen = gf_hdr_len (req, pathlen); - hdr = gf_hdr_new (req, pathlen); - GF_VALIDATE_OR_GOTO (this->name, hdr, unwind); - - req = gf_param (hdr); - - req->ino = hton64 (ino); - req->gen = hton64 (gen); - req->size = hton32 (size); - strcpy (req->path, loc->path); - - ret = protocol_client_xfer (frame, this, - CLIENT_CHANNEL (this, CHANNEL_LOWLAT), - GF_OP_TYPE_FOP_REQUEST, GF_PROTO_FOP_READLINK, - hdr, hdrlen, NULL, 0, NULL); - - return ret; -unwind: - if (hdr) - GF_FREE (hdr); - STACK_UNWIND_STRICT (readlink, frame, -1, EINVAL, - NULL, NULL); - return 0; - -} - - -/** - * client_mknod - mknod function for client protocol - * @frame: call frame - * @this: this translator structure - * @path: pathname of node - * @mode: - * @dev: - * - * external reference through client_protocol_xlator->fops->mknod - */ -int -client_mknod (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode, - dev_t dev, dict_t *params) -{ - gf_hdr_common_t *hdr = NULL; - gf_fop_mknod_req_t *req = NULL; - size_t hdrlen = -1; - int ret = -1; - size_t pathlen = 0; - size_t baselen = 0; - ino_t par = 0; - uint64_t gen = 0; - client_local_t *local = NULL; - - local = GF_CALLOC (1, sizeof (*local), gf_client_mt_client_local_t); - GF_VALIDATE_OR_GOTO (this->name, local, unwind); - - loc_copy (&local->loc, loc); - - frame->local = local; - - pathlen = STRLEN_0 (loc->path); - baselen = STRLEN_0 (loc->name); - ret = inode_ctx_get2 (loc->parent, this, &par, &gen); - if (loc->parent->ino && ret < 0) { - gf_log (this->name, GF_LOG_DEBUG, - "MKNOD %"PRId64"/%s (%s): failed to get remote inode " - "number for parent", - loc->parent->ino, loc->name, loc->path); - goto unwind; - } - - hdrlen = gf_hdr_len (req, pathlen + baselen); - hdr = gf_hdr_new (req, pathlen + baselen); - GF_VALIDATE_OR_GOTO (this->name, hdr, unwind); - - req = gf_param (hdr); - - req->par = hton64 (par); - req->gen = hton64 (gen); - req->mode = hton32 (mode); - req->dev = hton64 (dev); - strcpy (req->path, loc->path); - strcpy (req->bname + pathlen, loc->name); - - ret = protocol_client_xfer (frame, this, - CLIENT_CHANNEL (this, CHANNEL_LOWLAT), - GF_OP_TYPE_FOP_REQUEST, GF_PROTO_FOP_MKNOD, - hdr, hdrlen, NULL, 0, NULL); - - return ret; -unwind: - if (hdr) - GF_FREE (hdr); - STACK_UNWIND (frame, -1, EINVAL, loc->inode, NULL); - return 0; - -} - - -/** - * client_mkdir - mkdir function for client protocol - * @frame: call frame - * @this: this translator structure - * @path: pathname of directory - * @mode: - * - * external reference through client_protocol_xlator->fops->mkdir - */ -int -client_mkdir (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode, - dict_t *params) -{ - gf_hdr_common_t *hdr = NULL; - gf_fop_mkdir_req_t *req = NULL; - size_t hdrlen = -1; - int ret = -1; - size_t pathlen = 0; - size_t baselen = 0; - ino_t par = 0; - uint64_t gen = 0; - client_local_t *local = NULL; - - local = GF_CALLOC (1, sizeof (*local), gf_client_mt_client_local_t); - GF_VALIDATE_OR_GOTO (this->name, local, unwind); - - loc_copy (&local->loc, loc); - - frame->local = local; - - pathlen = STRLEN_0 (loc->path); - baselen = STRLEN_0 (loc->name); - ret = inode_ctx_get2 (loc->parent, this, &par, &gen); - if (loc->parent->ino && ret < 0) { - gf_log (this->name, GF_LOG_DEBUG, - "MKDIR %"PRId64"/%s (%s): failed to get remote inode " - "number for parent", - loc->parent->ino, loc->name, loc->path); - goto unwind; - } - - hdrlen = gf_hdr_len (req, pathlen + baselen); - hdr = gf_hdr_new (req, pathlen + baselen); - GF_VALIDATE_OR_GOTO (this->name, hdr, unwind); - - req = gf_param (hdr); - - req->par = hton64 (par); - req->gen = hton64 (gen); - req->mode = hton32 (mode); - strcpy (req->path, loc->path); - strcpy (req->bname + pathlen, loc->name); - - ret = protocol_client_xfer (frame, this, - CLIENT_CHANNEL (this, CHANNEL_LOWLAT), - GF_OP_TYPE_FOP_REQUEST, GF_PROTO_FOP_MKDIR, - hdr, hdrlen, NULL, 0, NULL); - - return ret; -unwind: - if (hdr) - GF_FREE (hdr); - STACK_UNWIND (frame, -1, EINVAL, loc->inode, NULL); - return 0; - -} - -/** - * client_unlink - unlink function for client protocol - * @frame: call frame - * @this: this translator structure - * @loc: location of file - * - * external reference through client_protocol_xlator->fops->unlink - */ - -int -client_unlink (call_frame_t *frame, xlator_t *this, loc_t *loc) -{ - gf_hdr_common_t *hdr = NULL; - gf_fop_unlink_req_t *req = NULL; - size_t hdrlen = -1; - int ret = -1; - size_t pathlen = 0; - size_t baselen = 0; - ino_t par = 0; - uint64_t gen = 0; - - pathlen = STRLEN_0 (loc->path); - baselen = STRLEN_0 (loc->name); - ret = inode_ctx_get2 (loc->parent, this, &par, &gen); - if (loc->parent->ino && ret < 0) { - gf_log (this->name, GF_LOG_DEBUG, - "UNLINK %"PRId64"/%s (%s): failed to get remote inode " - "number for parent", - loc->parent->ino, loc->name, loc->path); - goto unwind; - } - - hdrlen = gf_hdr_len (req, pathlen + baselen); - hdr = gf_hdr_new (req, pathlen + baselen); - GF_VALIDATE_OR_GOTO (this->name, hdr, unwind); - - req = gf_param (hdr); - - req->par = hton64 (par); - req->gen = hton64 (gen); - strcpy (req->path, loc->path); - strcpy (req->bname + pathlen, loc->name); - - ret = protocol_client_xfer (frame, this, - CLIENT_CHANNEL (this, CHANNEL_BULK), - GF_OP_TYPE_FOP_REQUEST, GF_PROTO_FOP_UNLINK, - hdr, hdrlen, NULL, 0, NULL); - - return ret; -unwind: - if (hdr) - GF_FREE (hdr); - STACK_UNWIND (frame, -1, EINVAL); - return 0; - -} - -/** - * client_rmdir - rmdir function for client protocol - * @frame: call frame - * @this: this translator structure - * @loc: location - * - * external reference through client_protocol_xlator->fops->rmdir - */ - -int -client_rmdir (call_frame_t *frame, xlator_t *this, loc_t *loc) -{ - gf_hdr_common_t *hdr = NULL; - gf_fop_rmdir_req_t *req = NULL; - size_t hdrlen = -1; - int ret = -1; - size_t pathlen = 0; - size_t baselen = 0; - ino_t par = 0; - uint64_t gen = 0; - - pathlen = STRLEN_0 (loc->path); - baselen = STRLEN_0 (loc->name); - ret = inode_ctx_get2 (loc->parent, this, &par, &gen); - if (loc->parent->ino && ret < 0) { - gf_log (this->name, GF_LOG_DEBUG, - "RMDIR %"PRId64"/%s (%s): failed to get remote inode " - "number for parent", - loc->parent->ino, loc->name, loc->path); - goto unwind; - } - - hdrlen = gf_hdr_len (req, pathlen + baselen); - hdr = gf_hdr_new (req, pathlen + baselen); - GF_VALIDATE_OR_GOTO (this->name, hdr, unwind); - - req = gf_param (hdr); - - req->par = hton64 (par); - req->gen = hton64 (gen); - strcpy (req->path, loc->path); - strcpy (req->bname + pathlen, loc->name); - - ret = protocol_client_xfer (frame, this, - CLIENT_CHANNEL (this, CHANNEL_BULK), - GF_OP_TYPE_FOP_REQUEST, GF_PROTO_FOP_RMDIR, - hdr, hdrlen, NULL, 0, NULL); - - return ret; -unwind: - if (hdr) - GF_FREE (hdr); - STACK_UNWIND (frame, -1, EINVAL); - return 0; - -} - - -/** - * client_symlink - symlink function for client protocol - * @frame: call frame - * @this: this translator structure - * @oldpath: pathname of target - * @newpath: pathname of symlink - * - * external reference through client_protocol_xlator->fops->symlink - */ - -int -client_symlink (call_frame_t *frame, xlator_t *this, const char *linkname, - loc_t *loc, dict_t *params) -{ - int ret = -1; - gf_hdr_common_t *hdr = NULL; - gf_fop_symlink_req_t *req = NULL; - size_t hdrlen = 0; - size_t pathlen = 0; - size_t newlen = 0; - size_t baselen = 0; - ino_t par = 0; - uint64_t gen = 0; - client_local_t *local = NULL; - - local = GF_CALLOC (1, sizeof (*local), gf_client_mt_client_local_t); - GF_VALIDATE_OR_GOTO (this->name, local, unwind); - - loc_copy (&local->loc, loc); - - frame->local = local; - - pathlen = STRLEN_0 (loc->path); - baselen = STRLEN_0 (loc->name); - newlen = STRLEN_0 (linkname); - ret = inode_ctx_get2 (loc->parent, this, &par, &gen); - if (loc->parent->ino && ret < 0) { - gf_log (this->name, GF_LOG_DEBUG, - "SYMLINK %"PRId64"/%s (%s): failed to get remote inode" - " number parent", - loc->parent->ino, loc->name, loc->path); - goto unwind; - } - - hdrlen = gf_hdr_len (req, pathlen + baselen + newlen); - hdr = gf_hdr_new (req, pathlen + baselen + newlen); - GF_VALIDATE_OR_GOTO (this->name, hdr, unwind); - - req = gf_param (hdr); - - req->par = hton64 (par); - req->gen = hton64 (gen); - strcpy (req->path, loc->path); - strcpy (req->bname + pathlen, loc->name); - strcpy (req->linkname + pathlen + baselen, linkname); - - ret = protocol_client_xfer (frame, this, - CLIENT_CHANNEL (this, CHANNEL_LOWLAT), - GF_OP_TYPE_FOP_REQUEST, GF_PROTO_FOP_SYMLINK, - hdr, hdrlen, NULL, 0, NULL); - return ret; -unwind: - if (hdr) - GF_FREE (hdr); - STACK_UNWIND (frame, -1, EINVAL, loc->inode, NULL); - return 0; - -} - -/** - * client_rename - rename function for client protocol - * @frame: call frame - * @this: this translator structure - * @oldloc: location of old pathname - * @newloc: location of new pathname - * - * external reference through client_protocol_xlator->fops->rename - */ - -int -client_rename (call_frame_t *frame, xlator_t *this, loc_t *oldloc, - loc_t *newloc) -{ - int ret = -1; - gf_hdr_common_t *hdr = NULL; - gf_fop_rename_req_t *req = NULL; - size_t hdrlen = 0; - size_t oldpathlen = 0; - size_t oldbaselen = 0; - size_t newpathlen = 0; - size_t newbaselen = 0; - ino_t oldpar = 0; - uint64_t oldgen = 0; - ino_t newpar = 0; - uint64_t newgen = 0; - - oldpathlen = STRLEN_0 (oldloc->path); - oldbaselen = STRLEN_0 (oldloc->name); - newpathlen = STRLEN_0 (newloc->path); - newbaselen = STRLEN_0 (newloc->name); - ret = inode_ctx_get2 (oldloc->parent, this, &oldpar, &oldgen); - if (oldloc->parent->ino && ret < 0) { - gf_log (this->name, GF_LOG_DEBUG, - "RENAME %"PRId64"/%s (%s): failed to get remote inode " - "number for source parent", - oldloc->parent->ino, oldloc->name, oldloc->path); - goto unwind; - } - - ret = inode_ctx_get2 (newloc->parent, this, &newpar, &newgen); - if (newloc->parent->ino && ret < 0) { - gf_log (this->name, GF_LOG_DEBUG, - "CREATE %"PRId64"/%s (%s): failed to get remote inode " - "number for destination parent", - newloc->parent->ino, newloc->name, newloc->path); - goto unwind; - } - - hdrlen = gf_hdr_len (req, (oldpathlen + oldbaselen + - newpathlen + newbaselen)); - hdr = gf_hdr_new (req, (oldpathlen + oldbaselen + - newpathlen + newbaselen)); - - GF_VALIDATE_OR_GOTO (this->name, hdr, unwind); - - req = gf_param (hdr); - - req->oldpar = hton64 (oldpar); - req->oldgen = hton64 (oldgen); - req->newpar = hton64 (newpar); - req->newgen = hton64 (newgen); - - strcpy (req->oldpath, oldloc->path); - strcpy (req->oldbname + oldpathlen, oldloc->name); - strcpy (req->newpath + oldpathlen + oldbaselen, newloc->path); - strcpy (req->newbname + oldpathlen + oldbaselen + newpathlen, - newloc->name); - - ret = protocol_client_xfer (frame, this, - CLIENT_CHANNEL (this, CHANNEL_LOWLAT), - GF_OP_TYPE_FOP_REQUEST, GF_PROTO_FOP_RENAME, - hdr, hdrlen, NULL, 0, NULL); - return ret; -unwind: - if (hdr) - GF_FREE (hdr); - STACK_UNWIND (frame, -1, EINVAL, NULL); - return 0; - -} - -/** - * client_link - link function for client protocol - * @frame: call frame - * @this: this translator structure - * @oldloc: location of old pathname - * @newpath: new pathname - * - * external reference through client_protocol_xlator->fops->link - */ - -int -client_link (call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc) -{ - int ret = -1; - gf_hdr_common_t *hdr = NULL; - gf_fop_link_req_t *req = NULL; - size_t hdrlen = 0; - size_t oldpathlen = 0; - size_t newpathlen = 0; - size_t newbaselen = 0; - ino_t oldino = 0; - uint64_t oldgen = 0; - ino_t newpar = 0; - uint64_t newgen = 0; - client_local_t *local = NULL; - - local = GF_CALLOC (1, sizeof (*local), gf_client_mt_client_local_t); - GF_VALIDATE_OR_GOTO (this->name, local, unwind); - - loc_copy (&local->loc, oldloc); - - frame->local = local; - - oldpathlen = STRLEN_0 (oldloc->path); - newpathlen = STRLEN_0 (newloc->path); - newbaselen = STRLEN_0 (newloc->name); - - ret = inode_ctx_get2 (oldloc->inode, this, &oldino, &oldgen); - if (oldloc->inode->ino && ret < 0) { - gf_log (this->name, GF_LOG_DEBUG, - "LINK %"PRId64"/%s (%s) ==> %"PRId64" (%s): " - "failed to get remote inode number for source inode", - newloc->parent->ino, newloc->name, newloc->path, - oldloc->ino, oldloc->path); - goto unwind; - } - - ret = inode_ctx_get2 (newloc->parent, this, &newpar, &newgen); - if (newloc->parent->ino && ret < 0) { - gf_log (this->name, GF_LOG_DEBUG, - "LINK %"PRId64"/%s (%s) ==> %"PRId64" (%s): " - "failed to get remote inode number destination parent", - newloc->parent->ino, newloc->name, newloc->path, - oldloc->ino, oldloc->path); - goto unwind; - } - - hdrlen = gf_hdr_len (req, oldpathlen + newpathlen + newbaselen); - hdr = gf_hdr_new (req, oldpathlen + newpathlen + newbaselen); - GF_VALIDATE_OR_GOTO (this->name, hdr, unwind); - - req = gf_param (hdr); - - strcpy (req->oldpath, oldloc->path); - strcpy (req->newpath + oldpathlen, newloc->path); - strcpy (req->newbname + oldpathlen + newpathlen, newloc->name); - - req->oldino = hton64 (oldino); - req->oldgen = hton64 (oldgen); - req->newpar = hton64 (newpar); - req->newgen = hton64 (newgen); - - ret = protocol_client_xfer (frame, this, - CLIENT_CHANNEL (this, CHANNEL_LOWLAT), - GF_OP_TYPE_FOP_REQUEST, GF_PROTO_FOP_LINK, - hdr, hdrlen, NULL, 0, NULL); - return ret; -unwind: - if (hdr) - GF_FREE (hdr); - STACK_UNWIND (frame, -1, EINVAL, oldloc->inode, NULL); - return 0; -} - - -/** - * client_truncate - truncate function for client protocol - * @frame: call frame - * @this: this translator structure - * @loc: location - * @offset: - * - * external reference through client_protocol_xlator->fops->truncate - */ - -int -client_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset) -{ - gf_hdr_common_t *hdr = NULL; - gf_fop_truncate_req_t *req = NULL; - size_t hdrlen = -1; - int ret = -1; - size_t pathlen = 0; - ino_t ino = 0; - uint64_t gen = 0; - - pathlen = STRLEN_0 (loc->path); - ret = inode_ctx_get2 (loc->inode, this, &ino, &gen); - if (loc->inode->ino && ret < 0) { - gf_log (this->name, GF_LOG_DEBUG, - "TRUNCATE %"PRId64" (%s): " - "failed to get remote inode number", - loc->inode->ino, loc->path); - goto unwind; - } - - hdrlen = gf_hdr_len (req, pathlen); - hdr = gf_hdr_new (req, pathlen); - GF_VALIDATE_OR_GOTO (this->name, hdr, unwind); - - req = gf_param (hdr); - - req->ino = hton64 (ino); - req->gen = hton64 (gen); - req->offset = hton64 (offset); - strcpy (req->path, loc->path); - - ret = protocol_client_xfer (frame, this, - CLIENT_CHANNEL (this, CHANNEL_BULK), - GF_OP_TYPE_FOP_REQUEST, GF_PROTO_FOP_TRUNCATE, - hdr, hdrlen, NULL, 0, NULL); - - return ret; -unwind: - if (hdr) - GF_FREE (hdr); - STACK_UNWIND (frame, -1, EINVAL, NULL); - return 0; - -} - - -/** - * client_readv - readv function for client protocol - * @frame: call frame - * @this: this translator structure - * @fd: file descriptor structure - * @size: - * @offset: - * - * external reference through client_protocol_xlator->fops->readv - */ - -int -client_readv (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, - off_t offset) -{ - gf_hdr_common_t *hdr = NULL; - gf_fop_read_req_t *req = NULL; - size_t hdrlen = 0; - int64_t remote_fd = -1; - int ret = -1; - client_fd_ctx_t *fdctx = NULL; - client_conf_t *conf = NULL; - - conf = this->private; - - pthread_mutex_lock (&conf->mutex); - { - fdctx = this_fd_get_ctx (fd, this); - } - pthread_mutex_unlock (&conf->mutex); - - if (fdctx == NULL) { - gf_log (this->name, GF_LOG_TRACE, - "(%"PRId64"): failed to get fd ctx, EBADFD", - fd->inode->ino); - STACK_UNWIND (frame, -1, EBADFD, NULL, 0, NULL); - return 0; - } - - if (fdctx->remote_fd == -1) { - gf_log (this->name, GF_LOG_TRACE, - "(%"PRId64"): failed to get fd ctx, EBADFD", - fd->inode->ino); - STACK_UNWIND (frame, -1, EBADFD, NULL, 0, NULL); - return 0; - } - - remote_fd = fdctx->remote_fd; - hdrlen = gf_hdr_len (req, 0); - hdr = gf_hdr_new (req, 0); - GF_VALIDATE_OR_GOTO (this->name, hdr, unwind); - - req = gf_param (hdr); - - req->fd = hton64 (remote_fd); - req->size = hton32 (size); - req->offset = hton64 (offset); - - ret = protocol_client_xfer (frame, this, - CLIENT_CHANNEL (this, CHANNEL_BULK), - GF_OP_TYPE_FOP_REQUEST, GF_PROTO_FOP_READ, - hdr, hdrlen, NULL, 0, NULL); - - return 0; -unwind: - if (hdr) - GF_FREE (hdr); - STACK_UNWIND (frame, -1, EINVAL, NULL, 0, NULL); - return 0; - -} - -/** - * client_writev - writev function for client protocol - * @frame: call frame - * @this: this translator structure - * @fd: file descriptor structure - * @vector: - * @count: - * @offset: - * - * external reference through client_protocol_xlator->fops->writev - */ - -int -client_writev (call_frame_t *frame, xlator_t *this, fd_t *fd, - struct iovec *vector, int32_t count, off_t offset, - struct iobref *iobref) -{ - gf_hdr_common_t *hdr = NULL; - gf_fop_write_req_t *req = NULL; - size_t hdrlen = 0; - int64_t remote_fd = -1; - int ret = -1; - client_fd_ctx_t *fdctx = NULL; - client_conf_t *conf = NULL; - - conf = this->private; - - pthread_mutex_lock (&conf->mutex); - { - fdctx = this_fd_get_ctx (fd, this); - } - pthread_mutex_unlock (&conf->mutex); - - if (fdctx == NULL) { - gf_log (this->name, GF_LOG_TRACE, - "(%"PRId64"): failed to get fd ctx. EBADFD", - fd->inode->ino); - STACK_UNWIND (frame, -1, EBADFD, NULL); - return 0; - } - - if (fdctx->remote_fd == -1) { - gf_log (this->name, GF_LOG_TRACE, - "(%"PRId64"): failed to get fd ctx. EBADFD", - fd->inode->ino); - STACK_UNWIND (frame, -1, EBADFD, NULL); - return 0; - } - - remote_fd = fdctx->remote_fd; - hdrlen = gf_hdr_len (req, 0); - hdr = gf_hdr_new (req, 0); - GF_VALIDATE_OR_GOTO (this->name, hdr, unwind); - - req = gf_param (hdr); - - req->fd = hton64 (remote_fd); - req->size = hton32 (iov_length (vector, count)); - req->offset = hton64 (offset); - - ret = protocol_client_xfer (frame, this, - CLIENT_CHANNEL (this, CHANNEL_BULK), - GF_OP_TYPE_FOP_REQUEST, GF_PROTO_FOP_WRITE, - hdr, hdrlen, vector, count, iobref); - return ret; -unwind: - if (hdr) - GF_FREE (hdr); - STACK_UNWIND (frame, -1, EINVAL, NULL); - return 0; - -} - - -/** - * client_statfs - statfs function for client protocol - * @frame: call frame - * @this: this translator structure - * @loc: location - * - * external reference through client_protocol_xlator->fops->statfs - */ - -int -client_statfs (call_frame_t *frame, xlator_t *this, loc_t *loc) -{ - gf_hdr_common_t *hdr = NULL; - gf_fop_statfs_req_t *req = NULL; - size_t hdrlen = -1; - int ret = -1; - size_t pathlen = 0; - ino_t ino = 0; - ino_t gen = 0; - - pathlen = STRLEN_0 (loc->path); - - if (loc->inode) { - ret = inode_ctx_get2 (loc->inode, this, &ino, &gen); - if (loc->inode->ino && ret < 0) { - gf_log (this->name, GF_LOG_DEBUG, - "STATFS %"PRId64" (%s): " - "failed to get remote inode number", - loc->inode->ino, loc->path); - goto unwind; - } - } - - hdrlen = gf_hdr_len (req, pathlen); - hdr = gf_hdr_new (req, pathlen); - GF_VALIDATE_OR_GOTO (this->name, hdr, unwind); - - req = gf_param (hdr); - - req->ino = hton64 (ino); - req->gen = hton64 (gen); - strcpy (req->path, loc->path); - - ret = protocol_client_xfer (frame, this, - CLIENT_CHANNEL (this, CHANNEL_LOWLAT), - GF_OP_TYPE_FOP_REQUEST, GF_PROTO_FOP_STATFS, - hdr, hdrlen, NULL, 0, NULL); - - return ret; -unwind: - if (hdr) - GF_FREE (hdr); - STACK_UNWIND (frame, -1, EINVAL, NULL); - return 0; - -} - - -/** - * client_flush - flush function for client protocol - * @frame: call frame - * @this: this translator structure - * @fd: file descriptor structure - * - * external reference through client_protocol_xlator->fops->flush - */ - -int -client_flush (call_frame_t *frame, xlator_t *this, fd_t *fd) -{ - gf_hdr_common_t *hdr = NULL; - gf_fop_flush_req_t *req = NULL; - size_t hdrlen = 0; - int64_t remote_fd = -1; - int ret = -1; - client_fd_ctx_t *fdctx = NULL; - client_conf_t *conf = NULL; - - conf = this->private; - - pthread_mutex_lock (&conf->mutex); - { - fdctx = this_fd_get_ctx (fd, this); - } - pthread_mutex_unlock (&conf->mutex); - - if (fdctx == NULL) { - gf_log (this->name, GF_LOG_TRACE, - "(%"PRId64"): failed to get fd ctx. EBADFD", - fd->inode->ino); - STACK_UNWIND (frame, -1, EBADFD); - return 0; - } - - if (fdctx->remote_fd == -1) { - gf_log (this->name, GF_LOG_TRACE, - "(%"PRId64"): failed to get fd ctx. EBADFD", - fd->inode->ino); - STACK_UNWIND (frame, -1, EBADFD); - return 0; - } - - remote_fd = fdctx->remote_fd; - hdrlen = gf_hdr_len (req, 0); - hdr = gf_hdr_new (req, 0); - GF_VALIDATE_OR_GOTO (this->name, hdr, unwind); - - req = gf_param (hdr); - - req->fd = hton64 (remote_fd); - - ret = protocol_client_xfer (frame, this, - CLIENT_CHANNEL (this, CHANNEL_BULK), - GF_OP_TYPE_FOP_REQUEST, GF_PROTO_FOP_FLUSH, - hdr, hdrlen, NULL, 0, NULL); - - return 0; -unwind: - if (hdr) - GF_FREE (hdr); - STACK_UNWIND (frame, -1, EINVAL); - return 0; - -} - -/** - * client_fsync - fsync function for client protocol - * @frame: call frame - * @this: this translator structure - * @fd: file descriptor structure - * @flags: - * - * external reference through client_protocol_xlator->fops->fsync - */ - -int -client_fsync (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t flags) -{ - gf_hdr_common_t *hdr = NULL; - gf_fop_fsync_req_t *req = NULL; - size_t hdrlen = 0; - int64_t remote_fd = -1; - int32_t ret = -1; - client_fd_ctx_t *fdctx = NULL; - client_conf_t *conf = NULL; - - conf = this->private; - - pthread_mutex_lock (&conf->mutex); - { - fdctx = this_fd_get_ctx (fd, this); - } - pthread_mutex_unlock (&conf->mutex); - - if (fdctx == NULL) { - gf_log (this->name, GF_LOG_TRACE, - "(%"PRId64"): failed to get fd ctx. EBADFD", - fd->inode->ino); - STACK_UNWIND (frame, -1, EBADFD); - return 0; - } - - if (fdctx->remote_fd == -1) { - gf_log (this->name, GF_LOG_TRACE, - "(%"PRId64"): failed to get fd ctx. EBADFD", - fd->inode->ino); - STACK_UNWIND (frame, -1, EBADFD); - return 0; - } - - remote_fd = fdctx->remote_fd; - hdrlen = gf_hdr_len (req, 0); - hdr = gf_hdr_new (req, 0); - GF_VALIDATE_OR_GOTO (this->name, hdr, unwind); - - req = gf_param (hdr); - - req->fd = hton64 (remote_fd); - req->data = hton32 (flags); - - ret = protocol_client_xfer (frame, this, - CLIENT_CHANNEL (this, CHANNEL_BULK), - GF_OP_TYPE_FOP_REQUEST, GF_PROTO_FOP_FSYNC, - hdr, hdrlen, NULL, 0, NULL); - - return ret; -unwind: - if (hdr) - GF_FREE (hdr); - STACK_UNWIND (frame, -1, EINVAL); - return 0; - -} - -int -client_xattrop (call_frame_t *frame, xlator_t *this, loc_t *loc, - gf_xattrop_flags_t flags, dict_t *dict) -{ - gf_hdr_common_t *hdr = NULL; - gf_fop_xattrop_req_t *req = NULL; - size_t hdrlen = 0; - size_t dict_len = 0; - int32_t ret = -1; - size_t pathlen = 0; - ino_t ino = 0; - uint64_t gen = 0; - char *buf = NULL; - - GF_VALIDATE_OR_GOTO ("client", this, unwind); - - GF_VALIDATE_OR_GOTO (this->name, loc, unwind); - - if (dict) { - ret = dict_allocate_and_serialize (dict, &buf, &dict_len); - if (ret < 0) { - gf_log (this->name, GF_LOG_DEBUG, - "failed to get serialized length of dict(%p)", - dict); - goto unwind; - } - } - - pathlen = STRLEN_0 (loc->path); - - ret = inode_ctx_get2 (loc->inode, this, &ino, &gen); - if (loc->inode->ino && ret < 0) { - gf_log (this->name, GF_LOG_DEBUG, - "XATTROP %"PRId64" (%s): " - "failed to get remote inode number", - loc->inode->ino, loc->path); - goto unwind; - } - - hdrlen = gf_hdr_len (req, dict_len + pathlen); - hdr = gf_hdr_new (req, dict_len + pathlen); - GF_VALIDATE_OR_GOTO (this->name, hdr, unwind); - - req = gf_param (hdr); - - req->flags = hton32 (flags); - req->dict_len = hton32 (dict_len); - if (dict) { - memcpy (req->dict, buf, dict_len); - GF_FREE (buf); - } - - req->ino = hton64 (ino); - req->gen = hton64 (gen); - strcpy (req->path + dict_len, loc->path); - - ret = protocol_client_xfer (frame, this, - CLIENT_CHANNEL (this, CHANNEL_BULK), - GF_OP_TYPE_FOP_REQUEST, GF_PROTO_FOP_XATTROP, - hdr, hdrlen, NULL, 0, NULL); - return ret; -unwind: - if (hdr) - GF_FREE (hdr); - - STACK_UNWIND (frame, -1, EINVAL, NULL); - return 0; -} - - -int -client_fxattrop (call_frame_t *frame, xlator_t *this, fd_t *fd, - gf_xattrop_flags_t flags, dict_t *dict) -{ - gf_hdr_common_t *hdr = NULL; - gf_fop_fxattrop_req_t *req = NULL; - size_t hdrlen = 0; - size_t dict_len = 0; - int64_t remote_fd = -1; - int32_t ret = -1; - ino_t ino = 0; - client_fd_ctx_t *fdctx = NULL; - client_conf_t *conf = NULL; - - conf = this->private; - - if (dict) { - dict_len = dict_serialized_length (dict); - if (dict_len < 0) { - gf_log (this->name, GF_LOG_DEBUG, - "failed to get serialized length of dict(%p)", - dict); - goto unwind; - } - } - - pthread_mutex_lock (&conf->mutex); - { - fdctx = this_fd_get_ctx (fd, this); - } - pthread_mutex_unlock (&conf->mutex); - - if (fdctx == NULL) { - gf_log (this->name, GF_LOG_TRACE, - "(%"PRId64"): failed to get fd ctx. " - "returning EBADFD", - fd->inode->ino); - goto unwind; - } - - if (fdctx->remote_fd == -1) { - gf_log (this->name, GF_LOG_TRACE, - "(%"PRId64"): failed to get fd ctx. EBADFD", - fd->inode->ino); - goto unwind; - } - - ino = fd->inode->ino; - remote_fd = fdctx->remote_fd; - - hdrlen = gf_hdr_len (req, dict_len); - hdr = gf_hdr_new (req, dict_len); - GF_VALIDATE_OR_GOTO (this->name, hdr, unwind); - - req = gf_param (hdr); - - req->flags = hton32 (flags); - req->dict_len = hton32 (dict_len); - if (dict) { - ret = dict_serialize (dict, req->dict); - if (ret < 0) { - gf_log (this->name, GF_LOG_DEBUG, - "failed to serialize dictionary(%p)", - dict); - goto unwind; - } - } - req->fd = hton64 (remote_fd); - req->ino = hton64 (ino); - - ret = protocol_client_xfer (frame, this, - CLIENT_CHANNEL (this, CHANNEL_BULK), - GF_OP_TYPE_FOP_REQUEST, GF_PROTO_FOP_FXATTROP, - hdr, hdrlen, NULL, 0, NULL); - return ret; -unwind: - if (hdr) - GF_FREE (hdr); - - STACK_UNWIND (frame, -1, EBADFD, NULL); - return 0; - -} - -/** - * client_setxattr - setxattr function for client protocol - * @frame: call frame - * @this: this translator structure - * @loc: location - * @dict: dictionary which contains key:value to be set. - * @flags: - * - * external reference through client_protocol_xlator->fops->setxattr - */ - -int -client_setxattr (call_frame_t *frame, xlator_t *this, loc_t *loc, - dict_t *dict, int32_t flags) -{ - gf_hdr_common_t *hdr = NULL; - gf_fop_setxattr_req_t *req = NULL; - size_t hdrlen = 0; - size_t dict_len = 0; - int ret = -1; - size_t pathlen = 0; - ino_t ino = 0; - uint64_t gen = 0; - - dict_len = dict_serialized_length (dict); - if (dict_len < 0) { - gf_log (this->name, GF_LOG_DEBUG, - "failed to get serialized length of dict(%p)", - dict); - goto unwind; - } - - pathlen = STRLEN_0 (loc->path); - - ret = inode_ctx_get2 (loc->inode, this, &ino, &gen); - if (loc->inode->ino && ret < 0) { - gf_log (this->name, GF_LOG_DEBUG, - "SETXATTR %"PRId64" (%s): " - "failed to get remote inode number", - loc->inode->ino, loc->path); - goto unwind; - } - - hdrlen = gf_hdr_len (req, dict_len + pathlen); - hdr = gf_hdr_new (req, dict_len + pathlen); - GF_VALIDATE_OR_GOTO (this->name, hdr, unwind); - - req = gf_param (hdr); - - req->ino = hton64 (ino); - req->gen = hton64 (gen); - req->flags = hton32 (flags); - req->dict_len = hton32 (dict_len); - - ret = dict_serialize (dict, req->dict); - if (ret < 0) { - gf_log (this->name, GF_LOG_DEBUG, - "failed to serialize dictionary(%p)", - dict); - goto unwind; - } - - strcpy (req->path + dict_len, loc->path); - - ret = protocol_client_xfer (frame, this, - CLIENT_CHANNEL (this, CHANNEL_BULK), - GF_OP_TYPE_FOP_REQUEST, GF_PROTO_FOP_SETXATTR, - hdr, hdrlen, NULL, 0, NULL); - return ret; -unwind: - if (hdr) - GF_FREE (hdr); - - STACK_UNWIND (frame, -1, EINVAL); - return 0; -} - -/** - * client_fsetxattr - fsetxattr function for client protocol - * @frame: call frame - * @this: this translator structure - * @fd: fd - * @dict: dictionary which contains key:value to be set. - * @flags: - * - * external reference through client_protocol_xlator->fops->fsetxattr - */ - -int -client_fsetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd, - dict_t *dict, int32_t flags) -{ - gf_hdr_common_t *hdr = NULL; - gf_fop_fsetxattr_req_t *req = NULL; - size_t hdrlen = 0; - size_t dict_len = 0; - ino_t ino; - int ret = -1; - int64_t remote_fd = -1; - client_fd_ctx_t *fdctx = NULL; - client_conf_t *conf = NULL; - - conf = this->private; - - dict_len = dict_serialized_length (dict); - if (dict_len < 0) { - gf_log (this->name, GF_LOG_DEBUG, - "failed to get serialized length of dict(%p)", - dict); - goto unwind; - } - - pthread_mutex_lock (&conf->mutex); - { - fdctx = this_fd_get_ctx (fd, this); - } - pthread_mutex_unlock (&conf->mutex); - - if (fdctx == NULL) { - gf_log (this->name, GF_LOG_TRACE, - "(%"PRId64"): failed to get fd ctx. EBADFD", - fd->inode->ino); - goto unwind; - } - - if (fdctx->remote_fd == -1) { - gf_log (this->name, GF_LOG_TRACE, - "(%"PRId64"): failed to get fd ctx. EBADFD", - fd->inode->ino); - goto unwind; - } - - ino = fd->inode->ino; - remote_fd = fdctx->remote_fd; - - hdrlen = gf_hdr_len (req, dict_len); - hdr = gf_hdr_new (req, dict_len); - - GF_VALIDATE_OR_GOTO (this->name, hdr, unwind); - - req = gf_param (hdr); - - req->ino = hton64 (ino); - req->fd = hton64 (remote_fd); - req->flags = hton32 (flags); - req->dict_len = hton32 (dict_len); - - ret = dict_serialize (dict, req->dict); - if (ret < 0) { - gf_log (this->name, GF_LOG_DEBUG, - "failed to serialize dictionary(%p)", - dict); - goto unwind; - } - - ret = protocol_client_xfer (frame, this, - CLIENT_CHANNEL (this, CHANNEL_BULK), - GF_OP_TYPE_FOP_REQUEST, GF_PROTO_FOP_FSETXATTR, - hdr, hdrlen, NULL, 0, NULL); - return ret; -unwind: - if (hdr) - GF_FREE (hdr); - - STACK_UNWIND (frame, -1, EINVAL); - return 0; -} - -/** - * client_getxattr - getxattr function for client protocol - * @frame: call frame - * @this: this translator structure - * @loc: location structure - * - * external reference through client_protocol_xlator->fops->getxattr - */ - -int -client_getxattr (call_frame_t *frame, xlator_t *this, loc_t *loc, - const char *name) -{ - int ret = -1; - gf_hdr_common_t *hdr = NULL; - gf_fop_getxattr_req_t *req = NULL; - size_t hdrlen = 0; - size_t pathlen = 0; - size_t namelen = 0; - ino_t ino = 0; - uint64_t gen = 0; - - pathlen = STRLEN_0 (loc->path); - if (name) - namelen = STRLEN_0 (name); - - ret = inode_ctx_get2 (loc->inode, this, &ino, &gen); - if (loc->inode->ino && ret < 0) { - gf_log (this->name, GF_LOG_DEBUG, - "GETXATTR %"PRId64" (%s): " - "failed to get remote inode number", - loc->inode->ino, loc->path); - goto unwind; - } - - hdrlen = gf_hdr_len (req, pathlen + namelen); - hdr = gf_hdr_new (req, pathlen + namelen); - GF_VALIDATE_OR_GOTO (frame->this->name, hdr, unwind); - - req = gf_param (hdr); - - req->ino = hton64 (ino); - req->gen = hton64 (gen); - req->namelen = hton32 (namelen); - strcpy (req->path, loc->path); - if (name) - strcpy (req->name + pathlen, name); - - ret = protocol_client_xfer (frame, this, - CLIENT_CHANNEL (this, CHANNEL_LOWLAT), - GF_OP_TYPE_FOP_REQUEST, GF_PROTO_FOP_GETXATTR, - hdr, hdrlen, NULL, 0, NULL); - return ret; -unwind: - if (hdr) - GF_FREE (hdr); - - STACK_UNWIND (frame, -1, EINVAL, NULL); - return 0; -} - - -/** - * client_fgetxattr - fgetxattr function for client protocol - * @frame: call frame - * @this: this translator structure - * @fd: fd - * - * external reference through client_protocol_xlator->fops->fgetxattr - */ - -int -client_fgetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd, - const char *name) -{ - int ret = -1; - gf_hdr_common_t *hdr = NULL; - gf_fop_fgetxattr_req_t *req = NULL; - size_t hdrlen = 0; - int64_t remote_fd = -1; - size_t namelen = 0; - ino_t ino = 0; - client_fd_ctx_t *fdctx = NULL; - client_conf_t *conf = NULL; - - if (name) - namelen = STRLEN_0 (name); - - conf = this->private; - - pthread_mutex_lock (&conf->mutex); - { - fdctx = this_fd_get_ctx (fd, this); - } - pthread_mutex_unlock (&conf->mutex); - - if (fdctx == NULL) { - gf_log (this->name, GF_LOG_TRACE, - "(%"PRId64"): failed to get remote fd. EBADFD", - fd->inode->ino); - goto unwind; - } - - if (fdctx->remote_fd == -1) { - gf_log (this->name, GF_LOG_TRACE, - "(%"PRId64"): failed to get fd ctx. EBADFD", - fd->inode->ino); - goto unwind; - } - - ino = fd->inode->ino; - remote_fd = fdctx->remote_fd; - - hdrlen = gf_hdr_len (req, namelen); - hdr = gf_hdr_new (req, namelen); - - GF_VALIDATE_OR_GOTO (frame->this->name, hdr, unwind); - - req = gf_param (hdr); - - req->ino = hton64 (ino); - req->fd = hton64 (remote_fd); - req->namelen = hton32 (namelen); - - if (name) - strcpy (req->name, name); - - ret = protocol_client_xfer (frame, this, - CLIENT_CHANNEL (this, CHANNEL_LOWLAT), - GF_OP_TYPE_FOP_REQUEST, GF_PROTO_FOP_FGETXATTR, - hdr, hdrlen, NULL, 0, NULL); - return ret; -unwind: - if (hdr) - GF_FREE (hdr); - - STACK_UNWIND (frame, -1, EINVAL, NULL); - return 0; -} - - -/** - * client_removexattr - removexattr function for client protocol - * @frame: call frame - * @this: this translator structure - * @loc: location structure - * @name: - * - * external reference through client_protocol_xlator->fops->removexattr - */ - -int -client_removexattr (call_frame_t *frame, xlator_t *this, loc_t *loc, - const char *name) -{ - int ret = -1; - gf_hdr_common_t *hdr = NULL; - gf_fop_removexattr_req_t *req = NULL; - size_t hdrlen = 0; - size_t namelen = 0; - size_t pathlen = 0; - ino_t ino = 0; - uint64_t gen = 0; - - pathlen = STRLEN_0 (loc->path); - namelen = STRLEN_0 (name); - - ret = inode_ctx_get2 (loc->inode, this, &ino, &gen); - if (loc->inode->ino && ret < 0) { - gf_log (this->name, GF_LOG_DEBUG, - "REMOVEXATTR %"PRId64" (%s): " - "failed to get remote inode number", - loc->inode->ino, loc->path); - goto unwind; - } - - hdrlen = gf_hdr_len (req, pathlen + namelen); - hdr = gf_hdr_new (req, pathlen + namelen); - GF_VALIDATE_OR_GOTO (frame->this->name, hdr, unwind); - - req = gf_param (hdr); - - req->ino = hton64 (ino); - req->gen = hton64 (gen); - strcpy (req->path, loc->path); - strcpy (req->name + pathlen, name); - - ret = protocol_client_xfer (frame, this, - CLIENT_CHANNEL (this, CHANNEL_LOWLAT), - GF_OP_TYPE_FOP_REQUEST, GF_PROTO_FOP_REMOVEXATTR, - hdr, hdrlen, NULL, 0, NULL); - return ret; -unwind: - if (hdr) - GF_FREE (hdr); - STACK_UNWIND (frame, -1, EINVAL); - return 0; -} - -/** - * client_opendir - opendir function for client protocol - * @frame: call frame - * @this: this translator structure - * @loc: location structure - * - * external reference through client_protocol_xlator->fops->opendir - */ - -int -client_opendir (call_frame_t *frame, xlator_t *this, loc_t *loc, - fd_t *fd) -{ - gf_fop_opendir_req_t *req = NULL; - gf_hdr_common_t *hdr = NULL; - size_t hdrlen = 0; - int ret = -1; - ino_t ino = 0; - uint64_t gen = 0; - size_t pathlen = 0; - client_local_t *local = NULL; - - local = GF_CALLOC (1, sizeof (*local), gf_client_mt_client_local_t); - GF_VALIDATE_OR_GOTO (this->name, local, unwind); - - loc_copy (&local->loc, loc); - local->fd = fd_ref (fd); - - frame->local = local; - - ret = inode_ctx_get2 (loc->inode, this, &ino, &gen); - if (loc->inode->ino && ret < 0) { - gf_log (this->name, GF_LOG_DEBUG, - "OPENDIR %"PRId64" (%s): " - "failed to get remote inode number", - loc->inode->ino, loc->path); - goto unwind; - } - - pathlen = STRLEN_0 (loc->path); - - hdrlen = gf_hdr_len (req, pathlen); - hdr = gf_hdr_new (req, pathlen); - GF_VALIDATE_OR_GOTO (frame->this->name, hdr, unwind); - - req = gf_param (hdr); - - req->ino = hton64 (ino); - req->gen = hton64 (gen); - strcpy (req->path, loc->path); - - ret = protocol_client_xfer (frame, this, - CLIENT_CHANNEL (this, CHANNEL_LOWLAT), - GF_OP_TYPE_FOP_REQUEST, GF_PROTO_FOP_OPENDIR, - hdr, hdrlen, NULL, 0, NULL); - - return ret; -unwind: - if (hdr) - GF_FREE (hdr); - STACK_UNWIND (frame, -1, EINVAL, fd); - return 0; - -} - -/** - * client_readdirp - readdirp function for client protocol - * @frame: call frame - * @this: this translator structure - * - * external reference through client_protocol_xlator->fops->readdirp - */ - -int -client_readdirp (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, - off_t offset) -{ - gf_hdr_common_t *hdr = NULL; - gf_fop_readdirp_req_t *req = NULL; - size_t hdrlen = 0; - int64_t remote_fd = -1; - int ret = -1; - client_fd_ctx_t *fdctx = NULL; - client_conf_t *conf = NULL; - - conf = this->private; - - pthread_mutex_lock (&conf->mutex); - { - fdctx = this_fd_get_ctx (fd, this); - } - pthread_mutex_unlock (&conf->mutex); - - if (fdctx == NULL) { - gf_log (this->name, GF_LOG_TRACE, "(%"PRId64"): failed to get" - " fd ctx. EBADFD", fd->inode->ino); - goto unwind; - } - - if (fdctx->remote_fd == -1) { - gf_log (this->name, GF_LOG_TRACE, "(%"PRId64"): failed to get" - " fd ctx. EBADFD", fd->inode->ino); - goto unwind; - } - - remote_fd = fdctx->remote_fd; - hdrlen = gf_hdr_len (req, 0); - hdr = gf_hdr_new (req, 0); - GF_VALIDATE_OR_GOTO (this->name, hdr, unwind); - - req = gf_param (hdr); - GF_VALIDATE_OR_GOTO (this->name, hdr, unwind); - - req->fd = hton64 (remote_fd); - req->size = hton32 (size); - req->offset = hton64 (offset); - - ret = protocol_client_xfer (frame, this, - CLIENT_CHANNEL (this, CHANNEL_LOWLAT), - GF_OP_TYPE_FOP_REQUEST, GF_PROTO_FOP_READDIRP, - hdr, hdrlen, NULL, 0, NULL); - - return 0; -unwind: - if (hdr) - GF_FREE (hdr); - STACK_UNWIND (frame, -1, EBADFD, NULL); - return 0; - -} - - -/** - * client_readdir - readdir function for client protocol - * @frame: call frame - * @this: this translator structure - * - * external reference through client_protocol_xlator->fops->readdir - */ - -int -client_readdir (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, - off_t offset) -{ - gf_hdr_common_t *hdr = NULL; - gf_fop_readdir_req_t *req = NULL; - size_t hdrlen = 0; - int64_t remote_fd = -1; - int ret = -1; - client_fd_ctx_t *fdctx = NULL; - client_conf_t *conf = NULL; - - conf = this->private; - - pthread_mutex_lock (&conf->mutex); - { - fdctx = this_fd_get_ctx (fd, this); - } - pthread_mutex_unlock (&conf->mutex); - - if (fdctx == NULL) { - gf_log (this->name, GF_LOG_TRACE, - "(%"PRId64"): failed to get fd ctx. EBADFD", - fd->inode->ino); - goto unwind; - } - - if (fdctx->remote_fd == -1) { - gf_log (this->name, GF_LOG_TRACE, "(%"PRId64"): failed to get" - " fd ctx. EBADFD", fd->inode->ino); - goto unwind; - } - - remote_fd = fdctx->remote_fd; - hdrlen = gf_hdr_len (req, 0); - hdr = gf_hdr_new (req, 0); - GF_VALIDATE_OR_GOTO (this->name, hdr, unwind); - - req = gf_param (hdr); - GF_VALIDATE_OR_GOTO (this->name, hdr, unwind); - - req->fd = hton64 (remote_fd); - req->size = hton32 (size); - req->offset = hton64 (offset); - - ret = protocol_client_xfer (frame, this, - CLIENT_CHANNEL (this, CHANNEL_LOWLAT), - GF_OP_TYPE_FOP_REQUEST, GF_PROTO_FOP_READDIR, - hdr, hdrlen, NULL, 0, NULL); - - return 0; -unwind: - if (hdr) - GF_FREE (hdr); - STACK_UNWIND (frame, -1, EBADFD, NULL); - return 0; - -} - -/** - * client_fsyncdir - fsyncdir function for client protocol - * @frame: call frame - * @this: this translator structure - * @fd: file descriptor structure - * @flags: - * - * external reference through client_protocol_xlator->fops->fsyncdir - */ - -int -client_fsyncdir (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t flags) -{ - gf_hdr_common_t *hdr = NULL; - gf_fop_fsyncdir_req_t *req = NULL; - size_t hdrlen = 0; - int64_t remote_fd = -1; - int32_t ret = -1; - client_fd_ctx_t *fdctx = NULL; - client_conf_t *conf = NULL; - - conf = this->private; - - pthread_mutex_lock (&conf->mutex); - { - fdctx = this_fd_get_ctx (fd, this); - } - pthread_mutex_unlock (&conf->mutex); - - if (fdctx == NULL) { - gf_log (this->name, GF_LOG_TRACE, - "(%"PRId64"): failed to get fd ctx. EBADFD", - fd->inode->ino); - goto unwind; - } - - if (fdctx->remote_fd == -1) { - gf_log (this->name, GF_LOG_TRACE, "(%"PRId64"): failed to get" - " fd ctx. EBADFD", fd->inode->ino); - goto unwind; - } - - remote_fd = fdctx->remote_fd; - hdrlen = gf_hdr_len (req, 0); - hdr = gf_hdr_new (req, 0); - GF_VALIDATE_OR_GOTO (this->name, hdr, unwind); - - req = gf_param (hdr); - - req->data = hton32 (flags); - req->fd = hton64 (remote_fd); - - ret = protocol_client_xfer (frame, this, - CLIENT_CHANNEL (this, CHANNEL_BULK), - GF_OP_TYPE_FOP_REQUEST, GF_PROTO_FOP_FSYNCDIR, - hdr, hdrlen, NULL, 0, NULL); - - return ret; -unwind: - STACK_UNWIND (frame, -1, EBADFD); - return 0; -} - -/** - * client_access - access function for client protocol - * @frame: call frame - * @this: this translator structure - * @loc: location structure - * @mode: - * - * external reference through client_protocol_xlator->fops->access - */ - -int -client_access (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t mask) -{ - gf_hdr_common_t *hdr = NULL; - gf_fop_access_req_t *req = NULL; - size_t hdrlen = -1; - int ret = -1; - ino_t ino = 0; - uint64_t gen = 0; - size_t pathlen = 0; - - ret = inode_ctx_get2 (loc->inode, this, &ino, &gen); - if (loc->inode->ino && ret < 0) { - gf_log (this->name, GF_LOG_DEBUG, - "ACCESS %"PRId64" (%s): " - "failed to get remote inode number", - loc->inode->ino, loc->path); - goto unwind; - } - - pathlen = STRLEN_0 (loc->path); - - hdrlen = gf_hdr_len (req, pathlen); - hdr = gf_hdr_new (req, pathlen); - GF_VALIDATE_OR_GOTO (this->name, hdr, unwind); - - req = gf_param (hdr); - - req->ino = hton64 (ino); - req->gen = hton64 (gen); - req->mask = hton32 (mask); - strcpy (req->path, loc->path); - - ret = protocol_client_xfer (frame, this, - CLIENT_CHANNEL (this, CHANNEL_LOWLAT), - GF_OP_TYPE_FOP_REQUEST, GF_PROTO_FOP_ACCESS, - hdr, hdrlen, NULL, 0, NULL); - - return ret; -unwind: - if (hdr) - GF_FREE (hdr); - - STACK_UNWIND (frame, -1, EINVAL); - return 0; - -} - -/** - * client_ftrucate - ftruncate function for client protocol - * @frame: call frame - * @this: this translator structure - * @fd: file descriptor structure - * @offset: offset to truncate to - * - * external reference through client_protocol_xlator->fops->ftruncate - */ - -int -client_ftruncate (call_frame_t *frame, xlator_t *this, fd_t *fd, - off_t offset) -{ - gf_hdr_common_t *hdr = NULL; - gf_fop_ftruncate_req_t *req = NULL; - int64_t remote_fd = -1; - size_t hdrlen = -1; - int ret = -1; - client_fd_ctx_t *fdctx = NULL; - client_conf_t *conf = NULL; - - conf = this->private; - - pthread_mutex_lock (&conf->mutex); - { - fdctx = this_fd_get_ctx (fd, this); - } - pthread_mutex_unlock (&conf->mutex); - - if (fdctx == NULL) { - gf_log (this->name, GF_LOG_TRACE, - "(%"PRId64"): failed to get fd ctx. EBADFD", - fd->inode->ino); - STACK_UNWIND (frame, -1, EBADFD, NULL); - return 0; - } - - if (fdctx->remote_fd == -1) { - gf_log (this->name, GF_LOG_TRACE, "(%"PRId64"): failed to get" - " fd ctx. EBADFD", fd->inode->ino); - goto unwind; - } - - remote_fd = fdctx->remote_fd; - hdrlen = gf_hdr_len (req, 0); - hdr = gf_hdr_new (req, 0); - GF_VALIDATE_OR_GOTO (this->name, hdr, unwind); - - req = gf_param (hdr); - - req->fd = hton64 (remote_fd); - req->offset = hton64 (offset); - - ret = protocol_client_xfer (frame, this, - CLIENT_CHANNEL (this, CHANNEL_BULK), - GF_OP_TYPE_FOP_REQUEST, GF_PROTO_FOP_FTRUNCATE, - hdr, hdrlen, NULL, 0, NULL); - - return ret; -unwind: - if (hdr) - GF_FREE (hdr); - - STACK_UNWIND (frame, -1, EINVAL, NULL); - return 0; - -} - -/** - * client_fstat - fstat function for client protocol - * @frame: call frame - * @this: this translator structure - * @fd: file descriptor structure - * - * external reference through client_protocol_xlator->fops->fstat - */ - -int -client_fstat (call_frame_t *frame, xlator_t *this, fd_t *fd) -{ - gf_hdr_common_t *hdr = NULL; - gf_fop_fstat_req_t *req = NULL; - int64_t remote_fd = -1; - size_t hdrlen = -1; - int ret = -1; - client_fd_ctx_t *fdctx = NULL; - client_conf_t *conf = NULL; - - conf = this->private; - - pthread_mutex_lock (&conf->mutex); - { - fdctx = this_fd_get_ctx (fd, this); - } - pthread_mutex_unlock (&conf->mutex); - - if (fdctx == NULL) { - gf_log (this->name, GF_LOG_TRACE, - "(%"PRId64"): failed to get fd ctx. EBADFD", - fd->inode->ino); - STACK_UNWIND (frame, -1, EBADFD, NULL); - return 0; - } - - if (fdctx->remote_fd == -1) { - gf_log (this->name, GF_LOG_TRACE, "(%"PRId64"): failed to get" - " fd ctx. EBADFD", fd->inode->ino); - goto unwind; - } - - remote_fd = fdctx->remote_fd; - hdrlen = gf_hdr_len (req, 0); - hdr = gf_hdr_new (req, 0); - GF_VALIDATE_OR_GOTO (this->name, hdr, unwind); - - req = gf_param (hdr); - - req->fd = hton64 (remote_fd); - - ret = protocol_client_xfer (frame, this, - CLIENT_CHANNEL (this, CHANNEL_BULK), - GF_OP_TYPE_FOP_REQUEST, GF_PROTO_FOP_FSTAT, - hdr, hdrlen, NULL, 0, NULL); - - return ret; -unwind: - if (hdr) - GF_FREE (hdr); - - STACK_UNWIND (frame, -1, EINVAL, NULL); - return 0; - -} - -/** - * client_lk - lk function for client protocol - * @frame: call frame - * @this: this translator structure - * @fd: file descriptor structure - * @cmd: lock command - * @lock: - * - * external reference through client_protocol_xlator->fops->lk - */ - -int -client_lk (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t cmd, - struct gf_flock *flock) -{ - int ret = -1; - gf_hdr_common_t *hdr = NULL; - gf_fop_lk_req_t *req = NULL; - size_t hdrlen = 0; - int64_t remote_fd = -1; - int32_t gf_cmd = 0; - int32_t gf_type = 0; - client_fd_ctx_t *fdctx = NULL; - client_conf_t *conf = NULL; - - conf = this->private; - - pthread_mutex_lock (&conf->mutex); - { - fdctx = this_fd_get_ctx (fd, this); - } - pthread_mutex_unlock (&conf->mutex); - - if (fdctx == NULL) { - gf_log (this->name, GF_LOG_TRACE, - "(%"PRId64"): failed to get fd ctx. EBADFD", - fd->inode->ino); - STACK_UNWIND (frame, -1, EBADFD, NULL); - return 0; - } - - if (fdctx->remote_fd == -1) { - gf_log (this->name, GF_LOG_TRACE, "(%"PRId64"): failed to get" - " fd ctx. EBADFD", fd->inode->ino); - STACK_UNWIND (frame, -1, EBADFD, NULL); - return 0; - } - - remote_fd = fdctx->remote_fd; - if (cmd == F_GETLK || cmd == F_GETLK64) - gf_cmd = GF_LK_GETLK; - else if (cmd == F_SETLK || cmd == F_SETLK64) - gf_cmd = GF_LK_SETLK; - else if (cmd == F_SETLKW || cmd == F_SETLKW64) - gf_cmd = GF_LK_SETLKW; - else { - gf_log (this->name, GF_LOG_DEBUG, - "Unknown cmd (%d)!", gf_cmd); - goto unwind; - } - - switch (flock->l_type) { - case F_RDLCK: - gf_type = GF_LK_F_RDLCK; - break; - case F_WRLCK: - gf_type = GF_LK_F_WRLCK; - break; - case F_UNLCK: - gf_type = GF_LK_F_UNLCK; - break; - } - - hdrlen = gf_hdr_len (req, 0); - hdr = gf_hdr_new (req, 0); - GF_VALIDATE_OR_GOTO (this->name, hdr, unwind); - - req = gf_param (hdr); - - req->fd = hton64 (remote_fd); - req->cmd = hton32 (gf_cmd); - req->type = hton32 (gf_type); - gf_flock_from_flock (&req->flock, flock); - - ret = protocol_client_xfer (frame, this, - CLIENT_CHANNEL (this, CHANNEL_BULK), - GF_OP_TYPE_FOP_REQUEST, GF_PROTO_FOP_LK, - hdr, hdrlen, NULL, 0, NULL); - return ret; -unwind: - if (hdr) - GF_FREE (hdr); - - STACK_UNWIND (frame, -1, EINVAL, NULL); - return 0; -} - -/** - * client_inodelk - inodelk function for client protocol - * @frame: call frame - * @this: this translator structure - * @inode: inode structure - * @cmd: lock command - * @lock: flock struct - * - * external reference through client_protocol_xlator->fops->inodelk - */ - -int -client_inodelk (call_frame_t *frame, xlator_t *this, const char *volume, - loc_t *loc, int32_t cmd, struct gf_flock *flock) -{ - int ret = -1; - gf_hdr_common_t *hdr = NULL; - gf_fop_inodelk_req_t *req = NULL; - size_t hdrlen = 0; - int32_t gf_cmd = 0; - int32_t gf_type = 0; - ino_t ino = 0; - uint64_t gen = 0; - size_t pathlen = 0; - size_t vollen = 0; - - pathlen = STRLEN_0 (loc->path); - vollen = STRLEN_0 (volume); - - ret = inode_ctx_get2 (loc->inode, this, &ino, &gen); - if (loc->inode->ino && ret < 0) { - gf_log (this->name, GF_LOG_DEBUG, - "INODELK %"PRId64" (%s): " - "failed to get remote inode number", - loc->inode->ino, loc->path); - goto unwind; - } - - if (cmd == F_GETLK || cmd == F_GETLK64) - gf_cmd = GF_LK_GETLK; - else if (cmd == F_SETLK || cmd == F_SETLK64) - gf_cmd = GF_LK_SETLK; - else if (cmd == F_SETLKW || cmd == F_SETLKW64) - gf_cmd = GF_LK_SETLKW; - else { - gf_log (this->name, GF_LOG_DEBUG, - "Unknown cmd (%d)!", gf_cmd); - goto unwind; - } - - switch (flock->l_type) { - case F_RDLCK: - gf_type = GF_LK_F_RDLCK; - break; - case F_WRLCK: - gf_type = GF_LK_F_WRLCK; - break; - case F_UNLCK: - gf_type = GF_LK_F_UNLCK; - break; - } - - hdrlen = gf_hdr_len (req, pathlen + vollen); - hdr = gf_hdr_new (req, pathlen + vollen); - GF_VALIDATE_OR_GOTO (this->name, hdr, unwind); - - req = gf_param (hdr); - - strcpy (req->path, loc->path); - strcpy (req->path + pathlen, volume); - - req->ino = hton64 (ino); - req->gen = hton64 (gen); - - req->cmd = hton32 (gf_cmd); - req->type = hton32 (gf_type); - gf_flock_from_flock (&req->flock, flock); - - - ret = protocol_client_xfer (frame, this, - CLIENT_CHANNEL (this, CHANNEL_BULK), - GF_OP_TYPE_FOP_REQUEST, - GF_PROTO_FOP_INODELK, - hdr, hdrlen, NULL, 0, NULL); - return ret; -unwind: - if (hdr) - GF_FREE (hdr); - - STACK_UNWIND (frame, -1, EINVAL); - return 0; - -} - - -/** - * client_finodelk - finodelk function for client protocol - * @frame: call frame - * @this: this translator structure - * @inode: inode structure - * @cmd: lock command - * @lock: flock struct - * - * external reference through client_protocol_xlator->fops->finodelk - */ - -int -client_finodelk (call_frame_t *frame, xlator_t *this, const char *volume, - fd_t *fd, int32_t cmd, struct gf_flock *flock) -{ - int ret = -1; - gf_hdr_common_t *hdr = NULL; - gf_fop_finodelk_req_t *req = NULL; - size_t hdrlen = 0; - size_t vollen = 0; - int32_t gf_cmd = 0; - int32_t gf_type = 0; - int64_t remote_fd = -1; - client_fd_ctx_t *fdctx = NULL; - client_conf_t *conf = NULL; - - vollen = STRLEN_0 (volume); - - conf = this->private; - - pthread_mutex_lock (&conf->mutex); - { - fdctx = this_fd_get_ctx (fd, this); - } - pthread_mutex_unlock (&conf->mutex); - - if (fdctx == NULL) { - gf_log (this->name, GF_LOG_TRACE, - "(%"PRId64"): failed to get fd ctx. EBADFD", - fd->inode->ino); - STACK_UNWIND (frame, -1, EBADFD); - return 0; - } - - if (fdctx->remote_fd == -1) { - gf_log (this->name, GF_LOG_TRACE, - "(%"PRId64"): failed to get fd ctx. EBADFD", - fd->inode->ino); - STACK_UNWIND (frame, -1, EBADFD); - return 0; - } - - remote_fd = fdctx->remote_fd; - if (cmd == F_GETLK || cmd == F_GETLK64) - gf_cmd = GF_LK_GETLK; - else if (cmd == F_SETLK || cmd == F_SETLK64) - gf_cmd = GF_LK_SETLK; - else if (cmd == F_SETLKW || cmd == F_SETLKW64) - gf_cmd = GF_LK_SETLKW; - else { - gf_log (this->name, GF_LOG_DEBUG, - "Unknown cmd (%d)!", gf_cmd); - goto unwind; - } - - switch (flock->l_type) { - case F_RDLCK: - gf_type = GF_LK_F_RDLCK; - break; - case F_WRLCK: - gf_type = GF_LK_F_WRLCK; - break; - case F_UNLCK: - gf_type = GF_LK_F_UNLCK; - break; - } - - hdrlen = gf_hdr_len (req, vollen); - hdr = gf_hdr_new (req, vollen); - GF_VALIDATE_OR_GOTO (this->name, hdr, unwind); - - req = gf_param (hdr); - - strcpy (req->volume, volume); - - req->fd = hton64 (remote_fd); - - req->cmd = hton32 (gf_cmd); - req->type = hton32 (gf_type); - gf_flock_from_flock (&req->flock, flock); - - ret = protocol_client_xfer (frame, this, - CLIENT_CHANNEL (this, CHANNEL_BULK), - GF_OP_TYPE_FOP_REQUEST, - GF_PROTO_FOP_FINODELK, - hdr, hdrlen, NULL, 0, NULL); - return ret; -unwind: - if (hdr) - GF_FREE (hdr); - - STACK_UNWIND (frame, -1, EINVAL); - return 0; -} - - -int -client_entrylk (call_frame_t *frame, xlator_t *this, const char *volume, - loc_t *loc, const char *name, entrylk_cmd cmd, - entrylk_type type) -{ - gf_hdr_common_t *hdr = NULL; - gf_fop_entrylk_req_t *req = NULL; - size_t pathlen = 0; - size_t vollen = 0; - size_t hdrlen = -1; - int ret = -1; - ino_t ino = 0; - uint64_t gen = 0; - size_t namelen = 0; - - pathlen = STRLEN_0 (loc->path); - vollen = STRLEN_0 (volume); - - if (name) - namelen = STRLEN_0 (name); - - ret = inode_ctx_get2 (loc->inode, this, &ino, &gen); - if (loc->inode->ino && ret < 0) { - gf_log (this->name, GF_LOG_DEBUG, - "ENTRYLK %"PRId64" (%s): " - "failed to get remote inode number", - loc->inode->ino, loc->path); - goto unwind; - } - - hdrlen = gf_hdr_len (req, pathlen + vollen + namelen); - hdr = gf_hdr_new (req, pathlen + vollen + namelen); - GF_VALIDATE_OR_GOTO (this->name, hdr, unwind); - - req = gf_param (hdr); - - req->ino = hton64 (ino); - req->gen = hton64 (gen); - req->namelen = hton64 (namelen); - - strcpy (req->path, loc->path); - if (name) - strcpy (req->name + pathlen, name); - strcpy (req->volume + pathlen + namelen, volume); - - req->cmd = hton32 (cmd); - req->type = hton32 (type); - - ret = protocol_client_xfer (frame, this, - CLIENT_CHANNEL (this, CHANNEL_LOWLAT), - GF_OP_TYPE_FOP_REQUEST, GF_PROTO_FOP_ENTRYLK, - hdr, hdrlen, NULL, 0, NULL); - - return ret; -unwind: - if (hdr) - GF_FREE (hdr); - - STACK_UNWIND (frame, -1, EINVAL); - return 0; - -} - - -int -client_fentrylk (call_frame_t *frame, xlator_t *this, const char *volume, - fd_t *fd, const char *name, entrylk_cmd cmd, - entrylk_type type) -{ - gf_hdr_common_t *hdr = NULL; - gf_fop_fentrylk_req_t *req = NULL; - int64_t remote_fd = -1; - size_t vollen = 0; - size_t namelen = 0; - size_t hdrlen = -1; - int ret = -1; - client_fd_ctx_t *fdctx = NULL; - client_conf_t *conf = NULL; - - if (name) - namelen = STRLEN_0 (name); - - conf = this->private; - - vollen = STRLEN_0 (volume); - - pthread_mutex_lock (&conf->mutex); - { - fdctx = this_fd_get_ctx (fd, this); - } - pthread_mutex_unlock (&conf->mutex); - - if (fdctx == NULL) { - gf_log (this->name, GF_LOG_DEBUG, - "(%"PRId64"): failed to get fd ctx. EBADFD", - fd->inode->ino); - STACK_UNWIND (frame, -1, EBADFD); - return 0; - } - - if (fdctx->remote_fd == -1) { - gf_log (this->name, GF_LOG_DEBUG, - "(%"PRId64"): failed to get fd ctx. EBADFD", - fd->inode->ino); - STACK_UNWIND (frame, -1, EBADFD); - return 0; - } - - remote_fd = fdctx->remote_fd; - hdrlen = gf_hdr_len (req, namelen + vollen); - hdr = gf_hdr_new (req, namelen + vollen); - GF_VALIDATE_OR_GOTO (this->name, hdr, unwind); - - req = gf_param (hdr); - - req->fd = hton64 (remote_fd); - req->namelen = hton64 (namelen); - - if (name) - strcpy (req->name, name); - - strcpy (req->volume + namelen, volume); - - req->cmd = hton32 (cmd); - req->type = hton32 (type); - - ret = protocol_client_xfer (frame, this, - CLIENT_CHANNEL (this, CHANNEL_LOWLAT), - GF_OP_TYPE_FOP_REQUEST, GF_PROTO_FOP_FENTRYLK, - hdr, hdrlen, NULL, 0, NULL); - - return ret; -unwind: - if (hdr) - GF_FREE (hdr); - - STACK_UNWIND (frame, -1, EINVAL); - return 0; -} - -/* - * client_lookup - lookup function for client protocol - * @frame: call frame - * @this: - * @loc: location - * - * not for external reference - */ - -int -client_lookup (call_frame_t *frame, xlator_t *this, loc_t *loc, - dict_t *xattr_req) -{ - gf_hdr_common_t *hdr = NULL; - gf_fop_lookup_req_t *req = NULL; - size_t hdrlen = -1; - int ret = -1; - ino_t ino = 0; - ino_t par = 0; - uint64_t gen = 0; - size_t dictlen = 0; - size_t pathlen = 0; - size_t baselen = 0; - int32_t op_ret = -1; - int32_t op_errno = EINVAL; - client_local_t *local = NULL; - char *buf = NULL; - - GF_VALIDATE_OR_GOTO (this->name, loc, unwind); - GF_VALIDATE_OR_GOTO (this->name, loc->path, unwind); - - local = GF_CALLOC (1, sizeof (*local), gf_client_mt_client_local_t); - GF_VALIDATE_OR_GOTO (this->name, local, unwind); - - loc_copy (&local->loc, loc); - - frame->local = local; - - if (loc->ino != 1 && loc->parent) { - ret = inode_ctx_get2 (loc->parent, this, &par, &gen); - if (loc->parent->ino && ret < 0) { - gf_log (this->name, GF_LOG_TRACE, - "LOOKUP %"PRId64"/%s (%s): failed to get " - "remote inode number for parent", - loc->parent->ino, loc->name, loc->path); - goto unwind; - } - GF_VALIDATE_OR_GOTO (this->name, loc->name, unwind); - baselen = STRLEN_0 (loc->name); - } else { - ino = 1; - } - - pathlen = STRLEN_0 (loc->path); - - if (xattr_req) { - ret = dict_allocate_and_serialize (xattr_req, &buf, &dictlen); - if (ret < 0) { - gf_log (this->name, GF_LOG_DEBUG, - "failed to get serialized length of dict(%p)", - xattr_req); - goto unwind; - } - } - - hdrlen = gf_hdr_len (req, pathlen + baselen + dictlen); - hdr = gf_hdr_new (req, pathlen + baselen + dictlen); - GF_VALIDATE_OR_GOTO (this->name, hdr, unwind); - - req = gf_param (hdr); - - req->ino = hton64 (ino); - req->gen = hton64 (gen); - req->par = hton64 (par); - strcpy (req->path, loc->path); - if (baselen) - strcpy (req->path + pathlen, loc->name); - - if (dictlen > 0) { - memcpy (req->dict + pathlen + baselen, buf, dictlen); - GF_FREE (buf); - } - - req->dictlen = hton32 (dictlen); - - ret = protocol_client_xfer (frame, this, - CLIENT_CHANNEL (this, CHANNEL_LOWLAT), - GF_OP_TYPE_FOP_REQUEST, GF_PROTO_FOP_LOOKUP, - hdr, hdrlen, NULL, 0, NULL); - return ret; - -unwind: - STACK_UNWIND (frame, op_ret, op_errno, (loc)?loc->inode:NULL, NULL, NULL); - return ret; -} - - -int -client_setattr (call_frame_t *frame, xlator_t *this, loc_t *loc, - struct iatt *stbuf, int32_t valid) -{ - gf_hdr_common_t *hdr = NULL; - gf_fop_setattr_req_t *req = NULL; - size_t hdrlen = 0; - size_t pathlen = 0; - ino_t ino = 0; - uint64_t gen = 0; - int ret = -1; - - GF_VALIDATE_OR_GOTO ("client", this, unwind); - GF_VALIDATE_OR_GOTO (this->name, frame, unwind); - - pathlen = STRLEN_0 (loc->path); - - ret = inode_ctx_get2 (loc->inode, this, &ino, &gen); - if (loc->inode->ino && ret < 0) { - gf_log (this->name, GF_LOG_TRACE, - "SETATTR %"PRId64" (%s): " - "failed to get remote inode number", - loc->inode->ino, loc->path); - goto unwind; - } - - hdrlen = gf_hdr_len (req, pathlen); - hdr = gf_hdr_new (req, pathlen); - GF_VALIDATE_OR_GOTO (this->name, hdr, unwind); - - req = gf_param (hdr); - - req->ino = hton64 (ino); - req->gen = hton64 (gen); - strcpy (req->path, loc->path); - - gf_stat_from_iatt (&req->stbuf, stbuf); - req->valid = hton32 (valid); - - ret = protocol_client_xfer (frame, this, - CLIENT_CHANNEL (this, CHANNEL_BULK), - GF_OP_TYPE_FOP_REQUEST, GF_PROTO_FOP_SETATTR, - hdr, hdrlen, NULL, 0, NULL); - - return ret; -unwind: - STACK_UNWIND (frame, -1, EINVAL, NULL); - return 0; -} - - -int -client_fsetattr (call_frame_t *frame, xlator_t *this, fd_t *fd, - struct iatt *stbuf, int32_t valid) -{ - gf_hdr_common_t *hdr = NULL; - gf_fop_fsetattr_req_t *req = NULL; - size_t hdrlen = 0; - int ret = -1; - client_fd_ctx_t *fdctx = NULL; - int64_t remote_fd = -1; - client_conf_t *conf = NULL; - - GF_VALIDATE_OR_GOTO ("client", this, unwind); - GF_VALIDATE_OR_GOTO (this->name, frame, unwind); - - conf = this->private; - - pthread_mutex_lock (&conf->mutex); - { - fdctx = this_fd_get_ctx (fd, this); - } - pthread_mutex_unlock (&conf->mutex); - - if (fdctx == NULL) { - gf_log (this->name, GF_LOG_TRACE, - "(%"PRId64"): failed to get fd ctx. EBADFD", - fd->inode->ino); - STACK_UNWIND (frame, -1, EBADFD, NULL, NULL); - return 0; - } - - if (fdctx->remote_fd == -1) { - gf_log (this->name, GF_LOG_TRACE, - "(%"PRId64"): failed to get fd ctx. EBADFD", - fd->inode->ino); - STACK_UNWIND (frame, -1, EBADFD, NULL, NULL); - return 0; - } - - remote_fd = fdctx->remote_fd; - hdrlen = gf_hdr_len (req, 0); - hdr = gf_hdr_new (req, 0); - GF_VALIDATE_OR_GOTO (this->name, hdr, unwind); - - req = gf_param (hdr); - - req->fd = hton64 (remote_fd); - - gf_stat_from_iatt (&req->stbuf, stbuf); - req->valid = hton32 (valid); - - ret = protocol_client_xfer (frame, this, - CLIENT_CHANNEL (this, CHANNEL_BULK), - GF_OP_TYPE_FOP_REQUEST, GF_PROTO_FOP_FSETATTR, - hdr, hdrlen, NULL, 0, NULL); - - return ret; -unwind: - STACK_UNWIND (frame, -1, EINVAL, NULL, NULL); - return 0; -} - - -int -client_fdctx_destroy (xlator_t *this, client_fd_ctx_t *fdctx) -{ - call_frame_t *fr = NULL; - int32_t ret = -1; - gf_hdr_common_t *hdr = NULL; - size_t hdrlen = 0; - gf_cbk_release_req_t *req = NULL; - gf_cbk_releasedir_req_t *reqdir = NULL; - int64_t remote_fd = -1; - int op = 0; - - remote_fd = fdctx->remote_fd; - - if (remote_fd == -1) - goto out; - - if (fdctx->is_dir) { - hdrlen = gf_hdr_len (reqdir, 0); - hdr = gf_hdr_new (reqdir, 0); - op = GF_CBK_RELEASEDIR; - reqdir = gf_param (hdr); - reqdir->fd = hton64 (remote_fd); - } else { - hdrlen = gf_hdr_len (req, 0); - hdr = gf_hdr_new (req, 0); - op = GF_CBK_RELEASE; - req = gf_param (hdr); - req->fd = hton64 (remote_fd); - } - - fr = create_frame (this, this->ctx->pool); - - ret = protocol_client_xfer (fr, this, - CLIENT_CHANNEL (this, CHANNEL_BULK), - GF_OP_TYPE_CBK_REQUEST, op, - hdr, hdrlen, NULL, 0, NULL); - -out: - inode_unref (fdctx->inode); - GF_FREE (fdctx); - - return ret; -} - - -/** - * client_releasedir - releasedir function for client protocol - * @this: this translator structure - * @fd: file descriptor structure - * - * external reference through client_protocol_xlator->cbks->releasedir - */ - -int -client_releasedir (xlator_t *this, fd_t *fd) -{ - int64_t remote_fd = -1; - client_conf_t *conf = NULL; - client_fd_ctx_t *fdctx = NULL; - - conf = this->private; - - pthread_mutex_lock (&conf->mutex); - { - fdctx = this_fd_del_ctx (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->mutex); - - if (remote_fd != -1) - client_fdctx_destroy (this, fdctx); - - return 0; -} - - -/** - * client_release - release function for client protocol - * @this: this translator structure - * @fd: file descriptor structure - * - * external reference through client_protocol_xlator->cbks->release - * - */ -int -client_release (xlator_t *this, fd_t *fd) -{ - int64_t remote_fd = -1; - client_conf_t *conf = NULL; - client_fd_ctx_t *fdctx = NULL; - - conf = this->private; - - pthread_mutex_lock (&conf->mutex); - { - fdctx = this_fd_del_ctx (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->mutex); - - if (remote_fd != -1) - client_fdctx_destroy (this, fdctx); - - return 0; -} - -/* - * MGMT_OPS - */ - -/* Callbacks */ - -int -client_fxattrop_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen, - struct iobuf *iobuf) -{ - gf_fop_xattrop_rsp_t *rsp = NULL; - int32_t op_ret = 0; - int32_t gf_errno = 0; - int32_t op_errno = 0; - int32_t dict_len = 0; - dict_t *dict = NULL; - int32_t ret = -1; - char *dictbuf = NULL; - - rsp = gf_param (hdr); - GF_VALIDATE_OR_GOTO (frame->this->name, rsp, fail); - - op_ret = ntoh32 (hdr->rsp.op_ret); - - if (op_ret >= 0) { - op_ret = -1; - dict_len = ntoh32 (rsp->dict_len); - - if (dict_len > 0) { - dictbuf = memdup (rsp->dict, dict_len); - GF_VALIDATE_OR_GOTO (frame->this->name, dictbuf, fail); - - dict = dict_new(); - GF_VALIDATE_OR_GOTO (frame->this->name, dict, fail); - - ret = dict_unserialize (dictbuf, dict_len, &dict); - if (ret < 0) { - gf_log (frame->this->name, GF_LOG_DEBUG, - "failed to serialize dictionary(%p)", - dict); - op_errno = -ret; - goto fail; - } else { - dict->extra_free = dictbuf; - dictbuf = NULL; - } - } - op_ret = 0; - } - gf_errno = ntoh32 (hdr->rsp.op_errno); - op_errno = gf_error_to_errno (gf_errno); - -fail: - STACK_UNWIND (frame, op_ret, op_errno, dict); - - if (dictbuf) - GF_FREE (dictbuf); - - if (dict) - dict_unref (dict); - - return 0; -} - - -int -client_xattrop_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen, - struct iobuf *iobuf) -{ - gf_fop_xattrop_rsp_t *rsp = NULL; - int32_t op_ret = -1; - int32_t gf_errno = EINVAL; - int32_t op_errno = 0; - int32_t dict_len = 0; - dict_t *dict = NULL; - int32_t ret = -1; - char *dictbuf = NULL; - - rsp = gf_param (hdr); - GF_VALIDATE_OR_GOTO (frame->this->name, rsp, fail); - - op_ret = ntoh32 (hdr->rsp.op_ret); - if (op_ret >= 0) { - op_ret = -1; - dict_len = ntoh32 (rsp->dict_len); - - if (dict_len > 0) { - dictbuf = memdup (rsp->dict, dict_len); - GF_VALIDATE_OR_GOTO (frame->this->name, dictbuf, fail); - - dict = get_new_dict(); - GF_VALIDATE_OR_GOTO (frame->this->name, dict, fail); - dict_ref (dict); - - ret = dict_unserialize (dictbuf, dict_len, &dict); - if (ret < 0) { - gf_log (frame->this->name, GF_LOG_DEBUG, - "failed to serialize dictionary(%p)", - dict); - goto fail; - } else { - dict->extra_free = dictbuf; - dictbuf = NULL; - } - } - op_ret = 0; - } - gf_errno = ntoh32 (hdr->rsp.op_errno); - op_errno = gf_error_to_errno (gf_errno); - - -fail: - STACK_UNWIND (frame, op_ret, op_errno, dict); - - if (dictbuf) - GF_FREE (dictbuf); - if (dict) - dict_unref (dict); - - return 0; -} - -/* - * client_create_cbk - create callback function for client protocol - * @frame: call frame - * @args: arguments in dictionary - * - * not for external reference - */ - -int -client_create_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen, - struct iobuf *iobuf) -{ - gf_fop_create_rsp_t *rsp = NULL; - int32_t op_ret = 0; - int32_t op_errno = 0; - fd_t *fd = NULL; - inode_t *inode = NULL; - struct iatt stbuf = {0, }; - struct iatt preparent = {0, }; - struct iatt postparent = {0, }; - int64_t remote_fd = 0; - int32_t ret = -1; - client_local_t *local = NULL; - client_conf_t *conf = NULL; - client_fd_ctx_t *fdctx = NULL; - ino_t ino = 0; - uint64_t gen = 0; - - local = frame->local; frame->local = NULL; - conf = frame->this->private; - fd = local->fd; - inode = local->loc.inode; - - rsp = gf_param (hdr); - - op_ret = ntoh32 (hdr->rsp.op_ret); - op_errno = ntoh32 (hdr->rsp.op_errno); - - if (op_ret >= 0) { - remote_fd = ntoh64 (rsp->fd); - gf_stat_to_iatt (&rsp->stat, &stbuf); - - gf_stat_to_iatt (&rsp->preparent, &preparent); - gf_stat_to_iatt (&rsp->postparent, &postparent); - - ino = stbuf.ia_ino; - gen = stbuf.ia_gen; - } - - if (op_ret >= 0) { - ret = inode_ctx_put2 (local->loc.inode, frame->this, ino, gen); - - if (ret < 0) { - gf_log (frame->this->name, GF_LOG_DEBUG, - "CREATE %"PRId64"/%s (%s): failed to set " - "remote inode number to inode ctx", - local->loc.parent->ino, local->loc.name, - local->loc.path); - op_ret = -1; - op_errno = EINVAL; - goto unwind_out; - } - - fdctx = GF_CALLOC (1, sizeof (*fdctx), - gf_client_mt_client_fd_ctx_t); - if (!fdctx) { - op_ret = -1; - op_errno = ENOMEM; - goto unwind_out; - } - - fdctx->remote_fd = remote_fd; - fdctx->inode = inode_ref (fd->inode); - fdctx->ino = ino; - fdctx->gen = gen; - fdctx->flags = local->flags; - - INIT_LIST_HEAD (&fdctx->sfd_pos); - - this_fd_set_ctx (fd, frame->this, &local->loc, fdctx); - - pthread_mutex_lock (&conf->mutex); - { - list_add_tail (&fdctx->sfd_pos, &conf->saved_fds); - } - pthread_mutex_unlock (&conf->mutex); - } -unwind_out: - STACK_UNWIND (frame, op_ret, op_errno, fd, inode, &stbuf, - &preparent, &postparent); - - client_local_wipe (local); - - return 0; -} - - -/* - * client_open_cbk - open callback for client protocol - * @frame: call frame - * @args: argument dictionary - * - * not for external reference - */ -int -client_open_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen, - struct iobuf *iobuf) -{ - int32_t op_ret = -1; - int32_t op_errno = ENOTCONN; - fd_t *fd = NULL; - int64_t remote_fd = 0; - gf_fop_open_rsp_t *rsp = NULL; - client_local_t *local = NULL; - client_conf_t *conf = NULL; - client_fd_ctx_t *fdctx = NULL; - ino_t ino = 0; - uint64_t gen = 0; - - - local = frame->local; - - if (local->op) { - local->op (frame, hdr, hdrlen, iobuf); - return 0; - } - - frame->local = NULL; - conf = frame->this->private; - fd = local->fd; - - rsp = gf_param (hdr); - - op_ret = ntoh32 (hdr->rsp.op_ret); - op_errno = ntoh32 (hdr->rsp.op_errno); - - if (op_ret >= 0) { - remote_fd = ntoh64 (rsp->fd); - } - - if (op_ret >= 0) { - fdctx = GF_CALLOC (1, sizeof (*fdctx), - gf_client_mt_client_fd_ctx_t); - if (!fdctx) { - op_ret = -1; - op_errno = ENOMEM; - goto unwind_out; - } - - inode_ctx_get2 (fd->inode, frame->this, &ino, &gen); - - fdctx->remote_fd = remote_fd; - fdctx->inode = inode_ref (fd->inode); - fdctx->ino = ino; - fdctx->gen = gen; - fdctx->flags = local->flags; - fdctx->wbflags = local->wbflags; - - INIT_LIST_HEAD (&fdctx->sfd_pos); - - this_fd_set_ctx (fd, frame->this, &local->loc, fdctx); - - pthread_mutex_lock (&conf->mutex); - { - list_add_tail (&fdctx->sfd_pos, &conf->saved_fds); - } - pthread_mutex_unlock (&conf->mutex); - } -unwind_out: - STACK_UNWIND (frame, op_ret, op_errno, fd); - - client_local_wipe (local); - - return 0; -} - -/* - * client_stat_cbk - stat callback for client protocol - * @frame: call frame - * @args: arguments dictionary - * - * not for external reference - */ - -int -client_stat_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen, - struct iobuf *iobuf) -{ - struct iatt stbuf = {0, }; - gf_fop_stat_rsp_t *rsp = NULL; - int32_t op_ret = 0; - int32_t op_errno = 0; - - rsp = gf_param (hdr); - - op_ret = ntoh32 (hdr->rsp.op_ret); - op_errno = gf_error_to_errno (ntoh32 (hdr->rsp.op_errno)); - - if (op_ret == 0) { - gf_stat_to_iatt (&rsp->stat, &stbuf); - } - - STACK_UNWIND (frame, op_ret, op_errno, &stbuf); - - return 0; -} - - -/* - * client_mknod_cbk - mknod callback for client protocol - * @frame: call frame - * @args: argument dictionary - * - * not for external reference - */ - -int -client_mknod_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen, - struct iobuf *iobuf) -{ - gf_fop_mknod_rsp_t *rsp = NULL; - int32_t op_ret = 0; - int32_t op_errno = 0; - struct iatt stbuf = {0, }; - inode_t *inode = NULL; - client_local_t *local = NULL; - int ret = 0; - struct iatt preparent = {0,}; - struct iatt postparent = {0,}; - - local = frame->local; - frame->local = NULL; - inode = local->loc.inode; - - rsp = gf_param (hdr); - - op_ret = ntoh32 (hdr->rsp.op_ret); - op_errno = gf_error_to_errno (ntoh32 (hdr->rsp.op_errno)); - - if (op_ret >= 0) { - gf_stat_to_iatt (&rsp->stat, &stbuf); - - ret = inode_ctx_put2 (local->loc.inode, frame->this, - stbuf.ia_ino, stbuf.ia_gen); - if (ret < 0) { - gf_log (frame->this->name, GF_LOG_DEBUG, - "MKNOD %"PRId64"/%s (%s): failed to set remote" - " inode number to inode ctx", - local->loc.parent->ino, local->loc.name, - local->loc.path); - - STACK_UNWIND (frame, -1, EINVAL, inode, NULL, - NULL, NULL); - return 0; - } - - gf_stat_to_iatt (&rsp->preparent, &preparent); - gf_stat_to_iatt (&rsp->postparent, &postparent); - } - - STACK_UNWIND (frame, op_ret, op_errno, inode, &stbuf, - &preparent, &postparent); - - client_local_wipe (local); - - return 0; -} - -/* - * client_symlink_cbk - symlink callback for client protocol - * @frame: call frame - * @args: argument dictionary - * - * not for external reference - */ - -int -client_symlink_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen, - struct iobuf *iobuf) -{ - gf_fop_symlink_rsp_t *rsp = NULL; - int32_t op_ret = 0; - int32_t op_errno = 0; - struct iatt stbuf = {0, }; - struct iatt preparent = {0,}; - struct iatt postparent = {0,}; - inode_t *inode = NULL; - client_local_t *local = NULL; - int ret = 0; - - local = frame->local; - frame->local = NULL; - inode = local->loc.inode; - - rsp = gf_param (hdr); - - op_ret = ntoh32 (hdr->rsp.op_ret); - op_errno = gf_error_to_errno (ntoh32 (hdr->rsp.op_errno)); - - if (op_ret >= 0) { - gf_stat_to_iatt (&rsp->stat, &stbuf); - - ret = inode_ctx_put2 (inode, frame->this, - stbuf.ia_ino, stbuf.ia_gen); - if (ret < 0) { - gf_log (frame->this->name, GF_LOG_DEBUG, - "SYMLINK %"PRId64"/%s (%s): failed to set " - "remote inode number to inode ctx", - local->loc.parent->ino, local->loc.name, - local->loc.path); - STACK_UNWIND (frame, -1, EINVAL, inode, NULL, - NULL, NULL); - return 0; - } - gf_stat_to_iatt (&rsp->preparent, &preparent); - gf_stat_to_iatt (&rsp->postparent, &postparent); - } - - STACK_UNWIND (frame, op_ret, op_errno, inode, &stbuf, - &preparent, &postparent); - - client_local_wipe (local); - - return 0; -} - -/* - * client_link_cbk - link callback for client protocol - * @frame: call frame - * @args: argument dictionary - * - * not for external reference - */ - -int -client_link_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen, - struct iobuf *iobuf) -{ - gf_fop_link_rsp_t *rsp = NULL; - int32_t op_ret = 0; - int32_t op_errno = 0; - struct iatt stbuf = {0, }; - inode_t *inode = NULL; - client_local_t *local = NULL; - struct iatt preparent = {0,}; - struct iatt postparent = {0,}; - - local = frame->local; - frame->local = NULL; - inode = local->loc.inode; - - rsp = gf_param (hdr); - - op_ret = ntoh32 (hdr->rsp.op_ret); - op_errno = gf_error_to_errno (ntoh32 (hdr->rsp.op_errno)); - - if (op_ret >= 0) { - gf_stat_to_iatt (&rsp->stat, &stbuf); - - gf_stat_to_iatt (&rsp->preparent, &preparent); - gf_stat_to_iatt (&rsp->postparent, &postparent); - } - - STACK_UNWIND (frame, op_ret, op_errno, inode, &stbuf, - &preparent, &postparent); - - client_local_wipe (local); - - return 0; -} - -/* - * client_truncate_cbk - truncate callback for client protocol - * @frame: call frame - * @args: argument dictionary - * - * not for external reference - */ - -int -client_truncate_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen, - struct iobuf *iobuf) -{ - gf_fop_truncate_rsp_t *rsp = NULL; - int32_t op_ret = 0; - int32_t op_errno = 0; - struct iatt prestat = {0, }; - struct iatt poststat = {0, }; - - rsp = gf_param (hdr); - - op_ret = ntoh32 (hdr->rsp.op_ret); - op_errno = gf_error_to_errno (ntoh32 (hdr->rsp.op_errno)); - - if (op_ret == 0) { - gf_stat_to_iatt (&rsp->prestat, &prestat); - gf_stat_to_iatt (&rsp->poststat, &poststat); - } - - STACK_UNWIND (frame, op_ret, op_errno, &prestat, &poststat); - - return 0; -} - -/* client_fstat_cbk - fstat callback for client protocol - * @frame: call frame - * @args: argument dictionary - * - * not for external reference - */ - -int -client_fstat_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen, - struct iobuf *iobuf) -{ - struct iatt stbuf = {0, }; - gf_fop_fstat_rsp_t *rsp = NULL; - int32_t op_ret = 0; - int32_t op_errno = 0; - - rsp = gf_param (hdr); - - op_ret = ntoh32 (hdr->rsp.op_ret); - op_errno = gf_error_to_errno (ntoh32 (hdr->rsp.op_errno)); - - if (op_ret == 0) { - gf_stat_to_iatt (&rsp->stat, &stbuf); - - } - - STACK_UNWIND (frame, op_ret, op_errno, &stbuf); - - return 0; -} - -/* - * client_ftruncate_cbk - ftruncate callback for client protocol - * @frame: call frame - * @args: argument dictionary - * - * not for external reference - */ -int -client_ftruncate_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen, - struct iobuf *iobuf) -{ - gf_fop_ftruncate_rsp_t *rsp = NULL; - int32_t op_ret = 0; - int32_t op_errno = 0; - struct iatt prestat = {0, }; - struct iatt poststat = {0, }; - - rsp = gf_param (hdr); - - op_ret = ntoh32 (hdr->rsp.op_ret); - op_errno = gf_error_to_errno (ntoh32 (hdr->rsp.op_errno)); - - if (op_ret == 0) { - gf_stat_to_iatt (&rsp->prestat, &prestat); - gf_stat_to_iatt (&rsp->poststat, &poststat); - } - - STACK_UNWIND (frame, op_ret, op_errno, &prestat, &poststat); - - return 0; -} - - -/* client_readv_cbk - readv callback for client protocol - * @frame: call frame - * @args: argument dictionary - * - * not for external referece - */ - -int -client_readv_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen, - struct iobuf *iobuf) -{ - gf_fop_read_rsp_t *rsp = NULL; - int32_t op_ret = 0; - int32_t op_errno = 0; - struct iovec vector = {0, }; - struct iatt stbuf = {0, }; - struct iobref *iobref = NULL; - - rsp = gf_param (hdr); - - op_ret = ntoh32 (hdr->rsp.op_ret); - op_errno = gf_error_to_errno (ntoh32 (hdr->rsp.op_errno)); - - if (op_ret != -1) { - iobref = iobref_new (); - gf_stat_to_iatt (&rsp->stat, &stbuf); - vector.iov_len = op_ret; - - if (op_ret > 0) { - vector.iov_base = iobuf->ptr; - iobref_add (iobref, iobuf); - } - } - - STACK_UNWIND (frame, op_ret, op_errno, &vector, 1, &stbuf, iobref); - - if (iobref) - iobref_unref (iobref); - - if (iobuf) - iobuf_unref (iobuf); - - return 0; -} - -/* - * client_write_cbk - write callback for client protocol - * @frame: cal frame - * @args: argument dictionary - * - * not for external reference - */ - -int -client_write_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen, - struct iobuf *iobuf) -{ - gf_fop_write_rsp_t *rsp = NULL; - int32_t op_ret = 0; - int32_t op_errno = 0; - struct iatt prestat = {0, }; - struct iatt poststat = {0, }; - - rsp = gf_param (hdr); - - op_ret = ntoh32 (hdr->rsp.op_ret); - op_errno = gf_error_to_errno (ntoh32 (hdr->rsp.op_errno)); - - if (op_ret >= 0) { - gf_stat_to_iatt (&rsp->prestat, &prestat); - gf_stat_to_iatt (&rsp->poststat, &poststat); - } - - STACK_UNWIND (frame, op_ret, op_errno, &prestat, &poststat); - - return 0; -} - - -int -client_readdirp_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen, - struct iobuf *iobuf) -{ - gf_fop_readdirp_rsp_t *rsp = NULL; - int32_t op_ret = 0; - int32_t op_errno = 0; - uint32_t buf_size = 0; - gf_dirent_t entries; - - rsp = gf_param (hdr); - - op_ret = ntoh32 (hdr->rsp.op_ret); - op_errno = ntoh32 (hdr->rsp.op_errno); - - INIT_LIST_HEAD (&entries.list); - if (op_ret > 0) { - buf_size = ntoh32 (rsp->size); - gf_dirent_unserialize (&entries, rsp->buf, buf_size); - } - - STACK_UNWIND (frame, op_ret, op_errno, &entries); - - gf_dirent_free (&entries); - - return 0; -} - - -int -client_readdir_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen, - struct iobuf *iobuf) -{ - gf_fop_readdir_rsp_t *rsp = NULL; - int32_t op_ret = 0; - int32_t op_errno = 0; - uint32_t buf_size = 0; - gf_dirent_t entries; - - rsp = gf_param (hdr); - - op_ret = ntoh32 (hdr->rsp.op_ret); - op_errno = ntoh32 (hdr->rsp.op_errno); - - INIT_LIST_HEAD (&entries.list); - if (op_ret > 0) { - buf_size = ntoh32 (rsp->size); - gf_dirent_unserialize (&entries, rsp->buf, buf_size); - } - - STACK_UNWIND (frame, op_ret, op_errno, &entries); - - gf_dirent_free (&entries); - - return 0; -} - -/* - * client_fsync_cbk - fsync callback for client protocol - * - * @frame: call frame - * @args: argument dictionary - * - * not for external reference - */ - -int -client_fsync_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen, - struct iobuf *iobuf) -{ - struct iatt prestat = {0, }; - struct iatt poststat = {0,}; - gf_fop_fsync_rsp_t *rsp = NULL; - int32_t op_ret = 0; - int32_t op_errno = 0; - - rsp = gf_param (hdr); - - op_ret = ntoh32 (hdr->rsp.op_ret); - op_errno = gf_error_to_errno (ntoh32 (hdr->rsp.op_errno)); - - if (op_ret == 0) { - gf_stat_to_iatt (&rsp->prestat, &prestat); - gf_stat_to_iatt (&rsp->poststat, &poststat); - } - - STACK_UNWIND (frame, op_ret, op_errno, &prestat, &poststat); - - return 0; -} - -/* - * client_unlink_cbk - unlink callback for client protocol - * @frame: call frame - * @args: argument dictionary - * - * not for external reference - */ - -int -client_unlink_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen, - struct iobuf *iobuf) -{ - gf_fop_unlink_rsp_t *rsp = NULL; - int32_t op_ret = 0; - int32_t op_errno = 0; - struct iatt preparent = {0,}; - struct iatt postparent = {0,}; - - rsp = gf_param (hdr); - - op_ret = ntoh32 (hdr->rsp.op_ret); - op_errno = gf_error_to_errno (ntoh32 (hdr->rsp.op_errno)); - - if (op_ret == 0) { - gf_stat_to_iatt (&rsp->preparent, &preparent); - gf_stat_to_iatt (&rsp->postparent, &postparent); - } - - STACK_UNWIND (frame, op_ret, op_errno, &preparent, &postparent); - - return 0; -} - -/* - * client_rename_cbk - rename callback for client protocol - * @frame: call frame - * @args: argument dictionary - * - * not for external reference - */ - -int -client_rename_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen, - struct iobuf *iobuf) -{ - struct iatt stbuf = {0, }; - gf_fop_rename_rsp_t *rsp = NULL; - int32_t op_ret = 0; - int32_t op_errno = 0; - struct iatt preoldparent = {0, }; - struct iatt postoldparent = {0, }; - struct iatt prenewparent = {0, }; - struct iatt postnewparent = {0, }; - - rsp = gf_param (hdr); - - op_ret = ntoh32 (hdr->rsp.op_ret); - op_errno = gf_error_to_errno (ntoh32 (hdr->rsp.op_errno)); - - if (op_ret == 0) { - gf_stat_to_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); - } - - STACK_UNWIND (frame, op_ret, op_errno, &stbuf, &preoldparent, - &postoldparent, &prenewparent, &postnewparent); - - return 0; -} - - -/* - * client_readlink_cbk - readlink callback for client protocol - * - * @frame: call frame - * @args: argument dictionary - * - * not for external reference - */ -int -client_readlink_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen, - struct iobuf *iobuf) -{ - gf_fop_readlink_rsp_t *rsp = NULL; - int32_t op_ret = 0; - int32_t op_errno = 0; - char *link = NULL; - struct iatt stbuf = {0,}; - - rsp = gf_param (hdr); - - op_ret = ntoh32 (hdr->rsp.op_ret); - op_errno = gf_error_to_errno (ntoh32 (hdr->rsp.op_errno)); - - if (op_ret > 0) { - link = rsp->path; - gf_stat_to_iatt (&rsp->buf, &stbuf); - } - - STACK_UNWIND (frame, op_ret, op_errno, link, &stbuf); - return 0; -} - -/* - * client_mkdir_cbk - mkdir callback for client protocol - * @frame: call frame - * @args: argument dictionary - * - * not for external reference - */ - -int -client_mkdir_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen, - struct iobuf *iobuf) -{ - gf_fop_mkdir_rsp_t *rsp = NULL; - int32_t op_ret = 0; - int32_t op_errno = 0; - struct iatt stbuf = {0, }; - inode_t *inode = NULL; - client_local_t *local = NULL; - int ret = 0; - struct iatt preparent = {0,}; - struct iatt postparent = {0,}; - - local = frame->local; - inode = local->loc.inode; - frame->local = NULL; - - rsp = gf_param (hdr); - - op_ret = ntoh32 (hdr->rsp.op_ret); - op_errno = gf_error_to_errno (ntoh32 (hdr->rsp.op_errno)); - - if (op_ret >= 0) { - gf_stat_to_iatt (&rsp->stat, &stbuf); - - ret = inode_ctx_put2 (inode, frame->this, stbuf.ia_ino, - stbuf.ia_gen); - if (ret < 0) { - gf_log (frame->this->name, GF_LOG_DEBUG, - "MKDIR %"PRId64"/%s (%s): failed to set " - "remote inode number to inode ctx", - local->loc.parent->ino, local->loc.name, - local->loc.path); - STACK_UNWIND (frame, -1, EINVAL, inode, NULL, - NULL, NULL); - return 0; - } - - gf_stat_to_iatt (&rsp->preparent, &preparent); - gf_stat_to_iatt (&rsp->postparent, &postparent); - } - - STACK_UNWIND (frame, op_ret, op_errno, inode, &stbuf, - &preparent, &postparent); - - client_local_wipe (local); - - return 0; -} - -/* - * client_flush_cbk - flush callback for client protocol - * - * @frame: call frame - * @args: argument dictionary - * - * not for external reference - */ - -int -client_flush_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen, - struct iobuf *iobuf) -{ - int32_t op_ret = 0; - int32_t op_errno = 0; - - op_ret = ntoh32 (hdr->rsp.op_ret); - op_errno = gf_error_to_errno (ntoh32 (hdr->rsp.op_errno)); - - STACK_UNWIND (frame, op_ret, op_errno); - - return 0; -} - -/* - * client_opendir_cbk - opendir callback for client protocol - * @frame: call frame - * @args: argument dictionary - * - * not for external reference - */ - -int -client_opendir_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen, - struct iobuf *iobuf) -{ - int32_t op_ret = -1; - int32_t op_errno = ENOTCONN; - fd_t *fd = NULL; - int64_t remote_fd = 0; - gf_fop_opendir_rsp_t *rsp = NULL; - client_local_t *local = NULL; - client_conf_t *conf = NULL; - client_fd_ctx_t *fdctx = NULL; - ino_t ino = 0; - uint64_t gen = 0; - - - local = frame->local; - - if (local->op) { - local->op (frame, hdr, hdrlen, iobuf); - return 0; - } - - frame->local = NULL; - conf = frame->this->private; - fd = local->fd; - - rsp = gf_param (hdr); - - op_ret = ntoh32 (hdr->rsp.op_ret); - op_errno = ntoh32 (hdr->rsp.op_errno); - - if (op_ret >= 0) { - remote_fd = ntoh64 (rsp->fd); - } - - if (op_ret >= 0) { - fdctx = GF_CALLOC (1, sizeof (*fdctx), - gf_client_mt_client_fd_ctx_t); - if (!fdctx) { - op_ret = -1; - op_errno = ENOMEM; - goto unwind_out; - } - - inode_ctx_get2 (fd->inode, frame->this, &ino, &gen); - - fdctx->remote_fd = remote_fd; - fdctx->inode = inode_ref (fd->inode); - fdctx->ino = ino; - fdctx->gen = gen; - - fdctx->is_dir = 1; - - INIT_LIST_HEAD (&fdctx->sfd_pos); - - this_fd_set_ctx (fd, frame->this, &local->loc, fdctx); - - pthread_mutex_lock (&conf->mutex); - { - list_add_tail (&fdctx->sfd_pos, &conf->saved_fds); - } - pthread_mutex_unlock (&conf->mutex); - } -unwind_out: - STACK_UNWIND (frame, op_ret, op_errno, fd); - - client_local_wipe (local); - - return 0; -} - -/* - * client_rmdir_cbk - rmdir callback for client protocol - * @frame: call frame - * @args: argument dictionary - * - * not for external reference - */ - -int -client_rmdir_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen, - struct iobuf *iobuf) -{ - gf_fop_rmdir_rsp_t *rsp = NULL; - int32_t op_ret = 0; - int32_t op_errno = 0; - struct iatt preparent = {0,}; - struct iatt postparent = {0,}; - - rsp = gf_param (hdr); - - op_ret = ntoh32 (hdr->rsp.op_ret); - op_errno = gf_error_to_errno (ntoh32 (hdr->rsp.op_errno)); - - if (op_ret == 0) { - gf_stat_to_iatt (&rsp->preparent, &preparent); - gf_stat_to_iatt (&rsp->postparent, &postparent); - } - - STACK_UNWIND (frame, op_ret, op_errno, &preparent, &postparent); - - return 0; -} - -/* - * client_access_cbk - access callback for client protocol - * @frame: call frame - * @args: argument dictionary - * - * not for external reference - */ - -int -client_access_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen, - struct iobuf *iobuf) -{ - gf_fop_access_rsp_t *rsp = NULL; - int32_t op_ret = 0; - int32_t op_errno = 0; - - rsp = gf_param (hdr); - - op_ret = ntoh32 (hdr->rsp.op_ret); - op_errno = gf_error_to_errno (ntoh32 (hdr->rsp.op_errno)); - - STACK_UNWIND (frame, op_ret, op_errno); - - return 0; -} - -/* - * client_lookup_cbk - lookup callback for client protocol - * - * @frame: call frame - * @args: arguments dictionary - * - * not for external reference - */ - -int -client_lookup_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen, - struct iobuf *iobuf) -{ - struct iatt stbuf = {0, }; - struct iatt postparent = {0, }; - inode_t *inode = NULL; - dict_t *xattr = NULL; - gf_fop_lookup_rsp_t *rsp = NULL; - int32_t op_ret = 0; - int32_t op_errno = 0; - size_t dict_len = 0; - char *dictbuf = NULL; - int32_t ret = -1; - int32_t gf_errno = 0; - client_local_t *local = NULL; - ino_t oldino = 0; - uint64_t oldgen = 0; - - local = frame->local; - inode = local->loc.inode; - frame->local = NULL; - - rsp = gf_param (hdr); - - op_ret = ntoh32 (hdr->rsp.op_ret); - - gf_stat_to_iatt (&rsp->postparent, &postparent); - - if (op_ret == 0) { - op_ret = -1; - gf_stat_to_iatt (&rsp->stat, &stbuf); - - ret = inode_ctx_get2 (inode, frame->this, &oldino, &oldgen); - if (oldino != stbuf.ia_ino || oldgen != stbuf.ia_gen) { - if (oldino) { - gf_log (frame->this->name, GF_LOG_DEBUG, - "LOOKUP %"PRId64"/%s (%s): " - "inode number changed from " - "{%"PRId64",%"PRId64"} to {%"PRId64",%"PRId64"}", - local->loc.parent ? - local->loc.parent->ino : (uint64_t) 0, - local->loc.name, - local->loc.path, - oldgen, oldino, stbuf.ia_gen, stbuf.ia_ino); - op_errno = ESTALE; - goto fail; - } - - ret = inode_ctx_put2 (inode, frame->this, - stbuf.ia_ino, stbuf.ia_gen); - if (ret < 0) { - gf_log (frame->this->name, GF_LOG_DEBUG, - "LOOKUP %"PRId64"/%s (%s) : " - "failed to set remote inode " - "number to inode ctx", - local->loc.parent ? - local->loc.parent->ino : (uint64_t) 0, - local->loc.name, - local->loc.path); - op_errno = EINVAL; - goto fail; - } - } - - dict_len = ntoh32 (rsp->dict_len); - - if (dict_len > 0) { - dictbuf = memdup (rsp->dict, dict_len); - GF_VALIDATE_OR_GOTO (frame->this->name, dictbuf, fail); - - xattr = dict_new(); - GF_VALIDATE_OR_GOTO (frame->this->name, xattr, fail); - - ret = dict_unserialize (dictbuf, dict_len, &xattr); - if (ret < 0) { - gf_log (frame->this->name, GF_LOG_DEBUG, - "%s (%"PRId64"): failed to " - "unserialize dictionary", - local->loc.path, inode->ino); - goto fail; - } else { - xattr->extra_free = dictbuf; - dictbuf = NULL; - } - } - op_ret = 0; - } - gf_errno = ntoh32 (hdr->rsp.op_errno); - op_errno = gf_error_to_errno (gf_errno); - -fail: - STACK_UNWIND (frame, op_ret, op_errno, inode, &stbuf, xattr, - &postparent); - - client_local_wipe (local); - - if (dictbuf) - GF_FREE (dictbuf); - - if (xattr) - dict_unref (xattr); - - return 0; -} - -static int32_t -client_setattr_cbk (call_frame_t *frame,gf_hdr_common_t *hdr, size_t hdrlen, - struct iobuf *iobuf) -{ - struct iatt statpre = {0, }; - struct iatt statpost = {0, }; - gf_fop_setattr_rsp_t *rsp = NULL; - int32_t op_ret = 0; - int32_t op_errno = 0; - - rsp = gf_param (hdr); - - op_ret = ntoh32 (hdr->rsp.op_ret); - op_errno = gf_error_to_errno (ntoh32 (hdr->rsp.op_errno)); - - if (op_ret == 0) { - gf_stat_to_iatt (&rsp->statpre, &statpre); - gf_stat_to_iatt (&rsp->statpost, &statpost); - } - - STACK_UNWIND (frame, op_ret, op_errno, &statpre, &statpost); - - return 0; -} - -static int32_t -client_fsetattr_cbk (call_frame_t *frame,gf_hdr_common_t *hdr, size_t hdrlen, - struct iobuf *iobuf) -{ - struct iatt statpre = {0, }; - struct iatt statpost = {0, }; - gf_fop_setattr_rsp_t *rsp = NULL; - int32_t op_ret = 0; - int32_t op_errno = 0; - - rsp = gf_param (hdr); - - op_ret = ntoh32 (hdr->rsp.op_ret); - op_errno = gf_error_to_errno (ntoh32 (hdr->rsp.op_errno)); - - if (op_ret == 0) { - gf_stat_to_iatt (&rsp->statpre, &statpre); - gf_stat_to_iatt (&rsp->statpost, &statpost); - } - - STACK_UNWIND (frame, op_ret, op_errno, &statpre, &statpost); - - return 0; -} - - -int -gf_free_direntry (dir_entry_t *head) -{ - dir_entry_t *prev = NULL; - dir_entry_t *trav = NULL; - - prev = head; - GF_VALIDATE_OR_GOTO ("client-protocol", prev, fail); - - trav = head->next; - while (trav) { - prev->next = trav->next; - GF_FREE (trav->name); - if (IA_ISLNK (trav->buf.ia_type)) - GF_FREE (trav->link); - GF_FREE (trav); - trav = prev->next; - } - GF_FREE (head); -fail: - return 0; -} - -/* - * client_statfs_cbk - statfs callback for client protocol - * @frame: call frame - * @args: argument dictionary - * - * not for external reference - */ - -int -client_statfs_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen, - struct iobuf *iobuf) -{ - struct statvfs stbuf = {0, }; - gf_fop_statfs_rsp_t *rsp = NULL; - int32_t op_ret = 0; - int32_t op_errno = 0; - - rsp = gf_param (hdr); - - op_ret = ntoh32 (hdr->rsp.op_ret); - op_errno = gf_error_to_errno (ntoh32 (hdr->rsp.op_errno)); - - if (op_ret == 0) { - gf_statfs_to_statfs (&rsp->statfs, &stbuf); - } - - STACK_UNWIND (frame, op_ret, op_errno, &stbuf); - - return 0; -} - -/* - * client_fsyncdir_cbk - fsyncdir callback for client protocol - * @frame: call frame - * @args: argument dictionary - * - * not for external reference - */ - -int -client_fsyncdir_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen, - struct iobuf *iobuf) -{ - int32_t op_ret = 0; - int32_t op_errno = 0; - - op_ret = ntoh32 (hdr->rsp.op_ret); - op_errno = gf_error_to_errno (ntoh32 (hdr->rsp.op_errno)); - - STACK_UNWIND (frame, op_ret, op_errno); - - return 0; -} - -/* - * client_setxattr_cbk - setxattr callback for client protocol - * @frame: call frame - * @args: argument dictionary - * - * not for external reference - */ - -int -client_setxattr_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen, - struct iobuf *iobuf) -{ - gf_fop_setxattr_rsp_t *rsp = NULL; - int32_t op_ret = 0; - int32_t op_errno = 0; - - rsp = gf_param (hdr); - - op_ret = ntoh32 (hdr->rsp.op_ret); - op_errno = gf_error_to_errno (ntoh32 (hdr->rsp.op_errno)); - - STACK_UNWIND (frame, op_ret, op_errno); - - return 0; -} - -/* - * client_getxattr_cbk - getxattr callback for client protocol - * @frame: call frame - * @args: argument dictionary - * - * not for external reference - */ - -int -client_getxattr_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen, - struct iobuf *iobuf) -{ - gf_fop_getxattr_rsp_t *rsp = NULL; - int32_t op_ret = 0; - int32_t gf_errno = 0; - int32_t op_errno = 0; - int32_t dict_len = 0; - dict_t *dict = NULL; - int32_t ret = -1; - char *dictbuf = NULL; - client_local_t *local = NULL; - - local = frame->local; - frame->local = NULL; - - rsp = gf_param (hdr); - GF_VALIDATE_OR_GOTO (frame->this->name, rsp, fail); - - op_ret = ntoh32 (hdr->rsp.op_ret); - - if (op_ret >= 0) { - op_ret = -1; - dict_len = ntoh32 (rsp->dict_len); - - if (dict_len > 0) { - dictbuf = memdup (rsp->dict, dict_len); - GF_VALIDATE_OR_GOTO (frame->this->name, dictbuf, fail); - - dict = dict_new(); - GF_VALIDATE_OR_GOTO (frame->this->name, dict, fail); - - ret = dict_unserialize (dictbuf, dict_len, &dict); - if (ret < 0) { - gf_log (frame->this->name, GF_LOG_DEBUG, - "%s (%"PRId64"): failed to " - "unserialize xattr dictionary", - local->loc.path, - local->loc.inode->ino); - goto fail; - } else { - dict->extra_free = dictbuf; - dictbuf = NULL; - } - } - op_ret = 0; - } - gf_errno = ntoh32 (hdr->rsp.op_errno); - op_errno = gf_error_to_errno (gf_errno); -fail: - STACK_UNWIND (frame, op_ret, op_errno, dict); - - client_local_wipe (local); - - if (dictbuf) - GF_FREE (dictbuf); - - if (dict) - dict_unref (dict); - - return 0; -} - -/* - * client_removexattr_cbk - removexattr callback for client protocol - * @frame: call frame - * @args: argument dictionary - * - * not for external reference - */ - -int -client_removexattr_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, - size_t hdrlen, struct iobuf *iobuf) -{ - int32_t op_ret = 0; - int32_t op_errno = 0; - - op_ret = ntoh32 (hdr->rsp.op_ret); - op_errno = gf_error_to_errno (ntoh32 (hdr->rsp.op_errno)); - - STACK_UNWIND (frame, op_ret, op_errno); - - return 0; -} - -/* - * client_lk_cbk - lk callback for client protocol - * @frame: call frame - * @args: argument dictionary - * - * not for external reference - */ - -int -client_lk_common_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen, - struct iobuf *iobuf) -{ - struct gf_flock lock = {0,}; - gf_fop_lk_rsp_t *rsp = NULL; - int32_t op_ret = 0; - int32_t op_errno = 0; - - rsp = gf_param (hdr); - - op_ret = ntoh32 (hdr->rsp.op_ret); - op_errno = gf_error_to_errno (ntoh32 (hdr->rsp.op_errno)); - - if (op_ret >= 0) { - gf_flock_to_flock (&rsp->flock, &lock); - } - - STACK_UNWIND (frame, op_ret, op_errno, &lock); - return 0; -} - -/* - * client_gf_file_lk_cbk - gf_file_lk callback for client protocol - * @frame: call frame - * @args: argument dictionary - * - * not for external reference - */ - -int -client_inodelk_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen, - struct iobuf *iobuf) -{ - gf_fop_inodelk_rsp_t *rsp = NULL; - int32_t op_ret = 0; - int32_t op_errno = 0; - - rsp = gf_param (hdr); - - op_ret = ntoh32 (hdr->rsp.op_ret); - op_errno = gf_error_to_errno (ntoh32 (hdr->rsp.op_errno)); - - STACK_UNWIND (frame, op_ret, op_errno); - return 0; -} - - -int -client_finodelk_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen, - struct iobuf *iobuf) -{ - gf_fop_finodelk_rsp_t *rsp = NULL; - int32_t op_ret = 0; - int32_t op_errno = 0; - - rsp = gf_param (hdr); - - op_ret = ntoh32 (hdr->rsp.op_ret); - op_errno = gf_error_to_errno (ntoh32 (hdr->rsp.op_errno)); - - STACK_UNWIND (frame, op_ret, op_errno); - return 0; -} - -/* - * client_entrylk_cbk - entrylk callback for client protocol - * @frame: call frame - * @args: argument dictionary - * - * not for external reference - */ - -int -client_entrylk_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen, - struct iobuf *iobuf) -{ - gf_fop_entrylk_rsp_t *rsp = NULL; - int32_t op_ret = 0; - int32_t op_errno = 0; - - rsp = gf_param (hdr); - - op_ret = ntoh32 (hdr->rsp.op_ret); - op_errno = gf_error_to_errno (ntoh32 (hdr->rsp.op_errno)); - - STACK_UNWIND (frame, op_ret, op_errno); - return 0; -} - -int -client_fentrylk_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen, - struct iobuf *iobuf) -{ - gf_fop_fentrylk_rsp_t *rsp = NULL; - int32_t op_ret = 0; - int32_t op_errno = 0; - - rsp = gf_param (hdr); - - op_ret = ntoh32 (hdr->rsp.op_ret); - op_errno = gf_error_to_errno (ntoh32 (hdr->rsp.op_errno)); - - STACK_UNWIND (frame, op_ret, op_errno); - return 0; -} - - - -/* - * client_getspec - getspec function for client protocol - * @frame: call frame - * @this: client protocol xlator structure - * @flag: - * - * external reference through client_protocol_xlator->fops->getspec - */ - -int -client_getspec (call_frame_t *frame, xlator_t *this, const char *key, - int32_t flag) -{ - gf_hdr_common_t *hdr = NULL; - gf_mop_getspec_req_t *req = NULL; - size_t hdrlen = -1; - int keylen = 0; - int ret = -1; - - if (key) - keylen = STRLEN_0 (key); - - hdrlen = gf_hdr_len (req, keylen); - hdr = gf_hdr_new (req, keylen); - GF_VALIDATE_OR_GOTO (this->name, hdr, unwind); - - req = gf_param (hdr); - req->flags = hton32 (flag); - req->keylen = hton32 (keylen); - if (keylen) - strcpy (req->key, key); - - ret = protocol_client_xfer (frame, this, - CLIENT_CHANNEL (this, CHANNEL_BULK), - GF_OP_TYPE_MOP_REQUEST, GF_MOP_GETSPEC, - hdr, hdrlen, NULL, 0, NULL); - - return ret; -unwind: - if (hdr) - GF_FREE (hdr); - STACK_UNWIND (frame, -1, EINVAL, NULL); - return 0; -} - -/* - * client_getspec_cbk - getspec callback for client protocol - * - * @frame: call frame - * @args: argument dictionary - * - * not for external reference - */ - -int -client_getspec_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen, - struct iobuf *iobuf) -{ - gf_mop_getspec_rsp_t *rsp = NULL; - char *spec_data = NULL; - int32_t op_ret = 0; - int32_t op_errno = 0; - int32_t gf_errno = 0; - - op_ret = ntoh32 (hdr->rsp.op_ret); - gf_errno = ntoh32 (hdr->rsp.op_errno); - op_errno = gf_error_to_errno (gf_errno); - rsp = gf_param (hdr); - - if (op_ret >= 0) { - spec_data = rsp->spec; - } - - STACK_UNWIND (frame, op_ret, op_errno, spec_data); - return 0; -} - - -int -client_rchecksum (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, - int32_t len) -{ - gf_hdr_common_t *hdr = NULL; - gf_fop_rchecksum_req_t *req = NULL; - size_t hdrlen = -1; - int ret = -1; - - int64_t remote_fd = -1; - client_fd_ctx_t *fdctx = NULL; - client_conf_t *conf = NULL; - - hdrlen = gf_hdr_len (req, 0); - hdr = gf_hdr_new (req, 0); - req = gf_param (hdr); - - conf = this->private; - - pthread_mutex_lock (&conf->mutex); - { - fdctx = this_fd_get_ctx (fd, this); - } - pthread_mutex_unlock (&conf->mutex); - - if (fdctx == NULL) { - gf_log (this->name, GF_LOG_TRACE, - "(%"PRId64"): failed to get fd ctx. EBADFD", - fd->inode->ino); - STACK_UNWIND (frame, -1, EBADFD, 0, NULL); - return 0; - } - - if (fdctx->remote_fd == -1) { - gf_log (this->name, GF_LOG_TRACE, - "(%"PRId64"): failed to get fd ctx. EBADFD", - fd->inode->ino); - STACK_UNWIND (frame, -1, EBADFD, 0, NULL); - return 0; - } - - remote_fd = fdctx->remote_fd; - - req->fd = hton64 (remote_fd); - req->offset = hton64 (offset); - req->len = hton32 (len); - - ret = protocol_client_xfer (frame, this, - CLIENT_CHANNEL (this, CHANNEL_BULK), - GF_OP_TYPE_FOP_REQUEST, GF_PROTO_FOP_RCHECKSUM, - hdr, hdrlen, NULL, 0, NULL); - - return ret; -} - - -int -client_rchecksum_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen, - struct iobuf *iobuf) -{ - gf_fop_rchecksum_rsp_t *rsp = NULL; - - int32_t op_ret = 0; - int32_t op_errno = 0; - int32_t gf_errno = 0; - uint32_t weak_checksum = 0; - unsigned char *strong_checksum = NULL; - - rsp = gf_param (hdr); - - op_ret = ntoh32 (hdr->rsp.op_ret); - gf_errno = ntoh32 (hdr->rsp.op_errno); - op_errno = gf_error_to_errno (gf_errno); - - if (op_ret >= 0) { - weak_checksum = rsp->weak_checksum; - strong_checksum = rsp->strong_checksum; - } - - STACK_UNWIND (frame, op_ret, op_errno, weak_checksum, strong_checksum); - - return 0; -} - - -/* - * client_setspec_cbk - setspec callback for client protocol - * @frame: call frame - * @args: argument dictionary - * - * not for external reference - */ - -int -client_setspec_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen, - struct iobuf *iobuf) -{ - int32_t op_ret = 0; - int32_t op_errno = 0; - - op_ret = ntoh32 (hdr->rsp.op_ret); - op_errno = gf_error_to_errno (ntoh32 (hdr->rsp.op_errno)); - - STACK_UNWIND (frame, op_ret, op_errno); - - return 0; -} - - - -int -protocol_client_reopendir_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, - size_t hdrlen, struct iobuf *iobuf) -{ - int32_t op_ret = -1; - int32_t op_errno = ENOTCONN; - int64_t remote_fd = -1; - gf_fop_open_rsp_t *rsp = NULL; - client_local_t *local = NULL; - client_conf_t *conf = NULL; - client_fd_ctx_t *fdctx = NULL; - - - local = frame->local; frame->local = NULL; - conf = frame->this->private; - fdctx = local->fdctx; - - rsp = gf_param (hdr); - - op_ret = ntoh32 (hdr->rsp.op_ret); - op_errno = ntoh32 (hdr->rsp.op_errno); - - if (op_ret >= 0) - remote_fd = ntoh64 (rsp->fd); - - gf_log (frame->this->name, GF_LOG_DEBUG, - "reopendir on %s returned %d (%"PRId64")", - local->loc.path, op_ret, remote_fd); - - pthread_mutex_lock (&conf->mutex); - { - fdctx->remote_fd = remote_fd; - - if (!fdctx->released) { - list_add_tail (&fdctx->sfd_pos, &conf->saved_fds); - fdctx = NULL; - } - } - pthread_mutex_unlock (&conf->mutex); - - if (fdctx) - client_fdctx_destroy (frame->this, fdctx); - - STACK_DESTROY (frame->root); - - client_local_wipe (local); - - return 0; -} - - - -int -protocol_client_reopendir (xlator_t *this, client_fd_ctx_t *fdctx) -{ - int ret = -1; - gf_hdr_common_t *hdr = NULL; - size_t hdrlen = 0; - gf_fop_opendir_req_t *req = NULL; - size_t pathlen = 0; - client_local_t *local = NULL; - inode_t *inode = NULL; - char *path = NULL; - call_frame_t *frame = NULL; - - inode = fdctx->inode; - - ret = inode_path (inode, NULL, &path); - if (ret < 0) { - goto out; - } - - local = GF_CALLOC (1, sizeof (*local), gf_client_mt_client_local_t); - if (!local) { - goto out; - } - - local->fdctx = fdctx; - local->op = protocol_client_reopendir_cbk; - local->loc.path = path; path = NULL; - - frame = create_frame (this, this->ctx->pool); - if (!frame) { - goto out; - } - - pathlen = STRLEN_0 (local->loc.path); - - hdrlen = gf_hdr_len (req, pathlen); - hdr = gf_hdr_new (req, pathlen); - - req = gf_param (hdr); - - req->ino = hton64 (fdctx->ino); - req->gen = hton64 (fdctx->gen); - - strcpy (req->path, local->loc.path); - - gf_log (frame->this->name, GF_LOG_DEBUG, - "attempting reopendir on %s", local->loc.path); - - frame->local = local; local = NULL; - - ret = protocol_client_xfer (frame, this, - CLIENT_CHANNEL (this, CHANNEL_LOWLAT), - GF_OP_TYPE_FOP_REQUEST, GF_PROTO_FOP_OPENDIR, - hdr, hdrlen, NULL, 0, NULL); - - return ret; - -out: - if (frame) - STACK_DESTROY (frame->root); - - if (local) - client_local_wipe (local); - - if (path) - GF_FREE (path); - - return 0; -} - - -int -protocol_client_reopen_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, - size_t hdrlen, struct iobuf *iobuf) -{ - int32_t op_ret = -1; - int32_t op_errno = ENOTCONN; - int64_t remote_fd = -1; - gf_fop_open_rsp_t *rsp = NULL; - client_local_t *local = NULL; - client_conf_t *conf = NULL; - client_fd_ctx_t *fdctx = NULL; - - - local = frame->local; frame->local = NULL; - conf = frame->this->private; - fdctx = local->fdctx; - - rsp = gf_param (hdr); - - op_ret = ntoh32 (hdr->rsp.op_ret); - op_errno = ntoh32 (hdr->rsp.op_errno); - - if (op_ret >= 0) - remote_fd = ntoh64 (rsp->fd); - - gf_log (frame->this->name, GF_LOG_DEBUG, - "reopen on %s returned %d (%"PRId64")", - local->loc.path, op_ret, remote_fd); - - pthread_mutex_lock (&conf->mutex); - { - fdctx->remote_fd = remote_fd; - - if (!fdctx->released) { - list_add_tail (&fdctx->sfd_pos, &conf->saved_fds); - fdctx = NULL; - } - } - pthread_mutex_unlock (&conf->mutex); - - if (fdctx) - client_fdctx_destroy (frame->this, fdctx); - - STACK_DESTROY (frame->root); - - client_local_wipe (local); - - return 0; -} - - -int -protocol_client_reopen (xlator_t *this, client_fd_ctx_t *fdctx) -{ - int ret = -1; - gf_hdr_common_t *hdr = NULL; - size_t hdrlen = 0; - gf_fop_open_req_t *req = NULL; - size_t pathlen = 0; - client_local_t *local = NULL; - inode_t *inode = NULL; - char *path = NULL; - call_frame_t *frame = NULL; - - inode = fdctx->inode; - - ret = inode_path (inode, NULL, &path); - if (ret < 0) { - goto out; - } - - local = GF_CALLOC (1, sizeof (*local), gf_client_mt_client_local_t); - if (!local) { - goto out; - } - - local->fdctx = fdctx; - local->op = protocol_client_reopen_cbk; - local->loc.path = path; path = NULL; - - frame = create_frame (this, this->ctx->pool); - if (!frame) { - goto out; - } - - pathlen = STRLEN_0 (local->loc.path); - - hdrlen = gf_hdr_len (req, pathlen); - hdr = gf_hdr_new (req, pathlen); - - req = gf_param (hdr); - - req->ino = hton64 (fdctx->ino); - req->gen = hton64 (fdctx->gen); - req->flags = hton32 (gf_flags_from_flags (fdctx->flags)); - req->wbflags = hton32 (fdctx->wbflags); - strcpy (req->path, local->loc.path); - - gf_log (frame->this->name, GF_LOG_DEBUG, - "attempting reopen on %s", local->loc.path); - - frame->local = local; local = NULL; - - ret = protocol_client_xfer (frame, this, - CLIENT_CHANNEL (this, CHANNEL_LOWLAT), - GF_OP_TYPE_FOP_REQUEST, GF_PROTO_FOP_OPEN, - hdr, hdrlen, NULL, 0, NULL); - - return ret; - -out: - if (frame) - STACK_DESTROY (frame->root); - - if (local) - client_local_wipe (local); - - if (path) - GF_FREE (path); - - return 0; - -} - - -int -protocol_client_post_handshake (call_frame_t *frame, xlator_t *this) -{ - client_conf_t *conf = NULL; - client_fd_ctx_t *tmp = NULL; - client_fd_ctx_t *fdctx = NULL; - xlator_list_t *parent = NULL; - struct list_head reopen_head; - - conf = this->private; - INIT_LIST_HEAD (&reopen_head); - - pthread_mutex_lock (&conf->mutex); - { - list_for_each_entry_safe (fdctx, tmp, &conf->saved_fds, - sfd_pos) { - if (fdctx->remote_fd != -1) - continue; - - list_del (&fdctx->sfd_pos); - list_add_tail (&fdctx->sfd_pos, &reopen_head); - } - } - pthread_mutex_unlock (&conf->mutex); - - 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); - } - - parent = this->parents; - - while (parent) { - xlator_notify (parent->xlator, GF_EVENT_CHILD_UP, - this); - parent = parent->next; - } - - return 0; -} - -/* - * client_setvolume_cbk - setvolume callback for client protocol - * @frame: call frame - * @args: argument dictionary - * - * not for external reference - */ - -int -client_setvolume_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen, - struct iobuf *iobuf) -{ - client_conf_t *conf = NULL; - gf_mop_setvolume_rsp_t *rsp = NULL; - client_connection_t *conn = NULL; - glusterfs_ctx_t *ctx = NULL; - xlator_t *this = NULL; - xlator_list_t *parent = NULL; - transport_t *trans = NULL; - dict_t *reply = NULL; - char *remote_subvol = NULL; - char *remote_error = NULL; - char *process_uuid = NULL; - int32_t ret = -1; - int32_t op_ret = -1; - int32_t op_errno = EINVAL; - int32_t dict_len = 0; - transport_t *peer_trans = NULL; - uint64_t peer_trans_int = 0; - - trans = frame->local; frame->local = NULL; - this = frame->this; - conn = trans->xl_private; - conf = this->private; - - rsp = gf_param (hdr); - - op_ret = ntoh32 (hdr->rsp.op_ret); - op_errno = gf_error_to_errno (ntoh32 (hdr->rsp.op_errno)); - - if (op_ret < 0) { - gf_log (this->name, GF_LOG_DEBUG, - "setvolume failed (%s)", - strerror (op_errno)); - goto out; - } - - reply = dict_new (); - GF_VALIDATE_OR_GOTO (this->name, reply, out); - - dict_len = ntoh32 (rsp->dict_len); - ret = dict_unserialize (rsp->buf, dict_len, &reply); - if (ret < 0) { - gf_log (frame->this->name, GF_LOG_DEBUG, - "failed to unserialize buffer(%p) to dictionary", - rsp->buf); - goto out; - } - - ret = dict_get_str (reply, "ERROR", &remote_error); - if (ret < 0) { - gf_log (this->name, GF_LOG_DEBUG, - "failed to get ERROR string from reply dictionary"); - } - - ret = dict_get_str (reply, "process-uuid", &process_uuid); - if (ret < 0) { - gf_log (this->name, GF_LOG_DEBUG, - "failed to get 'process-uuid' from reply dictionary"); - } - - if (op_ret < 0) { - gf_log (trans->xl->name, GF_LOG_ERROR, - "SETVOLUME on remote-host failed: %s", - remote_error ? remote_error : strerror (op_errno)); - errno = op_errno; - if (op_errno == ESTALE) { - parent = trans->xl->parents; - while (parent) { - xlator_notify (parent->xlator, - GF_EVENT_VOLFILE_MODIFIED, - trans->xl); - parent = parent->next; - } - } - - } else { - ret = dict_get_str (this->options, "remote-subvolume", - &remote_subvol); - if (!remote_subvol) - goto out; - - ctx = this->ctx; - - if (process_uuid && !strcmp (ctx->process_uuid,process_uuid)) { - ret = dict_get_uint64 (reply, "transport-ptr", - &peer_trans_int); - - peer_trans = (void *) (long) (peer_trans_int); - - gf_log (this->name, GF_LOG_WARNING, - "attaching to the local volume '%s'", - remote_subvol); - - transport_setpeer (trans, peer_trans); - - } - - gf_log (trans->xl->name, GF_LOG_INFO, - "Connected to %s, attached " - "to remote volume '%s'.", - trans->peerinfo.identifier, remote_subvol); - - pthread_mutex_lock (&(conn->lock)); - { - conn->connected = 1; - } - pthread_mutex_unlock (&(conn->lock)); - - protocol_client_post_handshake (frame, frame->this); - } - - conf->connecting = 0; -out: - - if (-1 == op_ret) { - /* Let the connection/re-connection happen in - * background, for now, don't hang here, - * tell the parents that i am all ok.. - */ - parent = trans->xl->parents; - while (parent) { - xlator_notify (parent->xlator, - GF_EVENT_CHILD_CONNECTING, trans->xl); - parent = parent->next; - } - conf->connecting= 1; - } - - STACK_DESTROY (frame->root); - - if (reply) - dict_unref (reply); - - return op_ret; -} - -/* - * client_enosys_cbk - - * @frame: call frame - * - * not for external reference - */ - -int -client_enosys_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen, - struct iobuf *iobuf) -{ - STACK_DESTROY (frame->root); - return 0; -} - - -void -client_protocol_reconnect (void *trans_ptr) -{ - transport_t *trans = NULL; - client_connection_t *conn = NULL; - struct timeval tv = {0, 0}; - int32_t ret = 0; - - trans = trans_ptr; - conn = trans->xl_private; - pthread_mutex_lock (&conn->lock); - { - if (conn->reconnect) - gf_timer_call_cancel (trans->xl->ctx, - conn->reconnect); - conn->reconnect = 0; - - if (conn->connected == 0) { - tv.tv_sec = 10; - - gf_log (trans->xl->name, GF_LOG_TRACE, - "attempting reconnect"); - ret = transport_connect (trans); - - conn->reconnect = - gf_timer_call_after (trans->xl->ctx, tv, - client_protocol_reconnect, - trans); - } else { - gf_log (trans->xl->name, GF_LOG_TRACE, - "breaking reconnect chain"); - } - } - pthread_mutex_unlock (&conn->lock); - - if (ret == -1 && errno != EINPROGRESS) { - default_notify (trans->xl, GF_EVENT_CHILD_DOWN, NULL); - } -} - -int -protocol_client_mark_fd_bad (xlator_t *this) -{ - client_conf_t *conf = NULL; - client_fd_ctx_t *tmp = NULL; - client_fd_ctx_t *fdctx = NULL; - - conf = this->private; - - pthread_mutex_lock (&conf->mutex); - { - list_for_each_entry_safe (fdctx, tmp, &conf->saved_fds, - sfd_pos) { - fdctx->remote_fd = -1; - } - } - pthread_mutex_unlock (&conf->mutex); - - return 0; -} - -/* - * client_protocol_cleanup - cleanup function - * @trans: transport object - * - */ - -int -protocol_client_cleanup (transport_t *trans) -{ - client_connection_t *conn = NULL; - struct saved_frames *saved_frames = NULL; - - conn = trans->xl_private; - - gf_log (trans->xl->name, GF_LOG_TRACE, - "cleaning up state in transport object %p", trans); - - pthread_mutex_lock (&conn->lock); - { - saved_frames = conn->saved_frames; - conn->saved_frames = gf_client_saved_frames_new (); - - /* bailout logic cleanup */ - if (conn->timer) { - gf_timer_call_cancel (trans->xl->ctx, conn->timer); - conn->timer = NULL; - } - - if (conn->reconnect == NULL) { - /* :O This part is empty.. any thing missing? */ - } - } - pthread_mutex_unlock (&conn->lock); - - gf_client_saved_frames_destroy (trans->xl, saved_frames, - gf_fops, gf_mops, gf_cbks); - - return 0; -} - - -/* cbk callbacks */ -int -client_releasedir_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, - size_t hdrlen, struct iobuf *iobuf) -{ - STACK_DESTROY (frame->root); - return 0; -} - - -int -client_release_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen, - struct iobuf *iobuf) -{ - STACK_DESTROY (frame->root); - return 0; -} - - -int -client_forget_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen, - struct iobuf *iobuf) -{ - gf_log ("", GF_LOG_CRITICAL, "fop not implemented"); - return 0; -} - - -int -client_log_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen, - struct iobuf *iobuf) -{ - gf_log ("", GF_LOG_CRITICAL, "fop not implemented"); - return 0; -} - - -static gf_op_t gf_fops[] = { - [GF_PROTO_FOP_STAT] = client_stat_cbk, - [GF_PROTO_FOP_READLINK] = client_readlink_cbk, - [GF_PROTO_FOP_MKNOD] = client_mknod_cbk, - [GF_PROTO_FOP_MKDIR] = client_mkdir_cbk, - [GF_PROTO_FOP_UNLINK] = client_unlink_cbk, - [GF_PROTO_FOP_RMDIR] = client_rmdir_cbk, - [GF_PROTO_FOP_SYMLINK] = client_symlink_cbk, - [GF_PROTO_FOP_RENAME] = client_rename_cbk, - [GF_PROTO_FOP_LINK] = client_link_cbk, - [GF_PROTO_FOP_TRUNCATE] = client_truncate_cbk, - [GF_PROTO_FOP_OPEN] = client_open_cbk, - [GF_PROTO_FOP_READ] = client_readv_cbk, - [GF_PROTO_FOP_WRITE] = client_write_cbk, - [GF_PROTO_FOP_STATFS] = client_statfs_cbk, - [GF_PROTO_FOP_FLUSH] = client_flush_cbk, - [GF_PROTO_FOP_FSYNC] = client_fsync_cbk, - [GF_PROTO_FOP_SETXATTR] = client_setxattr_cbk, - [GF_PROTO_FOP_GETXATTR] = client_getxattr_cbk, - [GF_PROTO_FOP_REMOVEXATTR] = client_removexattr_cbk, - [GF_PROTO_FOP_OPENDIR] = client_opendir_cbk, - [GF_PROTO_FOP_FSYNCDIR] = client_fsyncdir_cbk, - [GF_PROTO_FOP_ACCESS] = client_access_cbk, - [GF_PROTO_FOP_CREATE] = client_create_cbk, - [GF_PROTO_FOP_FTRUNCATE] = client_ftruncate_cbk, - [GF_PROTO_FOP_FSTAT] = client_fstat_cbk, - [GF_PROTO_FOP_LK] = client_lk_common_cbk, - [GF_PROTO_FOP_LOOKUP] = client_lookup_cbk, - [GF_PROTO_FOP_READDIR] = client_readdir_cbk, - [GF_PROTO_FOP_READDIRP] = client_readdirp_cbk, - [GF_PROTO_FOP_INODELK] = client_inodelk_cbk, - [GF_PROTO_FOP_FINODELK] = client_finodelk_cbk, - [GF_PROTO_FOP_ENTRYLK] = client_entrylk_cbk, - [GF_PROTO_FOP_FENTRYLK] = client_fentrylk_cbk, - [GF_PROTO_FOP_RCHECKSUM] = client_rchecksum_cbk, - [GF_PROTO_FOP_XATTROP] = client_xattrop_cbk, - [GF_PROTO_FOP_FXATTROP] = client_fxattrop_cbk, - [GF_PROTO_FOP_SETATTR] = client_setattr_cbk, - [GF_PROTO_FOP_FSETATTR] = client_fsetattr_cbk -}; - -static gf_op_t gf_mops[] = { - [GF_MOP_SETVOLUME] = client_setvolume_cbk, - [GF_MOP_GETVOLUME] = client_enosys_cbk, - [GF_MOP_SETSPEC] = client_setspec_cbk, - [GF_MOP_GETSPEC] = client_getspec_cbk, - [GF_MOP_PING] = client_ping_cbk, - [GF_MOP_LOG] = client_log_cbk -}; - -static gf_op_t gf_cbks[] = { - [GF_CBK_FORGET] = client_forget_cbk, - [GF_CBK_RELEASE] = client_release_cbk, - [GF_CBK_RELEASEDIR] = client_releasedir_cbk -}; - -/* - * client_protocol_interpret - protocol interpreter - * @trans: transport object - * @blk: data block - * - */ -int -protocol_client_interpret (xlator_t *this, transport_t *trans, - char *hdr_p, size_t hdrlen, struct iobuf *iobuf) -{ - int ret = -1; - call_frame_t *frame = NULL; - gf_hdr_common_t *hdr = NULL; - uint64_t callid = 0; - int type = -1; - int op = -1; - client_connection_t *conn = NULL; - - conn = trans->xl_private; - - hdr = (gf_hdr_common_t *)hdr_p; - - type = ntoh32 (hdr->type); - op = ntoh32 (hdr->op); - callid = ntoh64 (hdr->callid); - - frame = lookup_frame (trans, op, type, callid); - if (frame == NULL) { - gf_log (this->name, GF_LOG_WARNING, - "no frame for callid=%"PRId64" type=%d op=%d", - callid, type, op); - return 0; - } - - switch (type) { - case GF_OP_TYPE_FOP_REPLY: - if ((op > GF_PROTO_FOP_MAXVALUE) || - (op < 0)) { - gf_log (trans->xl->name, GF_LOG_WARNING, - "invalid fop '%d'", op); - } else { - ret = gf_fops[op] (frame, hdr, hdrlen, iobuf); - } - break; - case GF_OP_TYPE_MOP_REPLY: - if ((op > GF_MOP_MAXVALUE) || - (op < 0)) { - gf_log (trans->xl->name, GF_LOG_WARNING, - "invalid fop '%d'", op); - } else { - ret = gf_mops[op] (frame, hdr, hdrlen, iobuf); - } - break; - case GF_OP_TYPE_CBK_REPLY: - if ((op > GF_CBK_MAXVALUE) || - (op < 0)) { - gf_log (trans->xl->name, GF_LOG_WARNING, - "invalid cbk '%d'", op); - } else { - ret = gf_cbks[op] (frame, hdr, hdrlen, iobuf); - } - break; - default: - gf_log (trans->xl->name, GF_LOG_DEBUG, - "invalid packet type: %d", type); - break; - } - - return ret; -} - -int32_t -mem_acct_init (xlator_t *this) -{ - int ret = -1; - - if (!this) - return ret; - - ret = xlator_mem_acct_init (this, gf_client_mt_end + 1); - - if (ret != 0) { - gf_log (this->name, GF_LOG_ERROR, "Memory accounting init" - "failed"); - return ret; - } - - return ret; -} - - -/* - * init - initiliazation function. called during loading of client protocol - * @this: - * - */ - -int -init (xlator_t *this) -{ - transport_t *trans = NULL; - client_conf_t *conf = NULL; - client_connection_t *conn = NULL; - int32_t frame_timeout = 0; - int32_t ping_timeout = 0; - data_t *remote_subvolume = NULL; - int32_t ret = -1; - int i = 0; - - if (this->children) { - gf_log (this->name, GF_LOG_ERROR, - "FATAL: client protocol translator cannot have any " - "subvolumes"); - goto out; - } - - if (!this->parents) { - gf_log (this->name, GF_LOG_WARNING, - "Volume is dangling. "); - } - - remote_subvolume = dict_get (this->options, "remote-subvolume"); - if (remote_subvolume == NULL) { - gf_log (this->name, GF_LOG_ERROR, - "Option 'remote-subvolume' is not specified."); - goto out; - } - - ret = dict_get_int32 (this->options, "frame-timeout", - &frame_timeout); - if (ret >= 0) { - gf_log (this->name, GF_LOG_DEBUG, - "setting frame-timeout to %d", frame_timeout); - } else { - gf_log (this->name, GF_LOG_DEBUG, - "defaulting frame-timeout to 30mins"); - frame_timeout = 1800; - } - - ret = dict_get_int32 (this->options, "ping-timeout", - &ping_timeout); - if (ret >= 0) { - gf_log (this->name, GF_LOG_DEBUG, - "setting ping-timeout to %d", ping_timeout); - } else { - gf_log (this->name, GF_LOG_DEBUG, - "defaulting ping-timeout to 42"); - ping_timeout = GF_UNIVERSAL_ANSWER; - } - - conf = GF_CALLOC (1, sizeof (client_conf_t), - gf_client_mt_client_conf_t); - - protocol_common_init (); - - pthread_mutex_init (&conf->mutex, NULL); - INIT_LIST_HEAD (&conf->saved_fds); - - this->private = conf; - - for (i = 0; i < CHANNEL_MAX; i++) { - if (CHANNEL_LOWLAT == i) { - dict_set (this->options, "transport.socket.lowlat", - data_from_dynstr (gf_strdup ("true"))); - } - trans = transport_load (this->options, this); - if (trans == NULL) { - gf_log (this->name, GF_LOG_DEBUG, - "Failed to load transport"); - ret = -1; - goto out; - } - - conn = GF_CALLOC (1, sizeof (*conn), - gf_client_mt_client_connection_t); - - conn->saved_frames = gf_client_saved_frames_new (); - - conn->callid = 1; - - conn->frame_timeout = frame_timeout; - conn->ping_timeout = ping_timeout; - - pthread_mutex_init (&conn->lock, NULL); - - trans->xl_private = conn; - conf->transport[i] = transport_ref (trans); - } - -#ifndef GF_DARWIN_HOST_OS - { - struct rlimit lim; - - lim.rlim_cur = 1048576; - lim.rlim_max = 1048576; - - ret = setrlimit (RLIMIT_NOFILE, &lim); - if (ret == -1) { - gf_log (this->name, GF_LOG_WARNING, - "WARNING: Failed to set 'ulimit -n 1M': %s", - strerror(errno)); - lim.rlim_cur = 65536; - lim.rlim_max = 65536; - - ret = setrlimit (RLIMIT_NOFILE, &lim); - if (ret == -1) { - gf_log (this->name, GF_LOG_DEBUG, - "Failed to set max open fd to 64k: %s", - strerror(errno)); - } else { - gf_log (this->name, GF_LOG_DEBUG, - "max open fd set to 64k"); - } - - } - } -#endif - ret = 0; -out: - return ret; -} - -/* - * fini - finish function called during unloading of client protocol - * @this: - * - */ -void -fini (xlator_t *this) -{ - /* TODO: Check if its enough.. how to call transport's fini () */ - client_conf_t *conf = NULL; - - conf = this->private; - this->private = NULL; - - if (conf) { - GF_FREE (conf); - } - return; -} - - -int -protocol_client_handshake (xlator_t *this, transport_t *trans) -{ - gf_hdr_common_t *hdr = NULL; - gf_mop_setvolume_req_t *req = NULL; - dict_t *options = NULL; - int32_t ret = -1; - int hdrlen = 0; - int dict_len = 0; - call_frame_t *fr = NULL; - char *process_uuid_xl; - - options = this->options; - ret = dict_set_str (options, "protocol-version", GF_PROTOCOL_VERSION); - if (ret < 0) { - gf_log (this->name, GF_LOG_DEBUG, - "failed to set protocol version(%s) in handshake msg", - GF_PROTOCOL_VERSION); - } - - 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); - if (ret < 0) { - gf_log (this->name, GF_LOG_DEBUG, - "failed to set process-uuid(%s) in handshake msg", - process_uuid_xl); - } - - if (this->ctx->cmd_args.volfile_server) { - if (this->ctx->cmd_args.volfile_id) - ret = dict_set_str (options, "volfile-key", - this->ctx->cmd_args.volfile_id); - ret = dict_set_uint32 (options, "volfile-checksum", - this->graph->volfile_checksum); - } - - dict_len = dict_serialized_length (options); - if (dict_len < 0) { - gf_log (this->name, GF_LOG_DEBUG, - "failed to get serialized length of dict(%p)", - options); - ret = dict_len; - goto fail; - } - - hdrlen = gf_hdr_len (req, dict_len); - hdr = gf_hdr_new (req, dict_len); - GF_VALIDATE_OR_GOTO (this->name, hdr, fail); - - req = gf_param (hdr); - - ret = dict_serialize (options, req->buf); - if (ret < 0) { - gf_log (this->name, GF_LOG_DEBUG, - "failed to serialize dictionary(%p)", - options); - goto fail; - } - - req->dict_len = hton32 (dict_len); - fr = create_frame (this, this->ctx->pool); - GF_VALIDATE_OR_GOTO (this->name, fr, fail); - - fr->local = trans; - ret = protocol_client_xfer (fr, this, trans, - GF_OP_TYPE_MOP_REQUEST, GF_MOP_SETVOLUME, - hdr, hdrlen, NULL, 0, NULL); - return ret; -fail: - if (hdr) - GF_FREE (hdr); - return ret; -} - - -int -protocol_client_pollout (xlator_t *this, transport_t *trans) -{ - client_conf_t *conf = NULL; - - conf = trans->xl->private; - - pthread_mutex_lock (&conf->mutex); - { - gettimeofday (&conf->last_sent, NULL); - } - pthread_mutex_unlock (&conf->mutex); - - return 0; -} - - -int -protocol_client_pollin (xlator_t *this, transport_t *trans) -{ - client_conf_t *conf = NULL; - int ret = -1; - struct iobuf *iobuf = NULL; - char *hdr = NULL; - size_t hdrlen = 0; - - conf = trans->xl->private; - - pthread_mutex_lock (&conf->mutex); - { - gettimeofday (&conf->last_received, NULL); - } - pthread_mutex_unlock (&conf->mutex); - - ret = transport_receive (trans, &hdr, &hdrlen, &iobuf); - - if (ret == 0) - { - ret = protocol_client_interpret (this, trans, hdr, hdrlen, - iobuf); - } - - /* TODO: use mem-pool */ - GF_FREE (hdr); - - return ret; -} - -int -client_priv_dump (xlator_t *this) -{ - client_conf_t *conf = NULL; - int ret = -1; - client_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->mutex); - if (ret) { - gf_log("", GF_LOG_WARNING, "Unable to lock client %s" - " errno: %d", this->name, errno); - return -1; - } - - gf_proc_dump_build_key(key_prefix, "xlator.protocol.client", - "%s.priv", this->name); - - gf_proc_dump_add_section(key_prefix); - - list_for_each_entry(tmp, &conf->saved_fds, sfd_pos) { - gf_proc_dump_build_key(key, key_prefix, - "fd.%d.remote_fd", ++i); - gf_proc_dump_write(key, "%d", tmp->remote_fd); - } - - gf_proc_dump_build_key(key, key_prefix, "connecting"); - gf_proc_dump_write(key, "%d", conf->connecting); - gf_proc_dump_build_key(key, key_prefix, "last_sent"); - gf_proc_dump_write(key, "%s", ctime(&conf->last_sent.tv_sec)); - gf_proc_dump_build_key(key, key_prefix, "last_received"); - gf_proc_dump_write(key, "%s", ctime(&conf->last_received.tv_sec)); - - pthread_mutex_unlock(&conf->mutex); - - return 0; - -} - -int32_t -client_inodectx_dump (xlator_t *this, inode_t *inode) -{ - ino_t par = 0; - int ret = -1; - char key[GF_DUMP_MAX_BUF_LEN]; - - if (!inode) - return -1; - - if (!this) - return -1; - - ret = inode_ctx_get (inode, this, &par); - - if (ret != 0) - return ret; - - gf_proc_dump_build_key(key, "xlator.protocol.client", - "%s.inode.%ld.par", - this->name,inode->ino); - gf_proc_dump_write(key, "%ld", par); - - return 0; -} - -/* - * client_protocol_notify - notify function for client protocol - * @this: - * @trans: transport object - * @event - * - */ - -int -notify (xlator_t *this, int32_t event, void *data, ...) -{ - int i = 0; - int ret = 0; - int child_down = 1; - int was_not_down = 0; - transport_t *trans = NULL; - client_connection_t *conn = NULL; - client_conf_t *conf = NULL; - xlator_list_t *parent = NULL; - - conf = this->private; - trans = data; - - switch (event) { - case GF_EVENT_POLLOUT: - { - ret = protocol_client_pollout (this, trans); - - break; - } - case GF_EVENT_POLLIN: - { - ret = protocol_client_pollin (this, trans); - - break; - } - /* no break for ret check to happen below */ - case GF_EVENT_POLLERR: - { - ret = -1; - protocol_client_cleanup (trans); - - if (conf->connecting == 0) { - /* Let the connection/re-connection happen in - * background, for now, don't hang here, - * tell the parents that i am all ok.. - */ - parent = trans->xl->parents; - while (parent) { - parent->xlator->notify (parent->xlator, - GF_EVENT_CHILD_CONNECTING, - trans->xl); - parent = parent->next; - } - conf->connecting = 1; - } - - was_not_down = 0; - for (i = 0; i < CHANNEL_MAX; i++) { - conn = conf->transport[i]->xl_private; - if (conn->connected == 1) - was_not_down = 1; - } - - conn = trans->xl_private; - if (conn->connected) { - conn->connected = 0; - if (conn->reconnect == 0) - client_protocol_reconnect (trans); - } - - child_down = 1; - for (i = 0; i < CHANNEL_MAX; i++) { - trans = conf->transport[i]; - conn = trans->xl_private; - if (conn->connected == 1) - child_down = 0; - } - - if (child_down && was_not_down) { - gf_log (this->name, GF_LOG_INFO, "disconnected"); - - protocol_client_mark_fd_bad (this); - - parent = this->parents; - while (parent) { - xlator_notify (parent->xlator, - GF_EVENT_CHILD_DOWN, this); - parent = parent->next; - } - } - } - break; - - case GF_EVENT_PARENT_UP: - { - client_conf_t *conf = NULL; - int i = 0; - transport_t *trans = NULL; - - conf = this->private; - for (i = 0; i < CHANNEL_MAX; i++) { - trans = conf->transport[i]; - if (!trans) { - gf_log (this->name, GF_LOG_DEBUG, - "transport init failed"); - return -1; - } - - conn = trans->xl_private; - - gf_log (this->name, GF_LOG_DEBUG, - "got GF_EVENT_PARENT_UP, attempting connect " - "on transport"); - - client_protocol_reconnect (trans); - } - } - break; - - case GF_EVENT_CHILD_UP: - { - char *handshake = NULL; - - ret = dict_get_str (this->options, "disable-handshake", - &handshake); - gf_log (this->name, GF_LOG_DEBUG, - "got GF_EVENT_CHILD_UP"); - if ((ret < 0) || - (strcasecmp (handshake, "on"))) { - ret = protocol_client_handshake (this, trans); - } else { - conn = trans->xl_private; - conn->connected = 1; - ret = default_notify (this, event, trans); - } - - if (ret) - transport_disconnect (trans); - - } - break; - - default: - gf_log (this->name, GF_LOG_DEBUG, - "got %d, calling default_notify ()", event); - - default_notify (this, event, data); - break; - } - - return ret; -} - - -struct xlator_fops fops = { - .stat = client_stat, - .readlink = client_readlink, - .mknod = client_mknod, - .mkdir = client_mkdir, - .unlink = client_unlink, - .rmdir = client_rmdir, - .symlink = client_symlink, - .rename = client_rename, - .link = client_link, - .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, -}; - -struct xlator_cbks cbks = { - .release = client_release, - .releasedir = client_releasedir -}; - - -struct xlator_dumpops dumpops = { - .priv = client_priv_dump, - .inodectx = client_inodectx_dump, -}; - -struct volume_options options[] = { - { .key = {"username"}, - .type = GF_OPTION_TYPE_ANY - }, - { .key = {"password"}, - .type = GF_OPTION_TYPE_ANY - }, - { .key = {"transport-type"}, - .value = {"tcp", "socket", "ib-verbs", "unix", "ib-sdp", - "tcp/client", "ib-verbs/client"}, - .type = GF_OPTION_TYPE_STR - }, - { .key = {"remote-host"}, - .type = GF_OPTION_TYPE_INTERNET_ADDRESS - }, - { .key = {"remote-subvolume"}, - .type = GF_OPTION_TYPE_ANY - }, - { .key = {"frame-timeout"}, - .type = GF_OPTION_TYPE_TIME, - .min = 0, - .max = 86400, - }, - { .key = {"ping-timeout"}, - .type = GF_OPTION_TYPE_TIME, - .min = 1, - .max = 1013, - }, - { .key = {NULL} }, -}; diff --git a/xlators/protocol/legacy/client/src/client-protocol.h b/xlators/protocol/legacy/client/src/client-protocol.h deleted file mode 100644 index cd856d50e..000000000 --- a/xlators/protocol/legacy/client/src/client-protocol.h +++ /dev/null @@ -1,178 +0,0 @@ -/* - Copyright (c) 2006-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 _CLIENT_PROTOCOL_H -#define _CLIENT_PROTOCOL_H - -#ifndef _CONFIG_H -#define _CONFIG_H -#include "config.h" -#endif - -#include <stdio.h> -#include <arpa/inet.h> -#include "inode.h" -#include "timer.h" -#include "byte-order.h" -#include "saved-frames.h" - -#define CLIENT_PORT_CEILING 1023 - -#define GF_CLIENT_INODE_SELF 0 -#define GF_CLIENT_INODE_PARENT 1 - -#define CLIENT_CONF(this) ((client_conf_t *)(this->private)) - -#define RECEIVE_TIMEOUT(_cprivate,_current) \ - ((_cprivate->last_received.tv_sec + \ - _cprivate->frame_timeout) < \ - _current.tv_sec) - -#define SEND_TIMEOUT(_cprivate,_current) \ - ((_cprivate->last_sent.tv_sec + \ - _cprivate->frame_timeout) < \ - _current.tv_sec) - -enum { - CHANNEL_BULK = 0, - CHANNEL_LOWLAT = 1, - CHANNEL_MAX -}; - -#define CLIENT_CHANNEL client_channel - -struct client_connection; -typedef struct client_connection client_connection_t; - -#include "stack.h" -#include "xlator.h" -#include "transport.h" -#include "protocol.h" - -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; -} client_fd_ctx_t; - -struct _client_conf { - transport_t *transport[CHANNEL_MAX]; - struct list_head saved_fds; - struct timeval last_sent; - struct timeval last_received; - pthread_mutex_t mutex; - int connecting; -}; -typedef struct _client_conf client_conf_t; - -/* This will be stored in transport_t->xl_private */ -struct client_connection { - pthread_mutex_t lock; - uint64_t callid; - struct saved_frames *saved_frames; - int32_t frame_timeout; - int32_t ping_started; - int32_t ping_timeout; - int32_t transport_activity; - gf_timer_t *reconnect; - char connected; - uint64_t max_block_size; - gf_timer_t *timer; - gf_timer_t *ping_timer; -}; - -typedef struct { - loc_t loc; - loc_t loc2; - fd_t *fd; - gf_op_t op; - client_fd_ctx_t *fdctx; - uint32_t flags; - uint32_t wbflags; -} client_local_t; - - -static inline void -gf_string_to_stat(char *string, struct iatt *stbuf) -{ - uint64_t dev = 0; - uint64_t ino = 0; - uint32_t mode = 0; - uint32_t nlink = 0; - uint32_t uid = 0; - uint32_t gid = 0; - uint64_t rdev = 0; - uint64_t size = 0; - uint32_t blksize = 0; - uint64_t blocks = 0; - uint32_t atime = 0; - uint32_t atime_nsec = 0; - uint32_t mtime = 0; - uint32_t mtime_nsec = 0; - uint32_t ctime = 0; - uint32_t ctime_nsec = 0; - - sscanf (string, GF_STAT_PRINT_FMT_STR, - &dev, - &ino, - &mode, - &nlink, - &uid, - &gid, - &rdev, - &size, - &blksize, - &blocks, - &atime, - &atime_nsec, - &mtime, - &mtime_nsec, - &ctime, - &ctime_nsec); - - stbuf->ia_gen = dev; - stbuf->ia_ino = ino; - stbuf->ia_prot = ia_prot_from_st_mode (mode); - stbuf->ia_type = ia_type_from_st_mode (mode); - stbuf->ia_nlink = nlink; - stbuf->ia_uid = uid; - stbuf->ia_gid = gid; - stbuf->ia_rdev = rdev; - stbuf->ia_size = size; - stbuf->ia_blksize = blksize; - stbuf->ia_blocks = blocks; - - stbuf->ia_atime = atime; - stbuf->ia_mtime = mtime; - stbuf->ia_ctime = ctime; - - stbuf->ia_atime_nsec = atime_nsec; - stbuf->ia_mtime_nsec = mtime_nsec; - stbuf->ia_ctime_nsec = ctime_nsec; -} - -#endif diff --git a/xlators/protocol/legacy/client/src/saved-frames.c b/xlators/protocol/legacy/client/src/saved-frames.c deleted file mode 100644 index b884a9796..000000000 --- a/xlators/protocol/legacy/client/src/saved-frames.c +++ /dev/null @@ -1,196 +0,0 @@ -/* - Copyright (c) 2008-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/>. -*/ - - -#include "saved-frames.h" -#include "common-utils.h" -#include "protocol.h" -#include "xlator.h" -#include "client-mem-types.h" - - - -struct saved_frames * -gf_client_saved_frames_new (void) -{ - struct saved_frames *saved_frames = NULL; - - saved_frames = GF_CALLOC (sizeof (*saved_frames), 1, - gf_client_mt_saved_frames); - if (!saved_frames) { - return NULL; - } - - gf_log ("", 1, "here"); - INIT_LIST_HEAD (&saved_frames->fops.list); - INIT_LIST_HEAD (&saved_frames->mops.list); - INIT_LIST_HEAD (&saved_frames->cbks.list); - - return saved_frames; -} - - -struct saved_frame * -get_head_frame_for_type (struct saved_frames *frames, int8_t type) -{ - struct saved_frame *head_frame = NULL; - - switch (type) { - case GF_OP_TYPE_FOP_REQUEST: - case GF_OP_TYPE_FOP_REPLY: - head_frame = &frames->fops; - break; - case GF_OP_TYPE_MOP_REQUEST: - case GF_OP_TYPE_MOP_REPLY: - head_frame = &frames->mops; - break; - case GF_OP_TYPE_CBK_REQUEST: - case GF_OP_TYPE_CBK_REPLY: - head_frame = &frames->cbks; - break; - } - - return head_frame; -} - - -int -saved_frames_put (struct saved_frames *frames, call_frame_t *frame, - int32_t op, int8_t type, int64_t callid) -{ - struct saved_frame *saved_frame = NULL; - struct saved_frame *head_frame = NULL; - - head_frame = get_head_frame_for_type (frames, type); - - saved_frame = GF_CALLOC (sizeof (*saved_frame), 1, - gf_client_mt_saved_frame); - if (!saved_frame) { - return -ENOMEM; - } - - INIT_LIST_HEAD (&saved_frame->list); - saved_frame->frame = frame; - saved_frame->op = op; - saved_frame->type = type; - saved_frame->callid = callid; - - gettimeofday (&saved_frame->saved_at, NULL); - - list_add_tail (&saved_frame->list, &head_frame->list); - frames->count++; - - return 0; -} - - -call_frame_t * -saved_frames_get (struct saved_frames *frames, int32_t op, - int8_t type, int64_t callid) -{ - struct saved_frame *saved_frame = NULL; - struct saved_frame *tmp = NULL; - struct saved_frame *head_frame = NULL; - call_frame_t *frame = NULL; - - head_frame = get_head_frame_for_type (frames, type); - - list_for_each_entry (tmp, &head_frame->list, list) { - if (tmp->callid == callid) { - list_del_init (&tmp->list); - frames->count--; - saved_frame = tmp; - break; - } - } - - if (saved_frame) - frame = saved_frame->frame; - - GF_FREE (saved_frame); - - return frame; -} - -struct saved_frame * -saved_frames_get_timedout (struct saved_frames *frames, int8_t type, - uint32_t timeout, struct timeval *current) -{ - struct saved_frame *bailout_frame = NULL, *tmp = NULL; - struct saved_frame *head_frame = NULL; - - head_frame = get_head_frame_for_type (frames, type); - - if (!list_empty(&head_frame->list)) { - tmp = list_entry (head_frame->list.next, typeof (*tmp), list); - if ((tmp->saved_at.tv_sec + timeout) < current->tv_sec) { - bailout_frame = tmp; - list_del_init (&bailout_frame->list); - frames->count--; - } - } - - return bailout_frame; -} - -void -saved_frames_unwind (xlator_t *this, struct saved_frames *saved_frames, - struct saved_frame *head, - gf_op_t gf_ops[], char *gf_op_list[]) -{ - struct saved_frame *trav = NULL; - struct saved_frame *tmp = NULL; - - gf_hdr_common_t hdr = {0, }; - call_frame_t *frame = NULL; - - hdr.rsp.op_ret = hton32 (-1); - hdr.rsp.op_errno = hton32 (ENOTCONN); - - list_for_each_entry_safe (trav, tmp, &head->list, list) { - gf_log (this->name, GF_LOG_ERROR, - "forced unwinding frame type(%d) op(%s)", - trav->type, gf_op_list[trav->op]); - - hdr.type = hton32 (trav->type); - hdr.op = hton32 (trav->op); - - frame = trav->frame; - - saved_frames->count--; - - gf_ops[trav->op] (frame, &hdr, sizeof (hdr), NULL); - - list_del_init (&trav->list); - GF_FREE (trav); - } -} - - -void -gf_client_saved_frames_destroy (xlator_t *this, struct saved_frames *frames, - gf_op_t gf_fops[], gf_op_t gf_mops[], - gf_op_t gf_cbks[]) -{ - saved_frames_unwind (this, frames, &frames->fops, gf_fops, gf_fop_list); - saved_frames_unwind (this, frames, &frames->mops, gf_mops, gf_mop_list); - saved_frames_unwind (this, frames, &frames->cbks, gf_cbks, gf_cbk_list); - - GF_FREE (frames); -} diff --git a/xlators/protocol/legacy/client/src/saved-frames.h b/xlators/protocol/legacy/client/src/saved-frames.h deleted file mode 100644 index 9f7fe0a7d..000000000 --- a/xlators/protocol/legacy/client/src/saved-frames.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - Copyright (c) 2008-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 _SAVED_FRAMES_H -#define _SAVED_FRAMES_H - -#ifndef _CONFIG_H -#define _CONFIG_H -#include "config.h" -#endif - -#include <stdint.h> -#include <sys/time.h> -#include "stack.h" -#include "list.h" -#include "protocol.h" - -/* UGLY: have common typedef b/w saved-frames.c and protocol-client.c */ -typedef int32_t (*gf_op_t) (call_frame_t *frame, - gf_hdr_common_t *hdr, size_t hdrlen, - struct iobuf *iobuf); - - -struct saved_frame { - union { - struct list_head list; - struct { - struct saved_frame *frame_next; - struct saved_frame *frame_prev; - }; - }; - - struct timeval saved_at; - call_frame_t *frame; - int32_t op; - int8_t type; - uint64_t callid; -}; - - -struct saved_frames { - int64_t count; - struct saved_frame fops; - struct saved_frame mops; - struct saved_frame cbks; -}; - - -struct saved_frames *gf_client_saved_frames_new (); -int saved_frames_put (struct saved_frames *frames, call_frame_t *frame, - int32_t op, int8_t type, int64_t callid); -call_frame_t *saved_frames_get (struct saved_frames *frames, int32_t op, - int8_t type, int64_t callid); - -struct saved_frame * -saved_frames_get_timedout (struct saved_frames *frames, int8_t type, - uint32_t timeout, struct timeval *current); - -void gf_client_saved_frames_destroy (xlator_t *this, struct saved_frames *frames, - gf_op_t gf_fops[], gf_op_t gf_mops[], - gf_op_t gf_cbks[]); - -#endif /* _SAVED_FRAMES_H */ diff --git a/xlators/protocol/legacy/lib/Makefile.am b/xlators/protocol/legacy/lib/Makefile.am deleted file mode 100644 index d471a3f92..000000000 --- a/xlators/protocol/legacy/lib/Makefile.am +++ /dev/null @@ -1,3 +0,0 @@ -SUBDIRS = src - -CLEANFILES = diff --git a/xlators/protocol/legacy/lib/src/Makefile.am b/xlators/protocol/legacy/lib/src/Makefile.am deleted file mode 100644 index 1f0e93e30..000000000 --- a/xlators/protocol/legacy/lib/src/Makefile.am +++ /dev/null @@ -1,14 +0,0 @@ -lib_LTLIBRARIES = libgfproto.la - -libgfproto_la_CFLAGS = -fPIC -Wall -g -shared -nostartfiles $(GF_CFLAGS) $(GF_DARWIN_LIBGLUSTERFS_CFLAGS) - -libgfproto_la_CPPFLAGS = -D_FILE_OFFSET_BITS=64 -D__USE_FILE_OFFSET64 -D_GNU_SOURCE \ - -D$(GF_HOST_OS) -DLIBDIR=\"$(libdir)/glusterfs/$(PACKAGE_VERSION)/auth\" \ - -DTRANSPORTDIR=\"$(libdir)/glusterfs/$(PACKAGE_VERSION)/transport\" \ - -I$(CONTRIBDIR)/rbtree -I$(top_srcdir)/libglusterfs/src/ - -libgfproto_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la - -libgfproto_la_SOURCES = transport.c protocol.c - -noinst_HEADERS = transport.h protocol.h diff --git a/xlators/protocol/legacy/lib/src/protocol.c b/xlators/protocol/legacy/lib/src/protocol.c deleted file mode 100644 index 63950f43d..000000000 --- a/xlators/protocol/legacy/lib/src/protocol.c +++ /dev/null @@ -1,108 +0,0 @@ - -#include "globals.h" -#include "compat.h" -#include "protocol.h" - -char *gf_mop_list[GF_MOP_MAXVALUE]; -char *gf_cbk_list[GF_CBK_MAXVALUE]; - -static int -gf_dirent_nb_size (gf_dirent_t *entries) -{ - return (sizeof (struct gf_dirent_nb) + strlen (entries->d_name) + 1); -} - -int -gf_dirent_serialize (gf_dirent_t *entries, char *buf, size_t buf_size) -{ - struct gf_dirent_nb *entry_nb = NULL; - gf_dirent_t *entry = NULL; - int size = 0; - int entry_size = 0; - - - list_for_each_entry (entry, &entries->list, list) { - entry_size = gf_dirent_nb_size (entry); - - if (buf && (size + entry_size <= buf_size)) { - entry_nb = (void *) (buf + size); - - entry_nb->d_ino = hton64 (entry->d_ino); - entry_nb->d_off = hton64 (entry->d_off); - entry_nb->d_len = hton32 (entry->d_len); - entry_nb->d_type = hton32 (entry->d_type); - - gf_stat_from_iatt (&entry_nb->d_stat, &entry->d_stat); - - strcpy (entry_nb->d_name, entry->d_name); - } - size += entry_size; - } - - return size; -} - - -int -gf_dirent_unserialize (gf_dirent_t *entries, const char *buf, size_t buf_size) -{ - struct gf_dirent_nb *entry_nb = NULL; - int remaining_size = 0; - int least_dirent_size = 0; - int count = 0; - gf_dirent_t *entry = NULL; - int entry_strlen = 0; - int entry_len = 0; - - - remaining_size = buf_size; - least_dirent_size = (sizeof (struct gf_dirent_nb) + 2); - - while (remaining_size >= least_dirent_size) { - entry_nb = (void *)(buf + (buf_size - remaining_size)); - - entry_strlen = strnlen (entry_nb->d_name, remaining_size); - if (entry_strlen == remaining_size) { - break; - } - - entry_len = sizeof (gf_dirent_t) + entry_strlen + 1; - entry = GF_CALLOC (1, entry_len, gf_common_mt_gf_dirent_t); - if (!entry) { - break; - } - - entry->d_ino = ntoh64 (entry_nb->d_ino); - entry->d_off = ntoh64 (entry_nb->d_off); - entry->d_len = ntoh32 (entry_nb->d_len); - entry->d_type = ntoh32 (entry_nb->d_type); - - gf_stat_to_iatt (&entry_nb->d_stat, &entry->d_stat); - - strcpy (entry->d_name, entry_nb->d_name); - - list_add_tail (&entry->list, &entries->list); - - remaining_size -= (sizeof (*entry_nb) + entry_strlen + 1); - count++; - } - - return count; -} - -int -protocol_common_init (void) -{ - gf_mop_list[GF_MOP_SETVOLUME] = "SETVOLUME"; - gf_mop_list[GF_MOP_GETVOLUME] = "GETVOLUME"; - gf_mop_list[GF_MOP_SETSPEC] = "SETSPEC"; - gf_mop_list[GF_MOP_GETSPEC] = "GETSPEC"; - gf_mop_list[GF_MOP_LOG] = "LOG"; - gf_mop_list[GF_MOP_PING] = "PING"; - - gf_cbk_list[GF_CBK_FORGET] = "FORGET"; - gf_cbk_list[GF_CBK_RELEASE] = "RELEASE"; - gf_cbk_list[GF_CBK_RELEASEDIR] = "RELEASEDIR"; - - return 0; -} diff --git a/xlators/protocol/legacy/lib/src/protocol.h b/xlators/protocol/legacy/lib/src/protocol.h deleted file mode 100644 index 6c568ed0d..000000000 --- a/xlators/protocol/legacy/lib/src/protocol.h +++ /dev/null @@ -1,1118 +0,0 @@ -/* - Copyright (c) 2006-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 _PROTOCOL_H -#define _PROTOCOL_H - -#ifndef _CONFIG_H -#define _CONFIG_H -#include "config.h" -#endif - -#include <inttypes.h> -#include <sys/time.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/statvfs.h> -#include <unistd.h> -#include <fcntl.h> - -#include "byte-order.h" -#include "iatt.h" - -/* Any changes in the protocol structure or adding new '[f,m]ops' needs to - * bump the protocol version by "0.1" - */ - -#define GF_PROTOCOL_VERSION "3.0" - -extern char *gf_mop_list[]; -extern char *gf_cbk_list[]; - -/* NOTE: add members ONLY at the end (just before _MAXVALUE) */ -typedef enum { - GF_PROTO_FOP_STAT, /* 0 */ - GF_PROTO_FOP_READLINK, /* 1 */ - GF_PROTO_FOP_MKNOD, /* 2 */ - GF_PROTO_FOP_MKDIR, - GF_PROTO_FOP_UNLINK, - GF_PROTO_FOP_RMDIR, /* 5 */ - GF_PROTO_FOP_SYMLINK, - GF_PROTO_FOP_RENAME, - GF_PROTO_FOP_LINK, - GF_PROTO_FOP_TRUNCATE, - GF_PROTO_FOP_OPEN, /* 10 */ - GF_PROTO_FOP_READ, - GF_PROTO_FOP_WRITE, - GF_PROTO_FOP_STATFS, /* 15 */ - GF_PROTO_FOP_FLUSH, - GF_PROTO_FOP_FSYNC, - GF_PROTO_FOP_SETXATTR, - GF_PROTO_FOP_GETXATTR, - GF_PROTO_FOP_REMOVEXATTR,/* 20 */ - GF_PROTO_FOP_OPENDIR, - GF_PROTO_FOP_GETDENTS, - GF_PROTO_FOP_FSYNCDIR, - GF_PROTO_FOP_ACCESS, - GF_PROTO_FOP_CREATE, /* 25 */ - GF_PROTO_FOP_FTRUNCATE, - GF_PROTO_FOP_FSTAT, - GF_PROTO_FOP_LK, - GF_PROTO_FOP_LOOKUP, - GF_PROTO_FOP_SETDENTS, - GF_PROTO_FOP_READDIR, - GF_PROTO_FOP_INODELK, /* 35 */ - GF_PROTO_FOP_FINODELK, - GF_PROTO_FOP_ENTRYLK, - GF_PROTO_FOP_FENTRYLK, - GF_PROTO_FOP_CHECKSUM, - GF_PROTO_FOP_XATTROP, /* 40 */ - GF_PROTO_FOP_FXATTROP, - GF_PROTO_FOP_LOCK_NOTIFY, - GF_PROTO_FOP_LOCK_FNOTIFY, - GF_PROTO_FOP_FGETXATTR, - GF_PROTO_FOP_FSETXATTR, /* 45 */ - GF_PROTO_FOP_RCHECKSUM, - GF_PROTO_FOP_SETATTR, - GF_PROTO_FOP_FSETATTR, - GF_PROTO_FOP_READDIRP, - GF_PROTO_FOP_MAXVALUE, -} glusterfs_proto_fop_t; - -/* NOTE: add members ONLY at the end (just before _MAXVALUE) */ -typedef enum { - GF_MOP_SETVOLUME, /* 0 */ - GF_MOP_GETVOLUME, /* 1 */ - GF_MOP_STATS, - GF_MOP_SETSPEC, - GF_MOP_GETSPEC, - GF_MOP_PING, /* 5 */ - GF_MOP_LOG, - GF_MOP_NOTIFY, - GF_MOP_MAXVALUE, /* 8 */ -} glusterfs_mop_t; - -typedef enum { - GF_CBK_FORGET, /* 0 */ - GF_CBK_RELEASE, /* 1 */ - GF_CBK_RELEASEDIR, /* 2 */ - GF_CBK_MAXVALUE /* 3 */ -} glusterfs_cbk_t; - -typedef enum { - GF_OP_TYPE_FOP_REQUEST = 1, - GF_OP_TYPE_MOP_REQUEST, - GF_OP_TYPE_CBK_REQUEST, - GF_OP_TYPE_FOP_REPLY, - GF_OP_TYPE_MOP_REPLY, - GF_OP_TYPE_CBK_REPLY -} glusterfs_op_type_t; - - -struct gf_stat { - uint64_t ino; - uint64_t size; - uint64_t blocks; - uint64_t dev; - uint32_t rdev; - uint32_t mode; - uint32_t nlink; - uint32_t uid; - uint32_t gid; - uint32_t blksize; - uint32_t atime; - uint32_t atime_nsec; - uint32_t mtime ; - uint32_t mtime_nsec; - uint32_t ctime; - uint32_t ctime_nsec; -} __attribute__((packed)); - - -static inline void -gf_stat_to_stat (struct gf_stat *gf_stat, struct stat *stat) -{ - stat->st_dev = ntoh64 (gf_stat->dev); - stat->st_ino = ntoh64 (gf_stat->ino); - stat->st_mode = ntoh32 (gf_stat->mode); - stat->st_nlink = ntoh32 (gf_stat->nlink); - stat->st_uid = ntoh32 (gf_stat->uid); - stat->st_gid = ntoh32 (gf_stat->gid); - stat->st_rdev = ntoh32 (gf_stat->rdev); - stat->st_size = ntoh64 (gf_stat->size); - stat->st_blksize = ntoh32 (gf_stat->blksize); - stat->st_blocks = ntoh64 (gf_stat->blocks); - stat->st_atime = ntoh32 (gf_stat->atime); - stat->st_mtime = ntoh32 (gf_stat->mtime); - stat->st_ctime = ntoh32 (gf_stat->ctime); - ST_ATIM_NSEC_SET(stat, ntoh32 (gf_stat->atime_nsec)); - ST_MTIM_NSEC_SET(stat, ntoh32 (gf_stat->mtime_nsec)); - ST_CTIM_NSEC_SET(stat, ntoh32 (gf_stat->ctime_nsec)); -} - - -static inline void -gf_stat_from_stat (struct gf_stat *gf_stat, struct stat *stat) -{ - gf_stat->dev = hton64 (stat->st_dev); - gf_stat->ino = hton64 (stat->st_ino); - gf_stat->mode = hton32 (stat->st_mode); - gf_stat->nlink = hton32 (stat->st_nlink); - gf_stat->uid = hton32 (stat->st_uid); - gf_stat->gid = hton32 (stat->st_gid); - gf_stat->rdev = hton32 (stat->st_rdev); - gf_stat->size = hton64 (stat->st_size); - gf_stat->blksize = hton32 (stat->st_blksize); - gf_stat->blocks = hton64 (stat->st_blocks); - gf_stat->atime = hton32 (stat->st_atime); - gf_stat->mtime = hton32 (stat->st_mtime); - gf_stat->ctime = hton32 (stat->st_ctime); - gf_stat->atime_nsec = hton32 (ST_ATIM_NSEC(stat)); - gf_stat->mtime_nsec = hton32 (ST_MTIM_NSEC(stat)); - gf_stat->ctime_nsec = hton32 (ST_CTIM_NSEC(stat)); -} - - -static inline void -gf_stat_to_iatt (struct gf_stat *gf_stat, struct iatt *iatt) -{ - iatt->ia_ino = ntoh64 (gf_stat->ino); - iatt->ia_dev = ntoh64 (gf_stat->dev); - iatt->ia_type = ia_type_from_st_mode (ntoh32 (gf_stat->mode)); - iatt->ia_prot = ia_prot_from_st_mode (ntoh32 (gf_stat->mode)); - iatt->ia_nlink = ntoh32 (gf_stat->nlink); - iatt->ia_uid = ntoh32 (gf_stat->uid); - iatt->ia_gid = ntoh32 (gf_stat->gid); - iatt->ia_rdev = ntoh64 (gf_stat->rdev); - iatt->ia_size = ntoh64 (gf_stat->size); - iatt->ia_blksize = ntoh32 (gf_stat->blksize); - iatt->ia_blocks = ntoh64 (gf_stat->blocks); - iatt->ia_atime = ntoh32 (gf_stat->atime); - iatt->ia_atime_nsec = ntoh32 (gf_stat->atime_nsec); - iatt->ia_mtime = ntoh32 (gf_stat->mtime); - iatt->ia_mtime_nsec = ntoh32 (gf_stat->mtime_nsec); - iatt->ia_ctime = ntoh32 (gf_stat->ctime); - iatt->ia_ctime_nsec = ntoh32 (gf_stat->ctime_nsec); - - iatt->ia_gen = ntoh64 (gf_stat->dev); -} - - -static inline void -gf_stat_from_iatt (struct gf_stat *gf_stat, struct iatt *iatt) -{ - gf_stat->ino = hton64 (iatt->ia_ino); - gf_stat->dev = hton64 (iatt->ia_dev); - gf_stat->mode = hton32 (st_mode_from_ia (iatt->ia_prot, - iatt->ia_type)); - gf_stat->nlink = hton32 (iatt->ia_nlink); - gf_stat->uid = hton32 (iatt->ia_uid); - gf_stat->gid = hton32 (iatt->ia_gid); - gf_stat->rdev = hton32 (iatt->ia_rdev); - gf_stat->size = hton64 (iatt->ia_size); - gf_stat->blksize = hton32 (iatt->ia_blksize); - gf_stat->blocks = hton64 (iatt->ia_blocks); - gf_stat->atime = hton32 (iatt->ia_atime); - gf_stat->atime_nsec = hton32 (iatt->ia_atime_nsec); - gf_stat->mtime = hton32 (iatt->ia_mtime); - gf_stat->mtime_nsec = hton32 (iatt->ia_mtime_nsec); - gf_stat->ctime = hton32 (iatt->ia_ctime); - gf_stat->ctime_nsec = hton32 (iatt->ia_ctime_nsec); - - gf_stat->dev = hton64 (iatt->ia_gen); - -} - - -struct gf_statfs { - uint64_t bsize; - uint64_t frsize; - uint64_t blocks; - uint64_t bfree; - uint64_t bavail; - uint64_t files; - uint64_t ffree; - uint64_t favail; - uint64_t fsid; - uint64_t flag; - uint64_t namemax; -} __attribute__((packed)); - - -static inline void -gf_statfs_to_statfs (struct gf_statfs *gf_stat, struct statvfs *stat) -{ - stat->f_bsize = ntoh64 (gf_stat->bsize); - stat->f_frsize = ntoh64 (gf_stat->frsize); - stat->f_blocks = ntoh64 (gf_stat->blocks); - stat->f_bfree = ntoh64 (gf_stat->bfree); - stat->f_bavail = ntoh64 (gf_stat->bavail); - stat->f_files = ntoh64 (gf_stat->files); - stat->f_ffree = ntoh64 (gf_stat->ffree); - stat->f_favail = ntoh64 (gf_stat->favail); - stat->f_fsid = ntoh64 (gf_stat->fsid); - stat->f_flag = ntoh64 (gf_stat->flag); - stat->f_namemax = ntoh64 (gf_stat->namemax); -} - - -static inline void -gf_statfs_from_statfs (struct gf_statfs *gf_stat, struct statvfs *stat) -{ - gf_stat->bsize = hton64 (stat->f_bsize); - gf_stat->frsize = hton64 (stat->f_frsize); - gf_stat->blocks = hton64 (stat->f_blocks); - gf_stat->bfree = hton64 (stat->f_bfree); - gf_stat->bavail = hton64 (stat->f_bavail); - gf_stat->files = hton64 (stat->f_files); - gf_stat->ffree = hton64 (stat->f_ffree); - gf_stat->favail = hton64 (stat->f_favail); - gf_stat->fsid = hton64 (stat->f_fsid); - gf_stat->flag = hton64 (stat->f_flag); - gf_stat->namemax = hton64 (stat->f_namemax); -} - - -struct gf_flock { - uint16_t type; - uint16_t whence; - uint64_t start; - uint64_t len; - uint32_t pid; -} __attribute__((packed)); - - -static inline void -gf_flock_to_flock (struct gf_flock *gf_flock, struct gf_flock *flock) -{ - flock->l_type = ntoh16 (gf_flock->type); - flock->l_whence = ntoh16 (gf_flock->whence); - flock->l_start = ntoh64 (gf_flock->start); - flock->l_len = ntoh64 (gf_flock->len); - flock->l_pid = ntoh32 (gf_flock->pid); -} - - -static inline void -gf_flock_from_flock (struct gf_flock *gf_flock, struct gf_flock *flock) -{ - gf_flock->type = hton16 (flock->l_type); - gf_flock->whence = hton16 (flock->l_whence); - gf_flock->start = hton64 (flock->l_start); - gf_flock->len = hton64 (flock->l_len); - gf_flock->pid = hton32 (flock->l_pid); -} - - -struct gf_timespec { - uint32_t tv_sec; - uint32_t tv_nsec; -} __attribute__((packed)); - - -static inline void -gf_timespec_to_timespec (struct gf_timespec *gf_ts, struct timespec *ts) -{ - - ts[0].tv_sec = ntoh32 (gf_ts[0].tv_sec); - ts[0].tv_nsec = ntoh32 (gf_ts[0].tv_nsec); - ts[1].tv_sec = ntoh32 (gf_ts[1].tv_sec); - ts[1].tv_nsec = ntoh32 (gf_ts[1].tv_nsec); -} - - -static inline void -gf_timespec_from_timespec (struct gf_timespec *gf_ts, struct timespec *ts) -{ - gf_ts[0].tv_sec = hton32 (ts[0].tv_sec); - gf_ts[0].tv_nsec = hton32 (ts[0].tv_nsec); - gf_ts[1].tv_sec = hton32 (ts[1].tv_sec); - gf_ts[1].tv_nsec = hton32 (ts[1].tv_nsec); -} - - -#define GF_O_ACCMODE 003 -#define GF_O_RDONLY 00 -#define GF_O_WRONLY 01 -#define GF_O_RDWR 02 -#define GF_O_CREAT 0100 -#define GF_O_EXCL 0200 -#define GF_O_NOCTTY 0400 -#define GF_O_TRUNC 01000 -#define GF_O_APPEND 02000 -#define GF_O_NONBLOCK 04000 -#define GF_O_SYNC 010000 -#define GF_O_ASYNC 020000 - -#define GF_O_DIRECT 040000 -#define GF_O_DIRECTORY 0200000 -#define GF_O_NOFOLLOW 0400000 -#define GF_O_NOATIME 01000000 -#define GF_O_CLOEXEC 02000000 - -#define GF_O_LARGEFILE 0100000 - -#define XLATE_BIT(from, to, bit) do { \ - if (from & bit) \ - to = to | GF_##bit; \ - } while (0) - -#define UNXLATE_BIT(from, to, bit) do { \ - if (from & GF_##bit) \ - to = to | bit; \ - } while (0) - -#define XLATE_ACCESSMODE(from, to) do { \ - switch (from & O_ACCMODE) { \ - case O_RDONLY: to |= GF_O_RDONLY; \ - break; \ - case O_WRONLY: to |= GF_O_WRONLY; \ - break; \ - case O_RDWR: to |= GF_O_RDWR; \ - break; \ - } \ - } while (0) - -#define UNXLATE_ACCESSMODE(from, to) do { \ - switch (from & GF_O_ACCMODE) { \ - case GF_O_RDONLY: to |= O_RDONLY; \ - break; \ - case GF_O_WRONLY: to |= O_WRONLY; \ - break; \ - case GF_O_RDWR: to |= O_RDWR; \ - break; \ - } \ - } while (0) - -static inline uint32_t -gf_flags_from_flags (uint32_t flags) -{ - uint32_t gf_flags = 0; - - XLATE_ACCESSMODE (flags, gf_flags); - - XLATE_BIT (flags, gf_flags, O_CREAT); - XLATE_BIT (flags, gf_flags, O_EXCL); - XLATE_BIT (flags, gf_flags, O_NOCTTY); - XLATE_BIT (flags, gf_flags, O_TRUNC); - XLATE_BIT (flags, gf_flags, O_APPEND); - XLATE_BIT (flags, gf_flags, O_NONBLOCK); - XLATE_BIT (flags, gf_flags, O_SYNC); - XLATE_BIT (flags, gf_flags, O_ASYNC); - - XLATE_BIT (flags, gf_flags, O_DIRECT); - XLATE_BIT (flags, gf_flags, O_DIRECTORY); - XLATE_BIT (flags, gf_flags, O_NOFOLLOW); -#ifdef O_NOATIME - XLATE_BIT (flags, gf_flags, O_NOATIME); -#endif -#ifdef O_CLOEXEC - XLATE_BIT (flags, gf_flags, O_CLOEXEC); -#endif - XLATE_BIT (flags, gf_flags, O_LARGEFILE); - - return gf_flags; -} - -static inline uint32_t -gf_flags_to_flags (uint32_t gf_flags) -{ - uint32_t flags = 0; - - UNXLATE_ACCESSMODE (gf_flags, flags); - - UNXLATE_BIT (gf_flags, flags, O_CREAT); - UNXLATE_BIT (gf_flags, flags, O_EXCL); - UNXLATE_BIT (gf_flags, flags, O_NOCTTY); - UNXLATE_BIT (gf_flags, flags, O_TRUNC); - UNXLATE_BIT (gf_flags, flags, O_APPEND); - UNXLATE_BIT (gf_flags, flags, O_NONBLOCK); - UNXLATE_BIT (gf_flags, flags, O_SYNC); - UNXLATE_BIT (gf_flags, flags, O_ASYNC); - - UNXLATE_BIT (gf_flags, flags, O_DIRECT); - UNXLATE_BIT (gf_flags, flags, O_DIRECTORY); - UNXLATE_BIT (gf_flags, flags, O_NOFOLLOW); -#ifdef O_NOATIME - UNXLATE_BIT (gf_flags, flags, O_NOATIME); -#endif -#ifdef O_CLOEXEC - UNXLATE_BIT (gf_flags, flags, O_CLOEXEC); -#endif - UNXLATE_BIT (gf_flags, flags, O_LARGEFILE); - - return flags; -} - - -typedef struct { - uint64_t ino; - uint64_t gen; - char path[0]; /* NULL terminated */ -} __attribute__((packed)) gf_fop_stat_req_t;; -typedef struct { - struct gf_stat stat; -} __attribute__((packed)) gf_fop_stat_rsp_t; - - -typedef struct { - uint64_t ino; - uint64_t gen; - uint32_t size; - char path[0]; /* NULL terminated */ -} __attribute__((packed)) gf_fop_readlink_req_t; -typedef struct { - struct gf_stat buf; - char path[0]; /* NULL terminated */ -} __attribute__((packed)) gf_fop_readlink_rsp_t; - - -typedef struct { - uint64_t par; - uint64_t gen; - uint64_t dev; - uint32_t mode; - char path[0]; /* NULL terminated */ - char bname[0]; /* NULL terminated */ -} __attribute__((packed)) gf_fop_mknod_req_t; -typedef struct { - struct gf_stat stat; - struct gf_stat preparent; - struct gf_stat postparent; -} __attribute__((packed)) gf_fop_mknod_rsp_t; - - -typedef struct { - uint64_t par; - uint64_t gen; - uint32_t mode; - char path[0]; /* NULL terminated */ - char bname[0]; /* NULL terminated */ -} __attribute__((packed)) gf_fop_mkdir_req_t; -typedef struct { - struct gf_stat stat; - struct gf_stat preparent; - struct gf_stat postparent; -} __attribute__((packed)) gf_fop_mkdir_rsp_t; - - -typedef struct { - uint64_t par; - uint64_t gen; - char path[0]; /* NULL terminated */ - char bname[0]; /* NULL terminated */ -} __attribute__((packed)) gf_fop_unlink_req_t; -typedef struct { - struct gf_stat preparent; - struct gf_stat postparent; -} __attribute__((packed)) gf_fop_unlink_rsp_t; - - -typedef struct { - uint64_t par; - uint64_t gen; - char path[0]; - char bname[0]; /* NULL terminated */ -} __attribute__((packed)) gf_fop_rmdir_req_t; -typedef struct { - struct gf_stat preparent; - struct gf_stat postparent; -} __attribute__((packed)) gf_fop_rmdir_rsp_t; - - -typedef struct { - uint64_t par; - uint64_t gen; - char path[0]; - char bname[0]; - char linkname[0]; -} __attribute__((packed)) gf_fop_symlink_req_t; -typedef struct { - struct gf_stat stat; - struct gf_stat preparent; - struct gf_stat postparent; -}__attribute__((packed)) gf_fop_symlink_rsp_t; - - -typedef struct { - uint64_t oldpar; - uint64_t oldgen; - uint64_t newpar; - uint64_t newgen; - char oldpath[0]; - char oldbname[0]; /* NULL terminated */ - char newpath[0]; - char newbname[0]; /* NULL terminated */ -} __attribute__((packed)) gf_fop_rename_req_t; -typedef struct { - struct gf_stat stat; - struct gf_stat preoldparent; - struct gf_stat postoldparent; - struct gf_stat prenewparent; - struct gf_stat postnewparent; -} __attribute__((packed)) gf_fop_rename_rsp_t; - - -typedef struct { - uint64_t oldino; - uint64_t oldgen; - uint64_t newpar; - uint64_t newgen; - char oldpath[0]; - char newpath[0]; - char newbname[0]; -}__attribute__((packed)) gf_fop_link_req_t; -typedef struct { - struct gf_stat stat; - struct gf_stat preparent; - struct gf_stat postparent; -} __attribute__((packed)) gf_fop_link_rsp_t; - -typedef struct { - uint64_t ino; - uint64_t gen; - uint64_t offset; - char path[0]; -} __attribute__((packed)) gf_fop_truncate_req_t; -typedef struct { - struct gf_stat prestat; - struct gf_stat poststat; -} __attribute__((packed)) gf_fop_truncate_rsp_t; - - -typedef struct { - uint64_t ino; - uint64_t gen; - uint32_t flags; - uint32_t wbflags; - char path[0]; -} __attribute__((packed)) gf_fop_open_req_t; -typedef struct { - int64_t fd; -} __attribute__((packed)) gf_fop_open_rsp_t; - - -typedef struct { - uint64_t ino; - uint64_t gen; - int64_t fd; - uint64_t offset; - uint32_t size; -} __attribute__((packed)) gf_fop_read_req_t; -typedef struct { - struct gf_stat stat; - char buf[0]; -} __attribute__((packed)) gf_fop_read_rsp_t; - - -typedef struct { - uint64_t ino; - uint64_t gen; - int64_t fd; - uint64_t offset; - uint32_t size; -} __attribute__((packed)) gf_fop_write_req_t; -typedef struct { - struct gf_stat prestat; - struct gf_stat poststat; -} __attribute__((packed)) gf_fop_write_rsp_t; - - -typedef struct { - uint64_t ino; - uint64_t gen; - char path[0]; -} __attribute__((packed)) gf_fop_statfs_req_t; -typedef struct { - struct gf_statfs statfs; -} __attribute__((packed)) gf_fop_statfs_rsp_t; - - -typedef struct { - uint64_t ino; - uint64_t gen; - int64_t fd; -} __attribute__((packed)) gf_fop_flush_req_t; -typedef struct { } __attribute__((packed)) gf_fop_flush_rsp_t; - - -typedef struct fsync_req { - uint64_t ino; - uint64_t gen; - int64_t fd; - uint32_t data; -} __attribute__((packed)) gf_fop_fsync_req_t; -typedef struct { - struct gf_stat prestat; - struct gf_stat poststat; -} __attribute__((packed)) gf_fop_fsync_rsp_t; - - -typedef struct { - uint64_t ino; - uint64_t gen; - uint32_t flags; - uint32_t dict_len; - char dict[0]; - char path[0]; -} __attribute__((packed)) gf_fop_setxattr_req_t; -typedef struct { } __attribute__((packed)) gf_fop_setxattr_rsp_t; - - -typedef struct { - uint64_t ino; - uint64_t gen; - int64_t fd; - uint32_t flags; - uint32_t dict_len; - char dict[0]; -} __attribute__((packed)) gf_fop_fsetxattr_req_t; -typedef struct { } __attribute__((packed)) gf_fop_fsetxattr_rsp_t; - - -typedef struct { - uint64_t ino; - uint64_t gen; - uint32_t flags; - uint32_t dict_len; - char dict[0]; - char path[0]; -} __attribute__((packed)) gf_fop_xattrop_req_t; - -typedef struct { - uint32_t dict_len; - char dict[0]; -} __attribute__((packed)) gf_fop_xattrop_rsp_t; - - -typedef struct { - uint64_t ino; - uint64_t gen; - int64_t fd; - uint32_t flags; - uint32_t dict_len; - char dict[0]; -} __attribute__((packed)) gf_fop_fxattrop_req_t; - -typedef struct { - uint32_t dict_len; - char dict[0]; -} __attribute__((packed)) gf_fop_fxattrop_rsp_t; - - -typedef struct { - uint64_t ino; - uint64_t gen; - uint32_t namelen; - char path[0]; - char name[0]; -} __attribute__((packed)) gf_fop_getxattr_req_t; -typedef struct { - uint32_t dict_len; - char dict[0]; -} __attribute__((packed)) gf_fop_getxattr_rsp_t; - - -typedef struct { - uint64_t ino; - uint64_t gen; - int64_t fd; - uint32_t namelen; - char name[0]; -} __attribute__((packed)) gf_fop_fgetxattr_req_t; -typedef struct { - uint32_t dict_len; - char dict[0]; -} __attribute__((packed)) gf_fop_fgetxattr_rsp_t; - - -typedef struct { - uint64_t ino; - uint64_t gen; - char path[0]; - char name[0]; -} __attribute__((packed)) gf_fop_removexattr_req_t; -typedef struct { } __attribute__((packed)) gf_fop_removexattr_rsp_t; - - -typedef struct { - uint64_t ino; - uint64_t gen; - char path[0]; -} __attribute__((packed)) gf_fop_opendir_req_t; -typedef struct { - int64_t fd; -} __attribute__((packed)) gf_fop_opendir_rsp_t; - - -typedef struct fsyncdir_req { - uint64_t ino; - uint64_t gen; - int64_t fd; - int32_t data; -} __attribute__((packed)) gf_fop_fsyncdir_req_t; -typedef struct { -} __attribute__((packed)) gf_fop_fsyncdir_rsp_t; - - -typedef struct { - uint64_t ino; - uint64_t gen; - int64_t fd; - uint64_t offset; - uint32_t size; -} __attribute__((packed)) gf_fop_readdir_req_t; -typedef struct { - uint32_t size; - char buf[0]; -} __attribute__((packed)) gf_fop_readdir_rsp_t; - - -typedef struct { - uint64_t ino; - uint64_t gen; - int64_t fd; - uint64_t offset; - uint32_t size; -} __attribute__((packed)) gf_fop_readdirp_req_t; -typedef struct { - uint32_t size; - char buf[0]; -} __attribute__((packed)) gf_fop_readdirp_rsp_t; - - -typedef struct { - uint64_t ino; - uint64_t gen; - uint32_t mask; - char path[0]; -} __attribute__((packed)) gf_fop_access_req_t; -typedef struct { -} __attribute__((packed)) gf_fop_access_rsp_t; - - -typedef struct { - uint64_t par; - uint64_t gen; - uint32_t flags; - uint32_t mode; - char path[0]; - char bname[0]; -} __attribute__((packed)) gf_fop_create_req_t; -typedef struct { - struct gf_stat stat; - uint64_t fd; - struct gf_stat preparent; - struct gf_stat postparent; -} __attribute__((packed)) gf_fop_create_rsp_t; - - - -typedef struct { - uint64_t ino; - uint64_t gen; - int64_t fd; - uint64_t offset; -} __attribute__((packed)) gf_fop_ftruncate_req_t; -typedef struct { - struct gf_stat prestat; - struct gf_stat poststat; -} __attribute__((packed)) gf_fop_ftruncate_rsp_t; - - -typedef struct { - uint64_t ino; - uint64_t gen; - int64_t fd; -} __attribute__((packed)) gf_fop_fstat_req_t; -typedef struct { - struct gf_stat stat; -} __attribute__((packed)) gf_fop_fstat_rsp_t; - - -typedef struct { - uint64_t ino; - uint64_t gen; - int64_t fd; - uint32_t cmd; - uint32_t type; - struct gf_flock flock; -} __attribute__((packed)) gf_fop_lk_req_t; -typedef struct { - struct gf_flock flock; -} __attribute__((packed)) gf_fop_lk_rsp_t; - -typedef struct { - uint64_t ino; - uint64_t gen; - uint32_t cmd; - uint32_t type; - struct gf_flock flock; - char path[0]; - char volume[0]; -} __attribute__((packed)) gf_fop_inodelk_req_t; -typedef struct { -} __attribute__((packed)) gf_fop_inodelk_rsp_t; - -typedef struct { - uint64_t ino; - uint64_t gen; - int64_t fd; - uint32_t cmd; - uint32_t type; - struct gf_flock flock; - char volume[0]; -} __attribute__((packed)) gf_fop_finodelk_req_t; -typedef struct { -} __attribute__((packed)) gf_fop_finodelk_rsp_t; - -typedef struct { - uint64_t ino; - uint64_t gen; - uint32_t cmd; - uint32_t type; - uint64_t namelen; - char path[0]; - char name[0]; - char volume[0]; -} __attribute__((packed)) gf_fop_entrylk_req_t; -typedef struct { -} __attribute__((packed)) gf_fop_entrylk_rsp_t; - -typedef struct { - uint64_t ino; - uint64_t gen; - int64_t fd; - uint32_t cmd; - uint32_t type; - uint64_t namelen; - char name[0]; - char volume[0]; -} __attribute__((packed)) gf_fop_fentrylk_req_t; -typedef struct { -} __attribute__((packed)) gf_fop_fentrylk_rsp_t; - -typedef struct { - uint64_t ino; /* NOTE: used only in case of 'root' lookup */ - uint64_t par; - uint64_t gen; - uint32_t flags; - uint32_t dictlen; - char path[0]; - char bname[0]; - char dict[0]; -} __attribute__((packed)) gf_fop_lookup_req_t; -typedef struct { - struct gf_stat stat; - struct gf_stat postparent; - uint32_t dict_len; - char dict[0]; -} __attribute__((packed)) gf_fop_lookup_rsp_t; - -typedef struct { - uint64_t ino; - uint64_t gen; - uint32_t flag; - char path[0]; -} __attribute__((packed)) gf_fop_checksum_req_t; -typedef struct { - unsigned char fchecksum[0]; - unsigned char dchecksum[0]; -} __attribute__((packed)) gf_fop_checksum_rsp_t; - -typedef struct { - uint64_t ino; - uint64_t gen; - struct gf_stat stbuf; - int32_t valid; - char path[0]; -} __attribute__((packed)) gf_fop_setattr_req_t; -typedef struct { - struct gf_stat statpre; - struct gf_stat statpost; -} __attribute__((packed)) gf_fop_setattr_rsp_t; - -typedef struct { - int64_t fd; - struct gf_stat stbuf; - int32_t valid; -} __attribute__((packed)) gf_fop_fsetattr_req_t; -typedef struct { - struct gf_stat statpre; - struct gf_stat statpost; -} __attribute__((packed)) gf_fop_fsetattr_rsp_t; - -typedef struct { - int64_t fd; - uint64_t offset; - uint32_t len; -} __attribute__((packed)) gf_fop_rchecksum_req_t; -typedef struct { - uint32_t weak_checksum; - unsigned char strong_checksum[0]; -} __attribute__((packed)) gf_fop_rchecksum_rsp_t; - -typedef struct { - uint32_t flags; - uint32_t keylen; - char key[0]; -} __attribute__((packed)) gf_mop_getspec_req_t; -typedef struct { - char spec[0]; -} __attribute__((packed)) gf_mop_getspec_rsp_t; - - -typedef struct { - uint32_t msglen; - char msg[0]; -} __attribute__((packed)) gf_mop_log_req_t; -typedef struct { -} __attribute__((packed)) gf_mop_log_rsp_t; - - -typedef struct { - uint32_t dict_len; - char buf[0]; -} __attribute__((packed)) gf_mop_setvolume_req_t; -typedef struct { - uint32_t dict_len; - char buf[0]; -} __attribute__((packed)) gf_mop_setvolume_rsp_t; - - -typedef struct { -} __attribute__((packed)) gf_mop_ping_req_t; -typedef struct { -} __attribute__((packed)) gf_mop_ping_rsp_t; - -typedef struct { - uint32_t flags; - char buf[0]; -} __attribute__((packed)) gf_mop_notify_req_t; -typedef struct { - uint32_t flags; - char buf[0]; -} __attribute__((packed)) gf_mop_notify_rsp_t; - -typedef struct { - uint64_t ino; - uint64_t gen; - int64_t fd; -} __attribute__((packed)) gf_cbk_releasedir_req_t; -typedef struct { -} __attribute__((packed)) gf_cbk_releasedir_rsp_t; - - -typedef struct { - uint64_t ino; - uint64_t gen; - int64_t fd; -} __attribute__((packed)) gf_cbk_release_req_t; -typedef struct { -} __attribute__((packed)) gf_cbk_release_rsp_t; - - -typedef struct { - uint32_t count; - uint64_t ino_array[0]; -} __attribute__((packed)) gf_cbk_forget_req_t; -typedef struct { } __attribute__((packed)) gf_cbk_forget_rsp_t; - -typedef struct { - uint32_t pid; - uint32_t uid; - uint32_t gid; - - /* Number of groups being sent through the array above. */ - uint32_t ngrps; - - /* Array of groups to which the uid belongs apart from the primary group - * in gid. - */ - uint32_t groups[GF_REQUEST_MAXGROUPS]; - - uint64_t lk_owner; -} __attribute__ ((packed)) gf_hdr_req_t; - - -typedef struct { - uint32_t op_ret; - uint32_t op_errno; -} __attribute__ ((packed)) gf_hdr_rsp_t; - - -typedef struct { - uint64_t callid; - uint32_t type; - uint32_t op; - uint32_t size; - union { - gf_hdr_req_t req; - gf_hdr_rsp_t rsp; - } __attribute__ ((packed)); -} __attribute__ ((packed)) gf_hdr_common_t; - - -static inline gf_hdr_common_t * -__gf_hdr_new (int size) -{ - gf_hdr_common_t *hdr = NULL; - - /* TODO: use mem-pool */ - hdr = GF_CALLOC (sizeof (gf_hdr_common_t) + size, 1, - gf_common_mt_gf_hdr_common_t); - - if (!hdr) { - return NULL; - } - - hdr->size = hton32 (size); - - return hdr; -} - - -#define gf_hdr_len(type, x) (sizeof (gf_hdr_common_t) + sizeof (*type) + x) -#define gf_hdr_new(type, x) __gf_hdr_new (sizeof (*type) + x) - - -static inline void * -gf_param (gf_hdr_common_t *hdr) -{ - return ((void *)hdr) + sizeof (*hdr); -} - - -struct gf_dirent_nb { - uint64_t d_ino; - uint64_t d_off; - uint32_t d_len; - uint32_t d_type; - struct gf_stat d_stat; - char d_name[0]; -} __attribute__((packed)); - -int -gf_dirent_unserialize (gf_dirent_t *entries, const char *buf, size_t buf_size); -int -gf_dirent_serialize (gf_dirent_t *entries, char *buf, size_t buf_size); - -int protocol_common_init (void); - -#endif diff --git a/xlators/protocol/legacy/lib/src/transport.c b/xlators/protocol/legacy/lib/src/transport.c deleted file mode 100644 index 4396613ec..000000000 --- a/xlators/protocol/legacy/lib/src/transport.c +++ /dev/null @@ -1,422 +0,0 @@ -/* - Copyright (c) 2006-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/>. -*/ - -#include <dlfcn.h> -#include <stdlib.h> -#include <stdio.h> -#include <sys/poll.h> -#include <fnmatch.h> -#include <stdint.h> - -#ifndef _CONFIG_H -#define _CONFIG_H -#include "config.h" -#endif - -#include "logging.h" -#include "transport.h" -#include "glusterfs.h" -#include "xlator.h" -#include "list.h" - - -transport_t * -transport_load (dict_t *options, - xlator_t *xl) -{ - struct transport *trans = NULL, *return_trans = NULL; - char *name = NULL; - void *handle = NULL; - char *type = NULL; - char str[] = "ERROR"; - int32_t ret = -1; - int8_t is_tcp = 0, is_unix = 0, is_ibsdp = 0; - volume_opt_list_t *vol_opt = NULL; - - GF_VALIDATE_OR_GOTO("transport", options, fail); - GF_VALIDATE_OR_GOTO("transport", xl, fail); - - trans = GF_CALLOC (1, sizeof (struct transport), - gf_common_mt_transport); - GF_VALIDATE_OR_GOTO("transport", trans, fail); - - trans->xl = xl; - type = str; - - /* Backward compatibility */ - ret = dict_get_str (options, "transport-type", &type); - if (ret < 0) { - ret = dict_set_str (options, "transport-type", "socket"); - if (ret < 0) - gf_log ("dict", GF_LOG_DEBUG, - "setting transport-type failed"); - gf_log ("transport", GF_LOG_WARNING, - "missing 'option transport-type'. defaulting to " - "\"socket\""); - } else { - { - /* Backword compatibility to handle * /client, - * * /server. - */ - char *tmp = strchr (type, '/'); - if (tmp) - *tmp = '\0'; - } - - is_tcp = strcmp (type, "tcp"); - is_unix = strcmp (type, "unix"); - is_ibsdp = strcmp (type, "ib-sdp"); - if ((is_tcp == 0) || - (is_unix == 0) || - (is_ibsdp == 0)) { - if (is_unix == 0) - ret = dict_set_str (options, - "transport.address-family", - "unix"); - if (is_ibsdp == 0) - ret = dict_set_str (options, - "transport.address-family", - "inet-sdp"); - - if (ret < 0) - gf_log ("dict", GF_LOG_DEBUG, - "setting address-family failed"); - - ret = dict_set_str (options, - "transport-type", "socket"); - if (ret < 0) - gf_log ("dict", GF_LOG_DEBUG, - "setting transport-type failed"); - } - } - - ret = dict_get_str (options, "transport-type", &type); - if (ret < 0) { - GF_FREE (trans); - gf_log ("transport", GF_LOG_ERROR, - "'option transport-type <xx>' missing in volume '%s'", - xl->name); - goto fail; - } - - ret = gf_asprintf (&name, "%s/%s.so", TRANSPORTDIR, type); - if (-1 == ret) { - gf_log ("transport", GF_LOG_ERROR, "asprintf failed"); - goto fail; - } - gf_log ("transport", GF_LOG_DEBUG, - "attempt to load file %s", name); - - handle = dlopen (name, RTLD_NOW|RTLD_GLOBAL); - if (handle == NULL) { - gf_log ("transport", GF_LOG_ERROR, "%s", dlerror ()); - gf_log ("transport", GF_LOG_ERROR, - "volume '%s': transport-type '%s' is not valid or " - "not found on this machine", - xl->name, type); - GF_FREE (name); - GF_FREE (trans); - goto fail; - } - GF_FREE (name); - - trans->ops = dlsym (handle, "tops"); - if (trans->ops == NULL) { - gf_log ("transport", GF_LOG_ERROR, - "dlsym (transport_ops) on %s", dlerror ()); - GF_FREE (trans); - goto fail; - } - - trans->init = dlsym (handle, "init"); - if (trans->init == NULL) { - gf_log ("transport", GF_LOG_ERROR, - "dlsym (gf_transport_init) on %s", dlerror ()); - GF_FREE (trans); - goto fail; - } - - trans->fini = dlsym (handle, "fini"); - if (trans->fini == NULL) { - gf_log ("transport", GF_LOG_ERROR, - "dlsym (gf_transport_fini) on %s", dlerror ()); - GF_FREE (trans); - goto fail; - } - - vol_opt = GF_CALLOC (1, sizeof (volume_opt_list_t), - gf_common_mt_volume_opt_list_t); - vol_opt->given_opt = dlsym (handle, "options"); - if (vol_opt->given_opt == NULL) { - gf_log ("transport", GF_LOG_DEBUG, - "volume option validation not specified"); - } else { - list_add_tail (&vol_opt->list, &xl->volume_options); - if (-1 == - validate_xlator_volume_options (xl, - vol_opt->given_opt)) { - gf_log ("transport", GF_LOG_ERROR, - "volume option validation failed"); - GF_FREE (trans); - goto fail; - } - } - - ret = trans->init (trans); - if (ret != 0) { - gf_log ("transport", GF_LOG_ERROR, - "'%s' initialization failed", type); - GF_FREE (trans); - goto fail; - } - - pthread_mutex_init (&trans->lock, NULL); - return_trans = trans; -fail: - return return_trans; -} - - -int32_t -transport_submit (transport_t *this, char *buf, int32_t len, - struct iovec *vector, int count, - struct iobref *iobref) -{ - int32_t ret = -1; - transport_t *peer_trans = NULL; - struct iobuf *iobuf = NULL; - struct transport_msg *msg = NULL; - - if (this->peer_trans) { - peer_trans = this->peer_trans; - - msg = GF_CALLOC (1, sizeof (*msg), - gf_common_mt_transport_msg); - if (!msg) { - return -ENOMEM; - } - - msg->hdr = buf; - msg->hdrlen = len; - - if (vector) { - iobuf = iobuf_get (this->xl->ctx->iobuf_pool); - if (!iobuf) { - GF_FREE (msg->hdr); - GF_FREE (msg); - return -ENOMEM; - } - - iov_unload (iobuf->ptr, vector, count); - msg->iobuf = iobuf; - } - - pthread_mutex_lock (&peer_trans->handover.mutex); - { - list_add_tail (&msg->list, &peer_trans->handover.msgs); - pthread_cond_broadcast (&peer_trans->handover.cond); - } - pthread_mutex_unlock (&peer_trans->handover.mutex); - - return 0; - } - - GF_VALIDATE_OR_GOTO("transport", this, fail); - GF_VALIDATE_OR_GOTO("transport", this->ops, fail); - - ret = this->ops->submit (this, buf, len, vector, count, iobref); -fail: - return ret; -} - - -int32_t -transport_connect (transport_t *this) -{ - int ret = -1; - - GF_VALIDATE_OR_GOTO("transport", this, fail); - - ret = this->ops->connect (this); -fail: - return ret; -} - - -int32_t -transport_listen (transport_t *this) -{ - int ret = -1; - - GF_VALIDATE_OR_GOTO("transport", this, fail); - - ret = this->ops->listen (this); -fail: - return ret; -} - - -int32_t -transport_disconnect (transport_t *this) -{ - int32_t ret = -1; - - GF_VALIDATE_OR_GOTO("transport", this, fail); - - ret = this->ops->disconnect (this); -fail: - return ret; -} - - -int32_t -transport_destroy (transport_t *this) -{ - int32_t ret = -1; - - GF_VALIDATE_OR_GOTO("transport", this, fail); - - if (this->fini) - this->fini (this); - - pthread_mutex_destroy (&this->lock); - GF_FREE (this); -fail: - return ret; -} - - -transport_t * -transport_ref (transport_t *this) -{ - transport_t *return_this = NULL; - - GF_VALIDATE_OR_GOTO("transport", this, fail); - - pthread_mutex_lock (&this->lock); - { - this->refcount ++; - } - pthread_mutex_unlock (&this->lock); - - return_this = this; -fail: - return return_this; -} - - -int32_t -transport_receive (transport_t *this, char **hdr_p, size_t *hdrlen_p, - struct iobuf **iobuf_p) -{ - int32_t ret = -1; - - GF_VALIDATE_OR_GOTO("transport", this, fail); - - if (this->peer_trans) { - *hdr_p = this->handover.msg->hdr; - *hdrlen_p = this->handover.msg->hdrlen; - *iobuf_p = this->handover.msg->iobuf; - - return 0; - } - - ret = this->ops->receive (this, hdr_p, hdrlen_p, iobuf_p); -fail: - return ret; -} - - -int32_t -transport_unref (transport_t *this) -{ - int32_t refcount = 0; - int32_t ret = -1; - - GF_VALIDATE_OR_GOTO("transport", this, fail); - - pthread_mutex_lock (&this->lock); - { - refcount = --this->refcount; - } - pthread_mutex_unlock (&this->lock); - - if (refcount == 0) { - xlator_notify (this->xl, GF_EVENT_TRANSPORT_CLEANUP, this); - transport_destroy (this); - } - - ret = 0; -fail: - return ret; -} - - -void * -transport_peerproc (void *trans_data) -{ - transport_t *trans = NULL; - struct transport_msg *msg = NULL; - - trans = trans_data; - - while (1) { - pthread_mutex_lock (&trans->handover.mutex); - { - while (list_empty (&trans->handover.msgs)) - pthread_cond_wait (&trans->handover.cond, - &trans->handover.mutex); - - msg = list_entry (trans->handover.msgs.next, - struct transport_msg, list); - - list_del_init (&msg->list); - } - pthread_mutex_unlock (&trans->handover.mutex); - - trans->handover.msg = msg; - - xlator_notify (trans->xl, GF_EVENT_POLLIN, trans); - - GF_FREE (msg); - } -} - - -int -transport_setpeer (transport_t *trans, transport_t *peer_trans) -{ - trans->peer_trans = transport_ref (peer_trans); - - INIT_LIST_HEAD (&trans->handover.msgs); - pthread_cond_init (&trans->handover.cond, NULL); - pthread_mutex_init (&trans->handover.mutex, NULL); - pthread_create (&trans->handover.thread, NULL, - transport_peerproc, trans); - - peer_trans->peer_trans = transport_ref (trans); - - INIT_LIST_HEAD (&peer_trans->handover.msgs); - pthread_cond_init (&peer_trans->handover.cond, NULL); - pthread_mutex_init (&peer_trans->handover.mutex, NULL); - pthread_create (&peer_trans->handover.thread, NULL, - transport_peerproc, peer_trans); - - return 0; -} diff --git a/xlators/protocol/legacy/lib/src/transport.h b/xlators/protocol/legacy/lib/src/transport.h deleted file mode 100644 index 5b8b62caf..000000000 --- a/xlators/protocol/legacy/lib/src/transport.h +++ /dev/null @@ -1,106 +0,0 @@ -/* - Copyright (c) 2006-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 __TRANSPORT_H__ -#define __TRANSPORT_H__ - -#ifndef _CONFIG_H -#define _CONFIG_H -#include "config.h" -#endif - -#include <inttypes.h> - -struct transport_ops; -typedef struct transport transport_t; - -#include "xlator.h" -#include "dict.h" -#include "compat.h" - -typedef struct peer_info { - struct sockaddr_storage sockaddr; - socklen_t sockaddr_len; - char identifier[UNIX_PATH_MAX]; -}peer_info_t; - -struct transport_msg { - struct list_head list; - char *hdr; - int hdrlen; - struct iobuf *iobuf; -}; - -struct transport { - struct transport_ops *ops; - void *private; - void *xl_private; - pthread_mutex_t lock; - int32_t refcount; - - xlator_t *xl; - void *dnscache; - data_t *buf; - int32_t (*init) (transport_t *this); - void (*fini) (transport_t *this); - /* int (*notify) (transport_t *this, int event, void *data); */ - peer_info_t peerinfo; - peer_info_t myinfo; - - transport_t *peer_trans; - struct { - pthread_mutex_t mutex; - pthread_cond_t cond; - pthread_t thread; - struct list_head msgs; - struct transport_msg *msg; - } handover; - -}; - -struct transport_ops { - int32_t (*receive) (transport_t *this, char **hdr_p, size_t *hdrlen_p, - struct iobuf **iobuf_p); - int32_t (*submit) (transport_t *this, char *buf, int len, - struct iovec *vector, int count, - struct iobref *iobref); - int32_t (*connect) (transport_t *this); - int32_t (*listen) (transport_t *this); - int32_t (*disconnect) (transport_t *this); -}; - - -int32_t transport_listen (transport_t *this); -int32_t transport_connect (transport_t *this); -int32_t transport_disconnect (transport_t *this); -int32_t transport_notify (transport_t *this, int event); -int32_t transport_submit (transport_t *this, char *buf, int len, - struct iovec *vector, int count, - struct iobref *iobref); -int32_t transport_receive (transport_t *this, char **hdr_p, size_t *hdrlen_p, - struct iobuf **iobuf_p); -int32_t transport_destroy (transport_t *this); - -transport_t *transport_load (dict_t *options, xlator_t *xl); -transport_t *transport_ref (transport_t *trans); -int32_t transport_unref (transport_t *trans); - -int transport_setpeer (transport_t *trans, transport_t *trans_peer); - -#endif /* __TRANSPORT_H__ */ diff --git a/xlators/protocol/legacy/server/Makefile.am b/xlators/protocol/legacy/server/Makefile.am deleted file mode 100644 index d471a3f92..000000000 --- a/xlators/protocol/legacy/server/Makefile.am +++ /dev/null @@ -1,3 +0,0 @@ -SUBDIRS = src - -CLEANFILES = diff --git a/xlators/protocol/legacy/server/src/Makefile.am b/xlators/protocol/legacy/server/src/Makefile.am deleted file mode 100644 index bfc0b7eb6..000000000 --- a/xlators/protocol/legacy/server/src/Makefile.am +++ /dev/null @@ -1,26 +0,0 @@ - -xlator_LTLIBRARIES = server-old.la -xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/legacy/protocol - -server_old_la_LDFLAGS = -module -avoidversion - -server_old_la_SOURCES = server-protocol.c server-resolve.c server-helpers.c \ - authenticate.c - -server_old_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la \ - $(top_builddir)/xlators/protocol/legacy/lib/src/libgfproto.la - -noinst_HEADERS = server-protocol.h server-helpers.h server-mem-types.h \ - authenticate.h - -AM_CFLAGS = -fPIC -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE -Wall -D$(GF_HOST_OS) \ - -I$(top_srcdir)/libglusterfs/src -shared -nostartfiles \ - -DDATADIR=\"$(localstatedir)\" -DCONFDIR=\"$(sysconfdir)/glusterfs\" \ - -DLIBDIR=\"$(libdir)/glusterfs/$(PACKAGE_VERSION)/auth\" \ - $(GF_CFLAGS) -I$(top_srcdir)/xlators/protocol/legacy/lib/src \ - -I$(top_srcdir)/xlators/protocol/lib/src - -CLEANFILES = - -install-data-hook: - ln -sf server-old.so $(DESTDIR)$(xlatordir)/server.so diff --git a/xlators/protocol/legacy/server/src/authenticate.c b/xlators/protocol/legacy/server/src/authenticate.c deleted file mode 100644 index a01d7003c..000000000 --- a/xlators/protocol/legacy/server/src/authenticate.c +++ /dev/null @@ -1,249 +0,0 @@ -/* - Copyright (c) 2007-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 - -#ifndef _GNU_SOURCE -#define _GNU_SOURCE -#endif - -#include <stdio.h> -#include <dlfcn.h> -#include <errno.h> -#include "authenticate.h" - -static void -init (dict_t *this, - char *key, - data_t *value, - void *data) -{ - void *handle = NULL; - char *auth_file = NULL; - auth_handle_t *auth_handle = NULL; - auth_fn_t authenticate = NULL; - int *error = NULL; - int ret = 0; - - /* It gets over written */ - error = data; - - if (!strncasecmp (key, "ip", strlen ("ip"))) { - gf_log ("authenticate", GF_LOG_ERROR, - "AUTHENTICATION MODULE \"IP\" HAS BEEN REPLACED " - "BY \"ADDR\""); - dict_set (this, key, data_from_dynptr (NULL, 0)); - /* TODO: 1.3.x backword compatibility */ - // *error = -1; - // return; - key = "addr"; - } - - ret = gf_asprintf (&auth_file, "%s/%s.so", LIBDIR, key); - if (-1 == ret) { - gf_log ("authenticate", GF_LOG_ERROR, "asprintf failed"); - dict_set (this, key, data_from_dynptr (NULL, 0)); - *error = -1; - return; - } - - handle = dlopen (auth_file, RTLD_LAZY); - if (!handle) { - gf_log ("authenticate", GF_LOG_ERROR, "dlopen(%s): %s\n", - auth_file, dlerror ()); - dict_set (this, key, data_from_dynptr (NULL, 0)); - GF_FREE (auth_file); - *error = -1; - return; - } - GF_FREE (auth_file); - - authenticate = dlsym (handle, "gf_auth"); - if (!authenticate) { - gf_log ("authenticate", GF_LOG_ERROR, - "dlsym(gf_auth) on %s\n", dlerror ()); - dict_set (this, key, data_from_dynptr (NULL, 0)); - *error = -1; - return; - } - - auth_handle = GF_CALLOC (1, sizeof (*auth_handle), - gf_common_mt_auth_handle_t); - if (!auth_handle) { - gf_log ("authenticate", GF_LOG_ERROR, "Out of memory"); - dict_set (this, key, data_from_dynptr (NULL, 0)); - *error = -1; - return; - } - auth_handle->vol_opt = GF_CALLOC (1, sizeof (volume_opt_list_t), - gf_common_mt_volume_opt_list_t); - auth_handle->vol_opt->given_opt = dlsym (handle, "options"); - if (auth_handle->vol_opt->given_opt == NULL) { - gf_log ("authenticate", GF_LOG_DEBUG, - "volume option validation not specified"); - } - - auth_handle->authenticate = authenticate; - auth_handle->handle = handle; - - dict_set (this, key, - data_from_dynptr (auth_handle, sizeof (*auth_handle))); -} - -static void -fini (dict_t *this, - char *key, - data_t *value, - void *data) -{ - auth_handle_t *handle = data_to_ptr (value); - if (handle) { - dlclose (handle->handle); - } -} - -int32_t -gf_auth_init (xlator_t *xl, dict_t *auth_modules) -{ - int ret = 0; - auth_handle_t *handle = NULL; - data_pair_t *pair = NULL; - dict_foreach (auth_modules, init, &ret); - if (!ret) { - pair = auth_modules->members_list; - while (pair) { - handle = data_to_ptr (pair->value); - if (handle) { - list_add_tail (&(handle->vol_opt->list), - &(xl->volume_options)); - if (-1 == - validate_xlator_volume_options (xl, - handle->vol_opt->given_opt)) { - gf_log ("authenticate", GF_LOG_ERROR, - "volume option validation " - "failed"); - ret = -1; - } - } - pair = pair->next; - } - } - if (ret) { - gf_log (xl->name, GF_LOG_ERROR, "authentication init failed"); - dict_foreach (auth_modules, fini, &ret); - ret = -1; - } - return ret; -} - -static dict_t *__input_params; -static dict_t *__config_params; - -void -map (dict_t *this, - char *key, - data_t *value, - void *data) -{ - dict_t *res = data; - auth_fn_t authenticate; - auth_handle_t *handle = NULL; - - if (value && (handle = data_to_ptr (value)) && - (authenticate = handle->authenticate)) { - dict_set (res, key, - int_to_data (authenticate (__input_params, - __config_params))); - } else { - dict_set (res, key, int_to_data (AUTH_DONT_CARE)); - } -} - -void -reduce (dict_t *this, - char *key, - data_t *value, - void *data) -{ - int64_t val = 0; - int64_t *res = data; - if (!data) - return; - - val = data_to_int64 (value); - switch (val) - { - case AUTH_ACCEPT: - if (AUTH_DONT_CARE == *res) - *res = AUTH_ACCEPT; - break; - - case AUTH_REJECT: - *res = AUTH_REJECT; - break; - - case AUTH_DONT_CARE: - break; - } -} - - -auth_result_t -gf_authenticate (dict_t *input_params, - dict_t *config_params, - dict_t *auth_modules) -{ - dict_t *results = NULL; - int64_t result = AUTH_DONT_CARE; - - results = get_new_dict (); - __input_params = input_params; - __config_params = config_params; - - dict_foreach (auth_modules, map, results); - - dict_foreach (results, reduce, &result); - if (AUTH_DONT_CARE == result) { - data_t *peerinfo_data = dict_get (input_params, "peer-info-name"); - char *name = NULL; - - if (peerinfo_data) { - name = peerinfo_data->data; - } - - gf_log ("auth", GF_LOG_ERROR, - "no authentication module is interested in " - "accepting remote-client %s", name); - result = AUTH_REJECT; - } - - dict_destroy (results); - return result; -} - -void -gf_auth_fini (dict_t *auth_modules) -{ - int32_t dummy; - - dict_foreach (auth_modules, fini, &dummy); -} diff --git a/xlators/protocol/legacy/server/src/authenticate.h b/xlators/protocol/legacy/server/src/authenticate.h deleted file mode 100644 index d35304db2..000000000 --- a/xlators/protocol/legacy/server/src/authenticate.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - Copyright (c) 2007-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 _AUTHENTICATE_H -#define _AUTHENTICATE_H - -#ifndef _CONFIG_H -#define _CONFIG_H -#include "config.h" -#endif - -#ifndef _GNU_SOURCE -#define _GNU_SOURCE -#endif - -#include <stdio.h> -#include <fnmatch.h> -#include "dict.h" -#include "compat.h" -#include "list.h" -#include "xlator.h" - -typedef enum { - AUTH_ACCEPT, - AUTH_REJECT, - AUTH_DONT_CARE -} auth_result_t; - -typedef auth_result_t (*auth_fn_t) (dict_t *input_params, - dict_t *config_params); - -typedef struct { - void *handle; - auth_fn_t authenticate; - volume_opt_list_t *vol_opt; -} auth_handle_t; - -auth_result_t gf_authenticate (dict_t *input_params, - dict_t *config_params, - dict_t *auth_modules); -int32_t gf_auth_init (xlator_t *xl, dict_t *auth_modules); -void gf_auth_fini (dict_t *auth_modules); - -#endif /* _AUTHENTICATE_H */ diff --git a/xlators/protocol/legacy/server/src/server-helpers.c b/xlators/protocol/legacy/server/src/server-helpers.c deleted file mode 100644 index 15e46b3d6..000000000 --- a/xlators/protocol/legacy/server/src/server-helpers.c +++ /dev/null @@ -1,622 +0,0 @@ -/* - Copyright (c) 2006-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 "server-protocol.h" -#include "server-helpers.h" - - - -void -old_server_loc_wipe (loc_t *loc) -{ - if (loc->parent) { - inode_unref (loc->parent); - loc->parent = NULL; - } - - if (loc->inode) { - inode_unref (loc->inode); - loc->inode = NULL; - } - - if (loc->path) - GF_FREE ((char *)loc->path); -} - - -static void -old_server_resolve_wipe (server_resolve_t *resolve) -{ - struct resolve_comp *comp = NULL; - int i = 0; - - if (resolve->path) - GF_FREE (resolve->path); - - if (resolve->bname) - GF_FREE (resolve->bname); - - if (resolve->resolved) - GF_FREE (resolve->resolved); - - loc_wipe (&resolve->deep_loc); - - comp = resolve->components; - if (comp) { - for (i = 0; comp[i].basename; i++) { - if (comp[i].inode) - inode_unref (comp[i].inode); - } - GF_FREE (resolve->components); - } -} - - -void -free_old_server_state (server_state_t *state) -{ - if (state->trans) { - transport_unref (state->trans); - state->trans = NULL; - } - - if (state->fd) { - fd_unref (state->fd); - state->fd = NULL; - } - - if (state->params) { - dict_unref (state->params); - state->params = NULL; - } - - if (state->iobref) { - iobref_unref (state->iobref); - state->iobref = NULL; - } - - if (state->iobuf) { - iobuf_unref (state->iobuf); - state->iobuf = NULL; - } - - if (state->dict) { - dict_unref (state->dict); - state->dict = NULL; - } - - if (state->volume) - GF_FREE ((char *)state->volume); - - if (state->name) - GF_FREE (state->name); - - old_server_loc_wipe (&state->loc); - old_server_loc_wipe (&state->loc2); - - old_server_resolve_wipe (&state->resolve); - old_server_resolve_wipe (&state->resolve2); - - GF_FREE (state); -} - -static struct _lock_table * -gf_lock_table_new (void) -{ - struct _lock_table *new = NULL; - - new = GF_CALLOC (1, sizeof (struct _lock_table), - gf_server_mt_lock_table); - if (new == NULL) { - gf_log ("server-protocol", GF_LOG_CRITICAL, - "failed to allocate memory for new lock table"); - goto out; - } - INIT_LIST_HEAD (&new->dir_lockers); - INIT_LIST_HEAD (&new->file_lockers); - LOCK_INIT (&new->lock); -out: - return new; -} - - -static int -gf_server_nop_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno) -{ - server_state_t *state = NULL; - - state = CALL_STATE(frame); - - if (state) - free_old_server_state (state); - STACK_DESTROY (frame->root); - return 0; -} - - -static int -do_lock_table_cleanup (xlator_t *this, server_connection_t *conn, - call_frame_t *frame, struct _lock_table *ltable) -{ - struct list_head file_lockers, dir_lockers; - call_frame_t *tmp_frame = NULL; - struct gf_flock flock = {0, }; - xlator_t *bound_xl = NULL; - struct _locker *locker = NULL, *tmp = NULL; - int ret = -1; - - bound_xl = conn->bound_xl; - INIT_LIST_HEAD (&file_lockers); - INIT_LIST_HEAD (&dir_lockers); - - LOCK (<able->lock); - { - list_splice_init (<able->file_lockers, - &file_lockers); - - list_splice_init (<able->dir_lockers, &dir_lockers); - } - UNLOCK (<able->lock); - - GF_FREE (ltable); - - flock.l_type = F_UNLCK; - flock.l_start = 0; - flock.l_len = 0; - list_for_each_entry_safe (locker, - tmp, &file_lockers, lockers) { - tmp_frame = copy_frame (frame); - if (tmp_frame == NULL) { - gf_log (this->name, GF_LOG_ERROR, - "out of memory"); - goto out; - } - /* - pid = 0 is a special case that tells posix-locks - to release all locks from this transport - */ - tmp_frame->root->pid = 0; - tmp_frame->root->trans = conn; - - if (locker->fd) { - STACK_WIND (tmp_frame, gf_server_nop_cbk, - bound_xl, - bound_xl->fops->finodelk, - locker->volume, - locker->fd, F_SETLK, &flock); - fd_unref (locker->fd); - } else { - STACK_WIND (tmp_frame, gf_server_nop_cbk, - bound_xl, - bound_xl->fops->inodelk, - locker->volume, - &(locker->loc), F_SETLK, &flock); - loc_wipe (&locker->loc); - } - - GF_FREE (locker->volume); - - list_del_init (&locker->lockers); - GF_FREE (locker); - } - - tmp = NULL; - locker = NULL; - list_for_each_entry_safe (locker, tmp, &dir_lockers, lockers) { - tmp_frame = copy_frame (frame); - - tmp_frame->root->pid = 0; - tmp_frame->root->trans = conn; - - if (locker->fd) { - STACK_WIND (tmp_frame, gf_server_nop_cbk, - bound_xl, - bound_xl->fops->fentrylk, - locker->volume, - locker->fd, NULL, - ENTRYLK_UNLOCK, ENTRYLK_WRLCK); - fd_unref (locker->fd); - } else { - STACK_WIND (tmp_frame, gf_server_nop_cbk, - bound_xl, - bound_xl->fops->entrylk, - locker->volume, - &(locker->loc), NULL, - ENTRYLK_UNLOCK, ENTRYLK_WRLCK); - loc_wipe (&locker->loc); - } - - GF_FREE (locker->volume); - - list_del_init (&locker->lockers); - GF_FREE (locker); - } - ret = 0; - -out: - return ret; -} - - -static int -server_connection_cleanup_flush_cbk (call_frame_t *frame, void *cookie, - xlator_t *this, int32_t op_ret, - int32_t op_errno) -{ - fd_t *fd = NULL; - - fd = frame->local; - - fd_unref (fd); - frame->local = NULL; - - STACK_DESTROY (frame->root); - return 0; -} - - -static int -do_fd_cleanup (xlator_t *this, server_connection_t *conn, call_frame_t *frame, - fdentry_t *fdentries, int fd_count) -{ - fd_t *fd = NULL; - int i = 0, ret = -1; - call_frame_t *tmp_frame = NULL; - xlator_t *bound_xl = NULL; - - bound_xl = conn->bound_xl; - for (i = 0;i < fd_count; i++) { - fd = fdentries[i].fd; - - if (fd != NULL) { - tmp_frame = copy_frame (frame); - if (tmp_frame == NULL) { - gf_log (this->name, GF_LOG_ERROR, - "out of memory"); - goto out; - } - tmp_frame->local = fd; - - tmp_frame->root->pid = 0; - tmp_frame->root->trans = conn; - tmp_frame->root->lk_owner = 0; - STACK_WIND (tmp_frame, - server_connection_cleanup_flush_cbk, - bound_xl, bound_xl->fops->flush, fd); - } - } - - GF_FREE (fdentries); - ret = 0; - -out: - return ret; -} - -static int -do_connection_cleanup (xlator_t *this, server_connection_t *conn, - struct _lock_table *ltable, fdentry_t *fdentries, int fd_count) -{ - int ret = 0; - int saved_ret = 0; - call_frame_t *frame = NULL; - - frame = create_frame (this, this->ctx->pool); - if (frame == NULL) { - gf_log (this->name, GF_LOG_ERROR, "out of memory"); - goto out; - } - - saved_ret = do_lock_table_cleanup (this, conn, frame, ltable); - - if (fdentries != NULL) { - ret = do_fd_cleanup (this, conn, frame, fdentries, fd_count); - } - - STACK_DESTROY (frame->root); - - if (saved_ret || ret) { - ret = -1; - } - -out: - return ret; -} - - -int -gf_server_connection_cleanup (xlator_t *this, server_connection_t *conn) -{ - char do_cleanup = 0; - struct _lock_table *ltable = NULL; - fdentry_t *fdentries = NULL; - uint32_t fd_count = 0; - int ret = 0; - - if (conn == NULL) { - goto out; - } - - pthread_mutex_lock (&conn->lock); - { - conn->active_transports--; - if (conn->active_transports == 0) { - if (conn->ltable) { - ltable = conn->ltable; - conn->ltable = gf_lock_table_new (); - } - - if (conn->fdtable) { - fdentries = gf_fd_fdtable_get_all_fds (conn->fdtable, - &fd_count); - } - do_cleanup = 1; - } - } - pthread_mutex_unlock (&conn->lock); - - if (do_cleanup && conn->bound_xl) - ret = do_connection_cleanup (this, conn, ltable, fdentries, fd_count); - -out: - return ret; -} - - -static int -server_connection_destroy (xlator_t *this, server_connection_t *conn) -{ - call_frame_t *frame = NULL, *tmp_frame = NULL; - xlator_t *bound_xl = NULL; - int32_t ret = -1; - struct list_head file_lockers; - struct list_head dir_lockers; - struct _lock_table *ltable = NULL; - struct _locker *locker = NULL, *tmp = NULL; - struct gf_flock flock = {0,}; - fd_t *fd = NULL; - int32_t i = 0; - fdentry_t *fdentries = NULL; - uint32_t fd_count = 0; - - if (conn == NULL) { - ret = 0; - goto out; - } - - bound_xl = (xlator_t *) (conn->bound_xl); - - if (bound_xl) { - /* trans will have ref_count = 1 after this call, but its - ok since this function is called in - GF_EVENT_TRANSPORT_CLEANUP */ - frame = create_frame (this, this->ctx->pool); - - pthread_mutex_lock (&(conn->lock)); - { - if (conn->ltable) { - ltable = conn->ltable; - conn->ltable = NULL; - } - } - pthread_mutex_unlock (&conn->lock); - - INIT_LIST_HEAD (&file_lockers); - INIT_LIST_HEAD (&dir_lockers); - - if (ltable) { - LOCK (<able->lock); - { - list_splice_init (<able->file_lockers, - &file_lockers); - - list_splice_init (<able->dir_lockers, &dir_lockers); - } - UNLOCK (<able->lock); - GF_FREE (ltable); - } - - flock.l_type = F_UNLCK; - flock.l_start = 0; - flock.l_len = 0; - list_for_each_entry_safe (locker, - tmp, &file_lockers, lockers) { - tmp_frame = copy_frame (frame); - /* - pid = 0 is a special case that tells posix-locks - to release all locks from this transport - */ - tmp_frame->root->pid = 0; - tmp_frame->root->trans = conn; - - if (locker->fd) { - STACK_WIND (tmp_frame, gf_server_nop_cbk, - bound_xl, - bound_xl->fops->finodelk, - locker->volume, - locker->fd, F_SETLK, &flock); - fd_unref (locker->fd); - } else { - STACK_WIND (tmp_frame, gf_server_nop_cbk, - bound_xl, - bound_xl->fops->inodelk, - locker->volume, - &(locker->loc), F_SETLK, &flock); - loc_wipe (&locker->loc); - } - - GF_FREE (locker->volume); - - list_del_init (&locker->lockers); - GF_FREE (locker); - } - - tmp = NULL; - locker = NULL; - list_for_each_entry_safe (locker, tmp, &dir_lockers, lockers) { - tmp_frame = copy_frame (frame); - - tmp_frame->root->pid = 0; - tmp_frame->root->trans = conn; - - if (locker->fd) { - STACK_WIND (tmp_frame, gf_server_nop_cbk, - bound_xl, - bound_xl->fops->fentrylk, - locker->volume, - locker->fd, NULL, - ENTRYLK_UNLOCK, ENTRYLK_WRLCK); - fd_unref (locker->fd); - } else { - STACK_WIND (tmp_frame, gf_server_nop_cbk, - bound_xl, - bound_xl->fops->entrylk, - locker->volume, - &(locker->loc), NULL, - ENTRYLK_UNLOCK, ENTRYLK_WRLCK); - loc_wipe (&locker->loc); - } - - GF_FREE (locker->volume); - - - list_del_init (&locker->lockers); - GF_FREE (locker); - } - - pthread_mutex_lock (&(conn->lock)); - { - if (conn->fdtable) { - fdentries = gf_fd_fdtable_get_all_fds (conn->fdtable, - &fd_count); - gf_fd_fdtable_destroy (conn->fdtable); - conn->fdtable = NULL; - } - } - pthread_mutex_unlock (&conn->lock); - - if (fdentries != NULL) { - for (i = 0; i < fd_count; i++) { - fd = fdentries[i].fd; - if (fd != NULL) { - tmp_frame = copy_frame (frame); - tmp_frame->local = fd; - - STACK_WIND (tmp_frame, - server_connection_cleanup_flush_cbk, - bound_xl, - bound_xl->fops->flush, - fd); - } - } - GF_FREE (fdentries); - } - } - - if (frame) { - STACK_DESTROY (frame->root); - } - - gf_log (this->name, GF_LOG_INFO, "destroyed connection of %s", - conn->id); - - GF_FREE (conn->id); - GF_FREE (conn); - -out: - return ret; -} - - -server_connection_t * -gf_server_connection_get (xlator_t *this, const char *id) -{ - server_connection_t *conn = NULL; - server_connection_t *trav = NULL; - server_conf_t *conf = NULL; - - conf = this->private; - - pthread_mutex_lock (&conf->mutex); - { - list_for_each_entry (trav, &conf->conns, list) { - if (!strcmp (id, trav->id)) { - conn = trav; - break; - } - } - - if (!conn) { - conn = (void *) GF_CALLOC (1, sizeof (*conn), - gf_server_mt_server_connection_t); - - conn->id = gf_strdup (id); - conn->fdtable = gf_fd_fdtable_alloc (); - conn->ltable = gf_lock_table_new (); - - pthread_mutex_init (&conn->lock, NULL); - - list_add (&conn->list, &conf->conns); - } - - conn->ref++; - conn->active_transports++; - } - pthread_mutex_unlock (&conf->mutex); - - return conn; -} - - -void -gf_server_connection_put (xlator_t *this, server_connection_t *conn) -{ - server_conf_t *conf = NULL; - server_connection_t *todel = NULL; - - if (conn == NULL) { - goto out; - } - - conf = this->private; - - pthread_mutex_lock (&conf->mutex); - { - conn->ref--; - - if (!conn->ref) { - list_del_init (&conn->list); - todel = conn; - } - } - pthread_mutex_unlock (&conf->mutex); - - if (todel) { - server_connection_destroy (this, todel); - } - -out: - return; -} diff --git a/xlators/protocol/legacy/server/src/server-helpers.h b/xlators/protocol/legacy/server/src/server-helpers.h deleted file mode 100644 index cda0c36ef..000000000 --- a/xlators/protocol/legacy/server/src/server-helpers.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - Copyright (c) 2006-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 __SERVER_HELPERS_H__ -#define __SERVER_HELPERS_H__ - -#define CALL_STATE(frame) ((server_state_t *)frame->root->state) - -#define BOUND_XL(frame) ((xlator_t *) CALL_STATE(frame)->bound_xl) - -#define TRANSPORT_FROM_FRAME(frame) ((transport_t *) CALL_STATE(frame)->trans) - -#define SERVER_CONNECTION(frame) \ - ((server_connection_t *) TRANSPORT_FROM_FRAME(frame)->xl_private) - -#define SERVER_CONF(frame) \ - ((server_conf_t *)TRANSPORT_FROM_FRAME(frame)->xl->private) - -#define TRANSPORT_FROM_XLATOR(this) ((((server_conf_t *)this->private))->trans) - -#define INODE_LRU_LIMIT(this) \ - (((server_conf_t *)(this->private))->inode_lru_limit) - -#define IS_ROOT_INODE(inode) (inode == inode->table->root) - -#define IS_NOT_ROOT(pathlen) ((pathlen > 2)? 1 : 0) - -void free_old_server_state (server_state_t *state); - -void old_server_loc_wipe (loc_t *loc); - -#endif /* __SERVER_HELPERS_H__ */ diff --git a/xlators/protocol/legacy/server/src/server-mem-types.h b/xlators/protocol/legacy/server/src/server-mem-types.h deleted file mode 100644 index 5e15fd90f..000000000 --- a/xlators/protocol/legacy/server/src/server-mem-types.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - Copyright (c) 2008-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 __AFR_MEM_TYPES_H__ -#define __AFR_MEM_TYPES_H__ - -#include "mem-types.h" - -enum gf_server_mem_types_ { - gf_server_mt_dir_entry_t = gf_common_mt_end + 1, - gf_server_mt_volfile_ctx, - gf_server_mt_server_state_t, - gf_server_mt_server_conf_t, - gf_server_mt_locker, - gf_server_mt_lock_table, - gf_server_mt_char, - gf_server_mt_server_connection_t, - gf_server_mt_resolve_comp, - gf_server_mt_end -}; -#endif - diff --git a/xlators/protocol/legacy/server/src/server-protocol.c b/xlators/protocol/legacy/server/src/server-protocol.c deleted file mode 100644 index 0686398d1..000000000 --- a/xlators/protocol/legacy/server/src/server-protocol.c +++ /dev/null @@ -1,6587 +0,0 @@ -/* - Copyright (c) 2006-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 <time.h> -#include <sys/uio.h> -#include <sys/resource.h> - -#include <libgen.h> - -#include "transport.h" -#include "fnmatch.h" -#include "xlator.h" -#include "protocol.h" -#include "server-protocol.h" -#include "server-helpers.h" -#include "call-stub.h" -#include "defaults.h" -#include "list.h" -#include "dict.h" -#include "compat.h" -#include "compat-errno.h" -#include "statedump.h" -#include "md5.h" - - -static void -print_caller (char *str, int size, call_frame_t *frame) -{ - int filled = 0; - server_state_t *state = NULL; - transport_t *trans = NULL; - - state = CALL_STATE (frame); - trans = state->trans; - - filled += snprintf (str + filled, size - filled, - " Callid=%"PRId64", Client=%s", - frame->root->unique, - trans->peerinfo.identifier); - - return; -} - - -static void -server_print_resolve (char *str, int size, server_resolve_t *resolve) -{ - int filled = 0; - - if (!resolve) { - snprintf (str, size, "<nul>"); - return; - } - - filled += snprintf (str + filled, size - filled, - " Resolve={"); - if (resolve->fd_no != -1) - filled += snprintf (str + filled, size - filled, - "fd=%"PRId64",", (uint64_t) resolve->fd_no); - if (resolve->ino) - filled += snprintf (str + filled, size - filled, - "ino=%"PRIu64",", (uint64_t) resolve->ino); - if (resolve->par) - filled += snprintf (str + filled, size - filled, - "par=%"PRIu64",", (uint64_t) resolve->par); - if (resolve->gen) - filled += snprintf (str + filled, size - filled, - "gen=%"PRIu64",", (uint64_t) resolve->gen); - if (resolve->bname) - filled += snprintf (str + filled, size - filled, - "bname=%s,", resolve->bname); - if (resolve->path) - filled += snprintf (str + filled, size - filled, - "path=%s", resolve->path); - - filled += snprintf (str + filled, size - filled, "}"); -} - - -static void -server_print_loc (char *str, int size, loc_t *loc) -{ - int filled = 0; - - if (!loc) { - snprintf (str, size, "<nul>"); - return; - } - - filled += snprintf (str + filled, size - filled, - " Loc={"); - - if (loc->path) - filled += snprintf (str + filled, size - filled, - "path=%s,", loc->path); - if (loc->inode) - filled += snprintf (str + filled, size - filled, - "inode=%p,", loc->inode); - if (loc->parent) - filled += snprintf (str + filled, size - filled, - "parent=%p", loc->parent); - - filled += snprintf (str + filled, size - filled, "}"); -} - - -static void -server_print_params (char *str, int size, server_state_t *state) -{ - int filled = 0; - - filled += snprintf (str + filled, size - filled, - " Params={"); - - if (state->fd) - filled += snprintf (str + filled, size - filled, - "fd=%p,", state->fd); - if (state->valid) - filled += snprintf (str + filled, size - filled, - "valid=%d,", state->valid); - if (state->flags) - filled += snprintf (str + filled, size - filled, - "flags=%d,", state->flags); - if (state->wbflags) - filled += snprintf (str + filled, size - filled, - "wbflags=%d,", state->wbflags); - if (state->size) - filled += snprintf (str + filled, size - filled, - "size=%zu,", state->size); - if (state->offset) - filled += snprintf (str + filled, size - filled, - "offset=%"PRId64",", state->offset); - if (state->cmd) - filled += snprintf (str + filled, size - filled, - "cmd=%d,", state->cmd); - if (state->type) - filled += snprintf (str + filled, size - filled, - "type=%d,", state->type); - if (state->name) - filled += snprintf (str + filled, size - filled, - "name=%s,", state->name); - if (state->mask) - filled += snprintf (str + filled, size - filled, - "mask=%d,", state->mask); - if (state->volume) - filled += snprintf (str + filled, size - filled, - "volume=%s,", state->volume); - - filled += snprintf (str + filled, size - filled, - "bound_xl=%s}", state->bound_xl->name); -} - - -static int -server_resolve_is_empty (server_resolve_t *resolve) -{ - if (resolve->fd_no != -1) - return 0; - - if (resolve->ino != 0) - return 0; - - if (resolve->gen != 0) - return 0; - - if (resolve->par != 0) - return 0; - - if (resolve->path != 0) - return 0; - - if (resolve->bname != 0) - return 0; - - return 1; -} - -void -gf_server_print_request (call_frame_t *frame) -{ - server_conf_t *conf = NULL; - xlator_t *this = NULL; - server_state_t *state = NULL; - char resolve_vars[256]; - char resolve2_vars[256]; - char loc_vars[256]; - char loc2_vars[256]; - char other_vars[512]; - char caller[512]; - char *op = "UNKNOWN"; - - this = frame->this; - conf = this->private; - - state = CALL_STATE (frame); - - if (!conf->trace) - return; - - memset (resolve_vars, '\0', 256); - memset (resolve2_vars, '\0', 256); - memset (loc_vars, '\0', 256); - memset (loc2_vars, '\0', 256); - memset (other_vars, '\0', 256); - - print_caller (caller, 256, frame); - - if (!server_resolve_is_empty (&state->resolve)) { - server_print_resolve (resolve_vars, 256, &state->resolve); - server_print_loc (loc_vars, 256, &state->loc); - } - - if (!server_resolve_is_empty (&state->resolve2)) { - server_print_resolve (resolve2_vars, 256, &state->resolve2); - server_print_loc (loc2_vars, 256, &state->loc2); - } - - server_print_params (other_vars, 512, state); - - switch (frame->root->type) { - case GF_OP_TYPE_FOP_REQUEST: - case GF_OP_TYPE_FOP_REPLY: - op = gf_fop_list[frame->root->op]; - break; - case GF_OP_TYPE_MOP_REQUEST: - case GF_OP_TYPE_MOP_REPLY: - op = gf_mop_list[frame->root->op]; - break; - case GF_OP_TYPE_CBK_REQUEST: - case GF_OP_TYPE_CBK_REPLY: - op = gf_cbk_list[frame->root->op]; - break; - } - - gf_log (this->name, GF_LOG_INFO, - "%s%s%s%s%s%s%s", - gf_fop_list[frame->root->op], caller, - resolve_vars, loc_vars, resolve2_vars, loc2_vars, other_vars); -} - - -static void -server_print_reply (call_frame_t *frame, int op_ret, int op_errno) -{ - server_conf_t *conf = NULL; - server_state_t *state = NULL; - xlator_t *this = NULL; - char caller[512]; - char fdstr[32]; - char *op = "UNKNOWN"; - - this = frame->this; - conf = this->private; - - if (!conf->trace) - return; - - state = CALL_STATE (frame); - - print_caller (caller, 256, frame); - - switch (frame->root->type) { - case GF_OP_TYPE_FOP_REQUEST: - case GF_OP_TYPE_FOP_REPLY: - op = gf_fop_list[frame->root->op]; - break; - case GF_OP_TYPE_MOP_REQUEST: - case GF_OP_TYPE_MOP_REPLY: - op = gf_mop_list[frame->root->op]; - break; - case GF_OP_TYPE_CBK_REQUEST: - case GF_OP_TYPE_CBK_REPLY: - op = gf_cbk_list[frame->root->op]; - break; - } - - fdstr[0] = '\0'; - if (state->fd) - snprintf (fdstr, 32, " fd=%p", state->fd); - - gf_log (this->name, GF_LOG_INFO, - "%s%s => (%d, %d)%s", - op, caller, op_ret, op_errno, fdstr); -} - - - -static void -protocol_server_reply (call_frame_t *frame, int type, int op, - gf_hdr_common_t *hdr, size_t hdrlen, - struct iovec *vector, int count, - struct iobref *iobref) -{ - server_state_t *state = NULL; - xlator_t *bound_xl = NULL; - transport_t *trans = NULL; - int ret = 0; - - xlator_t *this = NULL; - - bound_xl = BOUND_XL (frame); - state = CALL_STATE (frame); - trans = state->trans; - this = frame->this; - - hdr->callid = hton64 (frame->root->unique); - hdr->type = hton32 (type); - hdr->op = hton32 (op); - - server_print_reply (frame, ntoh32 (hdr->rsp.op_ret), - gf_error_to_errno (ntoh32 (hdr->rsp.op_errno))); - - ret = transport_submit (trans, (char *)hdr, hdrlen, vector, - count, iobref); - if (ret < 0) { - gf_log ("protocol/server", GF_LOG_ERROR, - "frame %"PRId64": failed to submit. op= %d, type= %d", - frame->root->unique, op, type); - } - - STACK_DESTROY (frame->root); - - if (state) - free_old_server_state (state); - -} - - -static int -gf_add_locker (struct _lock_table *table, const char *volume, - loc_t *loc, fd_t *fd, pid_t pid) -{ - int32_t ret = -1; - struct _locker *new = NULL; - uint8_t dir = 0; - - new = GF_CALLOC (1, sizeof (struct _locker), - gf_server_mt_locker); - if (new == NULL) { - gf_log ("server", GF_LOG_ERROR, - "failed to allocate memory for \'struct _locker\'"); - goto out; - } - INIT_LIST_HEAD (&new->lockers); - - new->volume = gf_strdup (volume); - - if (fd == NULL) { - loc_copy (&new->loc, loc); - dir = IA_ISDIR (new->loc.inode->ia_type); - } else { - new->fd = fd_ref (fd); - dir = IA_ISDIR (fd->inode->ia_type); - } - - new->pid = pid; - - LOCK (&table->lock); - { - if (dir) - list_add_tail (&new->lockers, &table->dir_lockers); - else - list_add_tail (&new->lockers, &table->file_lockers); - } - UNLOCK (&table->lock); -out: - return ret; -} - - -static int -gf_del_locker (struct _lock_table *table, const char *volume, - loc_t *loc, fd_t *fd, pid_t pid) -{ - struct _locker *locker = NULL; - struct _locker *tmp = NULL; - int32_t ret = 0; - uint8_t dir = 0; - struct list_head *head = NULL; - struct list_head del; - - INIT_LIST_HEAD (&del); - - if (fd) { - dir = IA_ISDIR (fd->inode->ia_type); - } else { - dir = IA_ISDIR (loc->inode->ia_type); - } - - LOCK (&table->lock); - { - if (dir) { - head = &table->dir_lockers; - } else { - head = &table->file_lockers; - } - - list_for_each_entry_safe (locker, tmp, head, lockers) { - if (locker->fd && fd && - (locker->fd == fd) && (locker->pid == pid) - && !strcmp (locker->volume, volume)) { - list_move_tail (&locker->lockers, &del); - } else if (locker->loc.inode && - loc && - (locker->loc.inode == loc->inode) && - (locker->pid == pid) - && !strcmp (locker->volume, volume)) { - list_move_tail (&locker->lockers, &del); - } - } - } - UNLOCK (&table->lock); - - tmp = NULL; - locker = NULL; - - list_for_each_entry_safe (locker, tmp, &del, lockers) { - list_del_init (&locker->lockers); - if (locker->fd) - fd_unref (locker->fd); - else - loc_wipe (&locker->loc); - - GF_FREE (locker->volume); - GF_FREE (locker); - } - - return ret; -} - - -/* - * server_lk_cbk - lk callback for server protocol - * @frame: call frame - * @cookie: - * @this: - * @op_ret: - * @op_errno: - * @lock: - * - * not for external reference - */ -static int -server_lk_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, struct gf_flock *lock) -{ - gf_hdr_common_t *hdr = NULL; - gf_fop_lk_rsp_t *rsp = NULL; - size_t hdrlen = 0; - int32_t gf_errno = 0; - server_state_t *state = NULL; - - hdrlen = gf_hdr_len (rsp, 0); - hdr = gf_hdr_new (rsp, 0); - rsp = gf_param (hdr); - - hdr->rsp.op_ret = hton32 (op_ret); - gf_errno = gf_errno_to_error (op_errno); - hdr->rsp.op_errno = hton32 (gf_errno); - - if (op_ret == 0) { - gf_flock_from_flock (&rsp->flock, lock); - } else if (op_errno != ENOSYS) { - state = CALL_STATE(frame); - - gf_log (this->name, GF_LOG_TRACE, - "%"PRId64": LK %"PRId64" (%"PRId64") ==> %"PRId32" (%s)", - frame->root->unique, state->resolve.fd_no, - state->fd ? state->fd->inode->ino : 0, op_ret, - strerror (op_errno)); - } - - protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_PROTO_FOP_LK, - hdr, hdrlen, NULL, 0, NULL); - - return 0; -} - - -static int -server_inodelk_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno) -{ - server_connection_t *conn = NULL; - gf_hdr_common_t *hdr = NULL; - gf_fop_inodelk_rsp_t *rsp = NULL; - server_state_t *state = NULL; - size_t hdrlen = 0; - int32_t gf_errno = 0; - - conn = SERVER_CONNECTION(frame); - - state = CALL_STATE(frame); - - hdrlen = gf_hdr_len (rsp, 0); - hdr = gf_hdr_new (rsp, 0); - rsp = gf_param (hdr); - - hdr->rsp.op_ret = hton32 (op_ret); - gf_errno = gf_errno_to_error (op_errno); - hdr->rsp.op_errno = hton32 (gf_errno); - - if (op_ret >= 0) { - if (state->flock.l_type == F_UNLCK) - gf_del_locker (conn->ltable, state->volume, - &state->loc, NULL, frame->root->pid); - else - gf_add_locker (conn->ltable, state->volume, - &state->loc, NULL, frame->root->pid); - } else if (op_errno != ENOSYS) { - gf_log (this->name, GF_LOG_TRACE, - "%"PRId64": INODELK %s (%"PRId64") ==> %"PRId32" (%s)", - frame->root->unique, state->loc.path, - state->loc.inode ? state->loc.inode->ino : 0, op_ret, - strerror (op_errno)); - } - - protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_PROTO_FOP_INODELK, - hdr, hdrlen, NULL, 0, NULL); - - return 0; -} - - -static int -server_finodelk_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno) -{ - server_connection_t *conn = NULL; - gf_hdr_common_t *hdr = NULL; - gf_fop_finodelk_rsp_t *rsp = NULL; - server_state_t *state = NULL; - size_t hdrlen = 0; - int32_t gf_errno = 0; - - conn = SERVER_CONNECTION(frame); - - hdrlen = gf_hdr_len (rsp, 0); - hdr = gf_hdr_new (rsp, 0); - rsp = gf_param (hdr); - - hdr->rsp.op_ret = hton32 (op_ret); - gf_errno = gf_errno_to_error (op_errno); - hdr->rsp.op_errno = hton32 (gf_errno); - - state = CALL_STATE(frame); - - if (op_ret >= 0) { - if (state->flock.l_type == F_UNLCK) - gf_del_locker (conn->ltable, state->volume, - NULL, state->fd, - frame->root->pid); - else - gf_add_locker (conn->ltable, state->volume, - NULL, state->fd, - frame->root->pid); - } else if (op_errno != ENOSYS) { - gf_log (this->name, GF_LOG_TRACE, - "%"PRId64": FINODELK %"PRId64" (%"PRId64") ==> %"PRId32" (%s)", - frame->root->unique, state->resolve.fd_no, - state->fd ? state->fd->inode->ino : 0, op_ret, - strerror (op_errno)); - } - - protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_PROTO_FOP_FINODELK, - hdr, hdrlen, NULL, 0, NULL); - - return 0; -} - - -/* - * server_entrylk_cbk - - * @frame: call frame - * @cookie: - * @this: - * @op_ret: - * @op_errno: - * @lock: - * - * not for external reference - */ -static int -server_entrylk_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno) -{ - server_connection_t *conn = NULL; - gf_hdr_common_t *hdr = NULL; - gf_fop_entrylk_rsp_t *rsp = NULL; - server_state_t *state = NULL; - size_t hdrlen = 0; - int32_t gf_errno = 0; - - conn = SERVER_CONNECTION(frame); - - state = CALL_STATE(frame); - - hdrlen = gf_hdr_len (rsp, 0); - hdr = gf_hdr_new (rsp, 0); - rsp = gf_param (hdr); - - hdr->rsp.op_ret = hton32 (op_ret); - gf_errno = gf_errno_to_error (op_errno); - hdr->rsp.op_errno = hton32 (gf_errno); - - if (op_ret >= 0) { - if (state->cmd == ENTRYLK_UNLOCK) - gf_del_locker (conn->ltable, state->volume, - &state->loc, NULL, frame->root->pid); - else - gf_add_locker (conn->ltable, state->volume, - &state->loc, NULL, frame->root->pid); - } else if (op_errno != ENOSYS) { - gf_log (this->name, GF_LOG_TRACE, - "%"PRId64": INODELK %s (%"PRId64") ==> %"PRId32" (%s)", - frame->root->unique, state->loc.path, - state->loc.inode ? state->loc.inode->ino : 0, op_ret, - strerror (op_errno)); - } - - protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_PROTO_FOP_ENTRYLK, - hdr, hdrlen, NULL, 0, NULL); - - return 0; -} - - -static int -server_fentrylk_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno) -{ - server_connection_t *conn = NULL; - gf_hdr_common_t *hdr = NULL; - gf_fop_fentrylk_rsp_t *rsp = NULL; - server_state_t *state = NULL; - size_t hdrlen = 0; - int32_t gf_errno = 0; - - conn = SERVER_CONNECTION(frame); - - hdrlen = gf_hdr_len (rsp, 0); - hdr = gf_hdr_new (rsp, 0); - rsp = gf_param (hdr); - - hdr->rsp.op_ret = hton32 (op_ret); - gf_errno = gf_errno_to_error (op_errno); - hdr->rsp.op_errno = hton32 (gf_errno); - - state = CALL_STATE(frame); - if (op_ret >= 0) { - if (state->cmd == ENTRYLK_UNLOCK) - gf_del_locker (conn->ltable, state->volume, - NULL, state->fd, frame->root->pid); - else - gf_add_locker (conn->ltable, state->volume, - NULL, state->fd, frame->root->pid); - } else if (op_errno != ENOSYS) { - gf_log (this->name, GF_LOG_TRACE, - "%"PRId64": FENTRYLK %"PRId64" (%"PRId64") ==> %"PRId32" (%s)", - frame->root->unique, state->resolve.fd_no, - state->fd ? state->fd->inode->ino : 0, op_ret, - strerror (op_errno)); - } - - protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_PROTO_FOP_FENTRYLK, - hdr, hdrlen, NULL, 0, NULL); - - return 0; -} - - -/* - * server_access_cbk - access callback for server protocol - * @frame: call frame - * @cookie: - * @this: - * @op_ret: - * @op_errno: - * - * not for external reference - */ -static int -server_access_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno) -{ - gf_hdr_common_t *hdr = NULL; - gf_fop_access_rsp_t *rsp = NULL; - server_state_t *state = NULL; - size_t hdrlen = 0; - int32_t gf_errno = 0; - - state = CALL_STATE(frame); - - hdrlen = gf_hdr_len (rsp, 0); - hdr = gf_hdr_new (rsp, 0); - rsp = gf_param (hdr); - - hdr->rsp.op_ret = hton32 (op_ret); - gf_errno = gf_errno_to_error (op_errno); - hdr->rsp.op_errno = hton32 (gf_errno); - - protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_PROTO_FOP_ACCESS, - hdr, hdrlen, NULL, 0, NULL); - - return 0; -} - -/* - * server_rmdir_cbk - rmdir callback for server protocol - * @frame: call frame - * @cookie: - * @this: - * @op_ret: - * @op_errno: - * - * not for external reference - */ -static int -server_rmdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, struct iatt *preparent, - struct iatt *postparent) -{ - gf_hdr_common_t *hdr = NULL; - gf_fop_rmdir_rsp_t *rsp = NULL; - server_state_t *state = NULL; - int32_t gf_errno = 0; - size_t hdrlen = 0; - inode_t *parent = NULL; - - state = CALL_STATE(frame); - - if (op_ret == 0) { - inode_unlink (state->loc.inode, state->loc.parent, - state->loc.name); - parent = inode_parent (state->loc.inode, 0, NULL); - if (parent) - inode_unref (parent); - else - inode_forget (state->loc.inode, 0); - } else { - gf_log (this->name, GF_LOG_TRACE, - "%"PRId64": RMDIR %s (%"PRId64") ==> %"PRId32" (%s)", - frame->root->unique, state->loc.path, - state->loc.inode ? state->loc.inode->ino : 0, - op_ret, strerror (op_errno)); - } - - hdrlen = gf_hdr_len (rsp, 0); - hdr = gf_hdr_new (rsp, 0); - rsp = gf_param (hdr); - - hdr->rsp.op_ret = hton32 (op_ret); - gf_errno = gf_errno_to_error (op_errno); - hdr->rsp.op_errno = hton32 (gf_errno); - - if (op_ret == 0) { - gf_stat_from_iatt (&rsp->preparent, preparent); - gf_stat_from_iatt (&rsp->postparent, postparent); - } - - protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_PROTO_FOP_RMDIR, - hdr, hdrlen, NULL, 0, NULL); - - return 0; -} - -/* - * server_mkdir_cbk - mkdir callback for server protocol - * @frame: call frame - * @cookie: - * @this: - * @op_ret: - * @op_errno: - * @stbuf: - * - * not for external reference - */ -static int -server_mkdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, inode_t *inode, - struct iatt *stbuf, struct iatt *preparent, - struct iatt *postparent) -{ - gf_hdr_common_t *hdr = NULL; - gf_fop_mkdir_rsp_t *rsp = NULL; - server_state_t *state = NULL; - size_t hdrlen = 0; - int32_t gf_errno = 0; - inode_t *link_inode = NULL; - - state = CALL_STATE(frame); - - hdrlen = gf_hdr_len (rsp, 0); - hdr = gf_hdr_new (rsp, 0); - rsp = gf_param (hdr); - - hdr->rsp.op_ret = hton32 (op_ret); - gf_errno = gf_errno_to_error (op_errno); - hdr->rsp.op_errno = hton32 (gf_errno); - - if (op_ret >= 0) { - gf_stat_from_iatt (&rsp->stat, stbuf); - gf_stat_from_iatt (&rsp->preparent, preparent); - gf_stat_from_iatt (&rsp->postparent, postparent); - - link_inode = inode_link (inode, state->loc.parent, - state->loc.name, stbuf); - inode_lookup (link_inode); - inode_unref (link_inode); - } else { - gf_log (this->name, GF_LOG_TRACE, - "%"PRId64": MKDIR %s ==> %"PRId32" (%s)", - frame->root->unique, state->loc.path, - op_ret, strerror (op_errno)); - } - - protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_PROTO_FOP_MKDIR, - hdr, hdrlen, NULL, 0, NULL); - - return 0; -} - -/* - * server_mknod_cbk - mknod callback for server protocol - * @frame: call frame - * @cookie: - * @this: - * @op_ret: - * @op_errno: - * @stbuf: - * - * not for external reference - */ -static int -server_mknod_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, - inode_t *inode, struct iatt *stbuf, struct iatt *preparent, - struct iatt *postparent) -{ - gf_hdr_common_t *hdr = NULL; - gf_fop_mknod_rsp_t *rsp = NULL; - server_state_t *state = NULL; - int32_t gf_errno = 0; - size_t hdrlen = 0; - inode_t *link_inode = NULL; - - state = CALL_STATE(frame); - - hdrlen = gf_hdr_len (rsp, 0); - hdr = gf_hdr_new (rsp, 0); - rsp = gf_param (hdr); - - hdr->rsp.op_ret = hton32 (op_ret); - gf_errno = gf_errno_to_error (op_errno); - hdr->rsp.op_errno = hton32 (gf_errno); - - if (op_ret >= 0) { - gf_stat_from_iatt (&rsp->stat, stbuf); - gf_stat_from_iatt (&rsp->preparent, preparent); - gf_stat_from_iatt (&rsp->postparent, postparent); - - link_inode = inode_link (inode, state->loc.parent, - state->loc.name, stbuf); - inode_lookup (link_inode); - inode_unref (link_inode); - } else { - gf_log (this->name, GF_LOG_TRACE, - "%"PRId64": MKNOD %s ==> %"PRId32" (%s)", - frame->root->unique, state->loc.path, - op_ret, strerror (op_errno)); - } - - protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_PROTO_FOP_MKNOD, - hdr, hdrlen, NULL, 0, NULL); - - return 0; -} - -/* - * server_fsyncdir_cbk - fsyncdir callback for server protocol - * @frame: call frame - * @cookie: - * @this: - * @op_ret: - * @op_errno: - * - * not for external reference - */ -static int -server_fsyncdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno) -{ - gf_hdr_common_t *hdr = NULL; - gf_fop_fsyncdir_rsp_t *rsp = NULL; - size_t hdrlen = 0; - int32_t gf_errno = 0; - server_state_t *state = NULL; - - hdrlen = gf_hdr_len (rsp, 0); - hdr = gf_hdr_new (rsp, 0); - rsp = gf_param (hdr); - - if (op_ret < 0) { - state = CALL_STATE(frame); - - gf_log (this->name, GF_LOG_TRACE, - "%"PRId64": FSYNCDIR %"PRId64" (%"PRId64") ==> %"PRId32" (%s)", - frame->root->unique, state->resolve.fd_no, - state->fd ? state->fd->inode->ino : 0, op_ret, - strerror (op_errno)); - } - - hdr->rsp.op_ret = hton32 (op_ret); - gf_errno = gf_errno_to_error (op_errno); - hdr->rsp.op_errno = hton32 (gf_errno); - - protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_PROTO_FOP_FSYNCDIR, - hdr, hdrlen, NULL, 0, NULL); - - return 0; -} - - - -/* - * server_readdir_cbk - getdents callback for server protocol - * @frame: call frame - * @cookie: - * @this: - * @op_ret: - * @op_errno: - * - * not for external reference - */ -static int -server_readdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, gf_dirent_t *entries) -{ - gf_hdr_common_t *hdr = NULL; - gf_fop_readdir_rsp_t *rsp = NULL; - size_t hdrlen = 0; - size_t buf_size = 0; - int32_t gf_errno = 0; - server_state_t *state = NULL; - - if (op_ret > 0) - buf_size = gf_dirent_serialize (entries, NULL, 0); - - hdrlen = gf_hdr_len (rsp, buf_size); - hdr = gf_hdr_new (rsp, buf_size); - rsp = gf_param (hdr); - - hdr->rsp.op_ret = hton32 (op_ret); - gf_errno = gf_errno_to_error (op_errno); - hdr->rsp.op_errno = hton32 (gf_errno); - - if (op_ret > 0) { - rsp->size = hton32 (buf_size); - gf_dirent_serialize (entries, rsp->buf, buf_size); - } else { - state = CALL_STATE(frame); - - gf_log (this->name, GF_LOG_TRACE, - "%"PRId64": READDIR %"PRId64" (%"PRId64") ==> %"PRId32" (%s)", - frame->root->unique, state->resolve.fd_no, - state->fd ? state->fd->inode->ino : 0, op_ret, - strerror (op_errno)); - } - - protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_PROTO_FOP_READDIR, - hdr, hdrlen, NULL, 0, NULL); - - return 0; -} - - -/* - * server_releasedir_cbk - releasedir callback for server protocol - * @frame: call frame - * @cookie: - * @this: - * @op_ret: return value - * @op_errno: errno - * - * not for external reference - */ -static int -server_releasedir_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno) -{ - gf_hdr_common_t *hdr = NULL; - gf_cbk_releasedir_rsp_t *rsp = NULL; - size_t hdrlen = 0; - int32_t gf_errno = 0; - - hdrlen = gf_hdr_len (rsp, 0); - hdr = gf_hdr_new (rsp, 0); - rsp = gf_param (hdr); - - hdr->rsp.op_ret = hton32 (op_ret); - gf_errno = gf_errno_to_error (op_errno); - hdr->rsp.op_errno = hton32 (gf_errno); - - protocol_server_reply (frame, GF_OP_TYPE_CBK_REPLY, GF_CBK_RELEASEDIR, - hdr, hdrlen, NULL, 0, NULL); - - return 0; -} - - -/* - * server_opendir_cbk - opendir callback for server protocol - * @frame: call frame - * @cookie: - * @this: - * @op_ret: return value - * @op_errno: errno - * @fd: file descriptor structure of opened directory - * - * not for external reference - */ -static int -server_opendir_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, fd_t *fd) -{ - server_connection_t *conn = NULL; - gf_hdr_common_t *hdr = NULL; - gf_fop_opendir_rsp_t *rsp = NULL; - server_state_t *state = NULL; - size_t hdrlen = 0; - int32_t gf_errno = 0; - uint64_t fd_no = 0; - - conn = SERVER_CONNECTION (frame); - - state = CALL_STATE (frame); - - if (op_ret >= 0) { - fd_bind (fd); - - fd_no = gf_fd_unused_get (conn->fdtable, fd); - fd_ref (fd); // on behalf of the client - } else { - gf_log (this->name, GF_LOG_TRACE, - "%"PRId64": OPENDIR %s (%"PRId64") ==> %"PRId32" (%s)", - frame->root->unique, state->loc.path, - state->loc.inode ? state->loc.inode->ino : 0, - op_ret, strerror (op_errno)); - } - - hdrlen = gf_hdr_len (rsp, 0); - hdr = gf_hdr_new (rsp, 0); - rsp = gf_param (hdr); - - hdr->rsp.op_ret = hton32 (op_ret); - gf_errno = gf_errno_to_error (op_errno); - hdr->rsp.op_errno = hton32 (gf_errno); - rsp->fd = hton64 (fd_no); - - protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_PROTO_FOP_OPENDIR, - hdr, hdrlen, NULL, 0, NULL); - - return 0; -} - -/* - * server_statfs_cbk - statfs callback for server protocol - * @frame: call frame - * @cookie: - * @this: - * @op_ret: return value - * @op_errno: errno - * @buf: - * - * not for external reference - */ -static int -server_statfs_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, struct statvfs *buf) -{ - gf_hdr_common_t *hdr = NULL; - gf_fop_statfs_rsp_t *rsp = NULL; - server_state_t *state = NULL; - size_t hdrlen = 0; - int32_t gf_errno = 0; - - state = CALL_STATE (frame); - - hdrlen = gf_hdr_len (rsp, 0); - hdr = gf_hdr_new (rsp, 0); - rsp = gf_param (hdr); - - hdr->rsp.op_ret = hton32 (op_ret); - gf_errno = gf_errno_to_error (op_errno); - hdr->rsp.op_errno = hton32 (gf_errno); - - if (op_ret >= 0) { - gf_statfs_from_statfs (&rsp->statfs, buf); - } - - protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_PROTO_FOP_STATFS, - hdr, hdrlen, NULL, 0, NULL); - - return 0; -} - -/* - * server_removexattr_cbk - removexattr callback for server protocol - * @frame: call frame - * @cookie: - * @this: - * @op_ret: return value - * @op_errno: errno - * - * not for external reference - */ -static int -server_removexattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno) -{ - gf_hdr_common_t *hdr = NULL; - gf_fop_removexattr_rsp_t *rsp = NULL; - server_state_t *state = NULL; - size_t hdrlen = 0; - int32_t gf_errno = 0; - - state = CALL_STATE (frame); - - hdrlen = gf_hdr_len (rsp, 0); - hdr = gf_hdr_new (rsp, 0); - rsp = gf_param (hdr); - - hdr->rsp.op_ret = hton32 (op_ret); - gf_errno = gf_errno_to_error (op_errno); - hdr->rsp.op_errno = hton32 (gf_errno); - - protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_PROTO_FOP_REMOVEXATTR, - hdr, hdrlen, NULL, 0, NULL); - - return 0; -} - -/* - * server_getxattr_cbk - getxattr callback for server protocol - * @frame: call frame - * @cookie: - * @this: - * @op_ret: return value - * @op_errno: errno - * @value: - * - * not for external reference - */ -static int -server_getxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, dict_t *dict) -{ - gf_hdr_common_t *hdr = NULL; - gf_fop_getxattr_rsp_t *rsp = NULL; - server_state_t *state = NULL; - size_t hdrlen = 0; - int32_t len = 0; - int32_t gf_errno = 0; - int32_t ret = -1; - - state = CALL_STATE (frame); - - if (op_ret >= 0) { - len = dict_serialized_length (dict); - if (len < 0) { - gf_log (this->name, GF_LOG_ERROR, - "%s (%"PRId64"): failed to get serialized length of " - "reply dict", - state->loc.path, state->resolve.ino); - op_ret = -1; - op_errno = EINVAL; - len = 0; - } - } - - hdrlen = gf_hdr_len (rsp, len + 1); - hdr = gf_hdr_new (rsp, len + 1); - rsp = gf_param (hdr); - - if (op_ret >= 0) { - ret = dict_serialize (dict, rsp->dict); - if (len < 0) { - gf_log (this->name, GF_LOG_ERROR, - "%s (%"PRId64"): failed to serialize reply dict", - state->loc.path, state->resolve.ino); - op_ret = -1; - op_errno = -ret; - } - } - rsp->dict_len = hton32 (len); - - hdr->rsp.op_ret = hton32 (op_ret); - gf_errno = gf_errno_to_error (op_errno); - hdr->rsp.op_errno = hton32 (gf_errno); - - protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_PROTO_FOP_GETXATTR, - hdr, hdrlen, NULL, 0, NULL); - - return 0; -} - - -static int -server_fgetxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, dict_t *dict) -{ - gf_hdr_common_t *hdr = NULL; - gf_fop_fgetxattr_rsp_t *rsp = NULL; - server_state_t *state = NULL; - size_t hdrlen = 0; - int32_t len = 0; - int32_t gf_errno = 0; - int32_t ret = -1; - - state = CALL_STATE (frame); - - if (op_ret >= 0) { - len = dict_serialized_length (dict); - if (len < 0) { - gf_log (this->name, GF_LOG_ERROR, - "%s (%"PRId64"): failed to get serialized length of " - "reply dict", - state->loc.path, state->resolve.ino); - op_ret = -1; - op_errno = EINVAL; - len = 0; - } - } - - hdrlen = gf_hdr_len (rsp, len + 1); - hdr = gf_hdr_new (rsp, len + 1); - rsp = gf_param (hdr); - - if (op_ret >= 0) { - ret = dict_serialize (dict, rsp->dict); - if (len < 0) { - gf_log (this->name, GF_LOG_ERROR, - "%s (%"PRId64"): failed to serialize reply dict", - state->loc.path, state->resolve.ino); - op_ret = -1; - op_errno = -ret; - } - } - rsp->dict_len = hton32 (len); - - hdr->rsp.op_ret = hton32 (op_ret); - gf_errno = gf_errno_to_error (op_errno); - hdr->rsp.op_errno = hton32 (gf_errno); - - protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_PROTO_FOP_FGETXATTR, - hdr, hdrlen, NULL, 0, NULL); - - return 0; -} - - -/* - * server_setxattr_cbk - setxattr callback for server protocol - * @frame: call frame - * @cookie: - * @this: - * @op_ret: return value - * @op_errno: errno - * - * not for external reference - */ -static int -server_setxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno) -{ - gf_hdr_common_t *hdr = NULL; - gf_fop_setxattr_rsp_t *rsp = NULL; - server_state_t *state = NULL; - size_t hdrlen = 0; - int32_t gf_errno = 0; - - state = CALL_STATE (frame); - - hdrlen = gf_hdr_len (rsp, 0); - hdr = gf_hdr_new (rsp, 0); - rsp = gf_param (hdr); - - hdr->rsp.op_ret = hton32 (op_ret); - gf_errno = gf_errno_to_error (op_errno); - hdr->rsp.op_errno = hton32 (gf_errno); - - protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_PROTO_FOP_SETXATTR, - hdr, hdrlen, NULL, 0, NULL); - - return 0; -} - - -static int -server_fsetxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno) -{ - gf_hdr_common_t *hdr = NULL; - gf_fop_fsetxattr_rsp_t *rsp = NULL; - server_state_t *state = NULL; - size_t hdrlen = 0; - int32_t gf_errno = 0; - - state = CALL_STATE(frame); - - hdrlen = gf_hdr_len (rsp, 0); - hdr = gf_hdr_new (rsp, 0); - rsp = gf_param (hdr); - - hdr->rsp.op_ret = hton32 (op_ret); - gf_errno = gf_errno_to_error (op_errno); - hdr->rsp.op_errno = hton32 (gf_errno); - - protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_PROTO_FOP_FSETXATTR, - hdr, hdrlen, NULL, 0, NULL); - - return 0; -} - - -/* - * server_rename_cbk - rename callback for server protocol - * @frame: call frame - * @cookie: - * @this: - * @op_ret: return value - * @op_errno: errno - * - * not for external reference - */ -static int -server_rename_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, struct iatt *stbuf, - struct iatt *preoldparent, struct iatt *postoldparent, - struct iatt *prenewparent, struct iatt *postnewparent) -{ - gf_hdr_common_t *hdr = NULL; - gf_fop_rename_rsp_t *rsp = NULL; - server_state_t *state = NULL; - size_t hdrlen = 0; - int32_t gf_errno = 0; - - state = CALL_STATE(frame); - - hdrlen = gf_hdr_len (rsp, 0); - hdr = gf_hdr_new (rsp, 0); - rsp = gf_param (hdr); - - hdr->rsp.op_ret = hton32 (op_ret); - gf_errno = gf_errno_to_error (op_errno); - hdr->rsp.op_errno = hton32 (gf_errno); - - if (op_ret == 0) { - stbuf->ia_ino = state->loc.inode->ino; - stbuf->ia_type = state->loc.inode->ia_type; - - gf_log (state->bound_xl->name, GF_LOG_TRACE, - "%"PRId64": RENAME_CBK (%"PRId64") %"PRId64"/%s " - "==> %"PRId64"/%s", - frame->root->unique, state->loc.inode->ino, - state->loc.parent->ino, state->loc.name, - state->loc2.parent->ino, state->loc2.name); - - inode_rename (state->itable, - state->loc.parent, state->loc.name, - state->loc2.parent, state->loc2.name, - state->loc.inode, stbuf); - gf_stat_from_iatt (&rsp->stat, stbuf); - - gf_stat_from_iatt (&rsp->preoldparent, preoldparent); - gf_stat_from_iatt (&rsp->postoldparent, postoldparent); - - gf_stat_from_iatt (&rsp->prenewparent, prenewparent); - gf_stat_from_iatt (&rsp->postnewparent, postnewparent); - } - - protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_PROTO_FOP_RENAME, - hdr, hdrlen, NULL, 0, NULL); - - return 0; -} - - -/* - * server_unlink_cbk - unlink callback for server protocol - * @frame: call frame - * @cookie: - * @this: - * @op_ret: return value - * @op_errno: errno - * - * not for external reference - */ -static int -server_unlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, struct iatt *preparent, - struct iatt *postparent) -{ - gf_hdr_common_t *hdr = NULL; - gf_fop_unlink_rsp_t *rsp = NULL; - server_state_t *state = NULL; - size_t hdrlen = 0; - int32_t gf_errno = 0; - inode_t *parent = NULL; - - state = CALL_STATE(frame); - - if (op_ret == 0) { - gf_log (state->bound_xl->name, GF_LOG_TRACE, - "%"PRId64": UNLINK_CBK %"PRId64"/%s (%"PRId64")", - frame->root->unique, state->loc.parent->ino, - state->loc.name, state->loc.inode->ino); - - inode_unlink (state->loc.inode, state->loc.parent, - state->loc.name); - - parent = inode_parent (state->loc.inode, 0, NULL); - if (parent) - inode_unref (parent); - else - inode_forget (state->loc.inode, 0); - } else { - gf_log (this->name, GF_LOG_DEBUG, - "%"PRId64": UNLINK %s (%"PRId64") ==> %"PRId32" (%s)", - frame->root->unique, state->loc.path, - state->loc.inode ? state->loc.inode->ino : 0, - op_ret, strerror (op_errno)); - } - - hdrlen = gf_hdr_len (rsp, 0); - hdr = gf_hdr_new (rsp, 0); - rsp = gf_param (hdr); - - hdr->rsp.op_ret = hton32 (op_ret); - gf_errno = gf_errno_to_error (op_errno); - hdr->rsp.op_errno = hton32 (gf_errno); - - if (op_ret == 0) { - gf_stat_from_iatt (&rsp->preparent, preparent); - gf_stat_from_iatt (&rsp->postparent, postparent); - } - - protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_PROTO_FOP_UNLINK, - hdr, hdrlen, NULL, 0, NULL); - - return 0; -} - -/* - * server_symlink_cbk - symlink callback for server protocol - * @frame: call frame - * @cookie: - * @this: - * @op_ret: return value - * @op_errno: errno - * - * not for external reference - */ -static int -server_symlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, inode_t *inode, - struct iatt *stbuf, struct iatt *preparent, - struct iatt *postparent) -{ - gf_hdr_common_t *hdr = NULL; - gf_fop_symlink_rsp_t *rsp = NULL; - server_state_t *state = NULL; - size_t hdrlen = 0; - int32_t gf_errno = 0; - inode_t *link_inode = NULL; - - state = CALL_STATE(frame); - - hdrlen = gf_hdr_len (rsp, 0); - hdr = gf_hdr_new (rsp, 0); - rsp = gf_param (hdr); - - hdr->rsp.op_ret = hton32 (op_ret); - gf_errno = gf_errno_to_error (op_errno); - hdr->rsp.op_errno = hton32 (gf_errno_to_error (op_errno)); - - if (op_ret >= 0) { - gf_stat_from_iatt (&rsp->stat, stbuf); - gf_stat_from_iatt (&rsp->preparent, preparent); - gf_stat_from_iatt (&rsp->postparent, postparent); - - link_inode = inode_link (inode, state->loc.parent, - state->loc.name, stbuf); - inode_lookup (link_inode); - inode_unref (link_inode); - } else { - gf_log (this->name, GF_LOG_DEBUG, - "%"PRId64": SYMLINK %s (%"PRId64") ==> %"PRId32" (%s)", - frame->root->unique, state->loc.path, - state->loc.inode ? state->loc.inode->ino : 0, - op_ret, strerror (op_errno)); - } - - protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_PROTO_FOP_SYMLINK, - hdr, hdrlen, NULL, 0, NULL); - - return 0; -} - - -/* - * server_link_cbk - link callback for server protocol - * @frame: call frame - * @this: - * @op_ret: - * @op_errno: - * @stbuf: - * - * not for external reference - */ -static int -server_link_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, inode_t *inode, - struct iatt *stbuf, struct iatt *preparent, - struct iatt *postparent) -{ - gf_hdr_common_t *hdr = NULL; - gf_fop_link_rsp_t *rsp = NULL; - server_state_t *state = NULL; - int32_t gf_errno = 0; - size_t hdrlen = 0; - inode_t *link_inode = NULL; - - state = CALL_STATE(frame); - - hdrlen = gf_hdr_len (rsp, 0); - hdr = gf_hdr_new (rsp, 0); - rsp = gf_param (hdr); - - hdr->rsp.op_ret = hton32 (op_ret); - gf_errno = gf_errno_to_error (op_errno); - hdr->rsp.op_errno = hton32 (gf_errno); - - if (op_ret == 0) { - stbuf->ia_ino = state->loc.inode->ino; - - gf_stat_from_iatt (&rsp->stat, stbuf); - gf_stat_from_iatt (&rsp->preparent, preparent); - gf_stat_from_iatt (&rsp->postparent, postparent); - - gf_log (state->bound_xl->name, GF_LOG_TRACE, - "%"PRId64": LINK (%"PRId64") %"PRId64"/%s ==> %"PRId64"/%s", - frame->root->unique, inode->ino, - state->loc2.parent->ino, - state->loc2.name, state->loc.parent->ino, - state->loc.name); - - link_inode = inode_link (inode, state->loc2.parent, - state->loc2.name, stbuf); - inode_unref (link_inode); - } else { - gf_log (state->bound_xl->name, GF_LOG_DEBUG, - "%"PRId64": LINK (%"PRId64") %"PRId64"/%s ==> %"PRId64"/%s " - " ==> %"PRId32" (%s)", - frame->root->unique, state->resolve2.ino, - state->resolve2.par, - state->resolve2.bname, state->resolve.par, - state->resolve.bname, - op_ret, strerror (op_errno)); - } - - protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_PROTO_FOP_LINK, - hdr, hdrlen, NULL, 0, NULL); - - return 0; -} - - -/* - * server_truncate_cbk - truncate callback for server protocol - * @frame: call frame - * @cookie: - * @this: - * @op_ret: - * @op_errno: - * @stbuf: - * - * not for external reference - */ -static int -server_truncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, struct iatt *prebuf, - struct iatt *postbuf) -{ - gf_hdr_common_t *hdr = NULL; - gf_fop_truncate_rsp_t *rsp = NULL; - server_state_t *state = NULL; - size_t hdrlen = 0; - int32_t gf_errno = 0; - - state = CALL_STATE (frame); - - hdrlen = gf_hdr_len (rsp, 0); - hdr = gf_hdr_new (rsp, 0); - rsp = gf_param (hdr); - - hdr->rsp.op_ret = hton32 (op_ret); - gf_errno = gf_errno_to_error (op_errno); - hdr->rsp.op_errno = hton32 (gf_errno); - - if (op_ret == 0) { - gf_stat_from_iatt (&rsp->prestat, prebuf); - gf_stat_from_iatt (&rsp->poststat, postbuf); - } else { - gf_log (this->name, GF_LOG_DEBUG, - "%"PRId64": TRUNCATE %s (%"PRId64") ==> %"PRId32" (%s)", - frame->root->unique, state->loc.path, - state->loc.inode ? state->loc.inode->ino : 0, - op_ret, strerror (op_errno)); - } - - protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_PROTO_FOP_TRUNCATE, - hdr, hdrlen, NULL, 0, NULL); - - return 0; -} - -/* - * server_fstat_cbk - fstat callback for server protocol - * @frame: call frame - * @cookie: - * @this: - * @op_ret: - * @op_errno: - * @stbuf: - * - * not for external reference - */ -static int -server_fstat_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, struct iatt *stbuf) -{ - gf_hdr_common_t *hdr = NULL; - gf_fop_fstat_rsp_t *rsp = NULL; - size_t hdrlen = 0; - int32_t gf_errno = 0; - server_state_t *state = NULL; - - hdrlen = gf_hdr_len (rsp, 0); - hdr = gf_hdr_new (rsp, 0); - rsp = gf_param (hdr); - - hdr->rsp.op_ret = hton32 (op_ret); - gf_errno = gf_errno_to_error (op_errno); - hdr->rsp.op_errno = hton32 (gf_errno); - - if (op_ret == 0) { - gf_stat_from_iatt (&rsp->stat, stbuf); - } else { - state = CALL_STATE(frame); - - gf_log (this->name, GF_LOG_DEBUG, - "%"PRId64": FSTAT %"PRId64" (%"PRId64") ==> %"PRId32" (%s)", - frame->root->unique, state->resolve.fd_no, - state->fd ? state->fd->inode->ino : 0, op_ret, - strerror (op_errno)); - } - - protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_PROTO_FOP_FSTAT, - hdr, hdrlen, NULL, 0, NULL); - - return 0; -} - -/* - * server_ftruncate_cbk - ftruncate callback for server protocol - * @frame: call frame - * @cookie: - * @this: - * @op_ret: - * @op_errno: - * @stbuf: - * - * not for external reference - */ -static int -server_ftruncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, struct iatt *prebuf, - struct iatt *postbuf) -{ - gf_hdr_common_t *hdr = NULL; - gf_fop_ftruncate_rsp_t *rsp = NULL; - size_t hdrlen = 0; - int32_t gf_errno = 0; - server_state_t *state = NULL; - - hdrlen = gf_hdr_len (rsp, 0); - hdr = gf_hdr_new (rsp, 0); - rsp = gf_param (hdr); - - hdr->rsp.op_ret = hton32 (op_ret); - gf_errno = gf_errno_to_error (op_errno); - hdr->rsp.op_errno = hton32 (gf_errno); - - if (op_ret == 0) { - gf_stat_from_iatt (&rsp->prestat, prebuf); - gf_stat_from_iatt (&rsp->poststat, postbuf); - } else { - state = CALL_STATE (frame); - - gf_log (this->name, GF_LOG_DEBUG, - "%"PRId64": FTRUNCATE %"PRId64" (%"PRId64") ==> %"PRId32" (%s)", - frame->root->unique, state->resolve.fd_no, - state->fd ? state->fd->inode->ino : 0, op_ret, - strerror (op_errno)); - } - - protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_PROTO_FOP_FTRUNCATE, - hdr, hdrlen, NULL, 0, NULL); - - return 0; -} - - -/* - * server_flush_cbk - flush callback for server protocol - * @frame: call frame - * @cookie: - * @this: - * @op_ret: - * @op_errno: - * - * not for external reference - */ -static int -server_flush_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno) -{ - gf_hdr_common_t *hdr = NULL; - gf_fop_flush_rsp_t *rsp = NULL; - size_t hdrlen = 0; - int32_t gf_errno = 0; - server_state_t *state = NULL; - - if (op_ret < 0) { - state = CALL_STATE(frame); - - gf_log (this->name, GF_LOG_DEBUG, - "%"PRId64": FLUSH %"PRId64" (%"PRId64") ==> %"PRId32" (%s)", - frame->root->unique, state->resolve.fd_no, - state->fd ? state->fd->inode->ino : 0, op_ret, - strerror (op_errno)); - } - - hdrlen = gf_hdr_len (rsp, 0); - hdr = gf_hdr_new (rsp, 0); - - hdr->rsp.op_ret = hton32 (op_ret); - gf_errno = gf_errno_to_error (op_errno); - hdr->rsp.op_errno = hton32 (gf_errno); - - protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_PROTO_FOP_FLUSH, - hdr, hdrlen, NULL, 0, NULL); - - return 0; -} - -/* - * server_fsync_cbk - fsync callback for server protocol - * @frame: call frame - * @cookie: - * @this: - * @op_ret: - * @op_errno: - * - * not for external reference - */ -static int -server_fsync_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, struct iatt *prebuf, - struct iatt *postbuf) -{ - gf_hdr_common_t *hdr = NULL; - gf_fop_fsync_rsp_t *rsp = NULL; - size_t hdrlen = 0; - int32_t gf_errno = 0; - server_state_t *state = NULL; - - if (op_ret < 0) { - state = CALL_STATE(frame); - - gf_log (this->name, GF_LOG_DEBUG, - "%"PRId64": FSYNC %"PRId64" (%"PRId64") ==> %"PRId32" (%s)", - frame->root->unique, state->resolve.fd_no, - state->fd ? state->fd->inode->ino : 0, op_ret, - strerror (op_errno)); - } - - hdrlen = gf_hdr_len (rsp, 0); - hdr = gf_hdr_new (rsp, 0); - rsp = gf_param (hdr); - - hdr->rsp.op_ret = hton32 (op_ret); - gf_errno = gf_errno_to_error (op_errno); - hdr->rsp.op_errno = hton32 (gf_errno); - - if (op_ret >= 0) { - gf_stat_from_iatt (&(rsp->prestat), prebuf); - gf_stat_from_iatt (&(rsp->poststat), postbuf); - } - - protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_PROTO_FOP_FSYNC, - hdr, hdrlen, NULL, 0, NULL); - - return 0; -} - -/* - * server_release_cbk - rleease callback for server protocol - * @frame: call frame - * @cookie: - * @this: - * @op_ret: - * @op_errno: - * - * not for external reference - */ -static int -server_release_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno) -{ - gf_hdr_common_t *hdr = NULL; - gf_cbk_release_rsp_t *rsp = NULL; - size_t hdrlen = 0; - int32_t gf_errno = 0; - - hdrlen = gf_hdr_len (rsp, 0); - hdr = gf_hdr_new (rsp, 0); - - hdr->rsp.op_ret = hton32 (op_ret); - gf_errno = gf_errno_to_error (op_errno); - hdr->rsp.op_errno = hton32 (gf_errno); - - protocol_server_reply (frame, GF_OP_TYPE_CBK_REPLY, GF_CBK_RELEASE, - hdr, hdrlen, NULL, 0, NULL); - - return 0; -} - - -/* - * server_writev_cbk - writev callback for server protocol - * @frame: call frame - * @cookie: - * @this: - * @op_ret: - * @op_errno: - * - * not for external reference - */ - -static int -server_writev_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, struct iatt *prebuf, - struct iatt *postbuf) -{ - gf_hdr_common_t *hdr = NULL; - gf_fop_write_rsp_t *rsp = NULL; - size_t hdrlen = 0; - int32_t gf_errno = 0; - server_state_t *state = NULL; - - hdrlen = gf_hdr_len (rsp, 0); - hdr = gf_hdr_new (rsp, 0); - rsp = gf_param (hdr); - - hdr->rsp.op_ret = hton32 (op_ret); - gf_errno = gf_errno_to_error (op_errno); - hdr->rsp.op_errno = hton32 (gf_errno_to_error (op_errno)); - - if (op_ret >= 0) { - gf_stat_from_iatt (&rsp->prestat, prebuf); - gf_stat_from_iatt (&rsp->poststat, postbuf); - } else { - state = CALL_STATE(frame); - - gf_log (this->name, GF_LOG_DEBUG, - "%"PRId64": WRITEV %"PRId64" (%"PRId64") ==> %"PRId32" (%s)", - frame->root->unique, state->resolve.fd_no, - state->fd ? state->fd->inode->ino : 0, op_ret, - strerror (op_errno)); - } - - protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_PROTO_FOP_WRITE, - hdr, hdrlen, NULL, 0, NULL); - - return 0; -} - - -/* - * server_readv_cbk - readv callback for server protocol - * @frame: call frame - * @cookie: - * @this: - * @op_ret: - * @op_errno: - * @vector: - * @count: - * - * not for external reference - */ -static int -server_readv_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, - struct iovec *vector, int32_t count, - struct iatt *stbuf, struct iobref *iobref) -{ - gf_hdr_common_t *hdr = NULL; - gf_fop_read_rsp_t *rsp = NULL; - size_t hdrlen = 0; - int32_t gf_errno = 0; - server_state_t *state = NULL; - - hdrlen = gf_hdr_len (rsp, 0); - hdr = gf_hdr_new (rsp, 0); - rsp = gf_param (hdr); - - hdr->rsp.op_ret = hton32 (op_ret); - gf_errno = gf_errno_to_error (op_errno); - hdr->rsp.op_errno = hton32 (gf_errno); - - if (op_ret >= 0) { - gf_stat_from_iatt (&rsp->stat, stbuf); - } else { - state = CALL_STATE(frame); - - gf_log (this->name, GF_LOG_DEBUG, - "%"PRId64": READV %"PRId64" (%"PRId64") ==> %"PRId32" (%s)", - frame->root->unique, state->resolve.fd_no, - state->fd ? state->fd->inode->ino : 0, op_ret, - strerror (op_errno)); - } - - protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_PROTO_FOP_READ, - hdr, hdrlen, vector, count, iobref); - - return 0; -} - - -/* - * server_open_cbk - open callback for server protocol - * @frame: call frame - * @cookie: - * @this: - * @op_ret: - * @op_errno: - * @fd: - * - * not for external reference - */ -static int -server_open_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, fd_t *fd) -{ - server_connection_t *conn = NULL; - gf_hdr_common_t *hdr = NULL; - gf_fop_open_rsp_t *rsp = NULL; - server_state_t *state = NULL; - size_t hdrlen = 0; - int32_t gf_errno = 0; - uint64_t fd_no = 0; - - conn = SERVER_CONNECTION (frame); - - state = CALL_STATE (frame); - - if (op_ret >= 0) { - fd_bind (fd); - - fd_no = gf_fd_unused_get (conn->fdtable, fd); - fd_ref (fd); - } else { - gf_log (this->name, GF_LOG_DEBUG, - "%"PRId64": OPEN %s (%"PRId64") ==> %"PRId32" (%s)", - frame->root->unique, state->loc.path, - state->loc.inode ? state->loc.inode->ino : 0, - op_ret, strerror (op_errno)); - } - - hdrlen = gf_hdr_len (rsp, 0); - hdr = gf_hdr_new (rsp, 0); - rsp = gf_param (hdr); - - hdr->rsp.op_ret = hton32 (op_ret); - gf_errno = gf_errno_to_error (op_errno); - hdr->rsp.op_errno = hton32 (gf_errno); - rsp->fd = hton64 (fd_no); - - protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_PROTO_FOP_OPEN, - hdr, hdrlen, NULL, 0, NULL); - - return 0; -} - - -/* - * server_create_cbk - create callback for server - * @frame: call frame - * @cookie: - * @this: translator structure - * @op_ret: - * @op_errno: - * @fd: file descriptor - * @inode: inode structure - * @stbuf: struct iatt of created file - * - * not for external reference - */ -static int -server_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, - fd_t *fd, inode_t *inode, struct iatt *stbuf, - struct iatt *preparent, struct iatt *postparent) -{ - server_connection_t *conn = NULL; - gf_hdr_common_t *hdr = NULL; - gf_fop_create_rsp_t *rsp = NULL; - server_state_t *state = NULL; - size_t hdrlen = 0; - int32_t gf_errno = 0; - uint64_t fd_no = 0; - inode_t *link_inode = NULL; - - conn = SERVER_CONNECTION (frame); - - state = CALL_STATE (frame); - - if (op_ret >= 0) { - gf_log (state->bound_xl->name, GF_LOG_TRACE, - "%"PRId64": CREATE %"PRId64"/%s (%"PRId64")", - frame->root->unique, state->loc.parent->ino, - state->loc.name, stbuf->ia_ino); - - link_inode = inode_link (inode, state->loc.parent, - state->loc.name, stbuf); - - if (link_inode != inode) { - - /* - VERY racy code (if used anywhere else) - -- don't do this without understanding - */ - - inode_unref (fd->inode); - fd->inode = inode_ref (link_inode); - } - - inode_lookup (link_inode); - inode_unref (link_inode); - - fd_bind (fd); - - fd_no = gf_fd_unused_get (conn->fdtable, fd); - fd_ref (fd); - - if ((fd_no < 0) || (fd == 0)) { - op_ret = fd_no; - op_errno = errno; - } - } else { - gf_log (this->name, GF_LOG_DEBUG, - "%"PRId64": CREATE %s (%"PRId64") ==> %"PRId32" (%s)", - frame->root->unique, state->loc.path, - state->loc.inode ? state->loc.inode->ino : 0, - op_ret, strerror (op_errno)); - } - - hdrlen = gf_hdr_len (rsp, 0); - hdr = gf_hdr_new (rsp, 0); - rsp = gf_param (hdr); - - hdr->rsp.op_ret = hton32 (op_ret); - gf_errno = gf_errno_to_error (op_errno); - hdr->rsp.op_errno = hton32 (gf_errno); - rsp->fd = hton64 (fd_no); - - if (op_ret >= 0) { - gf_stat_from_iatt (&rsp->stat, stbuf); - gf_stat_from_iatt (&rsp->preparent, preparent); - gf_stat_from_iatt (&rsp->postparent, postparent); - } - - protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_PROTO_FOP_CREATE, - hdr, hdrlen, NULL, 0, NULL); - - return 0; -} - -/* - * server_readlink_cbk - readlink callback for server protocol - * @frame: call frame - * @cookie: - * @this: - * @op_ret: - * @op_errno: - * @buf: - * - * not for external reference - */ -static int -server_readlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, const char *buf, - struct iatt *sbuf) -{ - gf_hdr_common_t *hdr = NULL; - gf_fop_readlink_rsp_t *rsp = NULL; - server_state_t *state = NULL; - size_t hdrlen = 0; - size_t linklen = 0; - int32_t gf_errno = 0; - - state = CALL_STATE(frame); - - if (op_ret >= 0) { - linklen = strlen (buf) + 1; - } else { - gf_log (this->name, GF_LOG_DEBUG, - "%"PRId64": READLINK %s (%"PRId64") ==> %"PRId32" (%s)", - frame->root->unique, state->loc.path, - state->loc.inode ? state->loc.inode->ino : 0, - op_ret, strerror (op_errno)); - } - - hdrlen = gf_hdr_len (rsp, linklen); - hdr = gf_hdr_new (rsp, linklen); - rsp = gf_param (hdr); - - hdr->rsp.op_ret = hton32 (op_ret); - gf_errno = gf_errno_to_error (op_errno); - hdr->rsp.op_errno = hton32 (gf_errno_to_error (op_errno)); - - if (op_ret >= 0) { - gf_stat_from_iatt (&(rsp->buf), sbuf); - strcpy (rsp->path, buf); - } - - protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_PROTO_FOP_READLINK, - hdr, hdrlen, NULL, 0, NULL); - - return 0; -} - -/* - * server_stat_cbk - stat callback for server protocol - * @frame: call frame - * @cookie: - * @this: - * @op_ret: - * @op_errno: - * @stbuf: - * - * not for external reference - */ -static int -server_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, struct iatt *stbuf) -{ - gf_hdr_common_t *hdr = NULL; - gf_fop_stat_rsp_t *rsp = NULL; - server_state_t *state = NULL; - size_t hdrlen = 0; - int32_t gf_errno = 0; - - state = CALL_STATE (frame); - - hdrlen = gf_hdr_len (rsp, 0); - hdr = gf_hdr_new (rsp, 0); - rsp = gf_param (hdr); - - hdr->rsp.op_ret = hton32 (op_ret); - gf_errno = gf_errno_to_error (op_errno); - hdr->rsp.op_errno = hton32 (gf_errno_to_error (op_errno)); - - if (op_ret == 0) { - gf_stat_from_iatt (&rsp->stat, stbuf); - } else { - gf_log (this->name, GF_LOG_DEBUG, - "%"PRId64": STAT %s (%"PRId64") ==> %"PRId32" (%s)", - frame->root->unique, state->loc.path, - state->loc.inode ? state->loc.inode->ino : 0, - op_ret, strerror (op_errno)); - } - - protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_PROTO_FOP_STAT, - hdr, hdrlen, NULL, 0, NULL); - - return 0; -} - -/* - * server_setattr_cbk - setattr callback for server protocol - * @frame: call frame - * @cookie: - * @this: - * @op_ret: - * @op_errno: - * @stbuf: - * - * not for external reference - */ - -static int -server_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, - struct iatt *statpre, struct iatt *statpost) -{ - gf_hdr_common_t *hdr = NULL; - gf_fop_setattr_rsp_t *rsp = NULL; - server_state_t *state = NULL; - size_t hdrlen = 0; - int32_t gf_errno = 0; - - state = CALL_STATE (frame); - - hdrlen = gf_hdr_len (rsp, 0); - hdr = gf_hdr_new (rsp, 0); - rsp = gf_param (hdr); - - hdr->rsp.op_ret = hton32 (op_ret); - gf_errno = gf_errno_to_error (op_errno); - hdr->rsp.op_errno = hton32 (gf_errno_to_error (op_errno)); - - if (op_ret == 0) { - gf_stat_from_iatt (&rsp->statpre, statpre); - gf_stat_from_iatt (&rsp->statpost, statpost); - } else { - gf_log (this->name, GF_LOG_DEBUG, - "%"PRId64": SETATTR %s (%"PRId64") ==> %"PRId32" (%s)", - frame->root->unique, state->loc.path, - state->loc.inode ? state->loc.inode->ino : 0, - op_ret, strerror (op_errno)); - } - - protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_PROTO_FOP_SETATTR, - hdr, hdrlen, NULL, 0, NULL); - - return 0; -} - -/* - * server_setattr_cbk - setattr callback for server protocol - * @frame: call frame - * @cookie: - * @this: - * @op_ret: - * @op_errno: - * @stbuf: - * - * not for external reference - */ -static int -server_fsetattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, - struct iatt *statpre, struct iatt *statpost) -{ - gf_hdr_common_t *hdr = NULL; - gf_fop_fsetattr_rsp_t *rsp = NULL; - server_state_t *state = NULL; - size_t hdrlen = 0; - int32_t gf_errno = 0; - - state = CALL_STATE (frame); - - hdrlen = gf_hdr_len (rsp, 0); - hdr = gf_hdr_new (rsp, 0); - rsp = gf_param (hdr); - - hdr->rsp.op_ret = hton32 (op_ret); - gf_errno = gf_errno_to_error (op_errno); - hdr->rsp.op_errno = hton32 (gf_errno_to_error (op_errno)); - - if (op_ret == 0) { - gf_stat_from_iatt (&rsp->statpre, statpre); - gf_stat_from_iatt (&rsp->statpost, statpost); - } else { - gf_log (this->name, GF_LOG_DEBUG, - "%"PRId64": FSETATTR %"PRId64" (%"PRId64") ==> " - "%"PRId32" (%s)", - frame->root->unique, state->resolve.fd_no, - state->fd ? state->fd->inode->ino : 0, - op_ret, strerror (op_errno)); - } - - protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_PROTO_FOP_FSETATTR, - hdr, hdrlen, NULL, 0, NULL); - - return 0; -} - - -/* - * server_lookup_cbk - lookup callback for server protocol - * @frame: call frame - * @cookie: - * @this: - * @op_ret: - * @op_errno: - * @inode: - * @stbuf: - * - * not for external reference - */ -static int -server_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, - inode_t *inode, struct iatt *stbuf, dict_t *dict, - struct iatt *postparent) -{ - gf_hdr_common_t *hdr = NULL; - gf_fop_lookup_rsp_t *rsp = NULL; - server_state_t *state = NULL; - inode_t *root_inode = NULL; - int32_t dict_len = 0; - size_t hdrlen = 0; - int32_t gf_errno = 0; - int32_t ret = -1; - inode_t *link_inode = NULL; - loc_t fresh_loc = {0,}; - - state = CALL_STATE(frame); - - if (state->is_revalidate == 1 && op_ret == -1) { - state->is_revalidate = 2; - loc_copy (&fresh_loc, &state->loc); - inode_unref (fresh_loc.inode); - fresh_loc.inode = inode_new (state->itable); - - STACK_WIND (frame, server_lookup_cbk, - BOUND_XL (frame), BOUND_XL (frame)->fops->lookup, - &fresh_loc, state->dict); - - loc_wipe (&fresh_loc); - return 0; - } - - if (dict) { - dict_len = dict_serialized_length (dict); - if (dict_len < 0) { - gf_log (this->name, GF_LOG_ERROR, - "%s (%"PRId64"): failed to get serialized " - "length of reply dict", - state->loc.path, state->loc.inode->ino); - op_ret = -1; - op_errno = EINVAL; - dict_len = 0; - } - } - - hdrlen = gf_hdr_len (rsp, dict_len); - hdr = gf_hdr_new (rsp, dict_len); - rsp = gf_param (hdr); - - if ((op_ret >= 0) && dict) { - ret = dict_serialize (dict, rsp->dict); - if (ret < 0) { - gf_log (this->name, GF_LOG_ERROR, - "%s (%"PRId64"): failed to serialize reply dict", - state->loc.path, state->loc.inode->ino); - op_ret = -1; - op_errno = -ret; - dict_len = 0; - } - } - rsp->dict_len = hton32 (dict_len); - - hdr->rsp.op_ret = hton32 (op_ret); - gf_errno = gf_errno_to_error (op_errno); - hdr->rsp.op_errno = hton32 (gf_errno); - - if (postparent) - gf_stat_from_iatt (&rsp->postparent, postparent); - - if (op_ret == 0) { - root_inode = BOUND_XL(frame)->itable->root; - if (inode == root_inode) { - /* we just looked up root ("/") */ - stbuf->ia_ino = 1; - if (inode->ia_type == 0) - inode->ia_type = stbuf->ia_type; - } - - gf_stat_from_iatt (&rsp->stat, stbuf); - - if (inode->ino != 1) { - link_inode = inode_link (inode, state->loc.parent, - state->loc.name, stbuf); - inode_lookup (link_inode); - inode_unref (link_inode); - } - } else { - if (state->is_revalidate && op_errno == ENOENT) { - if (state->loc.inode->ino != 1) { - inode_unlink (state->loc.inode, - state->loc.parent, - state->loc.name); - } - } - - gf_log (this->name, - (op_errno == ENOENT ? GF_LOG_TRACE : GF_LOG_DEBUG), - "%"PRId64": LOOKUP %s (%"PRId64") ==> %"PRId32" (%s)", - frame->root->unique, state->loc.path, - state->loc.inode ? state->loc.inode->ino : 0, - op_ret, strerror (op_errno)); - } - - protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_PROTO_FOP_LOOKUP, - hdr, hdrlen, NULL, 0, NULL); - - return 0; -} - - -static int -server_xattrop_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, dict_t *dict) -{ - gf_hdr_common_t *hdr = NULL; - gf_fop_xattrop_rsp_t *rsp = NULL; - server_state_t *state = NULL; - size_t hdrlen = 0; - int32_t len = 0; - int32_t gf_errno = 0; - int32_t ret = -1; - - state = CALL_STATE (frame); - - if (op_ret < 0) { - gf_log (this->name, GF_LOG_DEBUG, - "%"PRId64": XATTROP %s (%"PRId64") ==> %"PRId32" (%s)", - frame->root->unique, state->loc.path, - state->loc.inode ? state->loc.inode->ino : 0, - op_ret, strerror (op_errno)); - } - - if ((op_ret >= 0) && dict) { - len = dict_serialized_length (dict); - if (len < 0) { - gf_log (this->name, GF_LOG_ERROR, - "%s (%"PRId64"): failed to get serialized length" - " for reply dict", - state->loc.path, state->loc.inode->ino); - op_ret = -1; - op_errno = EINVAL; - len = 0; - } - } - - hdrlen = gf_hdr_len (rsp, len + 1); - hdr = gf_hdr_new (rsp, len + 1); - rsp = gf_param (hdr); - - if ((op_ret >= 0) && dict) { - ret = dict_serialize (dict, rsp->dict); - if (ret < 0) { - gf_log (this->name, GF_LOG_ERROR, - "%s (%"PRId64"): failed to serialize reply dict", - state->loc.path, state->loc.inode->ino); - op_ret = -1; - op_errno = -ret; - len = 0; - } - } - rsp->dict_len = hton32 (len); - - hdr->rsp.op_ret = hton32 (op_ret); - gf_errno = gf_errno_to_error (op_errno); - hdr->rsp.op_errno = hton32 (gf_errno); - - protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_PROTO_FOP_XATTROP, - hdr, hdrlen, NULL, 0, NULL); - - return 0; -} - - -static int -server_fxattrop_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, dict_t *dict) -{ - gf_hdr_common_t *hdr = NULL; - gf_fop_xattrop_rsp_t *rsp = NULL; - size_t hdrlen = 0; - int32_t len = 0; - int32_t gf_errno = 0; - int32_t ret = -1; - server_state_t *state = NULL; - - state = CALL_STATE(frame); - - if (op_ret < 0) { - gf_log (this->name, GF_LOG_DEBUG, - "%"PRId64": FXATTROP %"PRId64" (%"PRId64") ==> %"PRId32" (%s)", - frame->root->unique, state->resolve.fd_no, - state->fd ? state->fd->inode->ino : 0, op_ret, - strerror (op_errno)); - } - - if ((op_ret >= 0) && dict) { - len = dict_serialized_length (dict); - if (len < 0) { - gf_log (this->name, GF_LOG_ERROR, - "fd - %"PRId64" (%"PRId64"): failed to get " - "serialized length for reply dict", - state->resolve.fd_no, state->fd->inode->ino); - op_ret = -1; - op_errno = EINVAL; - len = 0; - } - } - - hdrlen = gf_hdr_len (rsp, len + 1); - hdr = gf_hdr_new (rsp, len + 1); - rsp = gf_param (hdr); - - if ((op_ret >= 0) && dict) { - ret = dict_serialize (dict, rsp->dict); - if (ret < 0) { - gf_log (this->name, GF_LOG_ERROR, - "fd - %"PRId64" (%"PRId64"): failed to " - "serialize reply dict", - state->resolve.fd_no, state->fd->inode->ino); - op_ret = -1; - op_errno = -ret; - len = 0; - } - } - rsp->dict_len = hton32 (len); - - hdr->rsp.op_ret = hton32 (op_ret); - gf_errno = gf_errno_to_error (op_errno); - hdr->rsp.op_errno = hton32 (gf_errno); - - - protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_PROTO_FOP_FXATTROP, - hdr, hdrlen, NULL, 0, NULL); - - return 0; -} - - -static int -server_lookup_resume (call_frame_t *frame, xlator_t *bound_xl) -{ - server_state_t *state = NULL; - - state = CALL_STATE (frame); - - if (state->resolve.op_ret != 0) - goto err; - - if (!state->loc.inode) - state->loc.inode = inode_new (state->itable); - else - state->is_revalidate = 1; - - STACK_WIND (frame, server_lookup_cbk, - bound_xl, bound_xl->fops->lookup, - &state->loc, state->dict); - - return 0; -err: - server_lookup_cbk (frame, NULL, frame->this, state->resolve.op_ret, - state->resolve.op_errno, NULL, NULL, NULL, NULL); - - return 0; -} - - -static int -server_lookup (call_frame_t *frame, xlator_t *bound_xl, - gf_hdr_common_t *hdr, size_t hdrlen, - struct iobuf *iobuf) -{ - gf_fop_lookup_req_t *req = NULL; - server_state_t *state = NULL; - int32_t ret = -1; - size_t pathlen = 0; - size_t baselen = 0; - size_t dictlen = 0; - dict_t *xattr_req = NULL; - char *req_dictbuf = NULL; - - req = gf_param (hdr); - - state = CALL_STATE (frame); - - pathlen = STRLEN_0 (req->path); - dictlen = ntoh32 (req->dictlen); - - /* NOTE: lookup() uses req->ino only to identify if a lookup() - * is requested for 'root' or not - */ - state->resolve.ino = ntoh64 (req->ino); - if (state->resolve.ino != 1) - state->resolve.ino = 0; - - state->resolve.type = RESOLVE_DONTCARE; - state->resolve.par = ntoh64 (req->par); - state->resolve.gen = ntoh64 (req->gen); - state->resolve.path = gf_strdup (req->path); - - if (IS_NOT_ROOT (pathlen)) { - state->resolve.bname = gf_strdup (req->bname + pathlen); - baselen = STRLEN_0 (state->resolve.bname); - } - - if (dictlen) { - /* Unserialize the dictionary */ - req_dictbuf = memdup (req->dict + pathlen + baselen, dictlen); - - xattr_req = dict_new (); - - ret = dict_unserialize (req_dictbuf, dictlen, &xattr_req); - if (ret < 0) { - gf_log (bound_xl->name, GF_LOG_ERROR, - "%"PRId64": %s (%"PRId64"): failed to " - "unserialize req-buffer to dictionary", - frame->root->unique, state->resolve.path, - state->resolve.ino); - GF_FREE (req_dictbuf); - goto err; - } - - xattr_req->extra_free = req_dictbuf; - state->dict = xattr_req; - } - - gf_resolve_and_resume (frame, server_lookup_resume); - - return 0; -err: - if (xattr_req) - dict_unref (xattr_req); - - server_lookup_cbk (frame, NULL, frame->this, -1, EINVAL, NULL, NULL, - NULL, NULL); - return 0; -} - - -/* - * server_forget - forget function for server protocol - * - * not for external reference - */ -static int -server_forget (call_frame_t *frame, xlator_t *bound_xl, - gf_hdr_common_t *hdr, size_t hdrlen, - struct iobuf *iobuf) -{ - gf_log ("forget", GF_LOG_CRITICAL, "function not implemented"); - return 0; -} - - -static int -server_stat_resume (call_frame_t *frame, xlator_t *bound_xl) -{ - server_state_t *state = NULL; - - state = CALL_STATE (frame); - - if (state->resolve.op_ret != 0) - goto err; - - STACK_WIND (frame, server_stat_cbk, - bound_xl, bound_xl->fops->stat, &state->loc); - return 0; -err: - server_stat_cbk (frame, NULL, frame->this, state->resolve.op_ret, - state->resolve.op_errno, NULL); - return 0; -} - - -static int -server_stat (call_frame_t *frame, xlator_t *bound_xl, - gf_hdr_common_t *hdr, size_t hdrlen, - struct iobuf *iobuf) -{ - gf_fop_stat_req_t *req = NULL; - server_state_t *state = NULL; - - req = gf_param (hdr); - state = CALL_STATE (frame); - { - state->resolve.type = RESOLVE_MUST; - state->resolve.ino = ntoh64 (req->ino); - state->resolve.gen = ntoh64 (req->gen); - state->resolve.path = gf_strdup (req->path); - } - - gf_resolve_and_resume (frame, server_stat_resume); - - return 0; -} - - -static int -server_setattr_resume (call_frame_t *frame, xlator_t *bound_xl) -{ - server_state_t *state = NULL; - - state = CALL_STATE (frame); - - if (state->resolve.op_ret != 0) - goto err; - - STACK_WIND (frame, server_setattr_cbk, - bound_xl, bound_xl->fops->setattr, - &state->loc, &state->stbuf, state->valid); - return 0; -err: - server_setattr_cbk (frame, NULL, frame->this, state->resolve.op_ret, - state->resolve.op_errno, NULL, NULL); - - return 0; -} - - -static int -server_setattr (call_frame_t *frame, xlator_t *bound_xl, - gf_hdr_common_t *hdr, size_t hdrlen, - struct iobuf *iobuf) -{ - gf_fop_setattr_req_t *req = NULL; - server_state_t *state = NULL; - - req = gf_param (hdr); - state = CALL_STATE (frame); - - state->resolve.type = RESOLVE_MUST; - state->resolve.ino = ntoh64 (req->ino); - state->resolve.gen = ntoh64 (req->gen); - state->resolve.path = gf_strdup (req->path); - - gf_stat_to_iatt (&req->stbuf, &state->stbuf); - state->valid = ntoh32 (req->valid); - - gf_resolve_and_resume (frame, server_setattr_resume); - - return 0; -} - - -static int -server_fsetattr_resume (call_frame_t *frame, xlator_t *bound_xl) -{ - server_state_t *state = NULL; - - state = CALL_STATE (frame); - - if (state->resolve.op_ret != 0) - goto err; - - STACK_WIND (frame, server_fsetattr_cbk, - bound_xl, bound_xl->fops->fsetattr, - state->fd, &state->stbuf, state->valid); - return 0; -err: - server_fsetattr_cbk (frame, NULL, frame->this, state->resolve.op_ret, - state->resolve.op_errno, NULL, NULL); - - return 0; -} - - -static int -server_fsetattr (call_frame_t *frame, xlator_t *bound_xl, - gf_hdr_common_t *hdr, size_t hdrlen, - struct iobuf *iobuf) -{ - gf_fop_fsetattr_req_t *req = NULL; - server_state_t *state = NULL; - - - req = gf_param (hdr); - state = CALL_STATE (frame); - - state->resolve.type = RESOLVE_MUST; - state->resolve.fd_no = ntoh64 (req->fd); - - gf_stat_to_iatt (&req->stbuf, &state->stbuf); - state->valid = ntoh32 (req->valid); - - gf_resolve_and_resume (frame, server_fsetattr_resume); - - return 0; -} - - -static int -server_readlink_resume (call_frame_t *frame, xlator_t *bound_xl) -{ - server_state_t *state = NULL; - - state = CALL_STATE (frame); - - if (state->resolve.op_ret != 0) - goto err; - - STACK_WIND (frame, server_readlink_cbk, - bound_xl, bound_xl->fops->readlink, - &state->loc, state->size); - return 0; -err: - server_readlink_cbk (frame, NULL, frame->this, state->resolve.op_ret, - state->resolve.op_errno, NULL, NULL); - return 0; -} - - -static int -server_readlink (call_frame_t *frame, xlator_t *bound_xl, - gf_hdr_common_t *hdr, size_t hdrlen, - struct iobuf *iobuf) -{ - gf_fop_readlink_req_t *req = NULL; - server_state_t *state = NULL; - - req = gf_param (hdr); - state = CALL_STATE (frame); - - state->resolve.type = RESOLVE_MUST; - state->resolve.ino = ntoh64 (req->ino); - state->resolve.gen = ntoh64 (req->gen); - state->resolve.path = gf_strdup (req->path); - - state->size = ntoh32 (req->size); - - gf_resolve_and_resume (frame, server_readlink_resume); - - return 0; -} - - -static int -server_create_resume (call_frame_t *frame, xlator_t *bound_xl) -{ - server_state_t *state = NULL; - - state = CALL_STATE (frame); - - if (state->resolve.op_ret != 0) - goto err; - - state->loc.inode = inode_new (state->itable); - - state->fd = fd_create (state->loc.inode, frame->root->pid); - state->fd->flags = state->flags; - - STACK_WIND (frame, server_create_cbk, - bound_xl, bound_xl->fops->create, - &(state->loc), state->flags, state->mode, - state->fd, state->params); - - return 0; -err: - server_create_cbk (frame, NULL, frame->this, state->resolve.op_ret, - state->resolve.op_errno, NULL, NULL, NULL, - NULL, NULL); - return 0; -} - - -static int -server_create (call_frame_t *frame, xlator_t *bound_xl, - gf_hdr_common_t *hdr, size_t hdrlen, - struct iobuf *iobuf) -{ - gf_fop_create_req_t *req = NULL; - server_state_t *state = NULL; - int pathlen = 0; - - req = gf_param (hdr); - state = CALL_STATE (frame); - - pathlen = STRLEN_0 (req->path); - - state->resolve.type = RESOLVE_NOT; - state->resolve.par = ntoh64 (req->par); - state->resolve.gen = ntoh64 (req->gen); - state->resolve.path = gf_strdup (req->path); - state->resolve.bname = gf_strdup (req->bname + pathlen); - state->mode = ntoh32 (req->mode); - state->flags = gf_flags_to_flags (ntoh32 (req->flags)); - - gf_resolve_and_resume (frame, server_create_resume); - - return 0; -} - - -static int -server_open_resume (call_frame_t *frame, xlator_t *bound_xl) -{ - server_state_t *state = NULL; - - state = CALL_STATE (frame); - - if (state->resolve.op_ret != 0) - goto err; - - state->fd = fd_create (state->loc.inode, frame->root->pid); - state->fd->flags = state->flags; - - STACK_WIND (frame, server_open_cbk, - bound_xl, bound_xl->fops->open, - &state->loc, state->flags, state->fd, 0); - - return 0; -err: - server_open_cbk (frame, NULL, frame->this, state->resolve.op_ret, - state->resolve.op_errno, NULL); - return 0; -} - - -static int -server_open (call_frame_t *frame, xlator_t *bound_xl, - gf_hdr_common_t *hdr, size_t hdrlen, - struct iobuf *iobuf) -{ - gf_fop_open_req_t *req = NULL; - server_state_t *state = NULL; - - req = gf_param (hdr); - state = CALL_STATE (frame); - - state->resolve.type = RESOLVE_MUST; - state->resolve.ino = ntoh64 (req->ino); - state->resolve.gen = ntoh64 (req->gen); - state->resolve.path = gf_strdup (req->path); - - state->flags = gf_flags_to_flags (ntoh32 (req->flags)); - - gf_resolve_and_resume (frame, server_open_resume); - - return 0; -} - - -static int -server_readv_resume (call_frame_t *frame, xlator_t *bound_xl) -{ - server_state_t *state = NULL; - - state = CALL_STATE (frame); - - if (state->resolve.op_ret != 0) - goto err; - - STACK_WIND (frame, server_readv_cbk, - bound_xl, bound_xl->fops->readv, - state->fd, state->size, state->offset); - - return 0; -err: - server_readv_cbk (frame, NULL, frame->this, state->resolve.op_ret, - state->resolve.op_errno, NULL, 0, NULL, NULL); - return 0; -} - - -static int -server_readv (call_frame_t *frame, xlator_t *bound_xl, - gf_hdr_common_t *hdr, size_t hdrlen, - struct iobuf *iobuf) -{ - gf_fop_read_req_t *req = NULL; - server_state_t *state = NULL; - - req = gf_param (hdr); - state = CALL_STATE (frame); - - state->resolve.type = RESOLVE_MUST; - state->resolve.fd_no = ntoh64 (req->fd); - state->size = ntoh32 (req->size); - state->offset = ntoh64 (req->offset); - - gf_resolve_and_resume (frame, server_readv_resume); - - return 0; -} - - -static int -server_writev_resume (call_frame_t *frame, xlator_t *bound_xl) -{ - server_state_t *state = NULL; - struct iovec iov = {0, }; - - state = CALL_STATE (frame); - - if (state->resolve.op_ret != 0) - goto err; - - iov.iov_len = state->size; - - if (state->iobuf) { - iov.iov_base = state->iobuf->ptr; - } - - STACK_WIND (frame, server_writev_cbk, - bound_xl, bound_xl->fops->writev, - state->fd, &iov, 1, state->offset, state->iobref); - - return 0; -err: - server_writev_cbk (frame, NULL, frame->this, state->resolve.op_ret, - state->resolve.op_errno, NULL, NULL); - return 0; -} - - -static int -server_writev (call_frame_t *frame, xlator_t *bound_xl, - gf_hdr_common_t *hdr, size_t hdrlen, - struct iobuf *iobuf) -{ - gf_fop_write_req_t *req = NULL; - server_state_t *state = NULL; - struct iobref *iobref = NULL; - - req = gf_param (hdr); - state = CALL_STATE (frame); - - state->resolve.type = RESOLVE_MUST; - state->resolve.fd_no = ntoh64 (req->fd); - state->offset = ntoh64 (req->offset); - state->size = ntoh32 (req->size); - - if (iobuf) { - iobref = iobref_new (); - iobref_add (iobref, iobuf); - - state->iobuf = iobuf; - state->iobref = iobref; - } - - gf_resolve_and_resume (frame, server_writev_resume); - - return 0; -} - - -static int -server_release (call_frame_t *frame, xlator_t *bound_xl, - gf_hdr_common_t *hdr, size_t hdrlen, - struct iobuf *iobuf) -{ - gf_cbk_release_req_t *req = NULL; - server_state_t *state = NULL; - server_connection_t *conn = NULL; - - conn = SERVER_CONNECTION (frame); - state = CALL_STATE (frame); - req = gf_param (hdr); - - state->resolve.fd_no = ntoh64 (req->fd); - - gf_fd_put (conn->fdtable, state->resolve.fd_no); - - server_release_cbk (frame, NULL, frame->this, 0, 0); - - return 0; -} - - -static int -server_fsync_resume (call_frame_t *frame, xlator_t *bound_xl) -{ - server_state_t *state = NULL; - - state = CALL_STATE (frame); - - if (state->resolve.op_ret != 0) - goto err; - - STACK_WIND (frame, server_fsync_cbk, - bound_xl, bound_xl->fops->fsync, - state->fd, state->flags); - return 0; -err: - server_fsync_cbk (frame, NULL, frame->this, state->resolve.op_ret, - state->resolve.op_errno, NULL, NULL); - - return 0; -} - - -static int -server_fsync (call_frame_t *frame, xlator_t *bound_xl, - gf_hdr_common_t *hdr, size_t hdrlen, - struct iobuf *iobuf) -{ - gf_fop_fsync_req_t *req = NULL; - server_state_t *state = NULL; - - req = gf_param (hdr); - state = CALL_STATE (frame); - - state->resolve.type = RESOLVE_MUST; - state->resolve.fd_no = ntoh64 (req->fd); - state->flags = ntoh32 (req->data); - - gf_resolve_and_resume (frame, server_fsync_resume); - - return 0; -} - - - -static int -server_flush_resume (call_frame_t *frame, xlator_t *bound_xl) -{ - server_state_t *state = NULL; - - state = CALL_STATE (frame); - - if (state->resolve.op_ret != 0) - goto err; - - STACK_WIND (frame, server_flush_cbk, - bound_xl, bound_xl->fops->flush, state->fd); - return 0; -err: - server_flush_cbk (frame, NULL, frame->this, state->resolve.op_ret, - state->resolve.op_errno); - - return 0; -} - - -static int -server_flush (call_frame_t *frame, xlator_t *bound_xl, - gf_hdr_common_t *hdr, size_t hdrlen, - struct iobuf *iobuf) -{ - gf_fop_fsync_req_t *req = NULL; - server_state_t *state = NULL; - - req = gf_param (hdr); - state = CALL_STATE (frame); - - state->resolve.type = RESOLVE_MUST; - state->resolve.fd_no = ntoh64 (req->fd); - - gf_resolve_and_resume (frame, server_flush_resume); - - return 0; -} - - - -static int -server_ftruncate_resume (call_frame_t *frame, xlator_t *bound_xl) -{ - server_state_t *state = NULL; - - state = CALL_STATE (frame); - - if (state->resolve.op_ret != 0) - goto err; - - STACK_WIND (frame, server_ftruncate_cbk, - bound_xl, bound_xl->fops->ftruncate, - state->fd, state->offset); - return 0; -err: - server_ftruncate_cbk (frame, NULL, frame->this, state->resolve.op_ret, - state->resolve.op_errno, NULL, NULL); - - return 0; -} - - -static int -server_ftruncate (call_frame_t *frame, xlator_t *bound_xl, - gf_hdr_common_t *hdr, size_t hdrlen, - struct iobuf *iobuf) -{ - gf_fop_ftruncate_req_t *req = NULL; - server_state_t *state = NULL; - - req = gf_param (hdr); - state = CALL_STATE (frame); - - state->resolve.type = RESOLVE_MUST; - state->resolve.fd_no = ntoh64 (req->fd); - state->offset = ntoh64 (req->offset); - - gf_resolve_and_resume (frame, server_ftruncate_resume); - - return 0; -} - - -static int -server_fstat_resume (call_frame_t *frame, xlator_t *bound_xl) -{ - server_state_t *state = NULL; - - state = CALL_STATE (frame); - - if (state->resolve.op_ret != 0) - goto err; - - STACK_WIND (frame, server_fstat_cbk, - bound_xl, bound_xl->fops->fstat, - state->fd); - return 0; -err: - server_fstat_cbk (frame, NULL, frame->this, state->resolve.op_ret, - state->resolve.op_errno, NULL); - return 0; -} - - -static int -server_fstat (call_frame_t *frame, xlator_t *bound_xl, - gf_hdr_common_t *hdr, size_t hdrlen, - struct iobuf *iobuf) -{ - gf_fop_fstat_req_t *req = NULL; - server_state_t *state = NULL; - - req = gf_param (hdr); - state = CALL_STATE (frame); - - state->resolve.type = RESOLVE_MUST; - state->resolve.fd_no = ntoh64 (req->fd); - - gf_resolve_and_resume (frame, server_fstat_resume); - - return 0; -} - - -static int -server_truncate_resume (call_frame_t *frame, xlator_t *bound_xl) -{ - server_state_t *state = NULL; - - state = CALL_STATE (frame); - - if (state->resolve.op_ret != 0) - goto err; - - STACK_WIND (frame, server_truncate_cbk, - bound_xl, bound_xl->fops->truncate, - &state->loc, state->offset); - return 0; -err: - server_truncate_cbk (frame, NULL, frame->this, state->resolve.op_ret, - state->resolve.op_errno, NULL, NULL); - return 0; -} - - - -static int -server_truncate (call_frame_t *frame, xlator_t *bound_xl, - gf_hdr_common_t *hdr, size_t hdrlen, - struct iobuf *iobuf) -{ - gf_fop_truncate_req_t *req = NULL; - server_state_t *state = NULL; - - req = gf_param (hdr); - state = CALL_STATE (frame); - - state->resolve.type = RESOLVE_MUST; - state->resolve.path = gf_strdup (req->path); - state->resolve.ino = ntoh64 (req->ino); - state->resolve.gen = ntoh64 (req->gen); - state->offset = ntoh64 (req->offset); - - gf_resolve_and_resume (frame, server_truncate_resume); - - return 0; -} - - -static int -server_unlink_resume (call_frame_t *frame, xlator_t *bound_xl) -{ - server_state_t *state = NULL; - - state = CALL_STATE (frame); - - if (state->resolve.op_ret != 0) - goto err; - - STACK_WIND (frame, server_unlink_cbk, - bound_xl, bound_xl->fops->unlink, - &state->loc); - return 0; -err: - server_unlink_cbk (frame, NULL, frame->this, state->resolve.op_ret, - state->resolve.op_errno, NULL, NULL); - return 0; -} - - -static int -server_unlink (call_frame_t *frame, xlator_t *bound_xl, - gf_hdr_common_t *hdr, size_t hdrlen, - struct iobuf *iobuf) -{ - gf_fop_unlink_req_t *req = NULL; - server_state_t *state = NULL; - int pathlen = 0; - - req = gf_param (hdr); - state = CALL_STATE (frame); - - pathlen = STRLEN_0 (req->path); - - state->resolve.type = RESOLVE_MUST; - state->resolve.par = ntoh64 (req->par); - state->resolve.gen = ntoh64 (req->gen); - state->resolve.path = gf_strdup (req->path); - state->resolve.bname = gf_strdup (req->bname + pathlen); - - gf_resolve_and_resume (frame, server_unlink_resume); - - return 0; -} - - -static int -server_setxattr_resume (call_frame_t *frame, xlator_t *bound_xl) -{ - server_state_t *state = NULL; - - state = CALL_STATE (frame); - - if (state->resolve.op_ret != 0) - goto err; - - STACK_WIND (frame, server_setxattr_cbk, - bound_xl, bound_xl->fops->setxattr, - &state->loc, state->dict, state->flags); - return 0; -err: - server_setxattr_cbk (frame, NULL, frame->this, state->resolve.op_ret, - state->resolve.op_errno); - - return 0; -} - - -static int -server_setxattr (call_frame_t *frame, xlator_t *bound_xl, - gf_hdr_common_t *hdr, size_t hdrlen, - struct iobuf *iobuf) -{ - gf_fop_setxattr_req_t *req = NULL; - server_state_t *state = NULL; - dict_t *dict = NULL; - int32_t ret = -1; - size_t dict_len = 0; - char *req_dictbuf = NULL; - - req = gf_param (hdr); - state = CALL_STATE (frame); - - dict_len = ntoh32 (req->dict_len); - - state->resolve.type = RESOLVE_MUST; - state->resolve.path = gf_strdup (req->path + dict_len); - state->resolve.ino = ntoh64 (req->ino); - state->resolve.gen = ntoh64 (req->gen); - state->flags = ntoh32 (req->flags); - - if (dict_len) { - req_dictbuf = memdup (req->dict, dict_len); - - dict = dict_new (); - - ret = dict_unserialize (req_dictbuf, dict_len, &dict); - if (ret < 0) { - gf_log (bound_xl->name, GF_LOG_ERROR, - "%"PRId64": %s (%"PRId64"): failed to " - "unserialize request buffer to dictionary", - frame->root->unique, state->loc.path, - state->resolve.ino); - GF_FREE (req_dictbuf); - goto err; - } - - dict->extra_free = req_dictbuf; - state->dict = dict; - } - - gf_resolve_and_resume (frame, server_setxattr_resume); - - return 0; -err: - if (dict) - dict_unref (dict); - - server_setxattr_cbk (frame, NULL, frame->this, -1, EINVAL); - - return 0; - -} - - -static int -server_fsetxattr_resume (call_frame_t *frame, xlator_t *bound_xl) -{ - server_state_t *state = NULL; - - state = CALL_STATE (frame); - - if (state->resolve.op_ret != 0) - goto err; - - STACK_WIND (frame, server_setxattr_cbk, - bound_xl, bound_xl->fops->fsetxattr, - state->fd, state->dict, state->flags); - return 0; -err: - server_fsetxattr_cbk (frame, NULL, frame->this, state->resolve.op_ret, - state->resolve.op_errno); - - return 0; -} - - -static int -server_fsetxattr (call_frame_t *frame, xlator_t *bound_xl, - gf_hdr_common_t *hdr, size_t hdrlen, - struct iobuf *iobuf) -{ - gf_fop_fsetxattr_req_t *req = NULL; - server_state_t *state = NULL; - dict_t *dict = NULL; - int32_t ret = -1; - size_t dict_len = 0; - char *req_dictbuf = NULL; - - req = gf_param (hdr); - state = CALL_STATE (frame); - - dict_len = ntoh32 (req->dict_len); - - state->resolve.type = RESOLVE_MUST; - state->resolve.fd_no = ntoh64 (req->fd); - state->flags = ntoh32 (req->flags); - - if (dict_len) { - req_dictbuf = memdup (req->dict, dict_len); - - dict = dict_new (); - - ret = dict_unserialize (req_dictbuf, dict_len, &dict); - if (ret < 0) { - gf_log (bound_xl->name, GF_LOG_ERROR, - "%"PRId64": %s (%"PRId64"): failed to " - "unserialize request buffer to dictionary", - frame->root->unique, state->loc.path, - state->resolve.ino); - GF_FREE (req_dictbuf); - goto err; - } - - dict->extra_free = req_dictbuf; - state->dict = dict; - } - - gf_resolve_and_resume (frame, server_fsetxattr_resume); - - return 0; -err: - if (dict) - dict_unref (dict); - - server_setxattr_cbk (frame, NULL, frame->this, -1, EINVAL); - - return 0; -} - - -static int -server_fxattrop_resume (call_frame_t *frame, xlator_t *bound_xl) -{ - server_state_t *state = NULL; - - state = CALL_STATE (frame); - - if (state->resolve.op_ret != 0) - goto err; - - STACK_WIND (frame, server_fxattrop_cbk, - bound_xl, bound_xl->fops->fxattrop, - state->fd, state->flags, state->dict); - return 0; -err: - server_fxattrop_cbk (frame, NULL, frame->this, state->resolve.op_ret, - state->resolve.op_errno, NULL); - return 0; -} - - -static int -server_fxattrop (call_frame_t *frame, xlator_t *bound_xl, - gf_hdr_common_t *hdr, size_t hdrlen, - struct iobuf *iobuf) -{ - gf_fop_fxattrop_req_t *req = NULL; - dict_t *dict = NULL; - server_state_t *state = NULL; - size_t dict_len = 0; - char *req_dictbuf = NULL; - int32_t ret = -1; - - req = gf_param (hdr); - state = CALL_STATE(frame); - - dict_len = ntoh32 (req->dict_len); - - state->resolve.type = RESOLVE_MUST; - state->resolve.fd_no = ntoh64 (req->fd); - - state->resolve.ino = ntoh64 (req->ino); - state->resolve.gen = ntoh64 (req->gen); - state->flags = ntoh32 (req->flags); - - if (dict_len) { - /* Unserialize the dictionary */ - req_dictbuf = memdup (req->dict, dict_len); - - dict = dict_new (); - - ret = dict_unserialize (req_dictbuf, dict_len, &dict); - if (ret < 0) { - gf_log (bound_xl->name, GF_LOG_ERROR, - "fd - %"PRId64" (%"PRId64"): failed to unserialize " - "request buffer to dictionary", - state->resolve.fd_no, state->fd->inode->ino); - GF_FREE (req_dictbuf); - goto fail; - } - dict->extra_free = req_dictbuf; - state->dict = dict; - dict = NULL; - } - - gf_resolve_and_resume (frame, server_fxattrop_resume); - - return 0; - -fail: - if (dict) - dict_unref (dict); - - server_fxattrop_cbk (frame, NULL, frame->this, -1, EINVAL, NULL); - return 0; -} - - -static int -server_xattrop_resume (call_frame_t *frame, xlator_t *bound_xl) -{ - server_state_t *state = NULL; - - state = CALL_STATE (frame); - - if (state->resolve.op_ret != 0) - goto err; - - STACK_WIND (frame, server_xattrop_cbk, - bound_xl, bound_xl->fops->xattrop, - &state->loc, state->flags, state->dict); - return 0; -err: - server_xattrop_cbk (frame, NULL, frame->this, state->resolve.op_ret, - state->resolve.op_errno, NULL); - return 0; -} - - -static int -server_xattrop (call_frame_t *frame, xlator_t *bound_xl, - gf_hdr_common_t *hdr, size_t hdrlen, - struct iobuf *iobuf) -{ - gf_fop_xattrop_req_t *req = NULL; - dict_t *dict = NULL; - server_state_t *state = NULL; - size_t dict_len = 0; - char *req_dictbuf = NULL; - int32_t ret = -1; - - req = gf_param (hdr); - state = CALL_STATE(frame); - - dict_len = ntoh32 (req->dict_len); - - state->resolve.type = RESOLVE_MUST; - state->resolve.path = gf_strdup (req->path + dict_len); - state->resolve.ino = ntoh64 (req->ino); - state->resolve.gen = ntoh64 (req->gen); - state->flags = ntoh32 (req->flags); - - if (dict_len) { - /* Unserialize the dictionary */ - req_dictbuf = memdup (req->dict, dict_len); - - dict = dict_new (); - - ret = dict_unserialize (req_dictbuf, dict_len, &dict); - if (ret < 0) { - gf_log (bound_xl->name, GF_LOG_ERROR, - "fd - %"PRId64" (%"PRId64"): failed to unserialize " - "request buffer to dictionary", - state->resolve.fd_no, state->fd->inode->ino); - GF_FREE (req_dictbuf); - goto fail; - } - dict->extra_free = req_dictbuf; - state->dict = dict; - dict = NULL; - } - - gf_resolve_and_resume (frame, server_xattrop_resume); - - return 0; - -fail: - if (dict) - dict_unref (dict); - - server_xattrop_cbk (frame, NULL, frame->this, -1, EINVAL, NULL); - return 0; -} - - -static int -server_getxattr_resume (call_frame_t *frame, xlator_t *bound_xl) -{ - server_state_t *state = NULL; - - state = CALL_STATE (frame); - - if (state->resolve.op_ret != 0) - goto err; - - STACK_WIND (frame, server_getxattr_cbk, - bound_xl, bound_xl->fops->getxattr, - &state->loc, state->name); - return 0; -err: - server_getxattr_cbk (frame, NULL, frame->this, state->resolve.op_ret, - state->resolve.op_errno, NULL); - return 0; -} - - -static int -server_getxattr (call_frame_t *frame, xlator_t *bound_xl, - gf_hdr_common_t *hdr, size_t hdrlen, - struct iobuf *iobuf) -{ - gf_fop_getxattr_req_t *req = NULL; - server_state_t *state = NULL; - size_t namelen = 0; - size_t pathlen = 0; - - req = gf_param (hdr); - state = CALL_STATE (frame); - - pathlen = STRLEN_0 (req->path); - - state->resolve.type = RESOLVE_MUST; - state->resolve.path = gf_strdup (req->path); - state->resolve.ino = ntoh64 (req->ino); - state->resolve.gen = ntoh64 (req->gen); - - namelen = ntoh32 (req->namelen); - if (namelen) - state->name = gf_strdup (req->name + pathlen); - - gf_resolve_and_resume (frame, server_getxattr_resume); - - return 0; -} - - -static int -server_fgetxattr_resume (call_frame_t *frame, xlator_t *bound_xl) -{ - server_state_t *state = NULL; - - state = CALL_STATE (frame); - - if (state->resolve.op_ret != 0) - goto err; - - STACK_WIND (frame, server_fgetxattr_cbk, - bound_xl, bound_xl->fops->fgetxattr, - state->fd, state->name); - return 0; -err: - server_fgetxattr_cbk (frame, NULL, frame->this, state->resolve.op_ret, - state->resolve.op_errno, NULL); - return 0; -} - - -static int -server_fgetxattr (call_frame_t *frame, xlator_t *bound_xl, - gf_hdr_common_t *hdr, size_t hdrlen, - struct iobuf *iobuf) -{ - gf_fop_fgetxattr_req_t *req = NULL; - server_state_t *state = NULL; - size_t namelen = 0; - - req = gf_param (hdr); - state = CALL_STATE (frame); - - state->resolve.type = RESOLVE_MUST; - state->resolve.fd_no = ntoh64 (req->fd); - - namelen = ntoh32 (req->namelen); - if (namelen) - state->name = gf_strdup (req->name); - - gf_resolve_and_resume (frame, server_fgetxattr_resume); - - return 0; -} - - -static int -server_removexattr_resume (call_frame_t *frame, xlator_t *bound_xl) -{ - server_state_t *state = NULL; - - state = CALL_STATE (frame); - - if (state->resolve.op_ret != 0) - goto err; - - STACK_WIND (frame, server_removexattr_cbk, - bound_xl, bound_xl->fops->removexattr, - &state->loc, state->name); - return 0; -err: - server_removexattr_cbk (frame, NULL, frame->this, state->resolve.op_ret, - state->resolve.op_errno); - return 0; -} - - -static int -server_removexattr (call_frame_t *frame, xlator_t *bound_xl, - gf_hdr_common_t *hdr, size_t hdrlen, - struct iobuf *iobuf) -{ - gf_fop_removexattr_req_t *req = NULL; - server_state_t *state = NULL; - size_t pathlen = 0; - - req = gf_param (hdr); - state = CALL_STATE (frame); - pathlen = STRLEN_0 (req->path); - - state->resolve.type = RESOLVE_MUST; - state->resolve.path = gf_strdup (req->path); - state->resolve.ino = ntoh64 (req->ino); - state->resolve.gen = ntoh64 (req->gen); - state->name = gf_strdup (req->name + pathlen); - - gf_resolve_and_resume (frame, server_removexattr_resume); - - return 0; -} - - -static int -server_statfs_resume (call_frame_t *frame, xlator_t *bound_xl) -{ - server_state_t *state = NULL; - - state = CALL_STATE (frame); - - if (state->resolve.op_ret !=0) - goto err; - - STACK_WIND (frame, server_statfs_cbk, - bound_xl, bound_xl->fops->statfs, - &state->loc); - return 0; - -err: - server_statfs_cbk (frame, NULL, frame->this, state->resolve.op_ret, - state->resolve.op_errno, NULL); - return 0; -} - - -static int -server_statfs (call_frame_t *frame, xlator_t *bound_xl, - gf_hdr_common_t *hdr, size_t hdrlen, - struct iobuf *iobuf) -{ - gf_fop_statfs_req_t *req = NULL; - server_state_t *state = NULL; - - req = gf_param (hdr); - - state = CALL_STATE (frame); - - state->resolve.type = RESOLVE_MUST; - state->resolve.ino = ntoh64 (req->ino); - if (!state->resolve.ino) - state->resolve.ino = 1; - state->resolve.gen = ntoh64 (req->gen); - state->resolve.path = gf_strdup (req->path); - - gf_resolve_and_resume (frame, server_statfs_resume); - - return 0; -} - - -static int -server_opendir_resume (call_frame_t *frame, xlator_t *bound_xl) -{ - server_state_t *state = NULL; - - state = CALL_STATE (frame); - - if (state->resolve.op_ret != 0) - goto err; - - state->fd = fd_create (state->loc.inode, frame->root->pid); - - STACK_WIND (frame, server_opendir_cbk, - bound_xl, bound_xl->fops->opendir, - &state->loc, state->fd); - return 0; -err: - server_opendir_cbk (frame, NULL, frame->this, state->resolve.op_ret, - state->resolve.op_errno, NULL); - return 0; -} - - -static int -server_opendir (call_frame_t *frame, xlator_t *bound_xl, - gf_hdr_common_t *hdr, size_t hdrlen, - struct iobuf *iobuf) -{ - gf_fop_opendir_req_t *req = NULL; - server_state_t *state = NULL; - - req = gf_param (hdr); - state = CALL_STATE (frame); - - state->resolve.type = RESOLVE_MUST; - state->resolve.path = gf_strdup (req->path); - state->resolve.ino = ntoh64 (req->ino); - state->resolve.gen = ntoh64 (req->gen); - - gf_resolve_and_resume (frame, server_opendir_resume); - - return 0; -} - - -static int -server_releasedir (call_frame_t *frame, xlator_t *bound_xl, - gf_hdr_common_t *hdr, size_t hdrlen, - struct iobuf *iobuf) -{ - gf_cbk_releasedir_req_t *req = NULL; - server_connection_t *conn = NULL; - uint64_t fd_no = 0; - - conn = SERVER_CONNECTION (frame); - - req = gf_param (hdr); - - fd_no = ntoh64 (req->fd); - - gf_fd_put (conn->fdtable, fd_no); - - server_releasedir_cbk (frame, NULL, frame->this, 0, 0); - - return 0; -} - -/* - * server_readdirp_cbk - getdents callback for server protocol - * @frame: call frame - * @cookie: - * @this: - * @op_ret: - * @op_errno: - * - * not for external reference - */ -static int -server_readdirp_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, gf_dirent_t *entries) -{ - gf_hdr_common_t *hdr = NULL; - gf_fop_readdirp_rsp_t *rsp = NULL; - size_t hdrlen = 0; - size_t buf_size = 0; - int32_t gf_errno = 0; - server_state_t *state = NULL; - - if (op_ret > 0) - buf_size = gf_dirent_serialize (entries, NULL, 0); - - hdrlen = gf_hdr_len (rsp, buf_size); - hdr = gf_hdr_new (rsp, buf_size); - rsp = gf_param (hdr); - - hdr->rsp.op_ret = hton32 (op_ret); - gf_errno = gf_errno_to_error (op_errno); - hdr->rsp.op_errno = hton32 (gf_errno); - - if (op_ret > 0) { - rsp->size = hton32 (buf_size); - gf_dirent_serialize (entries, rsp->buf, buf_size); - } else { - state = CALL_STATE(frame); - - gf_log (this->name, GF_LOG_TRACE, - "%"PRId64": READDIRP %"PRId64" (%"PRId64") ==>" - "%"PRId32" (%s)", - frame->root->unique, state->resolve.fd_no, - state->fd ? state->fd->inode->ino : 0, op_ret, - strerror (op_errno)); - } - - protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_PROTO_FOP_READDIRP, - hdr, hdrlen, NULL, 0, NULL); - - return 0; -} - -static int -server_readdirp_resume (call_frame_t *frame, xlator_t *bound_xl) -{ - server_state_t *state = NULL; - - state = CALL_STATE (frame); - - if (state->resolve.op_ret != 0) - goto err; - - STACK_WIND (frame, server_readdirp_cbk, bound_xl, - bound_xl->fops->readdirp, state->fd, state->size, - state->offset); - - return 0; -err: - server_readdirp_cbk (frame, NULL, frame->this, state->resolve.op_ret, - state->resolve.op_errno, NULL); - return 0; -} - -/* - * server_readdirp - readdirp function for server protocol - * @frame: call frame - * @bound_xl: - * @params: parameter dictionary - * - * not for external reference - */ -static int -server_readdirp (call_frame_t *frame, xlator_t *bound_xl, gf_hdr_common_t *hdr, - size_t hdrlen, struct iobuf *iobuf) -{ - gf_fop_readdirp_req_t *req = NULL; - server_state_t *state = NULL; - server_connection_t *conn = NULL; - - conn = SERVER_CONNECTION(frame); - - req = gf_param (hdr); - state = CALL_STATE(frame); - - state->resolve.type = RESOLVE_MUST; - state->resolve.fd_no = ntoh64 (req->fd); - state->size = ntoh32 (req->size); - state->offset = ntoh64 (req->offset); - - gf_resolve_and_resume (frame, server_readdirp_resume); - - return 0; -} - - -static int - server_readdir_resume (call_frame_t *frame, xlator_t *bound_xl) -{ - server_state_t *state = NULL; - - state = CALL_STATE (frame); - - if (state->resolve.op_ret != 0) - goto err; - - STACK_WIND (frame, server_readdir_cbk, - bound_xl, - bound_xl->fops->readdir, - state->fd, state->size, state->offset); - - return 0; -err: - server_readdir_cbk (frame, NULL, frame->this, state->resolve.op_ret, - state->resolve.op_errno, NULL); - return 0; -} -/* - * server_readdir - readdir function for server protocol - * @frame: call frame - * @bound_xl: - * @params: parameter dictionary - * - * not for external reference - */ -static int -server_readdir (call_frame_t *frame, xlator_t *bound_xl, - gf_hdr_common_t *hdr, size_t hdrlen, - struct iobuf *iobuf) -{ - gf_fop_readdir_req_t *req = NULL; - server_state_t *state = NULL; - server_connection_t *conn = NULL; - - conn = SERVER_CONNECTION(frame); - - req = gf_param (hdr); - state = CALL_STATE(frame); - - state->resolve.type = RESOLVE_MUST; - state->resolve.fd_no = ntoh64 (req->fd); - state->size = ntoh32 (req->size); - state->offset = ntoh64 (req->offset); - - gf_resolve_and_resume (frame, server_readdir_resume); - - return 0; -} - -static int -server_fsyncdir_resume (call_frame_t *frame, xlator_t *bound_xl) -{ - server_state_t *state = NULL; - - state = CALL_STATE (frame); - - if (state->resolve.op_ret != 0) - goto err; - - STACK_WIND (frame, server_fsyncdir_cbk, - bound_xl, - bound_xl->fops->fsyncdir, - state->fd, state->flags); - return 0; - -err: - server_fsyncdir_cbk (frame, NULL, frame->this, - state->resolve.op_ret, - state->resolve.op_errno); - return 0; -} - -/* - * server_fsyncdir - fsyncdir function for server protocol - * @frame: call frame - * @bound_xl: - * @params: parameter dictionary - * - * not for external reference - */ -static int -server_fsyncdir (call_frame_t *frame, xlator_t *bound_xl, - gf_hdr_common_t *hdr, size_t hdrlen, - struct iobuf *iobuf) -{ - gf_fop_fsyncdir_req_t *req = NULL; - server_state_t *state = NULL; - server_connection_t *conn = NULL; - - conn = SERVER_CONNECTION (frame); - - req = gf_param (hdr); - state = CALL_STATE(frame); - - state->resolve.type = RESOLVE_MUST; - state->resolve.fd_no = ntoh64 (req->fd); - state->flags = ntoh32 (req->data); - - gf_resolve_and_resume (frame, server_fsyncdir_resume); - - return 0; -} - - -static int -server_mknod_resume (call_frame_t *frame, xlator_t *bound_xl) -{ - server_state_t *state = NULL; - - state = CALL_STATE (frame); - - if (state->resolve.op_ret != 0) - goto err; - - state->loc.inode = inode_new (state->itable); - - STACK_WIND (frame, server_mknod_cbk, - bound_xl, bound_xl->fops->mknod, - &(state->loc), state->mode, state->dev, - state->params); - - return 0; -err: - server_mknod_cbk (frame, NULL, frame->this, state->resolve.op_ret, - state->resolve.op_errno, NULL, NULL, NULL, NULL); - return 0; -} - - - -static int -server_mknod (call_frame_t *frame, xlator_t *bound_xl, - gf_hdr_common_t *hdr, size_t hdrlen, - struct iobuf *iobuf) -{ - gf_fop_mknod_req_t *req = NULL; - server_state_t *state = NULL; - size_t pathlen = 0; - - req = gf_param (hdr); - state = CALL_STATE (frame); - pathlen = STRLEN_0 (req->path); - - state->resolve.type = RESOLVE_NOT; - state->resolve.par = ntoh64 (req->par); - state->resolve.gen = ntoh64 (req->gen); - state->resolve.path = gf_strdup (req->path); - state->resolve.bname = gf_strdup (req->bname + pathlen); - - state->mode = ntoh32 (req->mode); - state->dev = ntoh64 (req->dev); - - gf_resolve_and_resume (frame, server_mknod_resume); - - return 0; -} - - -static int -server_mkdir_resume (call_frame_t *frame, xlator_t *bound_xl) - -{ - server_state_t *state = NULL; - - state = CALL_STATE (frame); - - if (state->resolve.op_ret != 0) - goto err; - - state->loc.inode = inode_new (state->itable); - - STACK_WIND (frame, server_mkdir_cbk, - bound_xl, bound_xl->fops->mkdir, - &(state->loc), state->mode, - state->params); - - return 0; -err: - server_mkdir_cbk (frame, NULL, frame->this, state->resolve.op_ret, - state->resolve.op_errno, NULL, NULL, NULL, NULL); - return 0; -} - - -static int -server_mkdir (call_frame_t *frame, xlator_t *bound_xl, - gf_hdr_common_t *hdr, size_t hdrlen, - struct iobuf *iobuf) -{ - gf_fop_mkdir_req_t *req = NULL; - server_state_t *state = NULL; - size_t pathlen = 0; - - req = gf_param (hdr); - state = CALL_STATE (frame); - pathlen = STRLEN_0 (req->path); - - state->resolve.type = RESOLVE_NOT; - state->resolve.par = ntoh64 (req->par); - state->resolve.gen = ntoh64 (req->gen); - state->resolve.path = gf_strdup (req->path); - state->resolve.bname = gf_strdup (req->bname + pathlen); - - state->mode = ntoh32 (req->mode); - - gf_resolve_and_resume (frame, server_mkdir_resume); - - return 0; -} - - -static int -server_rmdir_resume (call_frame_t *frame, xlator_t *bound_xl) -{ - server_state_t *state = NULL; - - state = CALL_STATE (frame); - - if (state->resolve.op_ret != 0) - goto err; - - STACK_WIND (frame, server_rmdir_cbk, - bound_xl, bound_xl->fops->rmdir, &state->loc); - return 0; -err: - server_rmdir_cbk (frame, NULL, frame->this, state->resolve.op_ret, - state->resolve.op_errno, NULL, NULL); - return 0; -} - -static int -server_rmdir (call_frame_t *frame, xlator_t *bound_xl, - gf_hdr_common_t *hdr, size_t hdrlen, - struct iobuf *iobuf) -{ - gf_fop_rmdir_req_t *req = NULL; - server_state_t *state = NULL; - int pathlen = 0; - - req = gf_param (hdr); - state = CALL_STATE (frame); - pathlen = STRLEN_0 (req->path); - - state->resolve.type = RESOLVE_MUST; - state->resolve.par = ntoh64 (req->par); - state->resolve.gen = ntoh64 (req->gen); - state->resolve.path = gf_strdup (req->path); - state->resolve.bname = gf_strdup (req->bname + pathlen); - - gf_resolve_and_resume (frame, server_rmdir_resume); - - return 0; -} - - -static int -server_inodelk_resume (call_frame_t *frame, xlator_t *bound_xl) -{ - server_state_t *state = NULL; - - state = CALL_STATE (frame); - - if (state->resolve.op_ret != 0) - goto err; - - STACK_WIND (frame, server_inodelk_cbk, - bound_xl, bound_xl->fops->inodelk, - state->volume, &state->loc, state->cmd, &state->flock); - return 0; -err: - server_inodelk_cbk (frame, NULL, frame->this, state->resolve.op_ret, - state->resolve.op_errno); - return 0; -} - - -static int -server_inodelk (call_frame_t *frame, xlator_t *bound_xl, - gf_hdr_common_t *hdr, size_t hdrlen, - struct iobuf *iobuf) -{ - gf_fop_inodelk_req_t *req = NULL; - server_state_t *state = NULL; - size_t pathlen = 0; - size_t vollen = 0; - int cmd = 0; - - req = gf_param (hdr); - state = CALL_STATE (frame); - pathlen = STRLEN_0 (req->path); - vollen = STRLEN_0 (req->volume + pathlen); - - state->resolve.type = RESOLVE_EXACT; - state->resolve.ino = ntoh64 (req->ino); - state->resolve.gen = ntoh64 (req->gen); - state->resolve.path = gf_strdup (req->path); - - cmd = ntoh32 (req->cmd); - switch (cmd) { - case GF_LK_GETLK: - state->cmd = F_GETLK; - break; - case GF_LK_SETLK: - state->cmd = F_SETLK; - break; - case GF_LK_SETLKW: - state->cmd = F_SETLKW; - break; - } - - state->type = ntoh32 (req->type); - state->volume = gf_strdup (req->volume + pathlen); - - gf_flock_to_flock (&req->flock, &state->flock); - - switch (state->type) { - case GF_LK_F_RDLCK: - state->flock.l_type = F_RDLCK; - break; - case GF_LK_F_WRLCK: - state->flock.l_type = F_WRLCK; - break; - case GF_LK_F_UNLCK: - state->flock.l_type = F_UNLCK; - break; - } - - gf_resolve_and_resume (frame, server_inodelk_resume); - - return 0; -} - -static int -server_finodelk_resume (call_frame_t *frame, xlator_t *bound_xl) -{ - server_state_t *state = NULL; - - state = CALL_STATE (frame); - - if (state->resolve.op_ret != 0) - goto err; - - STACK_WIND (frame, server_finodelk_cbk, - BOUND_XL(frame), - BOUND_XL(frame)->fops->finodelk, - state->volume, state->fd, state->cmd, &state->flock); - - return 0; -err: - server_finodelk_cbk (frame, NULL, frame->this, state->resolve.op_ret, - state->resolve.op_errno); - - return 0; -} - -static int -server_finodelk (call_frame_t *frame, xlator_t *bound_xl, - gf_hdr_common_t *hdr, size_t hdrlen, - struct iobuf *iobuf) -{ - gf_fop_finodelk_req_t *req = NULL; - server_state_t *state = NULL; - server_connection_t *conn = NULL; - - conn = SERVER_CONNECTION(frame); - - req = gf_param (hdr); - state = CALL_STATE(frame); - - state->resolve.type = RESOLVE_EXACT; - state->volume = gf_strdup (req->volume); - state->resolve.fd_no = ntoh64 (req->fd); - state->cmd = ntoh32 (req->cmd); - - switch (state->cmd) { - case GF_LK_GETLK: - state->cmd = F_GETLK; - break; - case GF_LK_SETLK: - state->cmd = F_SETLK; - break; - case GF_LK_SETLKW: - state->cmd = F_SETLKW; - break; - } - - state->type = ntoh32 (req->type); - - gf_flock_to_flock (&req->flock, &state->flock); - - switch (state->type) { - case GF_LK_F_RDLCK: - state->flock.l_type = F_RDLCK; - break; - case GF_LK_F_WRLCK: - state->flock.l_type = F_WRLCK; - break; - case GF_LK_F_UNLCK: - state->flock.l_type = F_UNLCK; - break; - } - - gf_resolve_and_resume (frame, server_finodelk_resume); - - return 0; -} - - -static int -server_entrylk_resume (call_frame_t *frame, xlator_t *bound_xl) -{ - server_state_t *state = NULL; - - state = CALL_STATE (frame); - - if (state->resolve.op_ret != 0) - goto err; - - STACK_WIND (frame, server_entrylk_cbk, - bound_xl, bound_xl->fops->entrylk, - state->volume, &state->loc, state->name, - state->cmd, state->type); - return 0; -err: - server_entrylk_cbk (frame, NULL, frame->this, state->resolve.op_ret, - state->resolve.op_errno); - return 0; -} - - -static int -server_entrylk (call_frame_t *frame, xlator_t *bound_xl, - gf_hdr_common_t *hdr, size_t hdrlen, - struct iobuf *iobuf) -{ - gf_fop_entrylk_req_t *req = NULL; - server_state_t *state = NULL; - size_t pathlen = 0; - size_t namelen = 0; - size_t vollen = 0; - - req = gf_param (hdr); - state = CALL_STATE (frame); - pathlen = STRLEN_0 (req->path); - namelen = ntoh64 (req->namelen); - vollen = STRLEN_0(req->volume + pathlen + namelen); - - state->resolve.type = RESOLVE_EXACT; - state->resolve.path = gf_strdup (req->path); - state->resolve.ino = ntoh64 (req->ino); - state->resolve.gen = ntoh64 (req->gen); - - if (namelen) - state->name = gf_strdup (req->name + pathlen); - state->volume = gf_strdup (req->volume + pathlen + namelen); - - state->cmd = ntoh32 (req->cmd); - state->type = ntoh32 (req->type); - - gf_resolve_and_resume (frame, server_entrylk_resume); - - return 0; -} - -static int -server_fentrylk_resume (call_frame_t *frame, xlator_t *bound_xl) -{ - server_state_t *state = NULL; - - state = CALL_STATE (frame); - - if (state->resolve.op_ret != 0) - goto err; - - STACK_WIND (frame, server_fentrylk_cbk, - BOUND_XL(frame), - BOUND_XL(frame)->fops->fentrylk, - state->volume, state->fd, state->name, - state->cmd, state->type); - - return 0; -err: - server_fentrylk_cbk (frame, NULL, frame->this, state->resolve.op_ret, - state->resolve.op_errno); - return 0; -} - -static int -server_fentrylk (call_frame_t *frame, xlator_t *bound_xl, - gf_hdr_common_t *hdr, size_t hdrlen, - struct iobuf *iobuf) -{ - gf_fop_fentrylk_req_t *req = NULL; - server_state_t *state = NULL; - size_t namelen = 0; - size_t vollen = 0; - server_connection_t *conn = NULL; - - conn = SERVER_CONNECTION (frame); - - req = gf_param (hdr); - state = CALL_STATE(frame); - vollen = STRLEN_0(req->volume + namelen); - - state->resolve.type = RESOLVE_EXACT; - state->resolve.fd_no = ntoh64 (req->fd); - state->cmd = ntoh32 (req->cmd); - state->type = ntoh32 (req->type); - namelen = ntoh64 (req->namelen); - if (namelen) - state->name = req->name; - state->volume = gf_strdup (req->volume + namelen); - - - gf_resolve_and_resume (frame, server_fentrylk_resume); - - return 0; -} - - -static int -server_access_resume (call_frame_t *frame, xlator_t *bound_xl) -{ - server_state_t *state = NULL; - - state = CALL_STATE (frame); - - if (state->resolve.op_ret != 0) - goto err; - - STACK_WIND (frame, server_access_cbk, - bound_xl, bound_xl->fops->access, - &state->loc, state->mask); - return 0; -err: - server_access_cbk (frame, NULL, frame->this, state->resolve.op_ret, - state->resolve.op_errno); - return 0; -} - - -static int -server_access (call_frame_t *frame, xlator_t *bound_xl, - gf_hdr_common_t *hdr, size_t hdrlen, - struct iobuf *iobuf) -{ - gf_fop_access_req_t *req = NULL; - server_state_t *state = NULL; - - req = gf_param (hdr); - state = CALL_STATE (frame); - - state->resolve.type = RESOLVE_MUST; - state->resolve.ino = hton64 (req->ino); - state->resolve.gen = hton64 (req->gen); - state->resolve.path = gf_strdup (req->path); - - state->mask = ntoh32 (req->mask); - - gf_resolve_and_resume (frame, server_access_resume); - - return 0; -} - - -static int -server_symlink_resume (call_frame_t *frame, xlator_t *bound_xl) -{ - server_state_t *state = NULL; - - state = CALL_STATE (frame); - - if (state->resolve.op_ret != 0) - goto err; - - state->loc.inode = inode_new (state->itable); - - STACK_WIND (frame, server_symlink_cbk, - bound_xl, bound_xl->fops->symlink, - state->name, &state->loc, state->params); - - return 0; -err: - server_symlink_cbk (frame, NULL, frame->this, state->resolve.op_ret, - state->resolve.op_errno, NULL, NULL, NULL, NULL); - return 0; -} - - - -static int -server_symlink (call_frame_t *frame, xlator_t *bound_xl, - gf_hdr_common_t *hdr, size_t hdrlen, - struct iobuf *iobuf) -{ - server_state_t *state = NULL; - gf_fop_symlink_req_t *req = NULL; - size_t pathlen = 0; - size_t baselen = 0; - - req = gf_param (hdr); - state = CALL_STATE (frame); - pathlen = STRLEN_0 (req->path); - baselen = STRLEN_0 (req->bname + pathlen); - - state->resolve.type = RESOLVE_NOT; - state->resolve.par = ntoh64 (req->par); - state->resolve.gen = ntoh64 (req->gen); - state->resolve.path = gf_strdup (req->path); - state->resolve.bname = gf_strdup (req->bname + pathlen); - state->name = gf_strdup (req->linkname + pathlen + baselen); - - gf_resolve_and_resume (frame, server_symlink_resume); - - return 0; -} - - -static int -server_link_resume (call_frame_t *frame, xlator_t *bound_xl) -{ - server_state_t *state = NULL; - int op_ret = 0; - int op_errno = 0; - - state = CALL_STATE (frame); - - if (state->resolve.op_ret != 0) { - op_ret = state->resolve.op_ret; - op_errno = state->resolve.op_errno; - goto err; - } - - if (state->resolve2.op_ret != 0) { - op_ret = state->resolve2.op_ret; - op_errno = state->resolve2.op_errno; - goto err; - } - - state->loc2.inode = inode_ref (state->loc.inode); - - STACK_WIND (frame, server_link_cbk, - bound_xl, bound_xl->fops->link, - &state->loc, &state->loc2); - return 0; -err: - server_link_cbk (frame, NULL, frame->this, op_ret, op_errno, - NULL, NULL, NULL, NULL); - return 0; -} - - -static int -server_link (call_frame_t *frame, xlator_t *this, - gf_hdr_common_t *hdr, size_t hdrlen, - struct iobuf *iobuf) -{ - gf_fop_link_req_t *req = NULL; - server_state_t *state = NULL; - size_t oldpathlen = 0; - size_t newpathlen = 0; - size_t newbaselen = 0; - - req = gf_param (hdr); - state = CALL_STATE (frame); - oldpathlen = STRLEN_0 (req->oldpath); - newpathlen = STRLEN_0 (req->newpath + oldpathlen); - newbaselen = STRLEN_0 (req->newbname + oldpathlen + newpathlen); - - state->resolve.type = RESOLVE_MUST; - state->resolve.path = gf_strdup (req->oldpath); - state->resolve.ino = ntoh64 (req->oldino); - state->resolve.gen = ntoh64 (req->oldgen); - - state->resolve2.type = RESOLVE_NOT; - state->resolve2.path = gf_strdup (req->newpath + oldpathlen); - state->resolve2.bname = gf_strdup (req->newbname + oldpathlen + newpathlen); - state->resolve2.par = ntoh64 (req->newpar); - state->resolve2.gen = ntoh64 (req->newgen); - - gf_resolve_and_resume (frame, server_link_resume); - - return 0; -} - - -static int -server_rename_resume (call_frame_t *frame, xlator_t *bound_xl) -{ - server_state_t *state = NULL; - int op_ret = 0; - int op_errno = 0; - - state = CALL_STATE (frame); - - if (state->resolve.op_ret != 0) { - op_ret = state->resolve.op_ret; - op_errno = state->resolve.op_errno; - goto err; - } - - if (state->resolve2.op_ret != 0) { - op_ret = state->resolve2.op_ret; - op_errno = state->resolve2.op_errno; - goto err; - } - - STACK_WIND (frame, server_rename_cbk, - bound_xl, bound_xl->fops->rename, - &state->loc, &state->loc2); - return 0; -err: - server_rename_cbk (frame, NULL, frame->this, op_ret, op_errno, - NULL, NULL, NULL, NULL, NULL); - return 0; -} - - -static int -server_rename (call_frame_t *frame, xlator_t *bound_xl, - gf_hdr_common_t *hdr, size_t hdrlen, - struct iobuf *iobuf) -{ - gf_fop_rename_req_t *req = NULL; - server_state_t *state = NULL; - size_t oldpathlen = 0; - size_t oldbaselen = 0; - size_t newpathlen = 0; - size_t newbaselen = 0; - - req = gf_param (hdr); - - state = CALL_STATE (frame); - oldpathlen = STRLEN_0 (req->oldpath); - oldbaselen = STRLEN_0 (req->oldbname + oldpathlen); - newpathlen = STRLEN_0 (req->newpath + oldpathlen + oldbaselen); - newbaselen = STRLEN_0 (req->newbname + oldpathlen + - oldbaselen + newpathlen); - - state->resolve.type = RESOLVE_MUST; - state->resolve.path = gf_strdup (req->oldpath); - state->resolve.bname = gf_strdup (req->oldbname + oldpathlen); - state->resolve.par = ntoh64 (req->oldpar); - state->resolve.gen = ntoh64 (req->oldgen); - - state->resolve2.type = RESOLVE_MAY; - state->resolve2.path = gf_strdup (req->newpath + oldpathlen + oldbaselen); - state->resolve2.bname = gf_strdup (req->newbname + oldpathlen + oldbaselen + - newpathlen); - state->resolve2.par = ntoh64 (req->newpar); - state->resolve2.gen = ntoh64 (req->newgen); - - gf_resolve_and_resume (frame, server_rename_resume); - - return 0; -} - -static int -server_lk_resume (call_frame_t *frame, xlator_t *bound_xl) -{ - server_state_t *state = NULL; - - state = CALL_STATE (frame); - - if (state->resolve.op_ret != 0) - goto err; - - STACK_WIND (frame, server_lk_cbk, - BOUND_XL(frame), - BOUND_XL(frame)->fops->lk, - state->fd, state->cmd, &state->flock); - - return 0; - -err: - server_lk_cbk (frame, NULL, frame->this, - state->resolve.op_ret, - state->resolve.op_errno, - NULL); - return 0; -} - -/* - * server_lk - lk function for server protocol - * @frame: call frame - * @bound_xl: - * @params: parameter dictionary - * - * not for external reference - */ - -static int -server_lk (call_frame_t *frame, xlator_t *bound_xl, - gf_hdr_common_t *hdr, size_t hdrlen, - struct iobuf *iobuf) -{ - gf_fop_lk_req_t *req = NULL; - server_state_t *state = NULL; - server_connection_t *conn = NULL; - - conn = SERVER_CONNECTION (frame); - - req = gf_param (hdr); - state = CALL_STATE (frame); - - state->resolve.fd_no = ntoh64 (req->fd); - state->cmd = ntoh32 (req->cmd); - state->type = ntoh32 (req->type); - - switch (state->cmd) { - case GF_LK_GETLK: - state->cmd = F_GETLK; - break; - case GF_LK_SETLK: - state->cmd = F_SETLK; - break; - case GF_LK_SETLKW: - state->cmd = F_SETLKW; - break; - } - - gf_flock_to_flock (&req->flock, &state->flock); - - switch (state->type) { - case GF_LK_F_RDLCK: - state->flock.l_type = F_RDLCK; - break; - case GF_LK_F_WRLCK: - state->flock.l_type = F_WRLCK; - break; - case GF_LK_F_UNLCK: - state->flock.l_type = F_UNLCK; - break; - default: - gf_log (bound_xl->name, GF_LOG_ERROR, - "fd - %"PRId64" (%"PRId64"): Unknown lock type: %"PRId32"!", - state->resolve.fd_no, state->fd->inode->ino, state->type); - break; - } - - - gf_resolve_and_resume (frame, server_lk_resume); - - return 0; -} - -/* xxx_MOPS */ -static int -_volfile_update_checksum (xlator_t *this, char *key, uint32_t checksum) -{ - server_conf_t *conf = NULL; - struct _volfile_ctx *temp_volfile = NULL; - - conf = this->private; - temp_volfile = conf->volfile; - - while (temp_volfile) { - if ((NULL == key) && (NULL == temp_volfile->key)) - break; - if ((NULL == key) || (NULL == temp_volfile->key)) { - temp_volfile = temp_volfile->next; - continue; - } - if (strcmp (temp_volfile->key, key) == 0) - break; - temp_volfile = temp_volfile->next; - } - - if (!temp_volfile) { - temp_volfile = GF_CALLOC (1, sizeof (struct _volfile_ctx), - gf_server_mt_volfile_ctx); - if (!temp_volfile) - goto out; - temp_volfile->next = conf->volfile; - temp_volfile->key = (key)? gf_strdup (key): NULL; - temp_volfile->checksum = checksum; - - conf->volfile = temp_volfile; - goto out; - } - - if (temp_volfile->checksum != checksum) { - gf_log (this->name, GF_LOG_CRITICAL, - "the volume file got modified between earlier access " - "and now, this may lead to inconsistency between " - "clients, advised to remount client"); - temp_volfile->checksum = checksum; - } - - out: - return 0; -} - - -size_t -build_volfile_path (xlator_t *this, const char *key, char *path, - size_t path_len) -{ - int ret = -1; - int free_filename = 0; - int free_conf_dir = 0; - char *filename = NULL; - char *conf_dir = CONFDIR; - struct stat buf = {0,}; - data_t * conf_dir_data = NULL; - char data_key[256] = {0,}; - - /* Inform users that this option is changed now */ - ret = dict_get_str (this->options, "client-volume-filename", - &filename); - if (ret == 0) { - gf_log (this->name, GF_LOG_WARNING, - "option 'client-volume-filename' is changed to " - "'volume-filename.<key>' which now takes 'key' as an " - "option to choose/fetch different files from server. " - "Refer documentation or contact developers for more " - "info. Currently defaulting to given file '%s'", - filename); - } - - if (key && !filename) { - sprintf (data_key, "volume-filename.%s", key); - ret = dict_get_str (this->options, data_key, &filename); - - if (ret < 0) { - - conf_dir_data = dict_get (this->options, "conf-dir"); - if (conf_dir_data) { - /* Check whether the specified directory exists, - or directory specified is non standard */ - ret = stat (conf_dir_data->data, &buf); - if ((ret != 0) || !S_ISDIR (buf.st_mode)) { - gf_log (this->name, GF_LOG_ERROR, - "Directory '%s' doesn't" - "exist, exiting.", - conf_dir_data->data); - ret = -1; - goto out; - } - /* Make sure that conf-dir doesn't - * contain ".." in path - */ - if ((gf_strstr (conf_dir_data->data, - "/", "..")) == -1) { - ret = -1; - gf_log (this->name, GF_LOG_ERROR, - "%s: invalid conf_dir", - conf_dir_data->data); - goto out; - } - - /* Make sure that key doesn't - * contain "../" in path - */ - - if ((gf_strstr (key, "/", "..")) == -1) { - ret = -1; - gf_log (this->name, GF_LOG_ERROR, - "%s: invalid key", key); - goto out; - } - - conf_dir = gf_strdup (conf_dir_data->data); - free_conf_dir = 1; - } - - ret = gf_asprintf (&filename, "%s/%s.vol", - conf_dir, key); - if (-1 == ret) - goto out; - - free_filename = 1; - } - } - - if (!filename) { - ret = dict_get_str (this->options, - "volume-filename.default", &filename); - if (ret < 0) { - gf_log (this->name, GF_LOG_DEBUG, - "no default volume filename given, " - "defaulting to %s", DEFAULT_VOLUME_FILE_PATH); - filename = DEFAULT_VOLUME_FILE_PATH; - } - } - - ret = -1; - - if ((filename) && (path_len > strlen (filename))) { - strcpy (path, filename); - ret = strlen (filename); - } - -out: - if (free_conf_dir) - GF_FREE (conf_dir); - - if (free_filename) - GF_FREE (filename); - - return ret; -} - -static int -_validate_volfile_checksum (xlator_t *this, char *key, - uint32_t checksum) -{ - char filename[PATH_MAX] = {0,}; - server_conf_t *conf = NULL; - struct _volfile_ctx *temp_volfile = NULL; - int ret = 0; - uint32_t local_checksum = 0; - - conf = this->private; - temp_volfile = conf->volfile; - - if (!checksum) - goto out; - - if (!temp_volfile) { - ret = build_volfile_path (this, key, filename, - sizeof (filename)); - if (ret <= 0) - goto out; - ret = open (filename, O_RDONLY); - if (-1 == ret) { - ret = 0; - gf_log (this->name, GF_LOG_DEBUG, - "failed to open volume file (%s) : %s", - filename, strerror (errno)); - goto out; - } - get_checksum_for_file (ret, &local_checksum); - _volfile_update_checksum (this, key, local_checksum); - close (ret); - } - - temp_volfile = conf->volfile; - while (temp_volfile) { - if ((NULL == key) && (NULL == temp_volfile->key)) - break; - if ((NULL == key) || (NULL == temp_volfile->key)) { - temp_volfile = temp_volfile->next; - continue; - } - if (strcmp (temp_volfile->key, key) == 0) - break; - temp_volfile = temp_volfile->next; - } - - if (!temp_volfile) - goto out; - - if ((temp_volfile->checksum) && - (checksum != temp_volfile->checksum)) - ret = -1; - -out: - return ret; -} - -/* Management Calls */ -/* - * mop_getspec - getspec function for server protocol - * @frame: call frame - * @bound_xl: - * @params: - * - */ -static int -mop_getspec (call_frame_t *frame, xlator_t *bound_xl, - gf_hdr_common_t *hdr, size_t hdrlen, - struct iobuf *iobuf) -{ - gf_hdr_common_t *_hdr = NULL; - gf_mop_getspec_rsp_t *rsp = NULL; - int32_t ret = -1; - int32_t op_errno = ENOENT; - int32_t gf_errno = 0; - int32_t spec_fd = -1; - size_t file_len = 0; - size_t _hdrlen = 0; - char filename[PATH_MAX] = {0,}; - struct stat stbuf = {0,}; - gf_mop_getspec_req_t *req = NULL; - uint32_t checksum = 0; - uint32_t flags = 0; - uint32_t keylen = 0; - char *key = NULL; - server_conf_t *conf = NULL; - - req = gf_param (hdr); - flags = ntoh32 (req->flags); - keylen = ntoh32 (req->keylen); - if (keylen) { - key = req->key; - } - - conf = frame->this->private; - - ret = build_volfile_path (frame->this, key, filename, - sizeof (filename)); - if (ret > 0) { - /* to allocate the proper buffer to hold the file data */ - ret = stat (filename, &stbuf); - if (ret < 0){ - gf_log (frame->this->name, GF_LOG_ERROR, - "Unable to stat %s (%s)", - filename, strerror (errno)); - goto fail; - } - - spec_fd = open (filename, O_RDONLY); - if (spec_fd < 0) { - gf_log (frame->this->name, GF_LOG_ERROR, - "Unable to open %s (%s)", - filename, strerror (errno)); - goto fail; - } - ret = 0; - file_len = stbuf.st_size; - if (conf->verify_volfile_checksum) { - get_checksum_for_file (spec_fd, &checksum); - _volfile_update_checksum (frame->this, key, checksum); - } - } else { - errno = ENOENT; - } - -fail: - op_errno = errno; - - _hdrlen = gf_hdr_len (rsp, file_len + 1); - _hdr = gf_hdr_new (rsp, file_len + 1); - rsp = gf_param (_hdr); - - _hdr->rsp.op_ret = hton32 (ret); - gf_errno = gf_errno_to_error (op_errno); - _hdr->rsp.op_errno = hton32 (gf_errno); - - if (file_len) { - ret = read (spec_fd, rsp->spec, file_len); - close (spec_fd); - } - protocol_server_reply (frame, GF_OP_TYPE_MOP_REPLY, GF_MOP_GETSPEC, - _hdr, _hdrlen, NULL, 0, NULL); - - return 0; -} - - - -static int -server_checksum (call_frame_t *frame, xlator_t *bound_xl, - gf_hdr_common_t *hdr, size_t hdrlen, - struct iobuf *iobuf) -{ - gf_hdr_common_t *rsp_hdr = NULL; - gf_mop_ping_rsp_t *rsp = NULL; /* Using for NULL */ - size_t rsp_hdrlen = 0; - int32_t gf_errno = 0; - - rsp_hdrlen = gf_hdr_len (rsp, 0); - rsp_hdr = gf_hdr_new (rsp, 0); - - gf_errno = gf_errno_to_error (ENOSYS); - hdr->rsp.op_errno = hton32 (gf_errno); - hdr->rsp.op_ret = -1; - - protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_PROTO_FOP_CHECKSUM, - rsp_hdr, rsp_hdrlen, NULL, 0, NULL); - - return 0; -} - - -static int -server_rchecksum_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, - uint32_t weak_checksum, uint8_t *strong_checksum) -{ - gf_hdr_common_t *hdr = NULL; - gf_fop_rchecksum_rsp_t *rsp = NULL; - size_t hdrlen = 0; - int32_t gf_errno = 0; - - hdrlen = gf_hdr_len (rsp, MD5_DIGEST_LEN + 1); - hdr = gf_hdr_new (rsp, MD5_DIGEST_LEN + 1); - rsp = gf_param (hdr); - - hdr->rsp.op_ret = hton32 (op_ret); - gf_errno = gf_errno_to_error (op_errno); - hdr->rsp.op_errno = hton32 (gf_errno); - - if (op_ret >= 0) { - rsp->weak_checksum = weak_checksum; - - memcpy (rsp->strong_checksum, - strong_checksum, MD5_DIGEST_LEN); - - rsp->strong_checksum[MD5_DIGEST_LEN] = '\0'; - } - - protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_PROTO_FOP_RCHECKSUM, - hdr, hdrlen, NULL, 0, NULL); - - return 0; -} - -static int -server_rchecksum_resume (call_frame_t *frame, xlator_t *bound_xl) -{ - server_state_t *state = NULL; - int op_ret = 0; - int op_errno = 0; - - state = CALL_STATE (frame); - - if (state->resolve.op_ret != 0) { - op_ret = state->resolve.op_ret; - op_errno = state->resolve.op_errno; - goto err; - } - - STACK_WIND (frame, server_rchecksum_cbk, - bound_xl, - bound_xl->fops->rchecksum, - state->fd, state->offset, state->size); - - return 0; -err: - server_rchecksum_cbk (frame, NULL, frame->this, -1, EINVAL, 0, NULL); - - return 0; - -} - -static int -server_rchecksum (call_frame_t *frame, xlator_t *bound_xl, - gf_hdr_common_t *hdr, size_t hdrlen, - struct iobuf *iobuf) -{ - gf_fop_rchecksum_req_t *req = NULL; - server_state_t *state = NULL; - server_connection_t *conn = NULL; - - conn = SERVER_CONNECTION(frame); - - req = gf_param (hdr); - - state = CALL_STATE(frame); - - state->resolve.type = RESOLVE_MAY; - state->resolve.fd_no = ntoh64 (req->fd); - state->offset = ntoh64 (req->offset); - state->size = ntoh32 (req->len); - - gf_resolve_and_resume (frame, server_rchecksum_resume); - - return 0; -} - - -/* - * mop_unlock - unlock management function for server protocol - * @frame: call frame - * @bound_xl: - * @params: parameter dictionary - * - */ -static int -mop_getvolume (call_frame_t *frame, xlator_t *bound_xl, - gf_hdr_common_t *hdr, size_t hdrlen, - struct iobuf *iobuf) -{ - return 0; -} - -struct __get_xl_struct { - const char *name; - xlator_t *reply; -}; - -static void __check_and_set (xlator_t *each, void *data) -{ - if (!strcmp (each->name, - ((struct __get_xl_struct *) data)->name)) - ((struct __get_xl_struct *) data)->reply = each; -} - -static xlator_t * -get_xlator_by_name (xlator_t *some_xl, const char *name) -{ - struct __get_xl_struct get = { - .name = name, - .reply = NULL - }; - - xlator_foreach (some_xl, __check_and_set, &get); - - return get.reply; -} - - -/* - * mop_setvolume - setvolume management function for server protocol - * @frame: call frame - * @bound_xl: - * @params: parameter dictionary - * - */ -static int -mop_setvolume (call_frame_t *frame, xlator_t *bound_xl, - gf_hdr_common_t *req_hdr, size_t req_hdrlen, - struct iobuf *iobuf) -{ - server_connection_t *conn = NULL; - server_conf_t *conf = NULL; - gf_hdr_common_t *rsp_hdr = NULL; - gf_mop_setvolume_req_t *req = NULL; - gf_mop_setvolume_rsp_t *rsp = NULL; - peer_info_t *peerinfo = NULL; - int32_t ret = -1; - int32_t op_ret = -1; - int32_t op_errno = EINVAL; - int32_t gf_errno = 0; - dict_t *reply = NULL; - dict_t *config_params = NULL; - dict_t *params = NULL; - char *name = NULL; - char *version = NULL; - char *process_uuid = NULL; - xlator_t *xl = NULL; - transport_t *trans = NULL; - size_t rsp_hdrlen = -1; - size_t dict_len = -1; - size_t req_dictlen = -1; - char *msg = NULL; - char *volfile_key = NULL; - uint32_t checksum = 0; - int32_t lru_limit = 1024; - - params = dict_new (); - reply = dict_new (); - - req = gf_param (req_hdr); - req_dictlen = ntoh32 (req->dict_len); - ret = dict_unserialize (req->buf, req_dictlen, ¶ms); - - config_params = dict_copy_with_ref (frame->this->options, NULL); - trans = TRANSPORT_FROM_FRAME(frame); - conf = SERVER_CONF(frame); - - if (ret < 0) { - ret = dict_set_str (reply, "ERROR", - "Internal error: failed to unserialize " - "request dictionary"); - if (ret < 0) - gf_log (bound_xl->name, GF_LOG_DEBUG, - "failed to set error msg \"%s\"", - "Internal error: failed to unserialize " - "request dictionary"); - - op_ret = -1; - op_errno = EINVAL; - goto fail; - } - - ret = dict_get_str (params, "process-uuid", &process_uuid); - if (ret < 0) { - ret = dict_set_str (reply, "ERROR", - "UUID not specified"); - if (ret < 0) - gf_log (bound_xl->name, GF_LOG_DEBUG, - "failed to set error msg"); - - op_ret = -1; - op_errno = EINVAL; - goto fail; - } - - - conn = gf_server_connection_get (frame->this, process_uuid); - if (trans->xl_private != conn) - trans->xl_private = conn; - - ret = dict_get_str (params, "protocol-version", &version); - if (ret < 0) { - ret = dict_set_str (reply, "ERROR", - "No version number specified"); - if (ret < 0) - gf_log (trans->xl->name, GF_LOG_DEBUG, - "failed to set error msg"); - - op_ret = -1; - op_errno = EINVAL; - goto fail; - } - - ret = strcmp (version, GF_PROTOCOL_VERSION); - if (ret != 0) { - ret = gf_asprintf (&msg, "protocol version mismatch: client(%s) " - "- server(%s)", version, GF_PROTOCOL_VERSION); - if (-1 == ret) { - gf_log (trans->xl->name, GF_LOG_ERROR, - "gf_asprintf failed while setting up error msg"); - goto fail; - } - ret = dict_set_dynstr (reply, "ERROR", msg); - if (ret < 0) - gf_log (trans->xl->name, GF_LOG_DEBUG, - "failed to set error msg"); - - op_ret = -1; - op_errno = EINVAL; - goto fail; - } - - ret = dict_get_str (params, - "remote-subvolume", &name); - if (ret < 0) { - ret = dict_set_str (reply, "ERROR", - "No remote-subvolume option specified"); - if (ret < 0) - gf_log (trans->xl->name, GF_LOG_DEBUG, - "failed to set error msg"); - - op_ret = -1; - op_errno = EINVAL; - goto fail; - } - - xl = get_xlator_by_name (frame->this, name); - if (xl == NULL) { - ret = gf_asprintf (&msg, "remote-subvolume \"%s\" is not found", - name); - if (-1 == ret) { - gf_log (trans->xl->name, GF_LOG_ERROR, - "gf_asprintf failed while setting error msg"); - goto fail; - } - ret = dict_set_dynstr (reply, "ERROR", msg); - if (ret < 0) - gf_log (trans->xl->name, GF_LOG_DEBUG, - "failed to set error msg"); - - op_ret = -1; - op_errno = ENOENT; - goto fail; - } - - if (conf->verify_volfile_checksum) { - ret = dict_get_uint32 (params, "volfile-checksum", &checksum); - if (ret == 0) { - ret = dict_get_str (params, "volfile-key", - &volfile_key); - - ret = _validate_volfile_checksum (trans->xl, - volfile_key, - checksum); - if (-1 == ret) { - ret = dict_set_str (reply, "ERROR", - "volume-file checksum " - "varies from earlier " - "access"); - if (ret < 0) - gf_log (trans->xl->name, GF_LOG_DEBUG, - "failed to set error msg"); - - op_ret = -1; - op_errno = ESTALE; - goto fail; - } - } - } - - - peerinfo = &trans->peerinfo; - ret = dict_set_static_ptr (params, "peer-info", peerinfo); - if (ret < 0) - gf_log (trans->xl->name, GF_LOG_DEBUG, - "failed to set peer-info"); - ret = dict_set_str (params, "peer-info-name", peerinfo->identifier); - if (ret < 0) - gf_log (trans->xl->name, GF_LOG_DEBUG, - "failed to set peer-info-name"); - - if (conf->auth_modules == NULL) { - gf_log (trans->xl->name, GF_LOG_ERROR, - "Authentication module not initialized"); - } - - ret = gf_authenticate (params, config_params, - conf->auth_modules); - if (ret == AUTH_ACCEPT) { - gf_log (trans->xl->name, GF_LOG_INFO, - "accepted client from %s", - peerinfo->identifier); - op_ret = 0; - conn->bound_xl = xl; - ret = dict_set_str (reply, "ERROR", "Success"); - if (ret < 0) - gf_log (trans->xl->name, GF_LOG_DEBUG, - "failed to set error msg"); - } else { - gf_log (trans->xl->name, GF_LOG_ERROR, - "Cannot authenticate client from %s", - peerinfo->identifier); - op_ret = -1; - op_errno = EACCES; - ret = dict_set_str (reply, "ERROR", "Authentication failed"); - if (ret < 0) - gf_log (bound_xl->name, GF_LOG_DEBUG, - "failed to set error msg"); - - goto fail; - } - - if (conn->bound_xl == NULL) { - ret = dict_set_str (reply, "ERROR", - "Check volfile and handshake " - "options in protocol/client"); - if (ret < 0) - gf_log (trans->xl->name, GF_LOG_DEBUG, - "failed to set error msg"); - - op_ret = -1; - op_errno = EACCES; - goto fail; - } - - if ((conn->bound_xl != NULL) && - (ret >= 0) && - (conn->bound_xl->itable == NULL)) { - /* create inode table for this bound_xl, if one doesn't - already exist */ - lru_limit = INODE_LRU_LIMIT (frame->this); - - gf_log (trans->xl->name, GF_LOG_TRACE, - "creating inode table with lru_limit=%"PRId32", " - "xlator=%s", lru_limit, conn->bound_xl->name); - - conn->bound_xl->itable = - inode_table_new (lru_limit, - conn->bound_xl); - } - - ret = dict_set_str (reply, "process-uuid", - xl->ctx->process_uuid); - - ret = dict_set_uint64 (reply, "transport-ptr", - ((uint64_t) (long) trans)); - -fail: - dict_len = dict_serialized_length (reply); - if (dict_len < 0) { - gf_log ("server", GF_LOG_DEBUG, - "failed to get serialized length of reply dict"); - op_ret = -1; - op_errno = EINVAL; - dict_len = 0; - } - - rsp_hdr = gf_hdr_new (rsp, dict_len); - rsp_hdrlen = gf_hdr_len (rsp, dict_len); - rsp = gf_param (rsp_hdr); - - if (dict_len) { - ret = dict_serialize (reply, rsp->buf); - if (ret < 0) { - gf_log ("server", GF_LOG_DEBUG, - "failed to serialize reply dict"); - op_ret = -1; - op_errno = -ret; - } - } - rsp->dict_len = hton32 (dict_len); - - rsp_hdr->rsp.op_ret = hton32 (op_ret); - gf_errno = gf_errno_to_error (op_errno); - rsp_hdr->rsp.op_errno = hton32 (gf_errno); - - protocol_server_reply (frame, GF_OP_TYPE_MOP_REPLY, GF_MOP_SETVOLUME, - rsp_hdr, rsp_hdrlen, NULL, 0, NULL); - - dict_unref (params); - dict_unref (reply); - dict_unref (config_params); - - return 0; -} - - -static int -mop_ping (call_frame_t *frame, xlator_t *bound_xl, - gf_hdr_common_t *hdr, size_t hdrlen, - struct iobuf *iobuf) -{ - gf_hdr_common_t *rsp_hdr = NULL; - gf_mop_ping_rsp_t *rsp = NULL; - size_t rsp_hdrlen = 0; - - rsp_hdrlen = gf_hdr_len (rsp, 0); - rsp_hdr = gf_hdr_new (rsp, 0); - - hdr->rsp.op_ret = 0; - - protocol_server_reply (frame, GF_OP_TYPE_MOP_REPLY, GF_MOP_PING, - rsp_hdr, rsp_hdrlen, NULL, 0, NULL); - - return 0; -} - - -static int -mop_log (call_frame_t *frame, xlator_t *bound_xl, - gf_hdr_common_t *hdr, size_t hdrlen, - struct iobuf *iobuf) -{ - gf_mop_log_req_t * req = NULL; - char * msg = NULL; - uint32_t msglen = 0; - - transport_t * trans = NULL; - - trans = TRANSPORT_FROM_FRAME (frame); - - req = gf_param (hdr); - msglen = ntoh32 (req->msglen); - - if (msglen) - msg = req->msg; - - gf_log_from_client (msg, trans->peerinfo.identifier); - - return 0; -} - - -/* ENOSYS operations (for backword compatibility) */ -static int -server_setdents (call_frame_t *frame, xlator_t *bound_xl, - gf_hdr_common_t *hdr, size_t hdrlen, - struct iobuf *iobuf) -{ - gf_hdr_common_t *rsp_hdr = NULL; - gf_mop_ping_rsp_t *rsp = NULL; /* Using for NULL */ - size_t rsp_hdrlen = 0; - int32_t gf_errno = 0; - - rsp_hdrlen = gf_hdr_len (rsp, 0); - rsp_hdr = gf_hdr_new (rsp, 0); - - gf_errno = gf_errno_to_error (ENOSYS); - hdr->rsp.op_errno = hton32 (gf_errno); - hdr->rsp.op_ret = -1; - - protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_PROTO_FOP_SETDENTS, - rsp_hdr, rsp_hdrlen, NULL, 0, NULL); - - return 0; -} - -/* */ -static int -server_getdents (call_frame_t *frame, xlator_t *bound_xl, - gf_hdr_common_t *hdr, size_t hdrlen, - struct iobuf *iobuf) -{ - gf_hdr_common_t *rsp_hdr = NULL; - gf_mop_ping_rsp_t *rsp = NULL; /* Using for NULL */ - size_t rsp_hdrlen = 0; - int32_t gf_errno = 0; - - rsp_hdrlen = gf_hdr_len (rsp, 0); - rsp_hdr = gf_hdr_new (rsp, 0); - - gf_errno = gf_errno_to_error (ENOSYS); - hdr->rsp.op_errno = hton32 (gf_errno); - hdr->rsp.op_ret = -1; - - protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_PROTO_FOP_GETDENTS, - rsp_hdr, rsp_hdrlen, NULL, 0, NULL); - - return 0; -} - -/* */ -static int -server_lock_notify (call_frame_t *frame, xlator_t *bound_xl, - gf_hdr_common_t *hdr, size_t hdrlen, - struct iobuf *iobuf) -{ - gf_hdr_common_t *rsp_hdr = NULL; - gf_mop_ping_rsp_t *rsp = NULL; /* Using for NULL */ - size_t rsp_hdrlen = 0; - int32_t gf_errno = 0; - - rsp_hdrlen = gf_hdr_len (rsp, 0); - rsp_hdr = gf_hdr_new (rsp, 0); - - gf_errno = gf_errno_to_error (ENOSYS); - hdr->rsp.op_errno = hton32 (gf_errno); - hdr->rsp.op_ret = -1; - - protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_PROTO_FOP_LOCK_NOTIFY, - rsp_hdr, rsp_hdrlen, NULL, 0, NULL); - - return 0; -} - -/* */ -static int -server_lock_fnotify (call_frame_t *frame, xlator_t *bound_xl, - gf_hdr_common_t *hdr, size_t hdrlen, - struct iobuf *iobuf) -{ - gf_hdr_common_t *rsp_hdr = NULL; - gf_mop_ping_rsp_t *rsp = NULL; /* Using for NULL */ - size_t rsp_hdrlen = 0; - int32_t gf_errno = 0; - - rsp_hdrlen = gf_hdr_len (rsp, 0); - rsp_hdr = gf_hdr_new (rsp, 0); - - gf_errno = gf_errno_to_error (ENOSYS); - hdr->rsp.op_errno = hton32 (gf_errno); - hdr->rsp.op_ret = -1; - - protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_PROTO_FOP_LOCK_FNOTIFY, - rsp_hdr, rsp_hdrlen, NULL, 0, NULL); - - return 0; -} - - -static int -mop_stats (call_frame_t *frame, xlator_t *bound_xl, - gf_hdr_common_t *hdr, size_t hdrlen, - struct iobuf *iobuf) -{ - gf_hdr_common_t *rsp_hdr = NULL; - gf_mop_ping_rsp_t *rsp = NULL; /* Using for NULL */ - size_t rsp_hdrlen = 0; - int32_t gf_errno = 0; - - rsp_hdrlen = gf_hdr_len (rsp, 0); - rsp_hdr = gf_hdr_new (rsp, 0); - - gf_errno = gf_errno_to_error (ENOSYS); - hdr->rsp.op_errno = hton32 (gf_errno); - hdr->rsp.op_ret = -1; - - protocol_server_reply (frame, GF_OP_TYPE_MOP_REPLY, GF_MOP_STATS, - rsp_hdr, rsp_hdrlen, NULL, 0, NULL); - - return 0; -} - - -/* - * get_frame_for_transport - get call frame for specified transport object - * - * @trans: transport object - * - */ -static call_frame_t * -get_frame_for_transport (transport_t *trans) -{ - call_frame_t *frame = NULL; - call_pool_t *pool = NULL; - server_connection_t *conn = NULL; - server_state_t *state = NULL;; - - GF_VALIDATE_OR_GOTO("server", trans, out); - - if (trans->xl && trans->xl->ctx) - pool = trans->xl->ctx->pool; - GF_VALIDATE_OR_GOTO("server", pool, out); - - frame = create_frame (trans->xl, pool); - GF_VALIDATE_OR_GOTO("server", frame, out); - - state = GF_CALLOC (1, sizeof (*state), - gf_server_mt_server_state_t); - GF_VALIDATE_OR_GOTO("server", state, out); - - conn = trans->xl_private; - if (conn) { - if (conn->bound_xl) - state->itable = conn->bound_xl->itable; - state->bound_xl = conn->bound_xl; - } - - state->trans = transport_ref (trans); - state->resolve.fd_no = -1; - state->resolve2.fd_no = -1; - - frame->root->trans = conn; - frame->root->state = state; /* which socket */ - frame->root->unique = 0; /* which call */ - -out: - return frame; -} - - -static int -server_decode_groups (call_frame_t *frame, gf_hdr_common_t *hdr) -{ - int i = 0; - - if ((!frame) || (!hdr)) - return 0; - - frame->root->ngrps = ntoh32 (hdr->req.ngrps); - if (frame->root->ngrps == 0) - return 0; - - if (frame->root->ngrps > GF_REQUEST_MAXGROUPS) - return -1; - - for (; i < frame->root->ngrps; ++i) - frame->root->groups[i] = ntoh32 (hdr->req.groups[i]); - - return 0; -} - - -/* - * get_frame_for_call - create a frame into the capable of - * generating and replying the reply packet by itself. - * By making a call with this frame, the last UNWIND - * function will have all needed state from its - * frame_t->root to send reply. - * @trans: - * @blk: - * @params: - * - * not for external reference - */ -static call_frame_t * -get_frame_for_call (transport_t *trans, gf_hdr_common_t *hdr) -{ - call_frame_t *frame = NULL; - int32_t ret = -1; - - frame = get_frame_for_transport (trans); - - frame->root->op = ntoh32 (hdr->op); - frame->root->type = ntoh32 (hdr->type); - - frame->root->uid = ntoh32 (hdr->req.uid); - frame->root->unique = ntoh64 (hdr->callid); /* which call */ - frame->root->gid = ntoh32 (hdr->req.gid); - frame->root->pid = ntoh32 (hdr->req.pid); - frame->root->lk_owner = ntoh64 (hdr->req.lk_owner); - ret = server_decode_groups (frame, hdr); - - if (ret) { - //FRAME_DESTROY (frame); - return NULL; - } - - return frame; -} - -/* - * prototype of operations function for each of mop and - * fop at server protocol level - * - * @frame: call frame pointer - * @bound_xl: the xlator that this frame is bound to - * @params: parameters dictionary - * - * to be used by protocol interpret, _not_ for exterenal reference - */ -typedef int32_t (*gf_op_t) (call_frame_t *frame, xlator_t *bould_xl, - gf_hdr_common_t *hdr, size_t hdrlen, - struct iobuf *iobuf); - - -static gf_op_t gf_fops[] = { - [GF_PROTO_FOP_STAT] = server_stat, - [GF_PROTO_FOP_READLINK] = server_readlink, - [GF_PROTO_FOP_MKNOD] = server_mknod, - [GF_PROTO_FOP_MKDIR] = server_mkdir, - [GF_PROTO_FOP_UNLINK] = server_unlink, - [GF_PROTO_FOP_RMDIR] = server_rmdir, - [GF_PROTO_FOP_SYMLINK] = server_symlink, - [GF_PROTO_FOP_RENAME] = server_rename, - [GF_PROTO_FOP_LINK] = server_link, - [GF_PROTO_FOP_TRUNCATE] = server_truncate, - [GF_PROTO_FOP_OPEN] = server_open, - [GF_PROTO_FOP_READ] = server_readv, - [GF_PROTO_FOP_WRITE] = server_writev, - [GF_PROTO_FOP_STATFS] = server_statfs, - [GF_PROTO_FOP_FLUSH] = server_flush, - [GF_PROTO_FOP_FSYNC] = server_fsync, - [GF_PROTO_FOP_SETXATTR] = server_setxattr, - [GF_PROTO_FOP_GETXATTR] = server_getxattr, - [GF_PROTO_FOP_FGETXATTR] = server_fgetxattr, - [GF_PROTO_FOP_FSETXATTR] = server_fsetxattr, - [GF_PROTO_FOP_REMOVEXATTR] = server_removexattr, - [GF_PROTO_FOP_OPENDIR] = server_opendir, - [GF_PROTO_FOP_FSYNCDIR] = server_fsyncdir, - [GF_PROTO_FOP_ACCESS] = server_access, - [GF_PROTO_FOP_CREATE] = server_create, - [GF_PROTO_FOP_FTRUNCATE] = server_ftruncate, - [GF_PROTO_FOP_FSTAT] = server_fstat, - [GF_PROTO_FOP_LK] = server_lk, - [GF_PROTO_FOP_LOOKUP] = server_lookup, - [GF_PROTO_FOP_READDIR] = server_readdir, - [GF_PROTO_FOP_READDIRP] = server_readdirp, - [GF_PROTO_FOP_INODELK] = server_inodelk, - [GF_PROTO_FOP_FINODELK] = server_finodelk, - [GF_PROTO_FOP_ENTRYLK] = server_entrylk, - [GF_PROTO_FOP_FENTRYLK] = server_fentrylk, - [GF_PROTO_FOP_CHECKSUM] = server_checksum, - [GF_PROTO_FOP_RCHECKSUM] = server_rchecksum, - [GF_PROTO_FOP_XATTROP] = server_xattrop, - [GF_PROTO_FOP_FXATTROP] = server_fxattrop, - [GF_PROTO_FOP_SETATTR] = server_setattr, - [GF_PROTO_FOP_FSETATTR] = server_fsetattr, - [GF_PROTO_FOP_SETDENTS] = server_setdents, - [GF_PROTO_FOP_GETDENTS] = server_getdents, - [GF_PROTO_FOP_LOCK_NOTIFY] = server_lock_notify, - [GF_PROTO_FOP_LOCK_FNOTIFY] = server_lock_fnotify, -}; - - - -static gf_op_t gf_mops[] = { - [GF_MOP_SETVOLUME] = mop_setvolume, - [GF_MOP_GETVOLUME] = mop_getvolume, - [GF_MOP_GETSPEC] = mop_getspec, - [GF_MOP_PING] = mop_ping, - [GF_MOP_LOG] = mop_log, - [GF_MOP_STATS] = mop_stats, -}; - -static gf_op_t gf_cbks[] = { - [GF_CBK_FORGET] = server_forget, - [GF_CBK_RELEASE] = server_release, - [GF_CBK_RELEASEDIR] = server_releasedir -}; - -static int -protocol_server_interpret (xlator_t *this, transport_t *trans, - char *hdr_p, size_t hdrlen, struct iobuf *iobuf) -{ - server_connection_t *conn = NULL; - gf_hdr_common_t *hdr = NULL; - xlator_t *bound_xl = NULL; - call_frame_t *frame = NULL; - peer_info_t *peerinfo = NULL; - int32_t type = -1; - int32_t op = -1; - int32_t ret = -1; - - hdr = (gf_hdr_common_t *)hdr_p; - type = ntoh32 (hdr->type); - op = ntoh32 (hdr->op); - - conn = trans->xl_private; - if (conn) - bound_xl = conn->bound_xl; - - peerinfo = &trans->peerinfo; - switch (type) { - case GF_OP_TYPE_FOP_REQUEST: - if ((op < 0) || (op >= GF_PROTO_FOP_MAXVALUE)) { - gf_log (this->name, GF_LOG_ERROR, - "invalid fop %"PRId32" from client %s", - op, peerinfo->identifier); - break; - } - if (bound_xl == NULL) { - gf_log (this->name, GF_LOG_ERROR, - "Received fop %"PRId32" before " - "authentication.", op); - break; - } - frame = get_frame_for_call (trans, hdr); - if (!frame) { - ret = -1; - goto out; - } - frame->op = op; - ret = gf_fops[op] (frame, bound_xl, hdr, hdrlen, iobuf); - break; - - case GF_OP_TYPE_MOP_REQUEST: - if ((op < 0) || (op >= GF_MOP_MAXVALUE)) { - gf_log (this->name, GF_LOG_ERROR, - "invalid mop %"PRId32" from client %s", - op, peerinfo->identifier); - break; - } - frame = get_frame_for_call (trans, hdr); - if (!frame) { - ret = -1; - goto out; - } - frame->op = op; - ret = gf_mops[op] (frame, bound_xl, hdr, hdrlen, iobuf); - break; - - case GF_OP_TYPE_CBK_REQUEST: - if ((op < 0) || (op >= GF_CBK_MAXVALUE)) { - gf_log (this->name, GF_LOG_ERROR, - "invalid cbk %"PRId32" from client %s", - op, peerinfo->identifier); - break; - } - if (bound_xl == NULL) { - gf_log (this->name, GF_LOG_ERROR, - "Received cbk %d before authentication.", op); - break; - } - - frame = get_frame_for_call (trans, hdr); - if (!frame) { - ret = -1; - goto out; - } - ret = gf_cbks[op] (frame, bound_xl, hdr, hdrlen, iobuf); - break; - - default: - break; - } -out: - return ret; -} - - -/* - * server_fd - fdtable dump function for server protocol - * @this: - * - */ -static int -server_fd (xlator_t *this) -{ - server_conf_t *conf = NULL; - server_connection_t *trav = NULL; - char key[GF_DUMP_MAX_BUF_LEN]; - int i = 1; - int ret = -1; - - if (!this) - return -1; - - conf = this->private; - if (!conf) { - gf_log (this->name, GF_LOG_WARNING, - "conf null in xlator"); - return -1; - } - - gf_proc_dump_add_section("xlator.protocol.server.conn"); - - ret = pthread_mutex_trylock (&conf->mutex); - if (ret) { - gf_log("", GF_LOG_WARNING, "Unable to dump fdtable" - " errno: %d", errno); - return -1; - } - - list_for_each_entry (trav, &conf->conns, list) { - if (trav->id) { - gf_proc_dump_build_key(key, - "xlator.protocol.server.conn", - "%d.id", i); - gf_proc_dump_write(key, "%s", trav->id); - } - - gf_proc_dump_build_key(key,"xlator.protocol.server.conn", - "%d.ref",i) - gf_proc_dump_write(key, "%d", trav->ref); - if (trav->bound_xl) { - gf_proc_dump_build_key(key, - "xlator.protocol.server.conn", - "%d.bound_xl", i); - gf_proc_dump_write(key, "%s", trav->bound_xl->name); - } - - gf_proc_dump_build_key(key, - "xlator.protocol.server.conn", - "%d.id", i); - fdtable_dump(trav->fdtable,key); - i++; - } - pthread_mutex_unlock (&conf->mutex); - - - return 0; - } - -static int -server_priv (xlator_t *this) -{ - return 0; -} - -static int -server_inode (xlator_t *this) -{ - server_conf_t *conf = NULL; - server_connection_t *trav = NULL; - char key[GF_DUMP_MAX_BUF_LEN]; - int i = 1; - int ret = -1; - - if (!this) - return -1; - - conf = this->private; - if (!conf) { - gf_log (this->name, GF_LOG_WARNING, - "conf null in xlator"); - return -1; - } - - ret = pthread_mutex_trylock (&conf->mutex); - if (ret) { - gf_log("", GF_LOG_WARNING, "Unable to dump itable" - " errno: %d", errno); - return -1; - } - - list_for_each_entry (trav, &conf->conns, list) { - if (trav->bound_xl && trav->bound_xl->itable) { - gf_proc_dump_build_key(key, - "xlator.protocol.server.conn", - "%d.bound_xl.%s", - i, trav->bound_xl->name); - inode_table_dump(trav->bound_xl->itable,key); - i++; - } - } - pthread_mutex_unlock (&conf->mutex); - - - return 0; -} - - -static void -get_auth_types (dict_t *this, char *key, data_t *value, void *data) -{ - dict_t *auth_dict = NULL; - char *saveptr = NULL; - char *tmp = NULL; - char *key_cpy = NULL; - int32_t ret = -1; - - auth_dict = data; - key_cpy = gf_strdup (key); - GF_VALIDATE_OR_GOTO("server", key_cpy, out); - - tmp = strtok_r (key_cpy, ".", &saveptr); - ret = strcmp (tmp, "auth"); - if (ret == 0) { - tmp = strtok_r (NULL, ".", &saveptr); - if (strcmp (tmp, "ip") == 0) { - /* TODO: backward compatibility, remove when - newer versions are available */ - tmp = "addr"; - gf_log ("server", GF_LOG_WARNING, - "assuming 'auth.ip' to be 'auth.addr'"); - } - ret = dict_set_dynptr (auth_dict, tmp, NULL, 0); - if (ret < 0) { - gf_log ("server", GF_LOG_DEBUG, - "failed to dict_set_dynptr"); - } - } - - GF_FREE (key_cpy); -out: - return; -} - - -static int -validate_auth_options (xlator_t *this, dict_t *dict) -{ - int ret = -1; - int error = 0; - xlator_list_t *trav = NULL; - data_pair_t *pair = NULL; - char *saveptr = NULL; - char *tmp = NULL; - char *key_cpy = NULL; - - trav = this->children; - while (trav) { - error = -1; - for (pair = dict->members_list; pair; pair = pair->next) { - key_cpy = gf_strdup (pair->key); - tmp = strtok_r (key_cpy, ".", &saveptr); - ret = strcmp (tmp, "auth"); - if (ret == 0) { - /* for module type */ - tmp = strtok_r (NULL, ".", &saveptr); - /* for volume name */ - tmp = strtok_r (NULL, ".", &saveptr); - } - - if (strcmp (tmp, trav->xlator->name) == 0) { - error = 0; - GF_FREE (key_cpy); - break; - } - GF_FREE (key_cpy); - } - if (-1 == error) { - gf_log (this->name, GF_LOG_ERROR, - "volume '%s' defined as subvolume, but no " - "authentication defined for the same", - trav->xlator->name); - break; - } - trav = trav->next; - } - - return error; -} - -int32_t -mem_acct_init (xlator_t *this) -{ - int ret = -1; - - if (!this) - return ret; - - ret = xlator_mem_acct_init (this, gf_server_mt_end + 1); - - if (ret != 0) { - gf_log (this->name, GF_LOG_ERROR, "Memory accounting init" - " failed"); - return ret; - } - - return ret; -} - - -/* - * init - called during server protocol initialization - * - * @this: - * - */ -int -init (xlator_t *this) -{ - int32_t ret = -1; - transport_t *trans = NULL; - server_conf_t *conf = NULL; - data_t *data = NULL; - data_t *trace = NULL; - - if (this->children == NULL) { - gf_log (this->name, GF_LOG_ERROR, - "protocol/server should have subvolume"); - goto out; - } - - trans = transport_load (this->options, this); - if (trans == NULL) { - gf_log (this->name, GF_LOG_ERROR, - "failed to load transport"); - goto out; - } - - ret = transport_listen (trans); - if (ret == -1) { - gf_log (this->name, GF_LOG_ERROR, - "failed to bind/listen on socket"); - goto out; - } - - conf = GF_CALLOC (1, sizeof (server_conf_t), - gf_server_mt_server_conf_t); - GF_VALIDATE_OR_GOTO(this->name, conf, out); - - INIT_LIST_HEAD (&conf->conns); - pthread_mutex_init (&conf->mutex, NULL); - - conf->trans = trans; - - conf->auth_modules = dict_new (); - GF_VALIDATE_OR_GOTO(this->name, conf->auth_modules, out); - - dict_foreach (this->options, get_auth_types, - conf->auth_modules); - ret = validate_auth_options (this, this->options); - if (ret == -1) { - /* logging already done in validate_auth_options function. */ - goto out; - } - - ret = gf_auth_init (this, conf->auth_modules); - if (ret) { - dict_unref (conf->auth_modules); - goto out; - } - - this->private = conf; - - ret = dict_get_int32 (this->options, "inode-lru-limit", - &conf->inode_lru_limit); - if (ret < 0) { - conf->inode_lru_limit = 1024; - } - - ret = dict_get_int32 (this->options, "limits.transaction-size", - &conf->max_block_size); - if (ret < 0) { - gf_log (this->name, GF_LOG_TRACE, - "defaulting limits.transaction-size to %d", - DEFAULT_BLOCK_SIZE); - conf->max_block_size = DEFAULT_BLOCK_SIZE; - } - - conf->verify_volfile_checksum = 1; - data = dict_get (this->options, "verify-volfile-checksum"); - if (data) { - ret = gf_string2boolean(data->data, - &conf->verify_volfile_checksum); - if (ret != 0) { - gf_log (this->name, GF_LOG_DEBUG, - "wrong value for verify-volfile-checksum"); - conf->verify_volfile_checksum = 1; - } - } - - trace = dict_get (this->options, "trace"); - if (trace) { - if (gf_string2boolean (trace->data, - &conf->trace) == -1) { - gf_log (this->name, GF_LOG_ERROR, - "'trace' takes on only boolean values."); - return -1; - } - } - -#ifndef GF_DARWIN_HOST_OS - { - struct rlimit lim; - - lim.rlim_cur = 1048576; - lim.rlim_max = 1048576; - - if (setrlimit (RLIMIT_NOFILE, &lim) == -1) { - gf_log (this->name, GF_LOG_WARNING, - "WARNING: Failed to set 'ulimit -n 1M': %s", - strerror(errno)); - lim.rlim_cur = 65536; - lim.rlim_max = 65536; - - if (setrlimit (RLIMIT_NOFILE, &lim) == -1) { - gf_log (this->name, GF_LOG_WARNING, - "Failed to set max open fd to 64k: %s", - strerror(errno)); - } else { - gf_log (this->name, GF_LOG_TRACE, - "max open fd set to 64k"); - } - } - } -#endif - this->graph->top = this; - - ret = 0; -out: - return ret; -} - - - -static int -protocol_server_pollin (xlator_t *this, transport_t *trans) -{ - char *hdr = NULL; - size_t hdrlen = 0; - int ret = -1; - struct iobuf *iobuf = NULL; - - - ret = transport_receive (trans, &hdr, &hdrlen, &iobuf); - - if (ret == 0) - ret = protocol_server_interpret (this, trans, hdr, - hdrlen, iobuf); - - /* TODO: use mem-pool */ - GF_FREE (hdr); - - return ret; -} - - -/* - * fini - finish function for server protocol, called before - * unloading server protocol. - * - * @this: - * - */ -void -fini (xlator_t *this) -{ - server_conf_t *conf = this->private; - - GF_VALIDATE_OR_GOTO(this->name, conf, out); - - if (conf->auth_modules) { - dict_unref (conf->auth_modules); - } - - GF_FREE (conf); - this->private = NULL; -out: - return; -} - -/* - * server_protocol_notify - notify function for server protocol - * @this: - * @trans: - * @event: - * - */ -int -notify (xlator_t *this, int32_t event, void *data, ...) -{ - int ret = 0; - transport_t *trans = NULL; - peer_info_t *peerinfo = NULL; - peer_info_t *myinfo = NULL; - - THIS = this; - trans = data; - if (!trans) { - gf_log (this->name, GF_LOG_ERROR, "!trans"); - goto out; - } - - peerinfo = &(trans->peerinfo); - myinfo = &(trans->myinfo); - - switch (event) { - case GF_EVENT_POLLIN: - ret = protocol_server_pollin (this, trans); - break; - case GF_EVENT_POLLERR: - { - gf_log (trans->xl->name, GF_LOG_INFO, "%s disconnected", - peerinfo->identifier); - - ret = -1; - transport_disconnect (trans); - if (trans->xl_private == NULL) { - gf_log (this->name, GF_LOG_DEBUG, - "POLLERR received on (%s) even before " - "handshake with (%s) is successful", - myinfo->identifier, peerinfo->identifier); - } else { - /* - * FIXME: shouldn't we check for return value? - * what should be done if cleanup fails? - */ - gf_server_connection_cleanup (this, trans->xl_private); - } - } - break; - - case GF_EVENT_TRANSPORT_CLEANUP: - { - if (trans->xl_private) { - gf_server_connection_put (this, trans->xl_private); - } else { - gf_log (this->name, GF_LOG_DEBUG, - "transport (%s) cleaned up even before " - "handshake with (%s) is successful", - myinfo->identifier, peerinfo->identifier); - } - } - break; - - default: - default_notify (this, event, data); - break; - } -out: - return ret; -} - - -struct xlator_fops fops = { -}; - -struct xlator_cbks cbks = { -}; - -struct xlator_dumpops dumpops = { - .inode = server_inode, - .priv = server_priv, - .fd = server_fd, -}; - - -struct volume_options options[] = { - { .key = {"transport-type"}, - .value = {"tcp", "socket", "ib-verbs", "unix", "ib-sdp", - "tcp/server", "ib-verbs/server"}, - .type = GF_OPTION_TYPE_STR - }, - { .key = {"volume-filename.*"}, - .type = GF_OPTION_TYPE_PATH, - }, - { .key = {"inode-lru-limit"}, - .type = GF_OPTION_TYPE_INT, - .min = 0, - .max = (1 * GF_UNIT_MB) - }, - { .key = {"client-volume-filename"}, - .type = GF_OPTION_TYPE_PATH - }, - { .key = {"verify-volfile-checksum"}, - .type = GF_OPTION_TYPE_BOOL - }, - { .key = {"trace"}, - .type = GF_OPTION_TYPE_BOOL - }, - { .key = {"conf-dir"}, - .type = GF_OPTION_TYPE_PATH, - }, - - { .key = {NULL} }, -}; diff --git a/xlators/protocol/legacy/server/src/server-protocol.h b/xlators/protocol/legacy/server/src/server-protocol.h deleted file mode 100644 index be6776033..000000000 --- a/xlators/protocol/legacy/server/src/server-protocol.h +++ /dev/null @@ -1,191 +0,0 @@ -/* - Copyright (c) 2006-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 _SERVER_PROTOCOL_H_ -#define _SERVER_PROTOCOL_H_ - -#ifndef _CONFIG_H -#define _CONFIG_H -#include "config.h" -#endif - -#include <pthread.h> - -#include "glusterfs.h" -#include "xlator.h" -#include "logging.h" -#include "call-stub.h" -#include "fd.h" -#include "byte-order.h" -#include "server-mem-types.h" -#include "authenticate.h" -#include "transport.h" - -#define DEFAULT_BLOCK_SIZE 4194304 /* 4MB */ -#define DEFAULT_VOLUME_FILE_PATH CONFDIR "/glusterfs.vol" - -typedef struct _server_state server_state_t; - -struct _locker { - struct list_head lockers; - char *volume; - loc_t loc; - fd_t *fd; - pid_t pid; -}; - -struct _lock_table { - struct list_head file_lockers; - struct list_head dir_lockers; - gf_lock_t lock; - size_t count; -}; - - -/* private structure per connection (transport object) - * used as transport_t->xl_private - */ -struct _server_connection { - struct list_head list; - char *id; - int ref; - int active_transports; - pthread_mutex_t lock; - char disconnected; - fdtable_t *fdtable; - struct _lock_table *ltable; - xlator_t *bound_xl; -}; - -typedef struct _server_connection server_connection_t; - - -server_connection_t * -gf_server_connection_get (xlator_t *this, const char *id); - -void -gf_server_connection_put (xlator_t *this, server_connection_t *conn); - -int -gf_server_connection_cleanup (xlator_t *this, server_connection_t *conn); - -struct _volfile_ctx { - struct _volfile_ctx *next; - char *key; - uint32_t checksum; -}; - -typedef struct { - struct _volfile_ctx *volfile; - - dict_t *auth_modules; - transport_t *trans; - int32_t max_block_size; - int32_t inode_lru_limit; - pthread_mutex_t mutex; - struct list_head conns; - gf_boolean_t verify_volfile_checksum; - gf_boolean_t trace; -} server_conf_t; - - -typedef enum { - RESOLVE_MUST = 1, - RESOLVE_NOT, - RESOLVE_MAY, - RESOLVE_DONTCARE, - RESOLVE_EXACT -} server_resolve_type_t; - - -struct resolve_comp { - char *basename; - ino_t ino; - uint64_t gen; - inode_t *inode; -}; - -typedef struct { - server_resolve_type_t type; - uint64_t fd_no; - ino_t ino; - uint64_t gen; - ino_t par; - char *path; - char *bname; - char *resolved; - int op_ret; - int op_errno; - loc_t deep_loc; - struct resolve_comp *components; - int comp_count; -} server_resolve_t; - - -typedef int (*server_resume_fn_t) (call_frame_t *frame, xlator_t *bound_xl); - -int -gf_resolve_and_resume (call_frame_t *frame, server_resume_fn_t fn); - -struct _server_state { - transport_t *trans; - xlator_t *bound_xl; - inode_table_t *itable; - - server_resume_fn_t resume_fn; - - loc_t loc; - loc_t loc2; - server_resolve_t resolve; - server_resolve_t resolve2; - - /* used within resolve_and_resume */ - loc_t *loc_now; - server_resolve_t *resolve_now; - - struct iatt stbuf; - int valid; - - fd_t *fd; - dict_t *params; - int flags; - int wbflags; - struct iobuf *iobuf; - struct iobref *iobref; - - size_t size; - off_t offset; - mode_t mode; - dev_t dev; - size_t nr_count; - int cmd; - int type; - char *name; - int name_len; - - int mask; - char is_revalidate; - dict_t *dict; - struct gf_flock flock; - const char *volume; - dir_entry_t *entry; -}; - - -#endif diff --git a/xlators/protocol/legacy/server/src/server-resolve.c b/xlators/protocol/legacy/server/src/server-resolve.c deleted file mode 100644 index 5a02be7ef..000000000 --- a/xlators/protocol/legacy/server/src/server-resolve.c +++ /dev/null @@ -1,658 +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 "server-protocol.h" -#include "server-helpers.h" - -#include "compat-errno.h" - -void -gf_server_print_request (call_frame_t *frame); - -static int -server_resolve_all (call_frame_t *frame); -static int -resolve_entry_simple (call_frame_t *frame); -static int -resolve_inode_simple (call_frame_t *frame); -static int -resolve_path_simple (call_frame_t *frame); - - -static int -component_count (const char *path) -{ - int count = 0; - const char *trav = NULL; - - trav = path; - - for (trav = path; *trav; trav++) { - if (*trav == '/') - count++; - } - - return count + 2; -} - - -static int -prepare_components (call_frame_t *frame) -{ - server_state_t *state = NULL; - xlator_t *this = NULL; - server_resolve_t *resolve = NULL; - char *resolved = NULL; - int count = 0; - struct resolve_comp *components = NULL; - int i = 0; - char *trav = NULL; - - - state = CALL_STATE (frame); - this = frame->this; - resolve = state->resolve_now; - - resolved = gf_strdup (resolve->path); - resolve->resolved = resolved; - - count = component_count (resolve->path); - components = GF_CALLOC (sizeof (*components), count, - gf_server_mt_resolve_comp); - resolve->components = components; - - components[0].basename = ""; - components[0].ino = 1; - components[0].gen = 0; - components[0].inode = state->itable->root; - - i = 1; - for (trav = resolved; *trav; trav++) { - if (*trav == '/') { - components[i].basename = trav + 1; - *trav = 0; - i++; - } - } - - return 0; -} - - -static int -resolve_loc_touchup (call_frame_t *frame) -{ - server_state_t *state = NULL; - server_resolve_t *resolve = NULL; - loc_t *loc = NULL; - char *path = NULL; - int ret = 0; - - state = CALL_STATE (frame); - - resolve = state->resolve_now; - loc = state->loc_now; - - if (!loc->path) { - if (loc->parent && resolve->bname) { - ret = inode_path (loc->parent, resolve->bname, &path); - } else if (loc->inode) { - ret = inode_path (loc->inode, NULL, &path); - } - - if (!path) - path = gf_strdup (resolve->path); - - loc->path = path; - } - - loc->name = strrchr (loc->path, '/'); - if (loc->name) - loc->name++; - - if (!loc->parent && loc->inode) { - loc->parent = inode_parent (loc->inode, 0, NULL); - } - - return 0; -} - - -static int -resolve_deep_continue (call_frame_t *frame) -{ - server_state_t *state = NULL; - xlator_t *this = NULL; - server_resolve_t *resolve = NULL; - int ret = 0; - - state = CALL_STATE (frame); - this = frame->this; - resolve = state->resolve_now; - - resolve->op_ret = 0; - resolve->op_errno = 0; - - if (resolve->par) - ret = resolve_entry_simple (frame); - else if (resolve->ino) - ret = resolve_inode_simple (frame); - else if (resolve->path) - ret = resolve_path_simple (frame); - - resolve_loc_touchup (frame); - - server_resolve_all (frame); - - return 0; -} - - -static int -resolve_deep_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int op_ret, int op_errno, inode_t *inode, struct iatt *buf, - dict_t *xattr, struct iatt *postparent) -{ - server_state_t *state = NULL; - server_resolve_t *resolve = NULL; - struct resolve_comp *components = NULL; - int i = 0; - inode_t *link_inode = NULL; - - state = CALL_STATE (frame); - resolve = state->resolve_now; - components = resolve->components; - - i = (long) cookie; - - if (op_ret == -1) { - goto get_out_of_here; - } - - if (i != 0) { - /* no linking for root inode */ - link_inode = inode_link (inode, resolve->deep_loc.parent, - resolve->deep_loc.name, buf); - inode_lookup (link_inode); - components[i].inode = link_inode; - link_inode = NULL; - } - - loc_wipe (&resolve->deep_loc); - - i++; /* next component */ - - if (!components[i].basename) { - /* all components of the path are resolved */ - goto get_out_of_here; - } - - /* join the current component with the path resolved until now */ - *(components[i].basename - 1) = '/'; - - resolve->deep_loc.path = gf_strdup (resolve->resolved); - resolve->deep_loc.parent = inode_ref (components[i-1].inode); - resolve->deep_loc.inode = inode_new (state->itable); - resolve->deep_loc.name = components[i].basename; - - STACK_WIND_COOKIE (frame, resolve_deep_cbk, (void *) (long) i, - BOUND_XL (frame), BOUND_XL (frame)->fops->lookup, - &resolve->deep_loc, NULL); - return 0; - -get_out_of_here: - resolve_deep_continue (frame); - return 0; -} - - -static int -resolve_path_deep (call_frame_t *frame) -{ - server_state_t *state = NULL; - xlator_t *this = NULL; - server_resolve_t *resolve = NULL; - int i = 0; - - state = CALL_STATE (frame); - this = frame->this; - resolve = state->resolve_now; - - gf_log (BOUND_XL (frame)->name, GF_LOG_DEBUG, - "RESOLVE %s() seeking deep resolution of %s", - gf_fop_list[frame->root->op], resolve->path); - - prepare_components (frame); - - /* start from the root */ - resolve->deep_loc.inode = state->itable->root; - resolve->deep_loc.path = gf_strdup ("/"); - resolve->deep_loc.name = ""; - - STACK_WIND_COOKIE (frame, resolve_deep_cbk, (void *) (long) i, - BOUND_XL (frame), BOUND_XL (frame)->fops->lookup, - &resolve->deep_loc, NULL); - return 0; -} - - -static int -resolve_path_simple (call_frame_t *frame) -{ - server_state_t *state = NULL; - xlator_t *this = NULL; - server_resolve_t *resolve = NULL; - struct resolve_comp *components = NULL; - int ret = -1; - int par_idx = 0; - int ino_idx = 0; - int i = 0; - - state = CALL_STATE (frame); - this = frame->this; - resolve = state->resolve_now; - components = resolve->components; - - if (!components) { - resolve->op_ret = -1; - resolve->op_errno = ENOENT; - goto out; - } - - for (i = 0; components[i].basename; i++) { - par_idx = ino_idx; - ino_idx = i; - } - - if (!components[par_idx].inode) { - resolve->op_ret = -1; - resolve->op_errno = ENOENT; - goto out; - } - - if (!components[ino_idx].inode && - (resolve->type == RESOLVE_MUST || resolve->type == RESOLVE_EXACT)) { - resolve->op_ret = -1; - resolve->op_errno = ENOENT; - goto out; - } - - if (components[ino_idx].inode && resolve->type == RESOLVE_NOT) { - resolve->op_ret = -1; - resolve->op_errno = EEXIST; - goto out; - } - - if (components[ino_idx].inode) - state->loc_now->inode = inode_ref (components[ino_idx].inode); - state->loc_now->parent = inode_ref (components[par_idx].inode); - - ret = 0; - -out: - return ret; -} - -/* - Check if the requirements are fulfilled by entries in the inode cache itself - Return value: - <= 0 - simple resolution was decisive and complete (either success or failure) - > 0 - indecisive, need to perform deep resolution -*/ - -static int -resolve_entry_simple (call_frame_t *frame) -{ - server_state_t *state = NULL; - xlator_t *this = NULL; - server_resolve_t *resolve = NULL; - inode_t *parent = NULL; - inode_t *inode = NULL; - int ret = 0; - - state = CALL_STATE (frame); - this = frame->this; - resolve = state->resolve_now; - - parent = inode_get (state->itable, resolve->par, 0); - if (!parent) { - /* simple resolution is indecisive. need to perform - deep resolution */ - resolve->op_ret = -1; - resolve->op_errno = ENOENT; - ret = 1; - - inode = inode_grep (state->itable, parent, resolve->bname); - if (inode != NULL) { - gf_log (this->name, GF_LOG_DEBUG, "%"PRId64": inode " - "(pointer:%p ino: %"PRIu64") present but parent" - " is NULL for path (%s)", frame->root->unique, - inode, inode->ino, resolve->path); - inode_unref (inode); - } - goto out; - } - -// if (parent->ino != 1 && parent->generation != resolve->gen) { - if (0) { - /* simple resolution is decisive - request was for a - stale handle */ - resolve->op_ret = -1; - resolve->op_errno = ENOENT; - ret = -1; - goto out; - } - - /* expected @parent was found from the inode cache */ - state->loc_now->parent = inode_ref (parent); - - inode = inode_grep (state->itable, parent, resolve->bname); - if (!inode) { - switch (resolve->type) { - case RESOLVE_DONTCARE: - case RESOLVE_NOT: - ret = 0; - break; - case RESOLVE_MAY: - ret = 1; - break; - default: - resolve->op_ret = -1; - resolve->op_errno = ENOENT; - ret = 1; - break; - } - - goto out; - } - - if (resolve->type == RESOLVE_NOT) { - gf_log (this->name, GF_LOG_DEBUG, "inode (pointer: %p ino:%" - PRIu64") found for path (%s) while type is RESOLVE_NOT", - inode, inode->ino, resolve->path); - resolve->op_ret = -1; - resolve->op_errno = EEXIST; - ret = -1; - goto out; - } - - ret = 0; - - state->loc_now->inode = inode_ref (inode); - -out: - if (parent) - inode_unref (parent); - - if (inode) - inode_unref (inode); - - return ret; -} - - -static int -server_resolve_entry (call_frame_t *frame) -{ - server_state_t *state = NULL; - xlator_t *this = NULL; - server_resolve_t *resolve = NULL; - int ret = 0; - loc_t *loc = NULL; - - state = CALL_STATE (frame); - this = frame->this; - resolve = state->resolve_now; - loc = state->loc_now; - - ret = resolve_entry_simple (frame); - - if (ret > 0) { - loc_wipe (loc); - resolve_path_deep (frame); - return 0; - } - - if (ret == 0) - resolve_loc_touchup (frame); - - server_resolve_all (frame); - - return 0; -} - - -static int -resolve_inode_simple (call_frame_t *frame) -{ - server_state_t *state = NULL; - xlator_t *this = NULL; - server_resolve_t *resolve = NULL; - inode_t *inode = NULL; - int ret = 0; - - state = CALL_STATE (frame); - this = frame->this; - resolve = state->resolve_now; - - if (resolve->type == RESOLVE_EXACT) { - inode = inode_get (state->itable, resolve->ino, resolve->gen); - } else { - inode = inode_get (state->itable, resolve->ino, 0); - } - - if (!inode) { - resolve->op_ret = -1; - resolve->op_errno = ENOENT; - ret = 1; - goto out; - } - -// if (inode->ino != 1 && inode->generation != resolve->gen) { - if (0) { - resolve->op_ret = -1; - resolve->op_errno = ENOENT; - ret = -1; - goto out; - } - - ret = 0; - - state->loc_now->inode = inode_ref (inode); - -out: - if (inode) - inode_unref (inode); - - return ret; -} - - -static int -server_resolve_inode (call_frame_t *frame) -{ - server_state_t *state = NULL; - int ret = 0; - loc_t *loc = NULL; - - state = CALL_STATE (frame); - loc = state->loc_now; - - ret = resolve_inode_simple (frame); - - if (ret > 0) { - loc_wipe (loc); - resolve_path_deep (frame); - return 0; - } - - if (ret == 0) - resolve_loc_touchup (frame); - - server_resolve_all (frame); - - return 0; -} - - -static int -server_resolve_fd (call_frame_t *frame) -{ - server_state_t *state = NULL; - xlator_t *this = NULL; - server_resolve_t *resolve = NULL; - server_connection_t *conn = NULL; - uint64_t fd_no = -1; - - state = CALL_STATE (frame); - this = frame->this; - resolve = state->resolve_now; - conn = SERVER_CONNECTION (frame); - - fd_no = resolve->fd_no; - - state->fd = gf_fd_fdptr_get (conn->fdtable, fd_no); - - if (!state->fd) { - resolve->op_ret = -1; - resolve->op_errno = EBADFD; - } - - server_resolve_all (frame); - - return 0; -} - - -static int -server_resolve (call_frame_t *frame) -{ - server_state_t *state = NULL; - xlator_t *this = NULL; - server_resolve_t *resolve = NULL; - - state = CALL_STATE (frame); - this = frame->this; - resolve = state->resolve_now; - - if (resolve->fd_no != -1) { - - server_resolve_fd (frame); - - } else if (resolve->par) { - - server_resolve_entry (frame); - - } else if (resolve->ino) { - - server_resolve_inode (frame); - - } else if (resolve->path) { - - resolve_path_deep (frame); - - } else { - - resolve->op_ret = -1; - resolve->op_errno = EINVAL; - - server_resolve_all (frame); - } - - return 0; -} - - -static int -server_resolve_done (call_frame_t *frame) -{ - server_state_t *state = NULL; - xlator_t *bound_xl = NULL; - - state = CALL_STATE (frame); - bound_xl = BOUND_XL (frame); - - gf_server_print_request (frame); - - state->resume_fn (frame, bound_xl); - - return 0; -} - - -/* - * This function is called multiple times, once per resolving one location/fd. - * state->resolve_now is used to decide which location/fd is to be resolved now - */ -static int -server_resolve_all (call_frame_t *frame) -{ - server_state_t *state = NULL; - xlator_t *this = NULL; - - this = frame->this; - state = CALL_STATE (frame); - - if (state->resolve_now == NULL) { - - state->resolve_now = &state->resolve; - state->loc_now = &state->loc; - - server_resolve (frame); - - } else if (state->resolve_now == &state->resolve) { - - state->resolve_now = &state->resolve2; - state->loc_now = &state->loc2; - - server_resolve (frame); - - } else if (state->resolve_now == &state->resolve2) { - - server_resolve_done (frame); - - } else { - gf_log (this->name, GF_LOG_ERROR, - "Invalid pointer for state->resolve_now"); - } - - return 0; -} - - -int -gf_resolve_and_resume (call_frame_t *frame, server_resume_fn_t fn) -{ - server_state_t *state = NULL; - xlator_t *this = NULL; - - state = CALL_STATE (frame); - state->resume_fn = fn; - - this = frame->this; - - server_resolve_all (frame); - - return 0; -} diff --git a/xlators/protocol/legacy/transport/Makefile.am b/xlators/protocol/legacy/transport/Makefile.am deleted file mode 100644 index e2f97437c..000000000 --- a/xlators/protocol/legacy/transport/Makefile.am +++ /dev/null @@ -1,3 +0,0 @@ -SUBDIRS = socket $(IBVERBS_SUBDIR) - -CLEANFILES = diff --git a/xlators/protocol/legacy/transport/ib-verbs/Makefile.am b/xlators/protocol/legacy/transport/ib-verbs/Makefile.am deleted file mode 100644 index f963effea..000000000 --- a/xlators/protocol/legacy/transport/ib-verbs/Makefile.am +++ /dev/null @@ -1 +0,0 @@ -SUBDIRS = src
\ No newline at end of file diff --git a/xlators/protocol/legacy/transport/ib-verbs/src/Makefile.am b/xlators/protocol/legacy/transport/ib-verbs/src/Makefile.am deleted file mode 100644 index 3db7aff98..000000000 --- a/xlators/protocol/legacy/transport/ib-verbs/src/Makefile.am +++ /dev/null @@ -1,19 +0,0 @@ -# TODO : need to change transportdir - -transport_LTLIBRARIES = ib-verbs.la -transportdir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/transport - -ib_verbs_la_LDFLAGS = -module -avoidversion - -ib_verbs_la_SOURCES = ib-verbs.c name.c -ib_verbs_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la \ - -libverbs $(top_builddir)/xlators/protocol/legacy/lib/src/libgfproto.la - -noinst_HEADERS = ib-verbs.h name.h ib-verbs-mem-types.h - -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)/xlators/protocol/legacy/transport/ib-verbs \ - -I$(top_srcdir)/xlators/protocol/legacy/lib/src - -CLEANFILES = *~ diff --git a/xlators/protocol/legacy/transport/ib-verbs/src/ib-verbs-mem-types.h b/xlators/protocol/legacy/transport/ib-verbs/src/ib-verbs-mem-types.h deleted file mode 100644 index 80e81e56b..000000000 --- a/xlators/protocol/legacy/transport/ib-verbs/src/ib-verbs-mem-types.h +++ /dev/null @@ -1,39 +0,0 @@ - -/* - Copyright (c) 2008-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 __IB_VERBS_MEM_TYPES_H__ -#define __IB_VERBS_MEM_TYPES_H__ - -#include "mem-types.h" - -enum gf_ib_verbs_mem_types_ { - gf_ibv_mt_ib_verbs_private_t = gf_common_mt_end + 1, - gf_ibv_mt_ib_verbs_ioq_t, - gf_ibv_mt_transport_t, - gf_ibv_mt_ib_verbs_local_t, - gf_ibv_mt_ib_verbs_post_t, - gf_ibv_mt_char, - gf_ibv_mt_qpent, - gf_ibv_mt_ib_verbs_device_t, - gf_ibv_mt_end -}; -#endif - diff --git a/xlators/protocol/legacy/transport/ib-verbs/src/ib-verbs.c b/xlators/protocol/legacy/transport/ib-verbs/src/ib-verbs.c deleted file mode 100644 index 8b52fa884..000000000 --- a/xlators/protocol/legacy/transport/ib-verbs/src/ib-verbs.c +++ /dev/null @@ -1,2625 +0,0 @@ -/* - Copyright (c) 2006-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 "dict.h" -#include "glusterfs.h" -#include "transport.h" -#include "protocol.h" -#include "logging.h" -#include "xlator.h" -#include "name.h" -#include "ib-verbs.h" -#include <signal.h> - -int32_t -gf_resolve_ip6 (const char *hostname, - uint16_t port, - int family, - void **dnscache, - struct addrinfo **addr_info); - -static uint16_t -ib_verbs_get_local_lid (struct ibv_context *context, - int32_t port) -{ - struct ibv_port_attr attr; - - if (ibv_query_port (context, port, &attr)) - return 0; - - return attr.lid; -} - -static const char * -get_port_state_str(enum ibv_port_state pstate) -{ - switch (pstate) { - case IBV_PORT_DOWN: return "PORT_DOWN"; - case IBV_PORT_INIT: return "PORT_INIT"; - case IBV_PORT_ARMED: return "PORT_ARMED"; - case IBV_PORT_ACTIVE: return "PORT_ACTIVE"; - case IBV_PORT_ACTIVE_DEFER: return "PORT_ACTIVE_DEFER"; - default: return "invalid state"; - } -} - -static int32_t -ib_check_active_port (struct ibv_context *ctx, uint8_t port) -{ - struct ibv_port_attr port_attr; - - int32_t ret = 0; - const char *state_str = NULL; - - if (!ctx) { - gf_log ("transport/ib-verbs", GF_LOG_ERROR, - "Error in supplied context"); - return -1; - } - - ret = ibv_query_port (ctx, port, &port_attr); - - if (ret) { - gf_log ("transport/ib-verbs", GF_LOG_ERROR, - "Failed to query port %u properties", port); - return -1; - } - - state_str = get_port_state_str (port_attr.state); - gf_log ("transport/ib-verbs", GF_LOG_TRACE, - "Infiniband PORT: (%u) STATE: (%s)", - port, state_str); - - if (port_attr.state == IBV_PORT_ACTIVE) - return 0; - - return -1; -} - -static int32_t -ib_get_active_port (struct ibv_context *ib_ctx) -{ - struct ibv_device_attr ib_device_attr; - - int32_t ret = -1; - uint8_t ib_port = 0; - - if (!ib_ctx) { - gf_log ("transport/ib-verbs", GF_LOG_ERROR, - "Error in supplied context"); - return -1; - } - if (ibv_query_device (ib_ctx, &ib_device_attr)) { - gf_log ("transport/ib-verbs", GF_LOG_ERROR, - "Failed to query device properties"); - return -1; - } - - for (ib_port = 1; ib_port <= ib_device_attr.phys_port_cnt; ++ib_port) { - ret = ib_check_active_port (ib_ctx, ib_port); - if (ret == 0) - return ib_port; - - gf_log ("transport/ib-verbs", GF_LOG_TRACE, - "Port:(%u) not active", ib_port); - continue; - } - return ret; -} - - - -static void -ib_verbs_put_post (ib_verbs_queue_t *queue, - ib_verbs_post_t *post) -{ - pthread_mutex_lock (&queue->lock); - if (post->prev) { - queue->active_count--; - post->prev->next = post->next; - } - if (post->next) - post->next->prev = post->prev; - post->prev = &queue->passive_posts; - post->next = post->prev->next; - post->prev->next = post; - post->next->prev = post; - queue->passive_count++; - pthread_mutex_unlock (&queue->lock); -} - - -static ib_verbs_post_t * -ib_verbs_new_post (ib_verbs_device_t *device, int32_t len) -{ - ib_verbs_post_t *post; - - post = (ib_verbs_post_t *) GF_CALLOC (1, sizeof (*post), - gf_ibv_mt_ib_verbs_post_t); - if (!post) - return NULL; - - post->buf_size = len; - - post->buf = valloc (len); - if (!post->buf) { - GF_FREE (post); - return NULL; - } - - post->mr = ibv_reg_mr (device->pd, - post->buf, - post->buf_size, - IBV_ACCESS_LOCAL_WRITE); - if (!post->mr) { - free (post->buf); - GF_FREE (post); - return NULL; - } - - return post; -} - - -static ib_verbs_post_t * -ib_verbs_get_post (ib_verbs_queue_t *queue) -{ - ib_verbs_post_t *post; - - pthread_mutex_lock (&queue->lock); - { - post = queue->passive_posts.next; - if (post == &queue->passive_posts) - post = NULL; - - if (post) { - if (post->prev) - post->prev->next = post->next; - if (post->next) - post->next->prev = post->prev; - post->prev = &queue->active_posts; - post->next = post->prev->next; - post->prev->next = post; - post->next->prev = post; - post->reused++; - queue->active_count++; - } - } - pthread_mutex_unlock (&queue->lock); - - return post; -} - -void -ib_verbs_destroy_post (ib_verbs_post_t *post) -{ - ibv_dereg_mr (post->mr); - free (post->buf); - GF_FREE (post); -} - - -static int32_t -__ib_verbs_quota_get (ib_verbs_peer_t *peer) -{ - int32_t ret = -1; - ib_verbs_private_t *priv = peer->trans->private; - - if (priv->connected && peer->quota > 0) { - ret = peer->quota--; - } - - return ret; -} - -/* - static int32_t - ib_verbs_quota_get (ib_verbs_peer_t *peer) - { - int32_t ret = -1; - ib_verbs_private_t *priv = peer->trans->private; - - pthread_mutex_lock (&priv->write_mutex); - { - ret = __ib_verbs_quota_get (peer); - } - pthread_mutex_unlock (&priv->write_mutex); - - return ret; - } -*/ - -static void -__ib_verbs_ioq_entry_free (ib_verbs_ioq_t *entry) -{ - list_del_init (&entry->list); - if (entry->iobref) - iobref_unref (entry->iobref); - - /* TODO: use mem-pool */ - GF_FREE (entry->buf); - - /* TODO: use mem-pool */ - GF_FREE (entry); -} - - -static void -__ib_verbs_ioq_flush (ib_verbs_peer_t *peer) -{ - ib_verbs_ioq_t *entry = NULL, *dummy = NULL; - - list_for_each_entry_safe (entry, dummy, &peer->ioq, list) { - __ib_verbs_ioq_entry_free (entry); - } -} - - -static int32_t -__ib_verbs_disconnect (transport_t *this) -{ - ib_verbs_private_t *priv = this->private; - int32_t ret = 0; - - if (priv->connected || priv->tcp_connected) { - fcntl (priv->sock, F_SETFL, O_NONBLOCK); - if (shutdown (priv->sock, SHUT_RDWR) != 0) { - gf_log ("transport/ib-verbs", - GF_LOG_DEBUG, - "shutdown () - error: %s", - strerror (errno)); - ret = -errno; - priv->tcp_connected = 0; - } - } - - return ret; -} - - -static int32_t -ib_verbs_post_send (struct ibv_qp *qp, - ib_verbs_post_t *post, - int32_t len) -{ - struct ibv_sge list = { - .addr = (unsigned long) post->buf, - .length = len, - .lkey = post->mr->lkey - }; - - struct ibv_send_wr wr = { - .wr_id = (unsigned long) post, - .sg_list = &list, - .num_sge = 1, - .opcode = IBV_WR_SEND, - .send_flags = IBV_SEND_SIGNALED, - }, *bad_wr; - - if (!qp) - return -1; - - return ibv_post_send (qp, &wr, &bad_wr); -} - - -static int32_t -__ib_verbs_ioq_churn_entry (ib_verbs_peer_t *peer, ib_verbs_ioq_t *entry) -{ - int32_t ret = 0, quota = 0; - ib_verbs_private_t *priv = peer->trans->private; - ib_verbs_device_t *device = priv->device; - ib_verbs_options_t *options = &priv->options; - ib_verbs_post_t *post = NULL; - int32_t len = 0; - - quota = __ib_verbs_quota_get (peer); - if (quota > 0) { - post = ib_verbs_get_post (&device->sendq); - if (!post) - post = ib_verbs_new_post (device, - (options->send_size + 2048)); - - len = iov_length ((const struct iovec *)&entry->vector, - entry->count); - if (len >= (options->send_size + 2048)) { - gf_log ("transport/ib-verbs", GF_LOG_ERROR, - "increase value of option 'transport.ib-verbs." - "work-request-send-size' (given=> %"PRId64") " - "to send bigger (%d) messages", - (options->send_size + 2048), len); - return -1; - } - - iov_unload (post->buf, - (const struct iovec *)&entry->vector, - entry->count); - - ret = ib_verbs_post_send (peer->qp, post, len); - if (!ret) { - __ib_verbs_ioq_entry_free (entry); - ret = len; - } else { - gf_log ("transport/ib-verbs", GF_LOG_DEBUG, - "ibv_post_send failed with ret = %d", ret); - ib_verbs_put_post (&device->sendq, post); - __ib_verbs_disconnect (peer->trans); - ret = -1; - } - } - - return ret; -} - - -static int32_t -__ib_verbs_ioq_churn (ib_verbs_peer_t *peer) -{ - ib_verbs_ioq_t *entry = NULL; - int32_t ret = 0; - - while (!list_empty (&peer->ioq)) - { - /* pick next entry */ - entry = peer->ioq_next; - - ret = __ib_verbs_ioq_churn_entry (peer, entry); - - if (ret <= 0) - break; - } - - /* - list_for_each_entry_safe (entry, dummy, &peer->ioq, list) { - ret = __ib_verbs_ioq_churn_entry (peer, entry); - if (ret <= 0) { - break; - } - } - */ - - return ret; -} - -static int32_t -__ib_verbs_quota_put (ib_verbs_peer_t *peer) -{ - int32_t ret; - - peer->quota++; - ret = peer->quota; - - if (!list_empty (&peer->ioq)) { - ret = __ib_verbs_ioq_churn (peer); - } - - return ret; -} - - -static int32_t -ib_verbs_quota_put (ib_verbs_peer_t *peer) -{ - int32_t ret; - ib_verbs_private_t *priv = peer->trans->private; - - pthread_mutex_lock (&priv->write_mutex); - { - ret = __ib_verbs_quota_put (peer); - } - pthread_mutex_unlock (&priv->write_mutex); - - return ret; -} - - -static int32_t -ib_verbs_post_recv (struct ibv_srq *srq, - ib_verbs_post_t *post) -{ - struct ibv_sge list = { - .addr = (unsigned long) post->buf, - .length = post->buf_size, - .lkey = post->mr->lkey - }; - - struct ibv_recv_wr wr = { - .wr_id = (unsigned long) post, - .sg_list = &list, - .num_sge = 1, - }, *bad_wr; - - return ibv_post_srq_recv (srq, &wr, &bad_wr); -} - - -static int32_t -ib_verbs_writev (transport_t *this, - ib_verbs_ioq_t *entry) -{ - int32_t ret = 0, need_append = 1; - ib_verbs_private_t *priv = this->private; - ib_verbs_peer_t *peer = NULL; - - pthread_mutex_lock (&priv->write_mutex); - { - if (!priv->connected) { - gf_log (this->xl->name, GF_LOG_DEBUG, - "ib-verbs is not connected to post a " - "send request"); - ret = -1; - goto unlock; - } - - peer = &priv->peer; - if (list_empty (&peer->ioq)) { - ret = __ib_verbs_ioq_churn_entry (peer, entry); - if (ret != 0) { - need_append = 0; - } - } - - if (need_append) { - list_add_tail (&entry->list, &peer->ioq); - } - } -unlock: - pthread_mutex_unlock (&priv->write_mutex); - return ret; -} - - -static ib_verbs_ioq_t * -ib_verbs_ioq_new (char *buf, int len, struct iovec *vector, - int count, struct iobref *iobref) -{ - ib_verbs_ioq_t *entry = NULL; - - /* TODO: use mem-pool */ - entry = GF_CALLOC (1, sizeof (*entry), gf_ibv_mt_ib_verbs_ioq_t); - - GF_ASSERT (count <= (MAX_IOVEC-2)); - - entry->header.colonO[0] = ':'; - entry->header.colonO[1] = 'O'; - entry->header.colonO[2] = '\0'; - entry->header.version = 42; - entry->header.size1 = hton32 (len); - entry->header.size2 = hton32 (iov_length (vector, count)); - - entry->vector[0].iov_base = &entry->header; - entry->vector[0].iov_len = sizeof (entry->header); - entry->count++; - - entry->vector[1].iov_base = buf; - entry->vector[1].iov_len = len; - entry->count++; - - if (vector && count) - { - memcpy (&entry->vector[2], vector, sizeof (*vector) * count); - entry->count += count; - } - - if (iobref) - entry->iobref = iobref_ref (iobref); - - entry->buf = buf; - - INIT_LIST_HEAD (&entry->list); - - return entry; -} - - -static int32_t -ib_verbs_submit (transport_t *this, char *buf, int32_t len, - struct iovec *vector, int count, struct iobref *iobref) -{ - int32_t ret = 0; - ib_verbs_ioq_t *entry = NULL; - - entry = ib_verbs_ioq_new (buf, len, vector, count, iobref); - ret = ib_verbs_writev (this, entry); - - if (ret > 0) { - ret = 0; - } - - return ret; -} - -static int -ib_verbs_receive (transport_t *this, char **hdr_p, size_t *hdrlen_p, - struct iobuf **iobuf_p) -{ - ib_verbs_private_t *priv = this->private; - /* TODO: return error if !priv->connected, check with locks */ - /* TODO: boundry checks for data_ptr/offset */ - char *copy_from = NULL; - ib_verbs_header_t *header = NULL; - uint32_t size1, size2, data_len = 0; - char *hdr = NULL; - struct iobuf *iobuf = NULL; - int32_t ret = 0; - - pthread_mutex_lock (&priv->recv_mutex); - { -/* - while (!priv->data_ptr) - pthread_cond_wait (&priv->recv_cond, &priv->recv_mutex); -*/ - - copy_from = priv->data_ptr + priv->data_offset; - - priv->data_ptr = NULL; - data_len = priv->data_len; - pthread_cond_broadcast (&priv->recv_cond); - } - pthread_mutex_unlock (&priv->recv_mutex); - - header = (ib_verbs_header_t *)copy_from; - if (strcmp (header->colonO, ":O")) { - gf_log ("transport/ib-verbs", GF_LOG_DEBUG, - "%s: corrupt header received", this->xl->name); - ret = -1; - goto err; - } - - size1 = ntoh32 (header->size1); - size2 = ntoh32 (header->size2); - - if (data_len != (size1 + size2 + sizeof (*header))) { - gf_log ("transport/ib-verbs", GF_LOG_DEBUG, - "%s: sizeof data read from transport is not equal " - "to the size specified in the header", - this->xl->name); - ret = -1; - goto err; - } - - copy_from += sizeof (*header); - - if (size1) { - hdr = GF_CALLOC (1, size1, gf_ibv_mt_char); - if (!hdr) { - gf_log (this->xl->name, GF_LOG_ERROR, - "unable to allocate header for peer %s", - this->peerinfo.identifier); - ret = -ENOMEM; - goto err; - } - memcpy (hdr, copy_from, size1); - copy_from += size1; - *hdr_p = hdr; - } - *hdrlen_p = size1; - - if (size2) { - iobuf = iobuf_get (this->xl->ctx->iobuf_pool); - if (!iobuf) { - gf_log (this->xl->name, GF_LOG_ERROR, - "unable to allocate IO buffer for peer %s", - this->peerinfo.identifier); - ret = -ENOMEM; - goto err; - } - memcpy (iobuf->ptr, copy_from, size2); - *iobuf_p = iobuf; - } - -err: - return ret; -} - - -static void -ib_verbs_destroy_cq (transport_t *this) -{ - ib_verbs_private_t *priv = this->private; - ib_verbs_device_t *device = priv->device; - - if (device->recv_cq) - ibv_destroy_cq (device->recv_cq); - device->recv_cq = NULL; - - if (device->send_cq) - ibv_destroy_cq (device->send_cq); - device->send_cq = NULL; - - return; -} - - -static int32_t -ib_verbs_create_cq (transport_t *this) -{ - ib_verbs_private_t *priv = this->private; - ib_verbs_options_t *options = &priv->options; - ib_verbs_device_t *device = priv->device; - int32_t ret = 0; - - device->recv_cq = ibv_create_cq (priv->device->context, - options->recv_count * 2, - device, - device->recv_chan, - 0); - if (!device->recv_cq) { - gf_log ("transport/ib-verbs", - GF_LOG_ERROR, - "%s: creation of CQ failed", - this->xl->name); - ret = -1; - } else if (ibv_req_notify_cq (device->recv_cq, 0)) { - gf_log ("transport/ib-verbs", - GF_LOG_ERROR, - "%s: ibv_req_notify_cq on CQ failed", - this->xl->name); - ret = -1; - } - - do { - /* TODO: make send_cq size dynamically adaptive */ - device->send_cq = ibv_create_cq (priv->device->context, - options->send_count * 1024, - device, - device->send_chan, - 0); - if (!device->send_cq) { - gf_log ("transport/ib-verbs", - GF_LOG_ERROR, - "%s: creation of send_cq failed", - this->xl->name); - ret = -1; - break; - } - - if (ibv_req_notify_cq (device->send_cq, 0)) { - gf_log ("transport/ib-verbs", - GF_LOG_ERROR, - "%s: ibv_req_notify_cq on send_cq failed", - this->xl->name); - ret = -1; - break; - } - } while (0); - - if (ret != 0) - ib_verbs_destroy_cq (this); - - return ret; -} - - -static void -ib_verbs_register_peer (ib_verbs_device_t *device, - int32_t qp_num, - ib_verbs_peer_t *peer) -{ - struct _qpent *ent; - ib_verbs_qpreg_t *qpreg = &device->qpreg; - int32_t hash = qp_num % 42; - - pthread_mutex_lock (&qpreg->lock); - ent = qpreg->ents[hash].next; - while ((ent != &qpreg->ents[hash]) && (ent->qp_num != qp_num)) - ent = ent->next; - if (ent->qp_num == qp_num) { - pthread_mutex_unlock (&qpreg->lock); - return; - } - ent = (struct _qpent *) GF_CALLOC (1, sizeof (*ent), gf_ibv_mt_qpent); - if (!ent) - return; - /* TODO: ref reg->peer */ - ent->peer = peer; - ent->next = &qpreg->ents[hash]; - ent->prev = ent->next->prev; - ent->next->prev = ent; - ent->prev->next = ent; - ent->qp_num = qp_num; - qpreg->count++; - pthread_mutex_unlock (&qpreg->lock); -} - - -static void -ib_verbs_unregister_peer (ib_verbs_device_t *device, - int32_t qp_num) -{ - struct _qpent *ent; - ib_verbs_qpreg_t *qpreg = &device->qpreg; - int32_t hash = qp_num % 42; - - pthread_mutex_lock (&qpreg->lock); - ent = qpreg->ents[hash].next; - while ((ent != &qpreg->ents[hash]) && (ent->qp_num != qp_num)) - ent = ent->next; - if (ent->qp_num != qp_num) { - pthread_mutex_unlock (&qpreg->lock); - return; - } - ent->prev->next = ent->next; - ent->next->prev = ent->prev; - /* TODO: unref reg->peer */ - GF_FREE (ent); - qpreg->count--; - pthread_mutex_unlock (&qpreg->lock); -} - - -static ib_verbs_peer_t * -__ib_verbs_lookup_peer (ib_verbs_device_t *device, int32_t qp_num) -{ - struct _qpent *ent = NULL; - ib_verbs_peer_t *peer = NULL; - ib_verbs_qpreg_t *qpreg = NULL; - int32_t hash = 0; - - qpreg = &device->qpreg; - hash = qp_num % 42; - ent = qpreg->ents[hash].next; - while ((ent != &qpreg->ents[hash]) && (ent->qp_num != qp_num)) - ent = ent->next; - - if (ent != &qpreg->ents[hash]) { - peer = ent->peer; - } - - return peer; -} - -/* -static ib_verbs_peer_t * -ib_verbs_lookup_peer (ib_verbs_device_t *device, - int32_t qp_num) -{ - ib_verbs_qpreg_t *qpreg = NULL; - ib_verbs_peer_t *peer = NULL; - - qpreg = &device->qpreg; - pthread_mutex_lock (&qpreg->lock); - { - peer = __ib_verbs_lookup_peer (device, qp_num); - } - pthread_mutex_unlock (&qpreg->lock); - - return peer; -} -*/ - - -static void -__ib_verbs_destroy_qp (transport_t *this) -{ - ib_verbs_private_t *priv = this->private; - - if (priv->peer.qp) { - ib_verbs_unregister_peer (priv->device, priv->peer.qp->qp_num); - ibv_destroy_qp (priv->peer.qp); - } - priv->peer.qp = NULL; - - return; -} - - -static int32_t -ib_verbs_create_qp (transport_t *this) -{ - ib_verbs_private_t *priv = this->private; - ib_verbs_options_t *options = &priv->options; - ib_verbs_device_t *device = priv->device; - int32_t ret = 0; - ib_verbs_peer_t *peer; - - peer = &priv->peer; - struct ibv_qp_init_attr init_attr = { - .send_cq = device->send_cq, - .recv_cq = device->recv_cq, - .srq = device->srq, - .cap = { - .max_send_wr = peer->send_count, - .max_recv_wr = peer->recv_count, - .max_send_sge = 1, - .max_recv_sge = 1 - }, - .qp_type = IBV_QPT_RC - }; - - struct ibv_qp_attr attr = { - .qp_state = IBV_QPS_INIT, - .pkey_index = 0, - .port_num = options->port, - .qp_access_flags = 0 - }; - - peer->qp = ibv_create_qp (device->pd, &init_attr); - if (!peer->qp) { - gf_log ("transport/ib-verbs", - GF_LOG_CRITICAL, - "%s: could not create QP", - this->xl->name); - ret = -1; - goto out; - } else if (ibv_modify_qp (peer->qp, &attr, - IBV_QP_STATE | - IBV_QP_PKEY_INDEX | - IBV_QP_PORT | - IBV_QP_ACCESS_FLAGS)) { - gf_log ("transport/ib-verbs", - GF_LOG_ERROR, - "%s: failed to modify QP to INIT state", - this->xl->name); - ret = -1; - goto out; - } - - peer->local_lid = ib_verbs_get_local_lid (device->context, - options->port); - peer->local_qpn = peer->qp->qp_num; - peer->local_psn = lrand48 () & 0xffffff; - - ib_verbs_register_peer (device, peer->qp->qp_num, peer); - -out: - if (ret == -1) - __ib_verbs_destroy_qp (this); - - return ret; -} - - -static void -ib_verbs_destroy_posts (transport_t *this) -{ - -} - - -static int32_t -__ib_verbs_create_posts (transport_t *this, - int32_t count, - int32_t size, - ib_verbs_queue_t *q) -{ - int32_t i; - int32_t ret = 0; - ib_verbs_private_t *priv = this->private; - ib_verbs_device_t *device = priv->device; - - for (i=0 ; i<count ; i++) { - ib_verbs_post_t *post; - - post = ib_verbs_new_post (device, size + 2048); - if (!post) { - gf_log ("transport/ib-verbs", - GF_LOG_ERROR, - "%s: post creation failed", - this->xl->name); - ret = -1; - break; - } - - ib_verbs_put_post (q, post); - } - return ret; -} - - -static int32_t -ib_verbs_create_posts (transport_t *this) -{ - int32_t i, ret; - ib_verbs_post_t *post = NULL; - ib_verbs_private_t *priv = this->private; - ib_verbs_options_t *options = &priv->options; - ib_verbs_device_t *device = priv->device; - - ret = __ib_verbs_create_posts (this, options->send_count, - options->send_size, - &device->sendq); - if (!ret) - ret = __ib_verbs_create_posts (this, options->recv_count, - options->recv_size, - &device->recvq); - - if (!ret) { - for (i=0 ; i<options->recv_count ; i++) { - post = ib_verbs_get_post (&device->recvq); - if (ib_verbs_post_recv (device->srq, post) != 0) { - ret = -1; - break; - } - } - } - - if (ret) - ib_verbs_destroy_posts (this); - - return ret; -} - - -static int32_t -ib_verbs_connect_qp (transport_t *this) -{ - ib_verbs_private_t *priv = this->private; - ib_verbs_options_t *options = &priv->options; - struct ibv_qp_attr attr = { - .qp_state = IBV_QPS_RTR, - .path_mtu = options->mtu, - .dest_qp_num = priv->peer.remote_qpn, - .rq_psn = priv->peer.remote_psn, - .max_dest_rd_atomic = 1, - .min_rnr_timer = 12, - .ah_attr = { - .is_global = 0, - .dlid = priv->peer.remote_lid, - .sl = 0, - .src_path_bits = 0, - .port_num = options->port - } - }; - if (ibv_modify_qp (priv->peer.qp, &attr, - IBV_QP_STATE | - IBV_QP_AV | - IBV_QP_PATH_MTU | - IBV_QP_DEST_QPN | - IBV_QP_RQ_PSN | - IBV_QP_MAX_DEST_RD_ATOMIC | - IBV_QP_MIN_RNR_TIMER)) { - gf_log ("transport/ib-verbs", - GF_LOG_CRITICAL, - "Failed to modify QP to RTR\n"); - return -1; - } - - /* TODO: make timeout and retry_cnt configurable from options */ - attr.qp_state = IBV_QPS_RTS; - attr.timeout = 14; - attr.retry_cnt = 7; - attr.rnr_retry = 7; - attr.sq_psn = priv->peer.local_psn; - attr.max_rd_atomic = 1; - if (ibv_modify_qp (priv->peer.qp, &attr, - IBV_QP_STATE | - IBV_QP_TIMEOUT | - IBV_QP_RETRY_CNT | - IBV_QP_RNR_RETRY | - IBV_QP_SQ_PSN | - IBV_QP_MAX_QP_RD_ATOMIC)) { - gf_log ("transport/ib-verbs", - GF_LOG_CRITICAL, - "Failed to modify QP to RTS\n"); - return -1; - } - - return 0; -} - -static int32_t -__ib_verbs_teardown (transport_t *this) -{ - ib_verbs_private_t *priv = this->private; - - __ib_verbs_destroy_qp (this); - - if (!list_empty (&priv->peer.ioq)) { - __ib_verbs_ioq_flush (&priv->peer); - } - - /* TODO: decrement cq size */ - return 0; -} - -/* - * return value: - * 0 = success (completed) - * -1 = error - * > 0 = incomplete - */ - -static int -__tcp_rwv (transport_t *this, struct iovec *vector, int count, - struct iovec **pending_vector, int *pending_count, - int write) -{ - ib_verbs_private_t *priv = NULL; - int sock = -1; - int ret = -1; - struct iovec *opvector = vector; - int opcount = count; - int moved = 0; - - priv = this->private; - sock = priv->sock; - - while (opcount) - { - if (write) - { - ret = writev (sock, opvector, opcount); - - if (ret == 0 || (ret == -1 && errno == EAGAIN)) - { - /* done for now */ - break; - } - } - else - { - ret = readv (sock, opvector, opcount); - - if (ret == -1 && errno == EAGAIN) - { - /* done for now */ - break; - } - } - - if (ret == 0) - { - gf_log (this->xl->name, GF_LOG_DEBUG, - "EOF from peer %s", this->peerinfo.identifier); - opcount = -1; - errno = ENOTCONN; - break; - } - - if (ret == -1) - { - if (errno == EINTR) - continue; - - gf_log (this->xl->name, GF_LOG_DEBUG, - "%s failed (%s)", write ? "writev" : "readv", - strerror (errno)); - if (write && !priv->connected && - (errno == ECONNREFUSED)) - gf_log (this->xl->name, GF_LOG_ERROR, - "possible mismatch of 'transport-type'" - " in protocol server and client. " - "check volume file"); - opcount = -1; - break; - } - - moved = 0; - - while (moved < ret) - { - if ((ret - moved) >= opvector[0].iov_len) - { - moved += opvector[0].iov_len; - opvector++; - opcount--; - } - else - { - opvector[0].iov_len -= (ret - moved); - opvector[0].iov_base += (ret - moved); - moved += (ret - moved); - } - while (opcount && !opvector[0].iov_len) - { - opvector++; - opcount--; - } - } - } - - if (pending_vector) - *pending_vector = opvector; - - if (pending_count) - *pending_count = opcount; - - return opcount; -} - - -static int -__tcp_readv (transport_t *this, struct iovec *vector, int count, - struct iovec **pending_vector, int *pending_count) -{ - int ret = -1; - - ret = __tcp_rwv (this, vector, count, - pending_vector, pending_count, 0); - - return ret; -} - - -static int -__tcp_writev (transport_t *this, struct iovec *vector, int count, - struct iovec **pending_vector, int *pending_count) -{ - int ret = -1; - ib_verbs_private_t *priv = this->private; - - ret = __tcp_rwv (this, vector, count, pending_vector, - pending_count, 1); - - if (ret > 0) { - /* TODO: Avoid multiple calls when socket is already - registered for POLLOUT */ - priv->idx = event_select_on (this->xl->ctx->event_pool, - priv->sock, priv->idx, -1, 1); - } else if (ret == 0) { - priv->idx = event_select_on (this->xl->ctx->event_pool, - priv->sock, - priv->idx, -1, 0); - } - - return ret; -} - - -static void * -ib_verbs_recv_completion_proc (void *data) -{ - struct ibv_comp_channel *chan = data; - ib_verbs_private_t *priv = NULL; - ib_verbs_device_t *device; - ib_verbs_post_t *post; - ib_verbs_peer_t *peer; - struct ibv_cq *event_cq; - struct ibv_wc wc; - void *event_ctx; - int32_t ret = 0; - - - while (1) { - ret = ibv_get_cq_event (chan, &event_cq, &event_ctx); - if (ret) { - gf_log ("transport/ib-verbs", GF_LOG_ERROR, - "ibv_get_cq_event failed, terminating recv " - "thread %d (%d)", ret, errno); - continue; - } - - device = event_ctx; - - ret = ibv_req_notify_cq (event_cq, 0); - if (ret) { - gf_log ("transport/ib-verbs", GF_LOG_ERROR, - "ibv_req_notify_cq on %s failed, terminating " - "recv thread: %d (%d)", - device->device_name, ret, errno); - continue; - } - - device = (ib_verbs_device_t *) event_ctx; - - while ((ret = ibv_poll_cq (event_cq, 1, &wc)) > 0) { - post = (ib_verbs_post_t *) (long) wc.wr_id; - - pthread_mutex_lock (&device->qpreg.lock); - { - peer = __ib_verbs_lookup_peer (device, - wc.qp_num); - - /* - * keep a refcount on transport so that it - * doesnot get freed because of some error - * indicated by wc.status till we are done - * with usage of peer and thereby that of trans. - */ - if (peer != NULL) { - transport_ref (peer->trans); - } - } - pthread_mutex_unlock (&device->qpreg.lock); - - if (wc.status != IBV_WC_SUCCESS) { - gf_log ("transport/ib-verbs", GF_LOG_ERROR, - "recv work request on `%s' returned " - "error (%d)", - device->device_name, - wc.status); - if (peer) { - transport_unref (peer->trans); - transport_disconnect (peer->trans); - } - - if (post) { - ib_verbs_post_recv (device->srq, post); - } - continue; - } - - if (peer) { - priv = peer->trans->private; - - pthread_mutex_lock (&priv->recv_mutex); - { - while (priv->data_ptr) - pthread_cond_wait (&priv->recv_cond, - &priv->recv_mutex); - - priv->data_ptr = post->buf; - priv->data_offset = 0; - priv->data_len = wc.byte_len; - - /*pthread_cond_broadcast (&priv->recv_cond);*/ - } - pthread_mutex_unlock (&priv->recv_mutex); - - if ((ret = xlator_notify (peer->trans->xl, GF_EVENT_POLLIN, - peer->trans, NULL)) == -1) { - gf_log ("transport/ib-verbs", - GF_LOG_DEBUG, - "pollin notification to %s " - "failed, disconnecting " - "transport", - peer->trans->xl->name); - transport_disconnect (peer->trans); - } - - transport_unref (peer->trans); - } else { - gf_log ("transport/ib-verbs", - GF_LOG_DEBUG, - "could not lookup peer for qp_num: %d", - wc.qp_num); - } - ib_verbs_post_recv (device->srq, post); - } - - if (ret < 0) { - gf_log ("transport/ib-verbs", - GF_LOG_ERROR, - "ibv_poll_cq on `%s' returned error " - "(ret = %d, errno = %d)", - device->device_name, ret, errno); - continue; - } - ibv_ack_cq_events (event_cq, 1); - } - return NULL; -} - - -static void * -ib_verbs_send_completion_proc (void *data) -{ - struct ibv_comp_channel *chan = data; - ib_verbs_post_t *post; - ib_verbs_peer_t *peer; - struct ibv_cq *event_cq; - void *event_ctx; - ib_verbs_device_t *device; - struct ibv_wc wc; - int32_t ret; - - while (1) { - ret = ibv_get_cq_event (chan, &event_cq, &event_ctx); - if (ret) { - gf_log ("transport/ib-verbs", GF_LOG_ERROR, - "ibv_get_cq_event on failed, terminating " - "send thread: %d (%d)", ret, errno); - continue; - } - - device = event_ctx; - - ret = ibv_req_notify_cq (event_cq, 0); - if (ret) { - gf_log ("transport/ib-verbs", GF_LOG_ERROR, - "ibv_req_notify_cq on %s failed, terminating " - "send thread: %d (%d)", - device->device_name, ret, errno); - continue; - } - - while ((ret = ibv_poll_cq (event_cq, 1, &wc)) > 0) { - post = (ib_verbs_post_t *) (long) wc.wr_id; - - pthread_mutex_lock (&device->qpreg.lock); - { - peer = __ib_verbs_lookup_peer (device, - wc.qp_num); - - /* - * keep a refcount on transport so that it - * doesnot get freed because of some error - * indicated by wc.status till we are done - * with usage of peer and thereby that of trans. - */ - if (peer != NULL) { - transport_ref (peer->trans); - } - } - pthread_mutex_unlock (&device->qpreg.lock); - - if (wc.status != IBV_WC_SUCCESS) { - gf_log ("transport/ib-verbs", GF_LOG_ERROR, - "send work request on `%s' returned " - "error wc.status = %d, wc.vendor_err " - "= %d, post->buf = %p, wc.byte_len = " - "%d, post->reused = %d", - device->device_name, wc.status, - wc.vendor_err, - post->buf, wc.byte_len, post->reused); - if (wc.status == IBV_WC_RETRY_EXC_ERR) - gf_log ("ib-verbs", GF_LOG_ERROR, - "connection between client and" - " server not working. check by" - " running 'ibv_srq_pingpong'. " - "also make sure subnet manager" - " is running (eg: 'opensm'), " - "or check if ib-verbs port is " - "valid (or active) by running " - " 'ibv_devinfo'. contact " - "Gluster Support Team if " - "the problem persists."); - if (peer) - transport_disconnect (peer->trans); - } - - if (post) { - ib_verbs_put_post (&device->sendq, post); - } - - if (peer) { - int quota_ret = ib_verbs_quota_put (peer); - if (quota_ret < 0) { - gf_log ("ib-verbs", GF_LOG_DEBUG, - "failed to send message"); - - } - - transport_unref (peer->trans); - } else { - gf_log ("transport/ib-verbs", GF_LOG_DEBUG, - "could not lookup peer for qp_num: %d", - wc.qp_num); - } - } - - if (ret < 0) { - gf_log ("transport/ib-verbs", GF_LOG_ERROR, - "ibv_poll_cq on `%s' returned error (ret = %d," - " errno = %d)", - device->device_name, ret, errno); - continue; - } - ibv_ack_cq_events (event_cq, 1); - } - - return NULL; -} - -static void -ib_verbs_options_init (transport_t *this) -{ - ib_verbs_private_t *priv = this->private; - ib_verbs_options_t *options = &priv->options; - int32_t mtu; - data_t *temp; - - /* TODO: validate arguments from options below */ - - options->send_size = this->xl->ctx->page_size * 4; /* 512 KB */ - options->recv_size = this->xl->ctx->page_size * 4; /* 512 KB */ - options->send_count = 32; - options->recv_count = 32; - - temp = dict_get (this->xl->options, - "transport.ib-verbs.work-request-send-count"); - if (temp) - options->send_count = data_to_int32 (temp); - - temp = dict_get (this->xl->options, - "transport.ib-verbs.work-request-recv-count"); - if (temp) - options->recv_count = data_to_int32 (temp); - - options->port = 0; - temp = dict_get (this->xl->options, - "transport.ib-verbs.port"); - if (temp) - options->port = data_to_uint64 (temp); - - options->mtu = mtu = IBV_MTU_2048; - temp = dict_get (this->xl->options, - "transport.ib-verbs.mtu"); - if (temp) - mtu = data_to_int32 (temp); - switch (mtu) { - case 256: options->mtu = IBV_MTU_256; - break; - case 512: options->mtu = IBV_MTU_512; - break; - case 1024: options->mtu = IBV_MTU_1024; - break; - case 2048: options->mtu = IBV_MTU_2048; - break; - case 4096: options->mtu = IBV_MTU_4096; - break; - default: - if (temp) - gf_log ("transport/ib-verbs", GF_LOG_WARNING, - "%s: unrecognized MTU value '%s', defaulting " - "to '2048'", this->xl->name, - data_to_str (temp)); - else - gf_log ("transport/ib-verbs", GF_LOG_TRACE, - "%s: defaulting MTU to '2048'", - this->xl->name); - options->mtu = IBV_MTU_2048; - break; - } - - temp = dict_get (this->xl->options, - "transport.ib-verbs.device-name"); - if (temp) - options->device_name = gf_strdup (temp->data); - - return; -} - -static void -ib_verbs_queue_init (ib_verbs_queue_t *queue) -{ - pthread_mutex_init (&queue->lock, NULL); - - queue->active_posts.next = &queue->active_posts; - queue->active_posts.prev = &queue->active_posts; - queue->passive_posts.next = &queue->passive_posts; - queue->passive_posts.prev = &queue->passive_posts; -} - - -static ib_verbs_device_t * -ib_verbs_get_device (transport_t *this, - struct ibv_context *ibctx) -{ - glusterfs_ctx_t *ctx = this->xl->ctx; - ib_verbs_private_t *priv = this->private; - ib_verbs_options_t *options = &priv->options; - char *device_name = priv->options.device_name; - uint32_t port = priv->options.port; - - uint8_t active_port = 0; - int32_t ret = 0; - int32_t i = 0; - - ib_verbs_device_t *trav; - - trav = ctx->ib; - while (trav) { - if ((!strcmp (trav->device_name, device_name)) && - (trav->port == port)) - break; - trav = trav->next; - } - - if (!trav) { - - trav = GF_CALLOC (1, sizeof (*trav), - gf_ibv_mt_ib_verbs_device_t); - if (!trav) - return NULL; - priv->device = trav; - - trav->context = ibctx; - - ret = ib_get_active_port (trav->context); - - if (ret < 0) { - if (!port) { - gf_log ("transport/ib-verbs", GF_LOG_ERROR, - "Failed to find any active ports and " - "none specified in volume file," - " exiting"); - return NULL; - } - } - - active_port = ret; - - if (port) { - ret = ib_check_active_port (trav->context, port); - if (ret < 0) { - gf_log ("transport/ib-verbs", GF_LOG_WARNING, - "On device %s: provided port:%u is " - "found to be offline, continuing to " - "use the same port", device_name, port); - } - } else { - priv->options.port = active_port; - port = active_port; - gf_log ("transport/ib-verbs", GF_LOG_TRACE, - "Port unspecified in volume file using active " - "port: %u", port); - } - - trav->device_name = gf_strdup (device_name); - trav->port = port; - - trav->next = ctx->ib; - ctx->ib = trav; - - trav->send_chan = ibv_create_comp_channel (trav->context); - if (!trav->send_chan) { - gf_log ("transport/ib-verbs", GF_LOG_ERROR, - "%s: could not create send completion channel", - device_name); - /* TODO: cleanup current mess */ - return NULL; - } - - trav->recv_chan = ibv_create_comp_channel (trav->context); - if (!trav->recv_chan) { - gf_log ("transport/ib-verbs", GF_LOG_ERROR, - "could not create recv completion channel"); - /* TODO: cleanup current mess */ - return NULL; - } - - if (ib_verbs_create_cq (this) < 0) { - gf_log ("transport/ib-verbs", GF_LOG_ERROR, - "%s: could not create CQ", - this->xl->name); - return NULL; - } - - /* protection domain */ - trav->pd = ibv_alloc_pd (trav->context); - - if (!trav->pd) { - gf_log ("transport/ib-verbs", GF_LOG_ERROR, - "%s: could not allocate protection domain", - this->xl->name); - return NULL; - } - - struct ibv_srq_init_attr attr = { - .attr = { - .max_wr = options->recv_count, - .max_sge = 1 - } - }; - trav->srq = ibv_create_srq (trav->pd, &attr); - - if (!trav->srq) { - gf_log ("transport/ib-verbs", GF_LOG_ERROR, - "%s: could not create SRQ", - this->xl->name); - return NULL; - } - - /* queue init */ - ib_verbs_queue_init (&trav->sendq); - ib_verbs_queue_init (&trav->recvq); - - if (ib_verbs_create_posts (this) < 0) { - gf_log ("transport/ib-verbs", GF_LOG_ERROR, - "%s: could not allocate posts", - this->xl->name); - return NULL; - } - - /* completion threads */ - ret = pthread_create (&trav->send_thread, - NULL, - ib_verbs_send_completion_proc, - trav->send_chan); - if (ret) { - gf_log ("transport/ib-verbs", GF_LOG_ERROR, - "could not create send completion thread"); - return NULL; - } - ret = pthread_create (&trav->recv_thread, - NULL, - ib_verbs_recv_completion_proc, - trav->recv_chan); - if (ret) { - gf_log ("transport/ib-verbs", GF_LOG_ERROR, - "could not create recv completion thread"); - return NULL; - } - - /* qpreg */ - pthread_mutex_init (&trav->qpreg.lock, NULL); - for (i=0; i<42; i++) { - trav->qpreg.ents[i].next = &trav->qpreg.ents[i]; - trav->qpreg.ents[i].prev = &trav->qpreg.ents[i]; - } - } - return trav; -} - -static int32_t -ib_verbs_init (transport_t *this) -{ - ib_verbs_private_t *priv = this->private; - ib_verbs_options_t *options = &priv->options; - struct ibv_device **dev_list; - struct ibv_context *ib_ctx = NULL; - int32_t ret = 0; - - ib_verbs_options_init (this); - - { - dev_list = ibv_get_device_list (NULL); - - if (!dev_list) { - gf_log ("transport/ib-verbs", - GF_LOG_CRITICAL, - "Failed to get IB devices"); - ret = -1; - goto cleanup; - } - - if (!*dev_list) { - gf_log ("transport/ib-verbs", - GF_LOG_CRITICAL, - "No IB devices found"); - ret = -1; - goto cleanup; - } - - if (!options->device_name) { - if (*dev_list) { - options->device_name = - gf_strdup (ibv_get_device_name (*dev_list)); - } else { - gf_log ("transport/ib-verbs", GF_LOG_CRITICAL, - "IB device list is empty. Check for " - "'ib_uverbs' module"); - return -1; - goto cleanup; - } - } - - while (*dev_list) { - if (!strcmp (ibv_get_device_name (*dev_list), - options->device_name)) { - ib_ctx = ibv_open_device (*dev_list); - - if (!ib_ctx) { - gf_log ("transport/ib-verbs", - GF_LOG_ERROR, - "Failed to get infiniband" - "device context"); - ret = -1; - goto cleanup; - } - break; - } - ++dev_list; - } - - priv->device = ib_verbs_get_device (this, ib_ctx); - - if (!priv->device) { - gf_log ("transport/ib-verbs", GF_LOG_ERROR, - "could not create ib_verbs device for %s", - options->device_name); - ret = -1; - goto cleanup; - } - } - - priv->peer.trans = this; - INIT_LIST_HEAD (&priv->peer.ioq); - - pthread_mutex_init (&priv->read_mutex, NULL); - pthread_mutex_init (&priv->write_mutex, NULL); - pthread_mutex_init (&priv->recv_mutex, NULL); - pthread_cond_init (&priv->recv_cond, NULL); - -cleanup: - if (-1 == ret) { - if (ib_ctx) - ibv_close_device (ib_ctx); - } - - if (dev_list) - ibv_free_device_list (dev_list); - - return ret; -} - - -static int32_t -ib_verbs_disconnect (transport_t *this) -{ - ib_verbs_private_t *priv = this->private; - int32_t ret = 0; - - pthread_mutex_lock (&priv->write_mutex); - { - ret = __ib_verbs_disconnect (this); - } - pthread_mutex_unlock (&priv->write_mutex); - - return ret; -} - - -static int32_t -__tcp_connect_finish (int fd) -{ - int ret = -1; - int optval = 0; - socklen_t optlen = sizeof (int); - - ret = getsockopt (fd, SOL_SOCKET, SO_ERROR, - (void *)&optval, &optlen); - - if (ret == 0 && optval) - { - errno = optval; - ret = -1; - } - - return ret; -} - -static inline void -ib_verbs_fill_handshake_data (char *buf, struct ib_verbs_nbio *nbio, - ib_verbs_private_t *priv) -{ - sprintf (buf, - "QP1:RECV_BLKSIZE=%08x:SEND_BLKSIZE=%08x\n" - "QP1:LID=%04x:QPN=%06x:PSN=%06x\n", - priv->peer.recv_size, - priv->peer.send_size, - priv->peer.local_lid, - priv->peer.local_qpn, - priv->peer.local_psn); - - nbio->vector.iov_base = buf; - nbio->vector.iov_len = strlen (buf) + 1; - nbio->count = 1; - return; -} - -static inline void -ib_verbs_fill_handshake_ack (char *buf, struct ib_verbs_nbio *nbio) -{ - sprintf (buf, "DONE\n"); - nbio->vector.iov_base = buf; - nbio->vector.iov_len = strlen (buf) + 1; - nbio->count = 1; - return; -} - -static int -ib_verbs_handshake_pollin (transport_t *this) -{ - int ret = 0; - ib_verbs_private_t *priv = this->private; - char *buf = priv->handshake.incoming.buf; - int32_t recv_buf_size, send_buf_size; - socklen_t sock_len; - - if (priv->handshake.incoming.state == IB_VERBS_HANDSHAKE_COMPLETE) { - return -1; - } - - pthread_mutex_lock (&priv->write_mutex); - { - while (priv->handshake.incoming.state != IB_VERBS_HANDSHAKE_COMPLETE) - { - switch (priv->handshake.incoming.state) - { - case IB_VERBS_HANDSHAKE_START: - buf = priv->handshake.incoming.buf = GF_CALLOC (1, 256, gf_ibv_mt_char); - ib_verbs_fill_handshake_data (buf, &priv->handshake.incoming, priv); - buf[0] = 0; - priv->handshake.incoming.state = IB_VERBS_HANDSHAKE_RECEIVING_DATA; - break; - - case IB_VERBS_HANDSHAKE_RECEIVING_DATA: - ret = __tcp_readv (this, - &priv->handshake.incoming.vector, - priv->handshake.incoming.count, - &priv->handshake.incoming.pending_vector, - &priv->handshake.incoming.pending_count); - if (ret == -1) { - goto unlock; - } - - if (ret > 0) { - gf_log (this->xl->name, GF_LOG_TRACE, - "partial header read on NB socket. continue later"); - goto unlock; - } - - if (!ret) { - priv->handshake.incoming.state = IB_VERBS_HANDSHAKE_RECEIVED_DATA; - } - break; - - case IB_VERBS_HANDSHAKE_RECEIVED_DATA: - ret = sscanf (buf, - "QP1:RECV_BLKSIZE=%08x:SEND_BLKSIZE=%08x\n" - "QP1:LID=%04x:QPN=%06x:PSN=%06x\n", - &recv_buf_size, - &send_buf_size, - &priv->peer.remote_lid, - &priv->peer.remote_qpn, - &priv->peer.remote_psn); - - if ((ret != 5) && (strncmp (buf, "QP1:", 4))) { - gf_log ("transport/ib-verbs", - GF_LOG_CRITICAL, - "%s: remote-host(%s)'s " - "transport type is different", - this->xl->name, - this->peerinfo.identifier); - ret = -1; - goto unlock; - } - - if (recv_buf_size < priv->peer.recv_size) - priv->peer.recv_size = recv_buf_size; - if (send_buf_size < priv->peer.send_size) - priv->peer.send_size = send_buf_size; - - gf_log ("transport/ib-verbs", GF_LOG_TRACE, - "%s: transacted recv_size=%d " - "send_size=%d", - this->xl->name, priv->peer.recv_size, - priv->peer.send_size); - - priv->peer.quota = priv->peer.send_count; - - if (ib_verbs_connect_qp (this)) { - gf_log ("transport/ib-verbs", - GF_LOG_ERROR, - "%s: failed to connect with " - "remote QP", this->xl->name); - ret = -1; - goto unlock; - } - ib_verbs_fill_handshake_ack (buf, &priv->handshake.incoming); - buf[0] = 0; - priv->handshake.incoming.state = IB_VERBS_HANDSHAKE_RECEIVING_ACK; - break; - - case IB_VERBS_HANDSHAKE_RECEIVING_ACK: - ret = __tcp_readv (this, - &priv->handshake.incoming.vector, - priv->handshake.incoming.count, - &priv->handshake.incoming.pending_vector, - &priv->handshake.incoming.pending_count); - if (ret == -1) { - goto unlock; - } - - if (ret > 0) { - gf_log (this->xl->name, GF_LOG_TRACE, - "partial header read on NB " - "socket. continue later"); - goto unlock; - } - - if (!ret) { - priv->handshake.incoming.state = IB_VERBS_HANDSHAKE_RECEIVED_ACK; - } - break; - - case IB_VERBS_HANDSHAKE_RECEIVED_ACK: - if (strncmp (buf, "DONE", 4)) { - gf_log ("transport/ib-verbs", - GF_LOG_DEBUG, - "%s: handshake-3 did not " - "return 'DONE' (%s)", - this->xl->name, buf); - ret = -1; - goto unlock; - } - ret = 0; - priv->connected = 1; - sock_len = sizeof (struct sockaddr_storage); - getpeername (priv->sock, - (struct sockaddr *) &this->peerinfo.sockaddr, - &sock_len); - - GF_FREE (priv->handshake.incoming.buf); - priv->handshake.incoming.buf = NULL; - priv->handshake.incoming.state = IB_VERBS_HANDSHAKE_COMPLETE; - } - } - } -unlock: - pthread_mutex_unlock (&priv->write_mutex); - - if (ret == -1) { - transport_disconnect (this); - } else { - ret = 0; - } - - if (!ret && priv->connected) { - ret = xlator_notify (this->xl, GF_EVENT_CHILD_UP, this); - } - - return ret; -} - -static int -ib_verbs_handshake_pollout (transport_t *this) -{ - ib_verbs_private_t *priv = this->private; - char *buf = priv->handshake.outgoing.buf; - int32_t ret = 0; - - if (priv->handshake.outgoing.state == IB_VERBS_HANDSHAKE_COMPLETE) { - return 0; - } - - pthread_mutex_unlock (&priv->write_mutex); - { - while (priv->handshake.outgoing.state != IB_VERBS_HANDSHAKE_COMPLETE) - { - switch (priv->handshake.outgoing.state) - { - case IB_VERBS_HANDSHAKE_START: - buf = priv->handshake.outgoing.buf = GF_CALLOC (1, 256, gf_ibv_mt_char); - ib_verbs_fill_handshake_data (buf, &priv->handshake.outgoing, priv); - priv->handshake.outgoing.state = IB_VERBS_HANDSHAKE_SENDING_DATA; - break; - - case IB_VERBS_HANDSHAKE_SENDING_DATA: - ret = __tcp_writev (this, - &priv->handshake.outgoing.vector, - priv->handshake.outgoing.count, - &priv->handshake.outgoing.pending_vector, - &priv->handshake.outgoing.pending_count); - if (ret == -1) { - goto unlock; - } - - if (ret > 0) { - gf_log (this->xl->name, GF_LOG_TRACE, - "partial header read on NB socket. continue later"); - goto unlock; - } - - if (!ret) { - priv->handshake.outgoing.state = IB_VERBS_HANDSHAKE_SENT_DATA; - } - break; - - case IB_VERBS_HANDSHAKE_SENT_DATA: - ib_verbs_fill_handshake_ack (buf, &priv->handshake.outgoing); - priv->handshake.outgoing.state = IB_VERBS_HANDSHAKE_SENDING_ACK; - break; - - case IB_VERBS_HANDSHAKE_SENDING_ACK: - ret = __tcp_writev (this, - &priv->handshake.outgoing.vector, - priv->handshake.outgoing.count, - &priv->handshake.outgoing.pending_vector, - &priv->handshake.outgoing.pending_count); - - if (ret == -1) { - goto unlock; - } - - if (ret > 0) { - gf_log (this->xl->name, GF_LOG_TRACE, - "partial header read on NB " - "socket. continue later"); - goto unlock; - } - - if (!ret) { - GF_FREE (priv->handshake.outgoing.buf); - priv->handshake.outgoing.buf = NULL; - priv->handshake.outgoing.state = IB_VERBS_HANDSHAKE_COMPLETE; - } - break; - } - } - } -unlock: - pthread_mutex_unlock (&priv->write_mutex); - - if (ret == -1) { - transport_disconnect (this); - } else { - ret = 0; - } - - return ret; -} - -static int -ib_verbs_handshake_pollerr (transport_t *this) -{ - ib_verbs_private_t *priv = this->private; - int32_t ret = 0; - char need_unref = 0; - - gf_log ("transport/ib-verbs", GF_LOG_DEBUG, - "%s: peer disconnected, cleaning up", - this->xl->name); - - pthread_mutex_lock (&priv->write_mutex); - { - __ib_verbs_teardown (this); - - if (priv->sock != -1) { - event_unregister (this->xl->ctx->event_pool, - priv->sock, priv->idx); - need_unref = 1; - - if (close (priv->sock) != 0) { - gf_log ("transport/ib-verbs", GF_LOG_ERROR, - "close () - error: %s", - strerror (errno)); - ret = -errno; - } - priv->tcp_connected = priv->connected = 0; - priv->sock = -1; - } - - if (priv->handshake.incoming.buf) { - GF_FREE (priv->handshake.incoming.buf); - priv->handshake.incoming.buf = NULL; - } - - priv->handshake.incoming.state = IB_VERBS_HANDSHAKE_START; - - if (priv->handshake.outgoing.buf) { - GF_FREE (priv->handshake.outgoing.buf); - priv->handshake.outgoing.buf = NULL; - } - - priv->handshake.outgoing.state = IB_VERBS_HANDSHAKE_START; - } - pthread_mutex_unlock (&priv->write_mutex); - - xlator_notify (this->xl, GF_EVENT_POLLERR, this, NULL); - - if (need_unref) - transport_unref (this); - - return 0; -} - - -static int -tcp_connect_finish (transport_t *this) -{ - ib_verbs_private_t *priv = this->private; - int error = 0, ret = 0; - - pthread_mutex_lock (&priv->write_mutex); - { - ret = __tcp_connect_finish (priv->sock); - - if (!ret) { - this->myinfo.sockaddr_len = - sizeof (this->myinfo.sockaddr); - ret = getsockname (priv->sock, - (struct sockaddr *)&this->myinfo.sockaddr, - &this->myinfo.sockaddr_len); - if (ret == -1) - { - gf_log (this->xl->name, GF_LOG_ERROR, - "getsockname on new client-socket %d " - "failed (%s)", - priv->sock, strerror (errno)); - close (priv->sock); - error = 1; - goto unlock; - } - - gf_ibverbs_get_transport_identifiers (this); - priv->tcp_connected = 1; - } - - if (ret == -1 && errno != EINPROGRESS) { - gf_log (this->xl->name, GF_LOG_ERROR, - "tcp connect to %s failed (%s)", - this->peerinfo.identifier, strerror (errno)); - error = 1; - } - } -unlock: - pthread_mutex_unlock (&priv->write_mutex); - - if (error) { - transport_disconnect (this); - } - - return ret; -} - -static int -ib_verbs_event_handler (int fd, int idx, void *data, - int poll_in, int poll_out, int poll_err) -{ - transport_t *this = data; - ib_verbs_private_t *priv = this->private; - ib_verbs_options_t *options = NULL; - int ret = 0; - - if (!priv->tcp_connected) { - ret = tcp_connect_finish (this); - if (priv->tcp_connected) { - options = &priv->options; - - priv->peer.send_count = options->send_count; - priv->peer.recv_count = options->recv_count; - priv->peer.send_size = options->send_size; - priv->peer.recv_size = options->recv_size; - - if ((ret = ib_verbs_create_qp (this)) < 0) { - gf_log ("transport/ib-verbs", GF_LOG_ERROR, - "%s: could not create QP", - this->xl->name); - transport_disconnect (this); - } - } - } - - if (!ret && poll_out && priv->tcp_connected) { - ret = ib_verbs_handshake_pollout (this); - } - - if (!ret && poll_in && priv->tcp_connected) { - if (priv->handshake.incoming.state == IB_VERBS_HANDSHAKE_COMPLETE) { - gf_log ("transport/ib-verbs", GF_LOG_ERROR, - "%s: pollin received on tcp socket (peer: %s) " - "after handshake is complete", - this->xl->name, this->peerinfo.identifier); - ib_verbs_handshake_pollerr (this); - return 0; - } - ret = ib_verbs_handshake_pollin (this); - } - - if (ret < 0 || poll_err) { - ret = ib_verbs_handshake_pollerr (this); - } - - return 0; -} - -static int -__tcp_nonblock (int fd) -{ - int flags = 0; - int ret = -1; - - flags = fcntl (fd, F_GETFL); - - if (flags != -1) - ret = fcntl (fd, F_SETFL, flags | O_NONBLOCK); - - return ret; -} - -static int32_t -ib_verbs_connect (struct transport *this) -{ - dict_t *options = this->xl->options; - - ib_verbs_private_t *priv = this->private; - - int32_t ret = 0; - gf_boolean_t non_blocking = 1; - struct sockaddr_storage sockaddr; - socklen_t sockaddr_len = 0; - - if (priv->connected) { - return 0; - } - - if (dict_get (options, "non-blocking-io")) { - char *nb_connect = data_to_str (dict_get (this->xl->options, - "non-blocking-io")); - - if (gf_string2boolean (nb_connect, &non_blocking) == -1) { - gf_log (this->xl->name, GF_LOG_ERROR, - "'non-blocking-io' takes only boolean " - "options, not taking any action"); - non_blocking = 1; - } - } - - ret = gf_ibverbs_client_get_remote_sockaddr (this, - (struct sockaddr *)&sockaddr, - &sockaddr_len); - if (ret != 0) { - gf_log (this->xl->name, GF_LOG_DEBUG, - "cannot get remote address to connect"); - return ret; - } - - pthread_mutex_lock (&priv->write_mutex); - { - if (priv->sock != -1) { - ret = 0; - goto unlock; - } - - priv->sock = socket (((struct sockaddr *)&sockaddr)->sa_family, - SOCK_STREAM, 0); - - if (priv->sock == -1) { - gf_log (this->xl->name, GF_LOG_ERROR, - "socket () - error: %s", strerror (errno)); - ret = -errno; - goto unlock; - } - - gf_log (this->xl->name, GF_LOG_TRACE, - "socket fd = %d", priv->sock); - - memcpy (&this->peerinfo.sockaddr, &sockaddr, sockaddr_len); - this->peerinfo.sockaddr_len = sockaddr_len; - - ((struct sockaddr *) &this->myinfo.sockaddr)->sa_family = - ((struct sockaddr *)&this->peerinfo.sockaddr)->sa_family; - - if (non_blocking) - { - ret = __tcp_nonblock (priv->sock); - - if (ret == -1) - { - gf_log (this->xl->name, GF_LOG_ERROR, - "could not set socket %d to non " - "blocking mode (%s)", - priv->sock, strerror (errno)); - close (priv->sock); - priv->sock = -1; - goto unlock; - } - } - - ret = gf_ibverbs_client_bind (this, - (struct sockaddr *)&this->myinfo.sockaddr, - &this->myinfo.sockaddr_len, priv->sock); - if (ret == -1) - { - gf_log (this->xl->name, GF_LOG_WARNING, - "client bind failed: %s", strerror (errno)); - close (priv->sock); - priv->sock = -1; - goto unlock; - } - - ret = connect (priv->sock, - (struct sockaddr *)&this->peerinfo.sockaddr, - this->peerinfo.sockaddr_len); - if (ret == -1 && errno != EINPROGRESS) - { - gf_log (this->xl->name, GF_LOG_ERROR, - "connection attempt failed (%s)", - strerror (errno)); - close (priv->sock); - priv->sock = -1; - goto unlock; - } - - priv->tcp_connected = priv->connected = 0; - - transport_ref (this); - - priv->handshake.incoming.state = IB_VERBS_HANDSHAKE_START; - priv->handshake.outgoing.state = IB_VERBS_HANDSHAKE_START; - - priv->idx = event_register (this->xl->ctx->event_pool, - priv->sock, ib_verbs_event_handler, - this, 1, 1); - } -unlock: - pthread_mutex_unlock (&priv->write_mutex); - - return ret; -} - -static int -ib_verbs_server_event_handler (int fd, int idx, void *data, - int poll_in, int poll_out, int poll_err) -{ - int32_t main_sock = -1; - transport_t *this, *trans = data; - ib_verbs_private_t *priv = NULL; - ib_verbs_private_t *trans_priv = (ib_verbs_private_t *) trans->private; - ib_verbs_options_t *options = NULL; - - if (!poll_in) - return 0; - - this = GF_CALLOC (1, sizeof (transport_t), - gf_ibv_mt_transport_t); - if (!this) - return 0; - - priv = GF_CALLOC (1, sizeof (ib_verbs_private_t), - gf_ibv_mt_ib_verbs_private_t); - if (!priv) { - GF_FREE (this); - return 0; - } - - this->private = priv; - /* Copy all the ib_verbs related values in priv, from trans_priv - as other than QP, all the values remain same */ - priv->device = trans_priv->device; - priv->options = trans_priv->options; - options = &priv->options; - - this->ops = trans->ops; - this->xl = trans->xl; - this->init = trans->init; - this->fini = trans->fini; - - memcpy (&this->myinfo.sockaddr, &trans->myinfo.sockaddr, - trans->myinfo.sockaddr_len); - this->myinfo.sockaddr_len = trans->myinfo.sockaddr_len; - - main_sock = (trans_priv)->sock; - this->peerinfo.sockaddr_len = sizeof (this->peerinfo.sockaddr); - priv->sock = accept (main_sock, - (struct sockaddr *)&this->peerinfo.sockaddr, - &this->peerinfo.sockaddr_len); - if (priv->sock == -1) { - gf_log ("ib-verbs/server", GF_LOG_ERROR, - "accept() failed: %s", - strerror (errno)); - GF_FREE (this->private); - GF_FREE (this); - return -1; - } - - priv->peer.trans = this; - transport_ref (this); - - gf_ibverbs_get_transport_identifiers (this); - - priv->tcp_connected = 1; - priv->handshake.incoming.state = IB_VERBS_HANDSHAKE_START; - priv->handshake.outgoing.state = IB_VERBS_HANDSHAKE_START; - - priv->peer.send_count = options->send_count; - priv->peer.recv_count = options->recv_count; - priv->peer.send_size = options->send_size; - priv->peer.recv_size = options->recv_size; - INIT_LIST_HEAD (&priv->peer.ioq); - - if (ib_verbs_create_qp (this) < 0) { - gf_log ("transport/ib-verbs", GF_LOG_ERROR, - "%s: could not create QP", - this->xl->name); - transport_disconnect (this); - return -1; - } - - priv->idx = event_register (this->xl->ctx->event_pool, priv->sock, - ib_verbs_event_handler, this, 1, 1); - - pthread_mutex_init (&priv->read_mutex, NULL); - pthread_mutex_init (&priv->write_mutex, NULL); - pthread_mutex_init (&priv->recv_mutex, NULL); - /* pthread_cond_init (&priv->recv_cond, NULL); */ - - return 0; -} - -static int32_t -ib_verbs_listen (transport_t *this) -{ - struct sockaddr_storage sockaddr; - socklen_t sockaddr_len; - ib_verbs_private_t *priv = this->private; - int opt = 1, ret = 0; - char service[NI_MAXSERV], host[NI_MAXHOST]; - - memset (&sockaddr, 0, sizeof (sockaddr)); - ret = gf_ibverbs_server_get_local_sockaddr (this, - (struct sockaddr *)&sockaddr, - &sockaddr_len); - if (ret != 0) { - gf_log (this->xl->name, GF_LOG_DEBUG, - "cannot find network address of server to bind to"); - goto err; - } - - priv->sock = socket (((struct sockaddr *)&sockaddr)->sa_family, - SOCK_STREAM, 0); - if (priv->sock == -1) { - gf_log ("ib-verbs/server", GF_LOG_CRITICAL, - "init: failed to create socket, error: %s", - strerror (errno)); - GF_FREE (this->private); - ret = -1; - goto err; - } - - memcpy (&this->myinfo.sockaddr, &sockaddr, sockaddr_len); - this->myinfo.sockaddr_len = sockaddr_len; - - ret = getnameinfo ((struct sockaddr *)&this->myinfo.sockaddr, - this->myinfo.sockaddr_len, - host, sizeof (host), - service, sizeof (service), - NI_NUMERICHOST); - if (ret != 0) { - gf_log (this->xl->name, GF_LOG_ERROR, - "getnameinfo failed (%s)", gai_strerror (ret)); - goto err; - } - sprintf (this->myinfo.identifier, "%s:%s", host, service); - - setsockopt (priv->sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof (opt)); - if (bind (priv->sock, - (struct sockaddr *)&sockaddr, - sockaddr_len) != 0) { - ret = -1; - gf_log ("ib-verbs/server", GF_LOG_ERROR, - "init: failed to bind to socket for %s (%s)", - this->myinfo.identifier, strerror (errno)); - goto err; - } - - if (listen (priv->sock, 10) != 0) { - gf_log ("ib-verbs/server", GF_LOG_ERROR, - "init: listen () failed on socket for %s (%s)", - this->myinfo.identifier, strerror (errno)); - ret = -1; - goto err; - } - - /* Register the main socket */ - priv->idx = event_register (this->xl->ctx->event_pool, priv->sock, - ib_verbs_server_event_handler, - transport_ref (this), 1, 0); - -err: - return ret; -} - -struct transport_ops tops = { - .receive = ib_verbs_receive, - .submit = ib_verbs_submit, - .connect = ib_verbs_connect, - .disconnect = ib_verbs_disconnect, - .listen = ib_verbs_listen, -}; - -int32_t -init (transport_t *this) -{ - ib_verbs_private_t *priv = GF_CALLOC (1, sizeof (*priv), - gf_ibv_mt_ib_verbs_private_t); - this->private = priv; - priv->sock = -1; - - if (ib_verbs_init (this)) { - gf_log (this->xl->name, GF_LOG_ERROR, - "Failed to initialize IB Device"); - return -1; - } - - return 0; -} - -void -fini (struct transport *this) -{ - /* TODO: verify this function does graceful finish */ - ib_verbs_private_t *priv = this->private; - this->private = NULL; - - pthread_mutex_destroy (&priv->recv_mutex); - pthread_mutex_destroy (&priv->write_mutex); - pthread_mutex_destroy (&priv->read_mutex); - /* pthread_cond_destroy (&priv->recv_cond); */ - - gf_log (this->xl->name, GF_LOG_TRACE, - "called fini on transport: %p", - this); - GF_FREE (priv); - return; -} - -int32_t -mem_acct_init (xlator_t *this) -{ - int ret = -1; - - if (!this) - return ret; - - ret = xlator_mem_acct_init (this, gf_common_mt_end + 1); - - if (ret != 0) { - gf_log (this->name, GF_LOG_ERROR, "Memory accounting init" - "failed"); - return ret; - } - - return ret; -} - -/* TODO: expand each option */ -struct volume_options options[] = { - { .key = {"transport.ib-verbs.port", - "ib-verbs-port"}, - .type = GF_OPTION_TYPE_INT, - .min = 1, - .max = 4, - .description = "check the option by 'ibv_devinfo'" - }, - { .key = {"transport.ib-verbs.mtu", - "ib-verbs-mtu"}, - .type = GF_OPTION_TYPE_INT, - }, - { .key = {"transport.ib-verbs.device-name", - "ib-verbs-device-name"}, - .type = GF_OPTION_TYPE_ANY, - .description = "check by 'ibv_devinfo'" - }, - { .key = {"transport.ib-verbs.work-request-send-count", - "ib-verbs-work-request-send-count"}, - .type = GF_OPTION_TYPE_INT, - }, - { .key = {"transport.ib-verbs.work-request-recv-count", - "ib-verbs-work-request-recv-count"}, - .type = GF_OPTION_TYPE_INT, - }, - { .key = {"remote-port", - "transport.remote-port", - "transport.ib-verbs.remote-port"}, - .type = GF_OPTION_TYPE_INT - }, - { .key = {"transport.ib-verbs.listen-port", "listen-port"}, - .type = GF_OPTION_TYPE_INT - }, - { .key = {"transport.ib-verbs.connect-path", "connect-path"}, - .type = GF_OPTION_TYPE_ANY - }, - { .key = {"transport.ib-verbs.bind-path", "bind-path"}, - .type = GF_OPTION_TYPE_ANY - }, - { .key = {"transport.ib-verbs.listen-path", "listen-path"}, - .type = GF_OPTION_TYPE_ANY - }, - { .key = {"transport.address-family", - "address-family"}, - .value = {"inet", "inet6", "inet/inet6", "inet6/inet", - "unix", "inet-sdp" }, - .type = GF_OPTION_TYPE_STR - }, - { .key = {"transport.socket.lowlat"}, - .type = GF_OPTION_TYPE_BOOL - }, - { .key = {NULL} } -}; diff --git a/xlators/protocol/legacy/transport/ib-verbs/src/ib-verbs.h b/xlators/protocol/legacy/transport/ib-verbs/src/ib-verbs.h deleted file mode 100644 index 3818609b0..000000000 --- a/xlators/protocol/legacy/transport/ib-verbs/src/ib-verbs.h +++ /dev/null @@ -1,220 +0,0 @@ -/* - Copyright (c) 2006-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 _XPORT_IB_VERBS_H -#define _XPORT_IB_VERBS_H - - -#ifndef _CONFIG_H -#define _CONFIG_H -#include "config.h" -#endif - -#ifndef MAX_IOVEC -#define MAX_IOVEC 16 -#endif /* MAX_IOVEC */ - -#include "xlator.h" -#include "event.h" -#include "ib-verbs-mem-types.h" - -#include <stdio.h> -#include <list.h> -#include <arpa/inet.h> -#include <infiniband/verbs.h> - -#define GF_DEFAULT_IBVERBS_LISTEN_PORT 6997 - -/* options per transport end point */ -struct _ib_verbs_options { - int32_t port; - char *device_name; - enum ibv_mtu mtu; - int32_t send_count; - int32_t recv_count; - uint64_t recv_size; - uint64_t send_size; -}; -typedef struct _ib_verbs_options ib_verbs_options_t; - - -struct _ib_verbs_header { - char colonO[3]; - uint32_t size1; - uint32_t size2; - char version; -} __attribute__((packed)); -typedef struct _ib_verbs_header ib_verbs_header_t; - -struct _ib_verbs_ioq { - union { - struct list_head list; - struct { - struct _ib_verbs_ioq *next; - struct _ib_verbs_ioq *prev; - }; - }; - ib_verbs_header_t header; - struct iovec vector[MAX_IOVEC]; - int count; - char *buf; - struct iobref *iobref; -}; -typedef struct _ib_verbs_ioq ib_verbs_ioq_t; - -/* represents one communication peer, two per transport_t */ -struct _ib_verbs_peer { - transport_t *trans; - struct ibv_qp *qp; - - int32_t recv_count; - int32_t send_count; - int32_t recv_size; - int32_t send_size; - - int32_t quota; - union { - struct list_head ioq; - struct { - ib_verbs_ioq_t *ioq_next; - ib_verbs_ioq_t *ioq_prev; - }; - }; - - /* QP attributes, needed to connect with remote QP */ - int32_t local_lid; - int32_t local_psn; - int32_t local_qpn; - int32_t remote_lid; - int32_t remote_psn; - int32_t remote_qpn; -}; -typedef struct _ib_verbs_peer ib_verbs_peer_t; - - -struct _ib_verbs_post { - struct _ib_verbs_post *next, *prev; - struct ibv_mr *mr; - char *buf; - int32_t buf_size; - char aux; - int32_t reused; - pthread_barrier_t wait; -}; -typedef struct _ib_verbs_post ib_verbs_post_t; - - -struct _ib_verbs_queue { - ib_verbs_post_t active_posts, passive_posts; - int32_t active_count, passive_count; - pthread_mutex_t lock; -}; -typedef struct _ib_verbs_queue ib_verbs_queue_t; - - -struct _ib_verbs_qpreg { - pthread_mutex_t lock; - int32_t count; - struct _qpent { - struct _qpent *next, *prev; - int32_t qp_num; - ib_verbs_peer_t *peer; - } ents[42]; -}; -typedef struct _ib_verbs_qpreg ib_verbs_qpreg_t; - -/* context per device, stored in global glusterfs_ctx_t->ib */ -struct _ib_verbs_device { - struct _ib_verbs_device *next; - const char *device_name; - struct ibv_context *context; - int32_t port; - struct ibv_pd *pd; - struct ibv_srq *srq; - ib_verbs_qpreg_t qpreg; - struct ibv_comp_channel *send_chan, *recv_chan; - struct ibv_cq *send_cq, *recv_cq; - ib_verbs_queue_t sendq, recvq; - pthread_t send_thread, recv_thread; -}; -typedef struct _ib_verbs_device ib_verbs_device_t; - -typedef enum { - IB_VERBS_HANDSHAKE_START = 0, - IB_VERBS_HANDSHAKE_SENDING_DATA, - IB_VERBS_HANDSHAKE_RECEIVING_DATA, - IB_VERBS_HANDSHAKE_SENT_DATA, - IB_VERBS_HANDSHAKE_RECEIVED_DATA, - IB_VERBS_HANDSHAKE_SENDING_ACK, - IB_VERBS_HANDSHAKE_RECEIVING_ACK, - IB_VERBS_HANDSHAKE_RECEIVED_ACK, - IB_VERBS_HANDSHAKE_COMPLETE, -} ib_verbs_handshake_state_t; - -struct ib_verbs_nbio { - int state; - char *buf; - int count; - struct iovec vector; - struct iovec *pending_vector; - int pending_count; -}; - - -struct _ib_verbs_private { - int32_t sock; - int32_t idx; - unsigned char connected; - unsigned char tcp_connected; - unsigned char ib_connected; - in_addr_t addr; - unsigned short port; - - /* IB Verbs Driver specific variables, pointers */ - ib_verbs_peer_t peer; - ib_verbs_device_t *device; - ib_verbs_options_t options; - - /* Used by trans->op->receive */ - char *data_ptr; - int32_t data_offset; - int32_t data_len; - - /* Mutex */ - pthread_mutex_t read_mutex; - pthread_mutex_t write_mutex; - pthread_barrier_t handshake_barrier; - char handshake_ret; - - pthread_mutex_t recv_mutex; - pthread_cond_t recv_cond; - - /* used during ib_verbs_handshake */ - struct { - struct ib_verbs_nbio incoming; - struct ib_verbs_nbio outgoing; - int state; - ib_verbs_header_t header; - char *buf; - size_t size; - } handshake; -}; -typedef struct _ib_verbs_private ib_verbs_private_t; - -#endif /* _XPORT_IB_VERBS_H */ diff --git a/xlators/protocol/legacy/transport/ib-verbs/src/name.c b/xlators/protocol/legacy/transport/ib-verbs/src/name.c deleted file mode 100644 index 511a33a22..000000000 --- a/xlators/protocol/legacy/transport/ib-verbs/src/name.c +++ /dev/null @@ -1,712 +0,0 @@ -/* - Copyright (c) 2008-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/>. -*/ - -#include <sys/types.h> -#include <sys/socket.h> -#include <errno.h> -#include <netdb.h> -#include <string.h> - -#ifdef CLIENT_PORT_CEILING -#undef CLIENT_PORT_CEILING -#endif - -#define CLIENT_PORT_CEILING 1024 - -#ifndef AF_INET_SDP -#define AF_INET_SDP 27 -#endif - -#include "transport.h" -#include "ib-verbs.h" - -int32_t -gf_resolve_ip6 (const char *hostname, - uint16_t port, - int family, - void **dnscache, - struct addrinfo **addr_info); - -static int32_t -af_inet_bind_to_port_lt_ceiling (int fd, struct sockaddr *sockaddr, - socklen_t sockaddr_len, int ceiling) -{ - int32_t ret = -1; - /* struct sockaddr_in sin = {0, }; */ - uint16_t port = ceiling - 1; - - while (port) - { - switch (sockaddr->sa_family) - { - case AF_INET6: - ((struct sockaddr_in6 *)sockaddr)->sin6_port = htons (port); - break; - - case AF_INET_SDP: - case AF_INET: - ((struct sockaddr_in *)sockaddr)->sin_port = htons (port); - break; - } - - ret = bind (fd, sockaddr, sockaddr_len); - - if (ret == 0) - break; - - if (ret == -1 && errno == EACCES) - break; - - port--; - } - - return ret; -} - -static int32_t -af_unix_client_bind (transport_t *this, - struct sockaddr *sockaddr, - socklen_t sockaddr_len, - int sock) -{ - data_t *path_data = NULL; - struct sockaddr_un *addr = NULL; - int32_t ret = -1; - - path_data = dict_get (this->xl->options, - "transport.ib-verbs.bind-path"); - if (path_data) { - char *path = data_to_str (path_data); - if (!path || strlen (path) > UNIX_PATH_MAX) { - gf_log (this->xl->name, GF_LOG_DEBUG, - "transport.ib-verbs.bind-path not specfied " - "for unix socket, letting connect to assign " - "default value"); - goto err; - } - - addr = (struct sockaddr_un *) sockaddr; - strcpy (addr->sun_path, path); - ret = bind (sock, (struct sockaddr *)addr, sockaddr_len); - if (ret == -1) { - gf_log (this->xl->name, GF_LOG_ERROR, - "cannot bind to unix-domain socket %d (%s)", - sock, strerror (errno)); - goto err; - } - } - -err: - return ret; -} - -static int32_t -client_fill_address_family (transport_t *this, struct sockaddr *sockaddr) -{ - data_t *address_family_data = NULL; - - address_family_data = dict_get (this->xl->options, - "transport.address-family"); - if (!address_family_data) { - data_t *remote_host_data = NULL, *connect_path_data = NULL; - remote_host_data = dict_get (this->xl->options, "remote-host"); - connect_path_data = dict_get (this->xl->options, - "transport.ib-verbs.connect-path"); - - if (!(remote_host_data || connect_path_data) || - (remote_host_data && connect_path_data)) { - gf_log (this->xl->name, GF_LOG_ERROR, - "address-family not specified and not able to " - "determine the same from other options " - "(remote-host:%s and connect-path:%s)", - data_to_str (remote_host_data), - data_to_str (connect_path_data)); - return -1; - } - - if (remote_host_data) { - gf_log (this->xl->name, GF_LOG_DEBUG, - "address-family not specified, guessing it " - "to be inet/inet6"); - sockaddr->sa_family = AF_UNSPEC; - } else { - gf_log (this->xl->name, GF_LOG_DEBUG, - "address-family not specified, guessing it " - "to be unix"); - sockaddr->sa_family = AF_UNIX; - } - - } else { - char *address_family = data_to_str (address_family_data); - if (!strcasecmp (address_family, "unix")) { - sockaddr->sa_family = AF_UNIX; - } else if (!strcasecmp (address_family, "inet")) { - sockaddr->sa_family = AF_INET; - } else if (!strcasecmp (address_family, "inet6")) { - sockaddr->sa_family = AF_INET6; - } else if (!strcasecmp (address_family, "inet-sdp")) { - sockaddr->sa_family = AF_INET_SDP; - } else if (!strcasecmp (address_family, "inet/inet6") - || !strcasecmp (address_family, "inet6/inet")) { - sockaddr->sa_family = AF_UNSPEC; - } else { - gf_log (this->xl->name, GF_LOG_ERROR, - "unknown address-family (%s) specified", - address_family); - return -1; - } - } - - return 0; -} - -static int32_t -af_inet_client_get_remote_sockaddr (transport_t *this, - struct sockaddr *sockaddr, - socklen_t *sockaddr_len) -{ - dict_t *options = this->xl->options; - data_t *remote_host_data = NULL; - data_t *remote_port_data = NULL; - char *remote_host = NULL; - uint16_t remote_port = 0; - struct addrinfo *addr_info = NULL; - int32_t ret = 0; - - remote_host_data = dict_get (options, "remote-host"); - if (remote_host_data == NULL) - { - gf_log (this->xl->name, GF_LOG_ERROR, - "option remote-host missing in volume %s", - this->xl->name); - ret = -1; - goto err; - } - - remote_host = data_to_str (remote_host_data); - if (remote_host == NULL) - { - gf_log (this->xl->name, GF_LOG_ERROR, - "option remote-host has data NULL in volume %s", - this->xl->name); - ret = -1; - goto err; - } - - remote_port_data = dict_get (options, "remote-port"); - if (remote_port_data == NULL) - { - gf_log (this->xl->name, GF_LOG_DEBUG, - "option remote-port missing in volume %s. " - "Defaulting to %d", - this->xl->name, GF_DEFAULT_IBVERBS_LISTEN_PORT); - - remote_port = GF_DEFAULT_IBVERBS_LISTEN_PORT; - } - else - { - remote_port = data_to_uint16 (remote_port_data); - } - - if (remote_port == (uint16_t)-1) - { - gf_log (this->xl->name, GF_LOG_ERROR, - "option remote-port has invalid port in volume %s", - this->xl->name); - ret = -1; - goto err; - } - - /* TODO: gf_resolve is a blocking call. kick in some - non blocking dns techniques */ - ret = gf_resolve_ip6 (remote_host, remote_port, - sockaddr->sa_family, - &this->dnscache, &addr_info); - if (ret == -1) { - gf_log (this->xl->name, GF_LOG_ERROR, - "DNS resolution failed on host %s", remote_host); - goto err; - } - - memcpy (sockaddr, addr_info->ai_addr, addr_info->ai_addrlen); - *sockaddr_len = addr_info->ai_addrlen; - -err: - return ret; -} - -static int32_t -af_unix_client_get_remote_sockaddr (transport_t *this, - struct sockaddr *sockaddr, - socklen_t *sockaddr_len) -{ - struct sockaddr_un *sockaddr_un = NULL; - char *connect_path = NULL; - data_t *connect_path_data = NULL; - int32_t ret = 0; - - connect_path_data = dict_get (this->xl->options, - "transport.ib-verbs.connect-path"); - if (!connect_path_data) { - gf_log (this->xl->name, GF_LOG_ERROR, - "option transport.ib-verbs.connect-path not " - "specified for address-family unix"); - ret = -1; - goto err; - } - - connect_path = data_to_str (connect_path_data); - if (!connect_path) { - gf_log (this->xl->name, GF_LOG_ERROR, - "connect-path is null-string"); - ret = -1; - goto err; - } - - if (strlen (connect_path) > UNIX_PATH_MAX) { - gf_log (this->xl->name, GF_LOG_ERROR, - "connect-path value length %"GF_PRI_SIZET" > " - "%d octets", strlen (connect_path), UNIX_PATH_MAX); - ret = -1; - goto err; - } - - gf_log (this->xl->name, - GF_LOG_DEBUG, - "using connect-path %s", connect_path); - sockaddr_un = (struct sockaddr_un *)sockaddr; - strcpy (sockaddr_un->sun_path, connect_path); - *sockaddr_len = sizeof (struct sockaddr_un); - -err: - return ret; -} - -static int32_t -af_unix_server_get_local_sockaddr (transport_t *this, - struct sockaddr *addr, - socklen_t *addr_len) -{ - data_t *listen_path_data = NULL; - char *listen_path = NULL; - int32_t ret = 0; - struct sockaddr_un *sunaddr = (struct sockaddr_un *)addr; - - - listen_path_data = dict_get (this->xl->options, - "transport.ib-verbs.listen-path"); - if (!listen_path_data) { - gf_log (this->xl->name, GF_LOG_ERROR, - "missing option listen-path"); - ret = -1; - goto err; - } - - listen_path = data_to_str (listen_path_data); - -#ifndef UNIX_PATH_MAX -#define UNIX_PATH_MAX 108 -#endif - - if (strlen (listen_path) > UNIX_PATH_MAX) { - gf_log (this->xl->name, GF_LOG_ERROR, - "option listen-path has value length %"GF_PRI_SIZET" > %d", - strlen (listen_path), UNIX_PATH_MAX); - ret = -1; - goto err; - } - - sunaddr->sun_family = AF_UNIX; - strcpy (sunaddr->sun_path, listen_path); - *addr_len = sizeof (struct sockaddr_un); - -err: - return ret; -} - -static int32_t -af_inet_server_get_local_sockaddr (transport_t *this, - struct sockaddr *addr, - socklen_t *addr_len) -{ - struct addrinfo hints, *res = 0; - data_t *listen_port_data = NULL, *listen_host_data = NULL; - uint16_t listen_port = -1; - char service[NI_MAXSERV], *listen_host = NULL; - dict_t *options = NULL; - int32_t ret = 0; - - options = this->xl->options; - - listen_port_data = dict_get (options, "transport.ib-verbs.listen-port"); - listen_host_data = dict_get (options, "transport.ib-verbs.bind-address"); - - if (listen_port_data) - { - listen_port = data_to_uint16 (listen_port_data); - } else { - if (addr->sa_family == AF_INET6) { - struct sockaddr_in6 *in = (struct sockaddr_in6 *) addr; - in->sin6_addr = in6addr_any; - in->sin6_port = htons(listen_port); - *addr_len = sizeof(struct sockaddr_in6); - goto out; - } else if (addr->sa_family == AF_INET) { - struct sockaddr_in *in = (struct sockaddr_in *) addr; - in->sin_addr.s_addr = htonl(INADDR_ANY); - in->sin_port = htons(listen_port); - *addr_len = sizeof(struct sockaddr_in); - goto out; - } - } - - if (listen_port == (uint16_t) -1) - listen_port = GF_DEFAULT_IBVERBS_LISTEN_PORT; - - - if (listen_host_data) - { - listen_host = data_to_str (listen_host_data); - } - - memset (service, 0, sizeof (service)); - sprintf (service, "%d", listen_port); - - memset (&hints, 0, sizeof (hints)); - hints.ai_family = addr->sa_family; - hints.ai_socktype = SOCK_STREAM; - hints.ai_flags = AI_ADDRCONFIG | AI_PASSIVE; - - ret = getaddrinfo(listen_host, service, &hints, &res); - if (ret != 0) { - gf_log (this->xl->name, - GF_LOG_ERROR, - "getaddrinfo failed for host %s, service %s (%s)", - listen_host, service, gai_strerror (ret)); - ret = -1; - goto out; - } - - memcpy (addr, res->ai_addr, res->ai_addrlen); - *addr_len = res->ai_addrlen; - - freeaddrinfo (res); - -out: - return ret; -} - -int32_t -gf_ibverbs_client_bind (transport_t *this, - struct sockaddr *sockaddr, - socklen_t *sockaddr_len, - int sock) -{ - int ret = 0; - - *sockaddr_len = sizeof (struct sockaddr_in6); - switch (sockaddr->sa_family) - { - case AF_INET_SDP: - case AF_INET: - *sockaddr_len = sizeof (struct sockaddr_in); - - case AF_INET6: - ret = af_inet_bind_to_port_lt_ceiling (sock, sockaddr, - *sockaddr_len, - CLIENT_PORT_CEILING); - if (ret == -1) { - gf_log (this->xl->name, GF_LOG_WARNING, - "cannot bind inet socket (%d) to port " - "less than %d (%s)", - sock, CLIENT_PORT_CEILING, strerror (errno)); - ret = 0; - } - break; - - case AF_UNIX: - *sockaddr_len = sizeof (struct sockaddr_un); - ret = af_unix_client_bind (this, (struct sockaddr *)sockaddr, - *sockaddr_len, sock); - break; - - default: - gf_log (this->xl->name, GF_LOG_ERROR, - "unknown address family %d", sockaddr->sa_family); - ret = -1; - break; - } - - return ret; -} - -int32_t -gf_ibverbs_client_get_remote_sockaddr (transport_t *this, - struct sockaddr *sockaddr, - socklen_t *sockaddr_len) -{ - int32_t ret = 0; - char is_inet_sdp = 0; - - ret = client_fill_address_family (this, sockaddr); - if (ret) { - ret = -1; - goto err; - } - - switch (sockaddr->sa_family) - { - case AF_INET_SDP: - sockaddr->sa_family = AF_INET; - is_inet_sdp = 1; - - case AF_INET: - case AF_INET6: - case AF_UNSPEC: - ret = af_inet_client_get_remote_sockaddr (this, - sockaddr, - sockaddr_len); - - if (is_inet_sdp) { - sockaddr->sa_family = AF_INET_SDP; - } - - break; - - case AF_UNIX: - ret = af_unix_client_get_remote_sockaddr (this, - sockaddr, - sockaddr_len); - break; - - default: - gf_log (this->xl->name, GF_LOG_ERROR, - "unknown address-family %d", sockaddr->sa_family); - ret = -1; - } - -err: - return ret; -} - -int32_t -gf_ibverbs_server_get_local_sockaddr (transport_t *this, - struct sockaddr *addr, - socklen_t *addr_len) -{ - data_t *address_family_data = NULL; - int32_t ret = 0; - char is_inet_sdp = 0; - - address_family_data = dict_get (this->xl->options, - "transport.address-family"); - if (address_family_data) { - char *address_family = NULL; - address_family = data_to_str (address_family_data); - - if (!strcasecmp (address_family, "inet")) { - addr->sa_family = AF_INET; - } else if (!strcasecmp (address_family, "inet6")) { - addr->sa_family = AF_INET6; - } else if (!strcasecmp (address_family, "inet-sdp")) { - addr->sa_family = AF_INET_SDP; - } else if (!strcasecmp (address_family, "unix")) { - addr->sa_family = AF_UNIX; - } else if (!strcasecmp (address_family, "inet/inet6") - || !strcasecmp (address_family, "inet6/inet")) { - addr->sa_family = AF_UNSPEC; - } else { - gf_log (this->xl->name, GF_LOG_ERROR, - "unknown address family (%s) specified", - address_family); - ret = -1; - goto err; - } - } else { - gf_log (this->xl->name, GF_LOG_DEBUG, - "option address-family not specified, defaulting " - "to inet/inet6"); - addr->sa_family = AF_UNSPEC; - } - - switch (addr->sa_family) - { - case AF_INET_SDP: - is_inet_sdp = 1; - addr->sa_family = AF_INET; - - case AF_INET: - case AF_INET6: - case AF_UNSPEC: - ret = af_inet_server_get_local_sockaddr (this, addr, addr_len); - if (is_inet_sdp && !ret) { - addr->sa_family = AF_INET_SDP; - } - break; - - case AF_UNIX: - ret = af_unix_server_get_local_sockaddr (this, addr, addr_len); - break; - } - -err: - return ret; -} - -int32_t -fill_inet6_inet_identifiers (transport_t *this, struct sockaddr_storage *addr, - int32_t addr_len, char *identifier) -{ - int32_t ret = 0, tmpaddr_len = 0; - char service[NI_MAXSERV], host[NI_MAXHOST]; - struct sockaddr_storage tmpaddr; - - memset (&tmpaddr, 0, sizeof (tmpaddr)); - tmpaddr = *addr; - tmpaddr_len = addr_len; - - if (((struct sockaddr *) &tmpaddr)->sa_family == AF_INET6) { - int32_t one_to_four, four_to_eight, twelve_to_sixteen; - int16_t eight_to_ten, ten_to_twelve; - - one_to_four = four_to_eight = twelve_to_sixteen = 0; - eight_to_ten = ten_to_twelve = 0; - - one_to_four = ((struct sockaddr_in6 *) - &tmpaddr)->sin6_addr.s6_addr32[0]; - four_to_eight = ((struct sockaddr_in6 *) - &tmpaddr)->sin6_addr.s6_addr32[1]; -#ifdef GF_SOLARIS_HOST_OS - eight_to_ten = S6_ADDR16(((struct sockaddr_in6 *) - &tmpaddr)->sin6_addr)[4]; -#else - eight_to_ten = ((struct sockaddr_in6 *) - &tmpaddr)->sin6_addr.s6_addr16[4]; -#endif - -#ifdef GF_SOLARIS_HOST_OS - ten_to_twelve = S6_ADDR16(((struct sockaddr_in6 *) - &tmpaddr)->sin6_addr)[5]; -#else - ten_to_twelve = ((struct sockaddr_in6 *) - &tmpaddr)->sin6_addr.s6_addr16[5]; -#endif - twelve_to_sixteen = ((struct sockaddr_in6 *) - &tmpaddr)->sin6_addr.s6_addr32[3]; - - /* ipv4 mapped ipv6 address has - bits 0-80: 0 - bits 80-96: 0xffff - bits 96-128: ipv4 address - */ - - if (one_to_four == 0 && - four_to_eight == 0 && - eight_to_ten == 0 && - ten_to_twelve == -1) { - struct sockaddr_in *in_ptr = (struct sockaddr_in *)&tmpaddr; - memset (&tmpaddr, 0, sizeof (tmpaddr)); - - in_ptr->sin_family = AF_INET; - in_ptr->sin_port = ((struct sockaddr_in6 *)addr)->sin6_port; - in_ptr->sin_addr.s_addr = twelve_to_sixteen; - tmpaddr_len = sizeof (*in_ptr); - } - } - - ret = getnameinfo ((struct sockaddr *) &tmpaddr, - tmpaddr_len, - host, sizeof (host), - service, sizeof (service), - NI_NUMERICHOST | NI_NUMERICSERV); - if (ret != 0) { - gf_log (this->xl->name, - GF_LOG_ERROR, - "getnameinfo failed (%s)", gai_strerror (ret)); - } - - sprintf (identifier, "%s:%s", host, service); - - return ret; -} - -int32_t -gf_ibverbs_get_transport_identifiers (transport_t *this) -{ - int32_t ret = 0; - char is_inet_sdp = 0; - - switch (((struct sockaddr *) &this->myinfo.sockaddr)->sa_family) - { - case AF_INET_SDP: - is_inet_sdp = 1; - ((struct sockaddr *) &this->peerinfo.sockaddr)->sa_family = ((struct sockaddr *) &this->myinfo.sockaddr)->sa_family = AF_INET; - - case AF_INET: - case AF_INET6: - { - ret = fill_inet6_inet_identifiers (this, - &this->myinfo.sockaddr, - this->myinfo.sockaddr_len, - this->myinfo.identifier); - if (ret == -1) { - gf_log (this->xl->name, GF_LOG_ERROR, - "can't fill inet/inet6 identifier for server"); - goto err; - } - - ret = fill_inet6_inet_identifiers (this, - &this->peerinfo.sockaddr, - this->peerinfo.sockaddr_len, - this->peerinfo.identifier); - if (ret == -1) { - gf_log (this->xl->name, GF_LOG_ERROR, - "can't fill inet/inet6 identifier for client"); - goto err; - } - - if (is_inet_sdp) { - ((struct sockaddr *) &this->peerinfo.sockaddr)->sa_family = ((struct sockaddr *) &this->myinfo.sockaddr)->sa_family = AF_INET_SDP; - } - } - break; - - case AF_UNIX: - { - struct sockaddr_un *sunaddr = NULL; - - sunaddr = (struct sockaddr_un *) &this->myinfo.sockaddr; - strcpy (this->myinfo.identifier, sunaddr->sun_path); - - sunaddr = (struct sockaddr_un *) &this->peerinfo.sockaddr; - strcpy (this->peerinfo.identifier, sunaddr->sun_path); - } - break; - - default: - gf_log (this->xl->name, GF_LOG_ERROR, - "unknown address family (%d)", - ((struct sockaddr *) &this->myinfo.sockaddr)->sa_family); - ret = -1; - break; - } - -err: - return ret; -} diff --git a/xlators/protocol/legacy/transport/ib-verbs/src/name.h b/xlators/protocol/legacy/transport/ib-verbs/src/name.h deleted file mode 100644 index 366077fdd..000000000 --- a/xlators/protocol/legacy/transport/ib-verbs/src/name.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - Copyright (c) 2008-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 _IB_VERBS_NAME_H -#define _IB_VERBS_NAME_H - -#include <sys/socket.h> -#include <sys/un.h> - -#include "compat.h" - -int32_t -gf_ibverbs_client_bind (transport_t *this, - struct sockaddr *sockaddr, - socklen_t *sockaddr_len, - int sock); - -int32_t -gf_ibverbs_client_get_remote_sockaddr (transport_t *this, - struct sockaddr *sockaddr, - socklen_t *sockaddr_len); - -int32_t -gf_ibverbs_server_get_local_sockaddr (transport_t *this, - struct sockaddr *addr, - socklen_t *addr_len); - -int32_t -gf_ibverbs_get_transport_identifiers (transport_t *this); - -#endif /* _IB_VERBS_NAME_H */ diff --git a/xlators/protocol/legacy/transport/socket/Makefile.am b/xlators/protocol/legacy/transport/socket/Makefile.am deleted file mode 100644 index f963effea..000000000 --- a/xlators/protocol/legacy/transport/socket/Makefile.am +++ /dev/null @@ -1 +0,0 @@ -SUBDIRS = src
\ No newline at end of file diff --git a/xlators/protocol/legacy/transport/socket/src/Makefile.am b/xlators/protocol/legacy/transport/socket/src/Makefile.am deleted file mode 100644 index 5952e18e9..000000000 --- a/xlators/protocol/legacy/transport/socket/src/Makefile.am +++ /dev/null @@ -1,19 +0,0 @@ -# TODO : change to proper transport dir - -transport_LTLIBRARIES = socket.la -transportdir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/transport - -socket_la_LDFLAGS = -module -avoidversion - -socket_la_SOURCES = socket.c name.c -socket_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la \ - $(top_builddir)/xlators/protocol/legacy/lib/src/libgfproto.la - -noinst_HEADERS = socket.h name.h socket-mem-types.h - -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)/xlators/protocol/legacy/transport/socket/src \ - -I$(top_srcdir)/xlators/protocol/legacy/lib/src - -CLEANFILES = *~ diff --git a/xlators/protocol/legacy/transport/socket/src/name.c b/xlators/protocol/legacy/transport/socket/src/name.c deleted file mode 100644 index 644a0bc5e..000000000 --- a/xlators/protocol/legacy/transport/socket/src/name.c +++ /dev/null @@ -1,740 +0,0 @@ -/* - Copyright (c) 2008-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/>. -*/ - -#include <sys/types.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <errno.h> -#include <netdb.h> -#include <string.h> - -#ifdef CLIENT_PORT_CEILING -#undef CLIENT_PORT_CEILING -#endif - -#define CLIENT_PORT_CEILING 1024 - -#ifndef AF_INET_SDP -#define AF_INET_SDP 27 -#endif - -static int gf_name_addr_enotspec_log; - -#include "transport.h" -#include "socket.h" - -int32_t -gf_resolve_ip6 (const char *hostname, - uint16_t port, - int family, - void **dnscache, - struct addrinfo **addr_info); - -static int32_t -af_inet_bind_to_port_lt_ceiling (int fd, struct sockaddr *sockaddr, - socklen_t sockaddr_len, int ceiling) -{ - int32_t ret = -1; - /* struct sockaddr_in sin = {0, }; */ - uint16_t port = ceiling - 1; - - while (port) - { - switch (sockaddr->sa_family) - { - case AF_INET6: - ((struct sockaddr_in6 *)sockaddr)->sin6_port = htons (port); - break; - - case AF_INET_SDP: - case AF_INET: - ((struct sockaddr_in *)sockaddr)->sin_port = htons (port); - break; - } - - ret = bind (fd, sockaddr, sockaddr_len); - - if (ret == 0) - break; - - if (ret == -1 && errno == EACCES) - break; - - port--; - } - - return ret; -} - -static int32_t -af_unix_client_bind (transport_t *this, - struct sockaddr *sockaddr, - socklen_t sockaddr_len, - int sock) -{ - data_t *path_data = NULL; - struct sockaddr_un *addr = NULL; - int32_t ret = 0; - - path_data = dict_get (this->xl->options, "transport.socket.bind-path"); - if (path_data) { - char *path = data_to_str (path_data); - if (!path || strlen (path) > UNIX_PATH_MAX) { - gf_log (this->xl->name, GF_LOG_TRACE, - "bind-path not specfied for unix socket, " - "letting connect to assign default value"); - goto err; - } - - addr = (struct sockaddr_un *) sockaddr; - strcpy (addr->sun_path, path); - ret = bind (sock, (struct sockaddr *)addr, sockaddr_len); - if (ret == -1) { - gf_log (this->xl->name, GF_LOG_ERROR, - "cannot bind to unix-domain socket %d (%s)", - sock, strerror (errno)); - goto err; - } - } else { - gf_log (this->xl->name, GF_LOG_TRACE, - "bind-path not specfied for unix socket, " - "letting connect to assign default value"); - } - -err: - return ret; -} - -static int32_t -client_fill_address_family (transport_t *this, sa_family_t *sa_family) -{ - data_t *address_family_data = NULL; - int32_t ret = -1; - - if (sa_family == NULL) { - goto out; - } - - address_family_data = dict_get (this->xl->options, - "transport.address-family"); - if (!address_family_data) { - data_t *remote_host_data = NULL, *connect_path_data = NULL; - remote_host_data = dict_get (this->xl->options, "remote-host"); - connect_path_data = dict_get (this->xl->options, - "transport.socket.connect-path"); - - if (!(remote_host_data || connect_path_data) || - (remote_host_data && connect_path_data)) { - GF_LOG_OCCASIONALLY (gf_name_addr_enotspec_log, - this->xl->name, GF_LOG_ERROR, - "transport.address-family not specified and " - "not able to determine the " - "same from other options (remote-host:%s and " - "transport.unix.connect-path:%s)", - data_to_str (remote_host_data), - data_to_str (connect_path_data)); - goto out; - } - - if (remote_host_data) { - gf_log (this->xl->name, GF_LOG_DEBUG, - "address-family not specified, guessing it " - "to be inet/inet6"); - *sa_family = AF_UNSPEC; - } else { - gf_log (this->xl->name, GF_LOG_DEBUG, - "address-family not specified, guessing it " - "to be unix"); - *sa_family = AF_UNIX; - } - - } else { - char *address_family = data_to_str (address_family_data); - if (!strcasecmp (address_family, "unix")) { - *sa_family = AF_UNIX; - } else if (!strcasecmp (address_family, "inet")) { - *sa_family = AF_INET; - } else if (!strcasecmp (address_family, "inet6")) { - *sa_family = AF_INET6; - } else if (!strcasecmp (address_family, "inet-sdp")) { - *sa_family = AF_INET_SDP; - } else if (!strcasecmp (address_family, "inet/inet6") - || !strcasecmp (address_family, "inet6/inet")) { - *sa_family = AF_UNSPEC; - } else { - gf_log (this->xl->name, GF_LOG_ERROR, - "unknown address-family (%s) specified", - address_family); - goto out; - } - } - - ret = 0; - -out: - return ret; -} - -static int32_t -af_inet_client_get_remote_sockaddr (transport_t *this, - struct sockaddr *sockaddr, - socklen_t *sockaddr_len) -{ - dict_t *options = this->xl->options; - data_t *remote_host_data = NULL; - data_t *remote_port_data = NULL; - char *remote_host = NULL; - uint16_t remote_port = 0; - struct addrinfo *addr_info = NULL; - int32_t ret = 0; - - remote_host_data = dict_get (options, "remote-host"); - if (remote_host_data == NULL) - { - gf_log (this->xl->name, GF_LOG_ERROR, - "option remote-host missing in volume %s", this->xl->name); - ret = -1; - goto err; - } - - remote_host = data_to_str (remote_host_data); - if (remote_host == NULL) - { - gf_log (this->xl->name, GF_LOG_ERROR, - "option remote-host has data NULL in volume %s", this->xl->name); - ret = -1; - goto err; - } - - remote_port_data = dict_get (options, "remote-port"); - if (remote_port_data == NULL) - { - gf_log (this->xl->name, GF_LOG_TRACE, - "option remote-port missing in volume %s. Defaulting to %d", - this->xl->name, GF_DEFAULT_SOCKET_LISTEN_PORT); - - remote_port = GF_DEFAULT_SOCKET_LISTEN_PORT; - } - else - { - remote_port = data_to_uint16 (remote_port_data); - } - - if (remote_port == (uint16_t)-1) - { - gf_log (this->xl->name, GF_LOG_ERROR, - "option remote-port has invalid port in volume %s", - this->xl->name); - ret = -1; - goto err; - } - - /* TODO: gf_resolve is a blocking call. kick in some - non blocking dns techniques */ - ret = gf_resolve_ip6 (remote_host, remote_port, - sockaddr->sa_family, &this->dnscache, &addr_info); - if (ret == -1) { - gf_log (this->xl->name, GF_LOG_ERROR, - "DNS resolution failed on host %s", remote_host); - goto err; - } - - memcpy (sockaddr, addr_info->ai_addr, addr_info->ai_addrlen); - *sockaddr_len = addr_info->ai_addrlen; - -err: - return ret; -} - -static int32_t -af_unix_client_get_remote_sockaddr (transport_t *this, - struct sockaddr *sockaddr, - socklen_t *sockaddr_len) -{ - struct sockaddr_un *sockaddr_un = NULL; - char *connect_path = NULL; - data_t *connect_path_data = NULL; - int32_t ret = 0; - - connect_path_data = dict_get (this->xl->options, - "transport.socket.connect-path"); - if (!connect_path_data) { - gf_log (this->xl->name, GF_LOG_ERROR, - "option transport.unix.connect-path not specified for " - "address-family unix"); - ret = -1; - goto err; - } - - connect_path = data_to_str (connect_path_data); - if (!connect_path) { - gf_log (this->xl->name, GF_LOG_ERROR, - "transport.unix.connect-path is null-string"); - ret = -1; - goto err; - } - - if (strlen (connect_path) > UNIX_PATH_MAX) { - gf_log (this->xl->name, GF_LOG_ERROR, - "connect-path value length %"GF_PRI_SIZET" > %d octets", - strlen (connect_path), UNIX_PATH_MAX); - ret = -1; - goto err; - } - - gf_log (this->xl->name, GF_LOG_TRACE, - "using connect-path %s", connect_path); - sockaddr_un = (struct sockaddr_un *)sockaddr; - strcpy (sockaddr_un->sun_path, connect_path); - *sockaddr_len = sizeof (struct sockaddr_un); - -err: - return ret; -} - -static int32_t -af_unix_server_get_local_sockaddr (transport_t *this, - struct sockaddr *addr, - socklen_t *addr_len) -{ - data_t *listen_path_data = NULL; - char *listen_path = NULL; - int32_t ret = 0; - struct sockaddr_un *sunaddr = (struct sockaddr_un *)addr; - - - listen_path_data = dict_get (this->xl->options, - "transport.socket.listen-path"); - if (!listen_path_data) { - gf_log (this->xl->name, GF_LOG_ERROR, - "missing option transport.socket.listen-path"); - ret = -1; - goto err; - } - - listen_path = data_to_str (listen_path_data); - -#ifndef UNIX_PATH_MAX -#define UNIX_PATH_MAX 108 -#endif - - if (strlen (listen_path) > UNIX_PATH_MAX) { - gf_log (this->xl->name, GF_LOG_ERROR, - "option transport.unix.listen-path has value length " - "%"GF_PRI_SIZET" > %d", - strlen (listen_path), UNIX_PATH_MAX); - ret = -1; - goto err; - } - - sunaddr->sun_family = AF_UNIX; - strcpy (sunaddr->sun_path, listen_path); - *addr_len = sizeof (struct sockaddr_un); - -err: - return ret; -} - -static int32_t -af_inet_server_get_local_sockaddr (transport_t *this, - struct sockaddr *addr, - socklen_t *addr_len) -{ - struct addrinfo hints, *res = 0; - data_t *listen_port_data = NULL, *listen_host_data = NULL; - uint16_t listen_port = -1; - char service[NI_MAXSERV], *listen_host = NULL; - dict_t *options = NULL; - int32_t ret = 0; - - options = this->xl->options; - - listen_port_data = dict_get (options, "transport.socket.listen-port"); - listen_host_data = dict_get (options, "transport.socket.bind-address"); - - if (listen_port_data) - { - listen_port = data_to_uint16 (listen_port_data); - } - - if (listen_port == (uint16_t) -1) - listen_port = GF_DEFAULT_SOCKET_LISTEN_PORT; - - - if (listen_host_data) - { - listen_host = data_to_str (listen_host_data); - } else { - if (addr->sa_family == AF_INET6) { - struct sockaddr_in6 *in = (struct sockaddr_in6 *) addr; - in->sin6_addr = in6addr_any; - in->sin6_port = htons(listen_port); - *addr_len = sizeof(struct sockaddr_in6); - goto out; - } else if (addr->sa_family == AF_INET) { - struct sockaddr_in *in = (struct sockaddr_in *) addr; - in->sin_addr.s_addr = htonl(INADDR_ANY); - in->sin_port = htons(listen_port); - *addr_len = sizeof(struct sockaddr_in); - goto out; - } - } - - memset (service, 0, sizeof (service)); - sprintf (service, "%d", listen_port); - - memset (&hints, 0, sizeof (hints)); - hints.ai_family = addr->sa_family; - hints.ai_socktype = SOCK_STREAM; - hints.ai_flags = AI_ADDRCONFIG | AI_PASSIVE; - - ret = getaddrinfo(listen_host, service, &hints, &res); - if (ret != 0) { - gf_log (this->xl->name, GF_LOG_ERROR, - "getaddrinfo failed for host %s, service %s (%s)", - listen_host, service, gai_strerror (ret)); - ret = -1; - goto out; - } - - memcpy (addr, res->ai_addr, res->ai_addrlen); - *addr_len = res->ai_addrlen; - - freeaddrinfo (res); - -out: - return ret; -} - -int32_t -gf_client_bind (transport_t *this, - struct sockaddr *sockaddr, - socklen_t *sockaddr_len, - int sock) -{ - int ret = 0; - - *sockaddr_len = sizeof (struct sockaddr_in6); - switch (sockaddr->sa_family) - { - case AF_INET_SDP: - case AF_INET: - *sockaddr_len = sizeof (struct sockaddr_in); - - case AF_INET6: - ret = af_inet_bind_to_port_lt_ceiling (sock, sockaddr, - *sockaddr_len, CLIENT_PORT_CEILING); - if (ret == -1) { - gf_log (this->xl->name, GF_LOG_WARNING, - "cannot bind inet socket (%d) to port less than %d (%s)", - sock, CLIENT_PORT_CEILING, strerror (errno)); - ret = 0; - } - break; - - case AF_UNIX: - *sockaddr_len = sizeof (struct sockaddr_un); - ret = af_unix_client_bind (this, (struct sockaddr *)sockaddr, - *sockaddr_len, sock); - break; - - default: - gf_log (this->xl->name, GF_LOG_ERROR, - "unknown address family %d", sockaddr->sa_family); - ret = -1; - break; - } - - return ret; -} - -int32_t -gf_socket_client_get_remote_sockaddr (transport_t *this, - struct sockaddr *sockaddr, - socklen_t *sockaddr_len, - sa_family_t *sa_family) -{ - int32_t ret = 0; - - if ((sockaddr == NULL) || (sockaddr_len == NULL) - || (sa_family == NULL)) { - ret = -1; - goto err; - } - - - ret = client_fill_address_family (this, &sockaddr->sa_family); - if (ret) { - ret = -1; - goto err; - } - - *sa_family = sockaddr->sa_family; - - switch (sockaddr->sa_family) - { - case AF_INET_SDP: - sockaddr->sa_family = AF_INET; - - case AF_INET: - case AF_INET6: - case AF_UNSPEC: - ret = af_inet_client_get_remote_sockaddr (this, sockaddr, - sockaddr_len); - break; - - case AF_UNIX: - ret = af_unix_client_get_remote_sockaddr (this, sockaddr, - sockaddr_len); - break; - - default: - gf_log (this->xl->name, GF_LOG_ERROR, - "unknown address-family %d", sockaddr->sa_family); - ret = -1; - } - - if (*sa_family == AF_UNSPEC) { - *sa_family = sockaddr->sa_family; - } - -err: - return ret; -} - - -static int32_t -server_fill_address_family (transport_t *this, sa_family_t *sa_family) -{ - data_t *address_family_data = NULL; - int32_t ret = -1; - - if (sa_family == NULL) { - goto out; - } - - address_family_data = dict_get (this->xl->options, - "transport.address-family"); - if (address_family_data) { - char *address_family = NULL; - address_family = data_to_str (address_family_data); - - if (!strcasecmp (address_family, "inet")) { - *sa_family = AF_INET; - } else if (!strcasecmp (address_family, "inet6")) { - *sa_family = AF_INET6; - } else if (!strcasecmp (address_family, "inet-sdp")) { - *sa_family = AF_INET_SDP; - } else if (!strcasecmp (address_family, "unix")) { - *sa_family = AF_UNIX; - } else if (!strcasecmp (address_family, "inet/inet6") - || !strcasecmp (address_family, "inet6/inet")) { - *sa_family = AF_UNSPEC; - } else { - gf_log (this->xl->name, GF_LOG_ERROR, - "unknown address family (%s) specified", address_family); - goto out; - } - } else { - gf_log (this->xl->name, GF_LOG_DEBUG, - "option address-family not specified, defaulting to inet/inet6"); - *sa_family = AF_UNSPEC; - } - - ret = 0; -out: - return ret; -} - - -int32_t -gf_socket_server_get_local_sockaddr (transport_t *this, struct sockaddr *addr, - socklen_t *addr_len, sa_family_t *sa_family) -{ - int32_t ret = -1; - - if ((addr == NULL) || (addr_len == NULL) || (sa_family == NULL)) { - goto err; - } - - ret = server_fill_address_family (this, &addr->sa_family); - if (ret == -1) { - goto err; - } - - *sa_family = addr->sa_family; - - switch (addr->sa_family) - { - case AF_INET_SDP: - addr->sa_family = AF_INET; - - case AF_INET: - case AF_INET6: - case AF_UNSPEC: - ret = af_inet_server_get_local_sockaddr (this, addr, addr_len); - break; - - case AF_UNIX: - ret = af_unix_server_get_local_sockaddr (this, addr, addr_len); - break; - } - - if (*sa_family == AF_UNSPEC) { - *sa_family = addr->sa_family; - } - -err: - return ret; -} - -static int32_t -fill_inet6_inet_identifiers (transport_t *this, struct sockaddr_storage *addr, - int32_t addr_len, char *identifier) -{ - int32_t ret = 0, tmpaddr_len = 0; - char service[NI_MAXSERV], host[NI_MAXHOST]; - struct sockaddr_storage tmpaddr; - - memset (&tmpaddr, 0, sizeof (tmpaddr)); - tmpaddr = *addr; - tmpaddr_len = addr_len; - - if (((struct sockaddr *) &tmpaddr)->sa_family == AF_INET6) { - int32_t one_to_four, four_to_eight, twelve_to_sixteen; - int16_t eight_to_ten, ten_to_twelve; - - one_to_four = four_to_eight = twelve_to_sixteen = 0; - eight_to_ten = ten_to_twelve = 0; - - one_to_four = ((struct sockaddr_in6 *) &tmpaddr)->sin6_addr.s6_addr32[0]; - four_to_eight = ((struct sockaddr_in6 *) &tmpaddr)->sin6_addr.s6_addr32[1]; -#ifdef GF_SOLARIS_HOST_OS - eight_to_ten = S6_ADDR16(((struct sockaddr_in6 *) &tmpaddr)->sin6_addr)[4]; -#else - eight_to_ten = ((struct sockaddr_in6 *) &tmpaddr)->sin6_addr.s6_addr16[4]; -#endif - -#ifdef GF_SOLARIS_HOST_OS - ten_to_twelve = S6_ADDR16(((struct sockaddr_in6 *) &tmpaddr)->sin6_addr)[5]; -#else - ten_to_twelve = ((struct sockaddr_in6 *) &tmpaddr)->sin6_addr.s6_addr16[5]; -#endif - - twelve_to_sixteen = ((struct sockaddr_in6 *) &tmpaddr)->sin6_addr.s6_addr32[3]; - - /* ipv4 mapped ipv6 address has - bits 0-80: 0 - bits 80-96: 0xffff - bits 96-128: ipv4 address - */ - - if (one_to_four == 0 && - four_to_eight == 0 && - eight_to_ten == 0 && - ten_to_twelve == -1) { - struct sockaddr_in *in_ptr = (struct sockaddr_in *)&tmpaddr; - memset (&tmpaddr, 0, sizeof (tmpaddr)); - - in_ptr->sin_family = AF_INET; - in_ptr->sin_port = ((struct sockaddr_in6 *)addr)->sin6_port; - in_ptr->sin_addr.s_addr = twelve_to_sixteen; - tmpaddr_len = sizeof (*in_ptr); - } - } - - ret = getnameinfo ((struct sockaddr *) &tmpaddr, - tmpaddr_len, - host, sizeof (host), - service, sizeof (service), - NI_NUMERICHOST | NI_NUMERICSERV); - if (ret != 0) { - gf_log (this->xl->name, GF_LOG_ERROR, - "getnameinfo failed (%s)", gai_strerror (ret)); - } - - sprintf (identifier, "%s:%s", host, service); - - return ret; -} - -int32_t -gf_get_transport_identifiers (transport_t *this) -{ - int32_t ret = 0; - char is_inet_sdp = 0; - - switch (((struct sockaddr *) &this->myinfo.sockaddr)->sa_family) - { - case AF_INET_SDP: - is_inet_sdp = 1; - ((struct sockaddr *) &this->peerinfo.sockaddr)->sa_family = ((struct sockaddr *) &this->myinfo.sockaddr)->sa_family = AF_INET; - - case AF_INET: - case AF_INET6: - { - ret = fill_inet6_inet_identifiers (this, - &this->myinfo.sockaddr, - this->myinfo.sockaddr_len, - this->myinfo.identifier); - if (ret == -1) { - gf_log (this->xl->name, GF_LOG_ERROR, - "cannot fill inet/inet6 identifier for server"); - goto err; - } - - ret = fill_inet6_inet_identifiers (this, - &this->peerinfo.sockaddr, - this->peerinfo.sockaddr_len, - this->peerinfo.identifier); - if (ret == -1) { - gf_log (this->xl->name, GF_LOG_ERROR, - "cannot fill inet/inet6 identifier for client"); - goto err; - } - - if (is_inet_sdp) { - ((struct sockaddr *) &this->peerinfo.sockaddr)->sa_family = ((struct sockaddr *) &this->myinfo.sockaddr)->sa_family = AF_INET_SDP; - } - } - break; - - case AF_UNIX: - { - struct sockaddr_un *sunaddr = NULL; - - sunaddr = (struct sockaddr_un *) &this->myinfo.sockaddr; - strcpy (this->myinfo.identifier, sunaddr->sun_path); - - sunaddr = (struct sockaddr_un *) &this->peerinfo.sockaddr; - strcpy (this->peerinfo.identifier, sunaddr->sun_path); - } - break; - - default: - gf_log (this->xl->name, GF_LOG_ERROR, - "unknown address family (%d)", - ((struct sockaddr *) &this->myinfo.sockaddr)->sa_family); - ret = -1; - break; - } - -err: - return ret; -} diff --git a/xlators/protocol/legacy/transport/socket/src/name.h b/xlators/protocol/legacy/transport/socket/src/name.h deleted file mode 100644 index 789cf13ef..000000000 --- a/xlators/protocol/legacy/transport/socket/src/name.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - Copyright (c) 2008-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 _SOCKET_NAME_H -#define _SOCKET_NAME_H - -#include "compat.h" - -int32_t -gf_client_bind (transport_t *this, - struct sockaddr *sockaddr, - socklen_t *sockaddr_len, - int sock); - -int32_t -gf_socket_client_get_remote_sockaddr (transport_t *this, - struct sockaddr *sockaddr, - socklen_t *sockaddr_len, - sa_family_t *sa_family); - -int32_t -gf_socket_server_get_local_sockaddr (transport_t *this, struct sockaddr *addr, - socklen_t *addr_len, sa_family_t *sa_family); - -int32_t -gf_get_transport_identifiers (transport_t *this); - -#endif /* _SOCKET_NAME_H */ diff --git a/xlators/protocol/legacy/transport/socket/src/socket-mem-types.h b/xlators/protocol/legacy/transport/socket/src/socket-mem-types.h deleted file mode 100644 index 937b9d7a8..000000000 --- a/xlators/protocol/legacy/transport/socket/src/socket-mem-types.h +++ /dev/null @@ -1,36 +0,0 @@ - -/* - Copyright (c) 2008-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 __SOCKET_MEM_TYPES_H__ -#define __SOCKET_MEM_TYPES_H__ - -#include "mem-types.h" - -enum gf_socket_mem_types_ { - gf_socket_mt_socket_private_t = gf_common_mt_end + 1, - gf_socket_mt_ioq, - gf_socket_mt_transport_t, - gf_socket_mt_socket_local_t, - gf_socket_mt_char, - gf_socket_mt_end -}; -#endif - diff --git a/xlators/protocol/legacy/transport/socket/src/socket.c b/xlators/protocol/legacy/transport/socket/src/socket.c deleted file mode 100644 index 9272b0584..000000000 --- a/xlators/protocol/legacy/transport/socket/src/socket.c +++ /dev/null @@ -1,1625 +0,0 @@ -/* - Copyright (c) 2008-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 "socket.h" -#include "name.h" -#include "dict.h" -#include "transport.h" -#include "logging.h" -#include "xlator.h" -#include "byte-order.h" -#include "common-utils.h" -#include "compat-errno.h" - -#include <fcntl.h> -#include <errno.h> -#include <netinet/tcp.h> - - -#define GF_LOG_ERRNO(errno) ((errno == ENOTCONN) ? GF_LOG_DEBUG : GF_LOG_ERROR) -#define SA(ptr) ((struct sockaddr *)ptr) - -static int socket_init (transport_t *this); - -/* - * return value: - * 0 = success (completed) - * -1 = error - * > 0 = incomplete - */ - -static int -__socket_rwv (transport_t *this, struct iovec *vector, int count, - struct iovec **pending_vector, int *pending_count, - int write) -{ - socket_private_t *priv = NULL; - int sock = -1; - int ret = -1; - struct iovec *opvector = NULL; - int opcount = 0; - int moved = 0; - - priv = this->private; - sock = priv->sock; - - opvector = vector; - opcount = count; - - while (opcount) { - if (write) { - ret = writev (sock, opvector, opcount); - - if (ret == 0 || (ret == -1 && errno == EAGAIN)) { - /* done for now */ - break; - } - } else { - ret = readv (sock, opvector, opcount); - - if (ret == -1 && errno == EAGAIN) { - /* done for now */ - break; - } - } - - if (ret == 0) { - /* Mostly due to 'umount' in client */ - gf_log (this->xl->name, GF_LOG_TRACE, - "EOF from peer %s", this->peerinfo.identifier); - opcount = -1; - errno = ENOTCONN; - break; - } - - if (ret == -1) { - if (errno == EINTR) - continue; - - gf_log (this->xl->name, GF_LOG_TRACE, - "%s failed (%s)", write ? "writev" : "readv", - strerror (errno)); - opcount = -1; - break; - } - - moved = 0; - - while (moved < ret) { - if ((ret - moved) >= opvector[0].iov_len) { - moved += opvector[0].iov_len; - opvector++; - opcount--; - } else { - opvector[0].iov_len -= (ret - moved); - opvector[0].iov_base += (ret - moved); - moved += (ret - moved); - } - while (opcount && !opvector[0].iov_len) { - opvector++; - opcount--; - } - } - } - - if (pending_vector) - *pending_vector = opvector; - - if (pending_count) - *pending_count = opcount; - - return opcount; -} - - -static int -__socket_readv (transport_t *this, struct iovec *vector, int count, - struct iovec **pending_vector, int *pending_count) -{ - int ret = -1; - - ret = __socket_rwv (this, vector, count, - pending_vector, pending_count, 0); - - return ret; -} - - -static int -__socket_writev (transport_t *this, struct iovec *vector, int count, - struct iovec **pending_vector, int *pending_count) -{ - int ret = -1; - - ret = __socket_rwv (this, vector, count, - pending_vector, pending_count, 1); - - return ret; -} - - -static int -__socket_disconnect (transport_t *this) -{ - socket_private_t *priv = NULL; - int ret = -1; - - priv = this->private; - - if (priv->sock != -1) { - ret = shutdown (priv->sock, SHUT_RDWR); - priv->connected = -1; - gf_log (this->xl->name, GF_LOG_TRACE, - "shutdown() returned %d. set connection state to -1", - ret); - } - - return ret; -} - - -static int -__socket_server_bind (transport_t *this) -{ - socket_private_t *priv = NULL; - int ret = -1; - int opt = 1; - - priv = this->private; - - ret = setsockopt (priv->sock, SOL_SOCKET, SO_REUSEADDR, - &opt, sizeof (opt)); - - if (ret == -1) { - gf_log (this->xl->name, GF_LOG_ERROR, - "setsockopt() for SO_REUSEADDR failed (%s)", - strerror (errno)); - } - - ret = bind (priv->sock, (struct sockaddr *)&this->myinfo.sockaddr, - this->myinfo.sockaddr_len); - - if (ret == -1) { - gf_log (this->xl->name, GF_LOG_ERROR, - "binding to %s failed: %s", - this->myinfo.identifier, strerror (errno)); - if (errno == EADDRINUSE) { - gf_log (this->xl->name, GF_LOG_ERROR, - "Port is already in use"); - } - } - - return ret; -} - - -static int -__socket_nonblock (int fd) -{ - int flags = 0; - int ret = -1; - - flags = fcntl (fd, F_GETFL); - - if (flags != -1) - ret = fcntl (fd, F_SETFL, flags | O_NONBLOCK); - - return ret; -} - - -static int -__socket_nodelay (int fd) -{ - int on = 1; - int ret = -1; - - ret = setsockopt (fd, IPPROTO_TCP, TCP_NODELAY, - &on, sizeof (on)); - if (!ret) - gf_log ("", GF_LOG_TRACE, - "NODELAY enabled for socket %d", fd); - - return ret; -} - - -static int -__socket_keepalive (int fd, int keepalive_intvl) -{ - int on = 1; - int ret = -1; - - ret = setsockopt (fd, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof (on)); - if (ret == -1) - goto err; - - if (keepalive_intvl == GF_USE_DEFAULT_KEEPALIVE) - goto done; - -#ifndef GF_LINUX_HOST_OS - ret = setsockopt (fd, IPPROTO_TCP, TCP_KEEPALIVE, &keepalive_intvl, - sizeof (keepalive_intvl)); - if (ret == -1) - goto err; -#else - ret = setsockopt (fd, IPPROTO_TCP, TCP_KEEPIDLE, &keepalive_intvl, - sizeof (keepalive_intvl)); - if (ret == -1) - goto err; - - ret = setsockopt (fd, IPPROTO_TCP, TCP_KEEPINTVL, &keepalive_intvl, - sizeof (keepalive_intvl)); - if (ret == -1) - goto err; -#endif - -done: - gf_log ("", GF_LOG_TRACE, "Keep-alive enabled for socket %d, interval " - "%d", fd, keepalive_intvl); - -err: - return ret; -} - - -static int -__socket_connect_finish (int fd) -{ - int ret = -1; - int optval = 0; - socklen_t optlen = sizeof (int); - - ret = getsockopt (fd, SOL_SOCKET, SO_ERROR, (void *)&optval, &optlen); - - if (ret == 0 && optval) { - errno = optval; - ret = -1; - } - - return ret; -} - - -static void -__socket_reset (transport_t *this) -{ - socket_private_t *priv = NULL; - - priv = this->private; - - /* TODO: use mem-pool on incoming data */ - - if (priv->incoming.hdr_p) - GF_FREE (priv->incoming.hdr_p); - - if (priv->incoming.iobuf) - iobuf_unref (priv->incoming.iobuf); - - memset (&priv->incoming, 0, sizeof (priv->incoming)); - - event_unregister (this->xl->ctx->event_pool, priv->sock, priv->idx); - close (priv->sock); - priv->sock = -1; - priv->idx = -1; - priv->connected = -1; -} - - -static struct ioq * -__socket_ioq_new (transport_t *this, char *buf, int len, - struct iovec *vector, int count, struct iobref *iobref) -{ - socket_private_t *priv = NULL; - struct ioq *entry = NULL; - - priv = this->private; - - /* TODO: use mem-pool */ - entry = GF_CALLOC (1, sizeof (*entry), - gf_common_mt_ioq); - if (!entry) - return NULL; - - GF_ASSERT (count <= (MAX_IOVEC-2)); - - entry->header.colonO[0] = ':'; - entry->header.colonO[1] = 'O'; - entry->header.colonO[2] = '\0'; - entry->header.version = 42; - entry->header.size1 = hton32 (len); - entry->header.size2 = hton32 (iov_length (vector, count)); - - entry->vector[0].iov_base = &entry->header; - entry->vector[0].iov_len = sizeof (entry->header); - entry->count++; - - entry->vector[1].iov_base = buf; - entry->vector[1].iov_len = len; - entry->count++; - - if (vector && count) { - memcpy (&entry->vector[2], vector, sizeof (*vector) * count); - entry->count += count; - } - - entry->pending_vector = entry->vector; - entry->pending_count = entry->count; - - if (iobref) - entry->iobref = iobref_ref (iobref); - - entry->buf = buf; - - INIT_LIST_HEAD (&entry->list); - - return entry; -} - - -static void -__socket_ioq_entry_free (struct ioq *entry) -{ - list_del_init (&entry->list); - if (entry->iobref) - iobref_unref (entry->iobref); - - /* TODO: use mem-pool */ - GF_FREE (entry->buf); - - /* TODO: use mem-pool */ - GF_FREE (entry); -} - - -static void -__socket_ioq_flush (transport_t *this) -{ - socket_private_t *priv = NULL; - struct ioq *entry = NULL; - - priv = this->private; - - while (!list_empty (&priv->ioq)) { - entry = priv->ioq_next; - __socket_ioq_entry_free (entry); - } - - return; -} - - -static int -__socket_ioq_churn_entry (transport_t *this, struct ioq *entry) -{ - int ret = -1; - - ret = __socket_writev (this, entry->pending_vector, - entry->pending_count, - &entry->pending_vector, - &entry->pending_count); - - if (ret == 0) { - /* current entry was completely written */ - GF_ASSERT (entry->pending_count == 0); - __socket_ioq_entry_free (entry); - } - - return ret; -} - - -static int -__socket_ioq_churn (transport_t *this) -{ - socket_private_t *priv = NULL; - int ret = 0; - struct ioq *entry = NULL; - - priv = this->private; - - while (!list_empty (&priv->ioq)) { - /* pick next entry */ - entry = priv->ioq_next; - - ret = __socket_ioq_churn_entry (this, entry); - - if (ret != 0) - break; - } - - if (list_empty (&priv->ioq)) { - /* all pending writes done, not interested in POLLOUT */ - priv->idx = event_select_on (this->xl->ctx->event_pool, - priv->sock, priv->idx, -1, 0); - } - - return ret; -} - - -static int -socket_event_poll_err (transport_t *this) -{ - socket_private_t *priv = NULL; - int ret = -1; - - priv = this->private; - - pthread_mutex_lock (&priv->lock); - { - __socket_ioq_flush (this); - __socket_reset (this); - } - pthread_mutex_unlock (&priv->lock); - - xlator_notify (this->xl, GF_EVENT_POLLERR, this); - - return ret; -} - - -static int -socket_event_poll_out (transport_t *this) -{ - socket_private_t *priv = NULL; - int ret = -1; - - priv = this->private; - - pthread_mutex_lock (&priv->lock); - { - if (priv->connected == 1) { - ret = __socket_ioq_churn (this); - - if (ret == -1) { - __socket_disconnect (this); - } - } - } - pthread_mutex_unlock (&priv->lock); - - xlator_notify (this->xl, GF_EVENT_POLLOUT, this); - - return ret; -} - - -static int -__socket_proto_validate_header (transport_t *this, - struct socket_header *header, - size_t *size1_p, size_t *size2_p) -{ - size_t size1 = 0; - size_t size2 = 0; - - if (strcmp (header->colonO, ":O")) { - gf_log (this->xl->name, GF_LOG_DEBUG, - "socket header signature does not match :O (%x.%x.%x)", - header->colonO[0], header->colonO[1], - header->colonO[2]); - return -1; - } - - if (header->version != 42) { - gf_log (this->xl->name, GF_LOG_DEBUG, - "socket header version does not match 42 != %d", - header->version); - return -1; - } - - size1 = ntoh32 (header->size1); - size2 = ntoh32 (header->size2); - - if (size1 <= 0 || size1 > 1048576) { - gf_log (this->xl->name, GF_LOG_DEBUG, - "socket header has incorrect size1=%"GF_PRI_SIZET, - size1); - return -1; - } - - if (size2 > (131072)) { - gf_log (this->xl->name, GF_LOG_DEBUG, - "socket header has incorrect size2=%"GF_PRI_SIZET, - size2); - return -1; - } - - if (size1_p) - *size1_p = size1; - - if (size2_p) - *size2_p = size2; - - return 0; -} - - - -/* socket protocol state machine */ - -static int -__socket_proto_state_machine (transport_t *this) -{ - int ret = -1; - socket_private_t *priv = NULL; - size_t size1 = 0; - size_t size2 = 0; - int previous_state = -1; - struct socket_header *hdr = NULL; - struct iobuf *iobuf = NULL; - - - priv = this->private; - - while (priv->incoming.state != SOCKET_PROTO_STATE_COMPLETE) { - /* debug check against infinite loops */ - if (previous_state == priv->incoming.state) { - gf_log (this->xl->name, GF_LOG_DEBUG, - "state did not change! (%d) breaking", - previous_state); - ret = -1; - goto unlock; - } - previous_state = priv->incoming.state; - - switch (priv->incoming.state) { - - case SOCKET_PROTO_STATE_NADA: - priv->incoming.pending_vector = - priv->incoming.vector; - - priv->incoming.pending_vector->iov_base = - &priv->incoming.header; - - priv->incoming.pending_vector->iov_len = - sizeof (struct socket_header); - - priv->incoming.state = - SOCKET_PROTO_STATE_HEADER_COMING; - break; - - case SOCKET_PROTO_STATE_HEADER_COMING: - - ret = __socket_readv (this, - priv->incoming.pending_vector, 1, - &priv->incoming.pending_vector, - NULL); - if (ret == 0) { - priv->incoming.state = - SOCKET_PROTO_STATE_HEADER_CAME; - break; - } - - if (ret == -1) { - gf_log (this->xl->name, GF_LOG_TRACE, - "read (%s) in state %d (%s)", - strerror (errno), - SOCKET_PROTO_STATE_HEADER_COMING, - this->peerinfo.identifier); - goto unlock; - } - - if (ret > 0) { - gf_log (this->xl->name, GF_LOG_TRACE, - "partial header read on NB socket."); - goto unlock; - } - break; - - case SOCKET_PROTO_STATE_HEADER_CAME: - hdr = &priv->incoming.header; - ret = __socket_proto_validate_header (this, hdr, - &size1, &size2); - - if (ret == -1) { - gf_log (this->xl->name, GF_LOG_ERROR, - "socket header validate failed (%s). " - "possible mismatch of transport-type " - "between server and client volumes, " - "or version mismatch", - this->peerinfo.identifier); - goto unlock; - } - - priv->incoming.hdrlen = size1; - priv->incoming.buflen = size2; - - /* TODO: use mem-pool */ - priv->incoming.hdr_p = GF_MALLOC (size1, - gf_common_mt_char); - if (size2) { - /* TODO: sanity check size2 < page size - */ - iobuf = iobuf_get (this->xl->ctx->iobuf_pool); - if (!iobuf) { - gf_log (this->xl->name, GF_LOG_ERROR, - "unable to allocate IO buffer " - "for peer %s", - this->peerinfo.identifier); - ret = -ENOMEM; - goto unlock; - } - priv->incoming.iobuf = iobuf; - priv->incoming.buf_p = iobuf->ptr; - } - - priv->incoming.vector[0].iov_base = - priv->incoming.hdr_p; - - priv->incoming.vector[0].iov_len = size1; - - priv->incoming.vector[1].iov_base = - priv->incoming.buf_p; - - priv->incoming.vector[1].iov_len = size2; - priv->incoming.count = size2 ? 2 : 1; - - priv->incoming.pending_vector = - priv->incoming.vector; - - priv->incoming.pending_count = - priv->incoming.count; - - priv->incoming.state = - SOCKET_PROTO_STATE_DATA_COMING; - break; - - case SOCKET_PROTO_STATE_DATA_COMING: - - ret = __socket_readv (this, - priv->incoming.pending_vector, - priv->incoming.pending_count, - &priv->incoming.pending_vector, - &priv->incoming.pending_count); - if (ret == 0) { - priv->incoming.state = - SOCKET_PROTO_STATE_DATA_CAME; - break; - } - - if (ret == -1) { - gf_log (this->xl->name, GF_LOG_DEBUG, - "read (%s) in state %d (%s)", - strerror (errno), - SOCKET_PROTO_STATE_DATA_COMING, - this->peerinfo.identifier); - goto unlock; - } - - if (ret > 0) { - gf_log (this->xl->name, GF_LOG_TRACE, - "partial data read on NB socket"); - goto unlock; - } - break; - - case SOCKET_PROTO_STATE_DATA_CAME: - memset (&priv->incoming.vector, 0, - sizeof (priv->incoming.vector)); - priv->incoming.pending_vector = NULL; - priv->incoming.pending_count = 0; - priv->incoming.state = SOCKET_PROTO_STATE_COMPLETE; - break; - - case SOCKET_PROTO_STATE_COMPLETE: - /* not reached */ - break; - - default: - gf_log (this->xl->name, GF_LOG_DEBUG, - "undefined state reached: %d", - priv->incoming.state); - goto unlock; - } - } -unlock: - - return ret; -} - - -static int -socket_proto_state_machine (transport_t *this) -{ - socket_private_t *priv = NULL; - int ret = 0; - - priv = this->private; - - pthread_mutex_lock (&priv->lock); - { - ret = __socket_proto_state_machine (this); - } - pthread_mutex_unlock (&priv->lock); - - return ret; -} - - -static int -socket_event_poll_in (transport_t *this) -{ - int ret = -1; - - ret = socket_proto_state_machine (this); - - /* call POLLIN on xlator even if complete block is not received, - just to keep the last_received timestamp ticking */ - - if (ret == 0) - ret = xlator_notify (this->xl, GF_EVENT_POLLIN, this); - - return ret; -} - - -static int -socket_connect_finish (transport_t *this) -{ - int ret = -1; - socket_private_t *priv = NULL; - int event = -1; - char notify_xlator = 0; - - priv = this->private; - - pthread_mutex_lock (&priv->lock); - { - if (priv->connected) - goto unlock; - - ret = __socket_connect_finish (priv->sock); - - if (ret == -1 && errno == EINPROGRESS) - ret = 1; - - if (ret == -1 && errno != EINPROGRESS) { - if (!priv->connect_finish_log) { - gf_log (this->xl->name, GF_LOG_ERROR, - "connection to %s failed (%s)", - this->peerinfo.identifier, - strerror (errno)); - priv->connect_finish_log = 1; - } - __socket_disconnect (this); - notify_xlator = 1; - event = GF_EVENT_POLLERR; - goto unlock; - } - - if (ret == 0) { - notify_xlator = 1; - - this->myinfo.sockaddr_len = - sizeof (this->myinfo.sockaddr); - - ret = getsockname (priv->sock, - SA (&this->myinfo.sockaddr), - &this->myinfo.sockaddr_len); - if (ret == -1) { - gf_log (this->xl->name, GF_LOG_DEBUG, - "getsockname on (%d) failed (%s)", - priv->sock, strerror (errno)); - __socket_disconnect (this); - event = GF_EVENT_POLLERR; - goto unlock; - } - - priv->connected = 1; - priv->connect_finish_log = 0; - event = GF_EVENT_CHILD_UP; - gf_get_transport_identifiers (this); - } - } -unlock: - pthread_mutex_unlock (&priv->lock); - - if (notify_xlator) - xlator_notify (this->xl, event, this); - - return 0; -} - - -static int -socket_event_handler (int fd, int idx, void *data, - int poll_in, int poll_out, int poll_err) -{ - transport_t *this = NULL; - socket_private_t *priv = NULL; - int ret = 0; - - this = data; - priv = this->private; - - pthread_mutex_lock (&priv->lock); - { - priv->idx = idx; - } - pthread_mutex_unlock (&priv->lock); - - if (!priv->connected) { - ret = socket_connect_finish (this); - } - - if (!ret && poll_out) { - ret = socket_event_poll_out (this); - } - - if (!ret && poll_in) { - ret = socket_event_poll_in (this); - } - - if (ret < 0 || poll_err) { - socket_event_poll_err (this); - transport_unref (this); - } - - return 0; -} - - -static int -socket_server_event_handler (int fd, int idx, void *data, - int poll_in, int poll_out, int poll_err) -{ - transport_t *this = NULL; - socket_private_t *priv = NULL; - int ret = 0; - int new_sock = -1; - transport_t *new_trans = NULL; - struct sockaddr_storage new_sockaddr = {0, }; - socklen_t addrlen = sizeof (new_sockaddr); - socket_private_t *new_priv = NULL; - glusterfs_ctx_t *ctx = NULL; - - this = data; - priv = this->private; - ctx = this->xl->ctx; - - pthread_mutex_lock (&priv->lock); - { - priv->idx = idx; - - if (poll_in) { - new_sock = accept (priv->sock, SA (&new_sockaddr), - &addrlen); - - if (new_sock == -1) - goto unlock; - - if (!priv->bio) { - ret = __socket_nonblock (new_sock); - - if (ret == -1) { - gf_log (this->xl->name, GF_LOG_DEBUG, - "NBIO on %d failed (%s)", - new_sock, strerror (errno)); - close (new_sock); - goto unlock; - } - } - - if (priv->nodelay) { - ret = __socket_nodelay (new_sock); - if (ret == -1) { - gf_log (this->xl->name, GF_LOG_ERROR, - "setsockopt() failed for " - "NODELAY (%s)", - strerror (errno)); - } - } - - if (priv->keepalive) { - ret = __socket_keepalive (new_sock, - priv->keepaliveintvl); - if (ret == -1) - gf_log (this->xl->name, GF_LOG_ERROR, - "Failed to set keep-alive: %s", - strerror (errno)); - } - - new_trans = GF_CALLOC (1, sizeof (*new_trans), - gf_common_mt_transport_t); - new_trans->xl = this->xl; - new_trans->fini = this->fini; - - memcpy (&new_trans->peerinfo.sockaddr, &new_sockaddr, - addrlen); - new_trans->peerinfo.sockaddr_len = addrlen; - - new_trans->myinfo.sockaddr_len = - sizeof (new_trans->myinfo.sockaddr); - - ret = getsockname (new_sock, - SA (&new_trans->myinfo.sockaddr), - &new_trans->myinfo.sockaddr_len); - if (ret == -1) { - gf_log (this->xl->name, GF_LOG_DEBUG, - "getsockname on %d failed (%s)", - new_sock, strerror (errno)); - close (new_sock); - goto unlock; - } - - gf_get_transport_identifiers (new_trans); - socket_init (new_trans); - new_trans->ops = this->ops; - new_trans->init = this->init; - new_trans->fini = this->fini; - - new_priv = new_trans->private; - - pthread_mutex_lock (&new_priv->lock); - { - new_priv->sock = new_sock; - new_priv->connected = 1; - - transport_ref (new_trans); - new_priv->idx = - event_register (ctx->event_pool, - new_sock, - socket_event_handler, - new_trans, 1, 0); - - if (new_priv->idx == -1) - ret = -1; - } - pthread_mutex_unlock (&new_priv->lock); - } - } -unlock: - pthread_mutex_unlock (&priv->lock); - - return ret; -} - - -static int -socket_disconnect (transport_t *this) -{ - socket_private_t *priv = NULL; - int ret = -1; - - priv = this->private; - - pthread_mutex_lock (&priv->lock); - { - ret = __socket_disconnect (this); - } - pthread_mutex_unlock (&priv->lock); - - return ret; -} - - -static int -socket_connect (transport_t *this) -{ - int ret = -1; - int sock = -1; - socket_private_t *priv = NULL; - struct sockaddr_storage sockaddr = {0, }; - socklen_t sockaddr_len = 0; - glusterfs_ctx_t *ctx = NULL; - sa_family_t sa_family = {0, }; - - priv = this->private; - ctx = this->xl->ctx; - - if (!priv) { - gf_log (this->xl->name, GF_LOG_DEBUG, - "connect() called on uninitialized transport"); - goto err; - } - - pthread_mutex_lock (&priv->lock); - { - sock = priv->sock; - } - pthread_mutex_unlock (&priv->lock); - - if (sock != -1) { - gf_log (this->xl->name, GF_LOG_TRACE, - "connect () called on transport already connected"); - ret = 0; - goto err; - } - - ret = gf_socket_client_get_remote_sockaddr (this, SA (&sockaddr), - &sockaddr_len, &sa_family); - if (ret == -1) { - /* logged inside client_get_remote_sockaddr */ - goto err; - } - - pthread_mutex_lock (&priv->lock); - { - if (priv->sock != -1) { - gf_log (this->xl->name, GF_LOG_TRACE, - "connect() -- already connected"); - goto unlock; - } - - memcpy (&this->peerinfo.sockaddr, &sockaddr, sockaddr_len); - this->peerinfo.sockaddr_len = sockaddr_len; - - priv->sock = socket (sa_family, SOCK_STREAM, 0); - if (priv->sock == -1) { - gf_log (this->xl->name, GF_LOG_ERROR, - "socket creation failed (%s)", - strerror (errno)); - goto unlock; - } - - /* Cant help if setting socket options fails. We can continue - * working nonetheless. - */ - if (setsockopt (priv->sock, SOL_SOCKET, SO_RCVBUF, - &priv->windowsize, - sizeof (priv->windowsize)) < 0) { - gf_log (this->xl->name, GF_LOG_ERROR, - "setting receive window size failed: %d: %d: " - "%s", priv->sock, priv->windowsize, - strerror (errno)); - } - - if (setsockopt (priv->sock, SOL_SOCKET, SO_SNDBUF, - &priv->windowsize, - sizeof (priv->windowsize)) < 0) { - gf_log (this->xl->name, GF_LOG_ERROR, - "setting send window size failed: %d: %d: " - "%s", priv->sock, priv->windowsize, - strerror (errno)); - } - - - if (priv->nodelay && priv->lowlat) { - ret = __socket_nodelay (priv->sock); - if (ret == -1) { - gf_log (this->xl->name, GF_LOG_ERROR, - "setsockopt() failed for NODELAY (%s)", - strerror (errno)); - } - } - - if (!priv->bio) { - ret = __socket_nonblock (priv->sock); - - if (ret == -1) { - gf_log (this->xl->name, GF_LOG_ERROR, - "NBIO on %d failed (%s)", - priv->sock, strerror (errno)); - close (priv->sock); - priv->sock = -1; - goto unlock; - } - } - - if (priv->keepalive) { - ret = __socket_keepalive (priv->sock, - priv->keepaliveintvl); - if (ret == -1) - gf_log (this->xl->name, GF_LOG_ERROR, - "Failed to set keep-alive: %s", - strerror (errno)); - } - - SA (&this->myinfo.sockaddr)->sa_family = - SA (&this->peerinfo.sockaddr)->sa_family; - - ret = gf_client_bind (this, SA (&this->myinfo.sockaddr), - &this->myinfo.sockaddr_len, priv->sock); - if (ret == -1) { - gf_log (this->xl->name, GF_LOG_WARNING, - "client bind failed: %s", strerror (errno)); - close (priv->sock); - priv->sock = -1; - goto unlock; - } - - ret = connect (priv->sock, SA (&this->peerinfo.sockaddr), - this->peerinfo.sockaddr_len); - - if (ret == -1 && errno != EINPROGRESS) { - gf_log (this->xl->name, GF_LOG_ERROR, - "connection attempt failed (%s)", - strerror (errno)); - close (priv->sock); - priv->sock = -1; - goto unlock; - } - - priv->connected = 0; - - transport_ref (this); - - priv->idx = event_register (ctx->event_pool, priv->sock, - socket_event_handler, this, 1, 1); - if (priv->idx == -1) - ret = -1; - } -unlock: - pthread_mutex_unlock (&priv->lock); - -err: - return ret; -} - - -static int -socket_listen (transport_t *this) -{ - socket_private_t * priv = NULL; - int ret = -1; - int sock = -1; - struct sockaddr_storage sockaddr; - socklen_t sockaddr_len; - peer_info_t *myinfo = NULL; - glusterfs_ctx_t *ctx = NULL; - sa_family_t sa_family = {0, }; - - priv = this->private; - myinfo = &this->myinfo; - ctx = this->xl->ctx; - - pthread_mutex_lock (&priv->lock); - { - sock = priv->sock; - } - pthread_mutex_unlock (&priv->lock); - - if (sock != -1) { - gf_log (this->xl->name, GF_LOG_DEBUG, - "already listening"); - return ret; - } - - ret = gf_socket_server_get_local_sockaddr (this, SA (&sockaddr), - &sockaddr_len, &sa_family); - if (ret == -1) { - return ret; - } - - pthread_mutex_lock (&priv->lock); - { - if (priv->sock != -1) { - gf_log (this->xl->name, GF_LOG_DEBUG, - "already listening"); - goto unlock; - } - - memcpy (&myinfo->sockaddr, &sockaddr, sockaddr_len); - myinfo->sockaddr_len = sockaddr_len; - - priv->sock = socket (sa_family, SOCK_STREAM, 0); - - if (priv->sock == -1) { - gf_log (this->xl->name, GF_LOG_ERROR, - "socket creation failed (%s)", - strerror (errno)); - goto unlock; - } - - /* Cant help if setting socket options fails. We can continue - * working nonetheless. - */ - if (setsockopt (priv->sock, SOL_SOCKET, SO_RCVBUF, - &priv->windowsize, - sizeof (priv->windowsize)) < 0) { - gf_log (this->xl->name, GF_LOG_ERROR, - "setting receive window size failed: %d: %d: " - "%s", priv->sock, priv->windowsize, - strerror (errno)); - } - - if (setsockopt (priv->sock, SOL_SOCKET, SO_SNDBUF, - &priv->windowsize, - sizeof (priv->windowsize)) < 0) { - gf_log (this->xl->name, GF_LOG_ERROR, - "setting send window size failed: %d: %d: " - "%s", priv->sock, priv->windowsize, - strerror (errno)); - } - - if (priv->nodelay) { - ret = __socket_nodelay (priv->sock); - if (ret == -1) { - gf_log (this->xl->name, GF_LOG_ERROR, - "setsockopt() failed for NODELAY (%s)", - strerror (errno)); - } - } - - if (!priv->bio) { - ret = __socket_nonblock (priv->sock); - - if (ret == -1) { - gf_log (this->xl->name, GF_LOG_ERROR, - "NBIO on %d failed (%s)", - priv->sock, strerror (errno)); - close (priv->sock); - priv->sock = -1; - goto unlock; - } - } - - ret = __socket_server_bind (this); - - if (ret == -1) { - /* logged inside __socket_server_bind() */ - close (priv->sock); - priv->sock = -1; - goto unlock; - } - - ret = listen (priv->sock, 10); - - if (ret == -1) { - gf_log (this->xl->name, GF_LOG_ERROR, - "could not set socket %d to listen mode (%s)", - priv->sock, strerror (errno)); - close (priv->sock); - priv->sock = -1; - goto unlock; - } - - transport_ref (this); - - priv->idx = event_register (ctx->event_pool, priv->sock, - socket_server_event_handler, - this, 1, 0); - - if (priv->idx == -1) { - gf_log (this->xl->name, GF_LOG_DEBUG, - "could not register socket %d with events", - priv->sock); - ret = -1; - close (priv->sock); - priv->sock = -1; - goto unlock; - } - } -unlock: - pthread_mutex_unlock (&priv->lock); - - return ret; -} - - -static int -socket_receive (transport_t *this, char **hdr_p, size_t *hdrlen_p, - struct iobuf **iobuf_p) -{ - socket_private_t *priv = NULL; - int ret = -1; - - priv = this->private; - - pthread_mutex_lock (&priv->lock); - { - if (priv->connected != 1) { - gf_log (this->xl->name, GF_LOG_DEBUG, - "socket not connected to receive"); - goto unlock; - } - - if (!hdr_p || !hdrlen_p || !iobuf_p) { - gf_log (this->xl->name, GF_LOG_DEBUG, - "bad parameters %p %p %p", - hdr_p, hdrlen_p, iobuf_p); - goto unlock; - } - - if (priv->incoming.state == SOCKET_PROTO_STATE_COMPLETE) { - *hdr_p = priv->incoming.hdr_p; - *hdrlen_p = priv->incoming.hdrlen; - *iobuf_p = priv->incoming.iobuf; - - memset (&priv->incoming, 0, sizeof (priv->incoming)); - priv->incoming.state = SOCKET_PROTO_STATE_NADA; - - ret = 0; - } - } -unlock: - pthread_mutex_unlock (&priv->lock); - - return ret; -} - - -/* TODO: implement per transfer limit */ -static int -socket_submit (transport_t *this, char *buf, int len, - struct iovec *vector, int count, - struct iobref *iobref) -{ - socket_private_t *priv = NULL; - int ret = -1; - char need_poll_out = 0; - char need_append = 1; - struct ioq *entry = NULL; - glusterfs_ctx_t *ctx = NULL; - - priv = this->private; - ctx = this->xl->ctx; - - pthread_mutex_lock (&priv->lock); - { - if (priv->connected != 1) { - if (!priv->submit_log && !priv->connect_finish_log) { - gf_log (this->xl->name, GF_LOG_DEBUG, - "not connected (priv->connected = %d)", - priv->connected); - priv->submit_log = 1; - } - goto unlock; - } - - priv->submit_log = 0; - entry = __socket_ioq_new (this, buf, len, vector, count, iobref); - if (!entry) - goto unlock; - - if (list_empty (&priv->ioq)) { - ret = __socket_ioq_churn_entry (this, entry); - - if (ret == 0) - need_append = 0; - - if (ret > 0) - need_poll_out = 1; - } - - if (need_append) { - list_add_tail (&entry->list, &priv->ioq); - ret = 0; - } - - if (need_poll_out) { - /* first entry to wait. continue writing on POLLOUT */ - priv->idx = event_select_on (ctx->event_pool, - priv->sock, - priv->idx, -1, 1); - } - } -unlock: - pthread_mutex_unlock (&priv->lock); - - return ret; -} - - -struct transport_ops tops = { - .listen = socket_listen, - .connect = socket_connect, - .disconnect = socket_disconnect, - .submit = socket_submit, - .receive = socket_receive -}; - - -static int -socket_init (transport_t *this) -{ - socket_private_t *priv = NULL; - gf_boolean_t tmp_bool = 0; - uint64_t windowsize = GF_DEFAULT_SOCKET_WINDOW_SIZE; - char *optstr = NULL; - uint32_t keepalive = 0; - - if (this->private) { - gf_log (this->xl->name, GF_LOG_DEBUG, - "double init attempted"); - return -1; - } - - priv = GF_CALLOC (1, sizeof (*priv), - gf_common_mt_socket_private_t); - if (!priv) { - gf_log (this->xl->name, GF_LOG_ERROR, - "calloc (1, %"GF_PRI_SIZET") returned NULL", - sizeof (*priv)); - return -1; - } - - pthread_mutex_init (&priv->lock, NULL); - - priv->sock = -1; - priv->idx = -1; - priv->connected = -1; - - INIT_LIST_HEAD (&priv->ioq); - - if (dict_get (this->xl->options, "non-blocking-io")) { - optstr = data_to_str (dict_get (this->xl->options, - "non-blocking-io")); - - if (gf_string2boolean (optstr, &tmp_bool) == -1) { - gf_log (this->xl->name, GF_LOG_ERROR, - "'non-blocking-io' takes only boolean options," - " not taking any action"); - tmp_bool = 1; - } - priv->bio = 0; - if (!tmp_bool) { - priv->bio = 1; - gf_log (this->xl->name, GF_LOG_WARNING, - "disabling non-blocking IO"); - } - } - - optstr = NULL; - - // By default, we enable NODELAY - priv->nodelay = 1; - if (dict_get (this->xl->options, "transport.socket.nodelay")) { - optstr = data_to_str (dict_get (this->xl->options, - "transport.socket.nodelay")); - - if (gf_string2boolean (optstr, &tmp_bool) == -1) { - gf_log (this->xl->name, GF_LOG_ERROR, - "'transport.socket.nodelay' takes only " - "boolean options, not taking any action"); - tmp_bool = 1; - } - if (!tmp_bool) { - priv->nodelay = 0; - gf_log (this->xl->name, GF_LOG_DEBUG, - "disabling nodelay"); - } - } - - - optstr = NULL; - if (dict_get_str (this->xl->options, "transport.window-size", - &optstr) == 0) { - if (gf_string2bytesize (optstr, &windowsize) != 0) { - gf_log (this->xl->name, GF_LOG_ERROR, - "invalid number format: %s", optstr); - return -1; - } - } - - optstr = NULL; - - if (dict_get_str (this->xl->options, "transport.socket.lowlat", - &optstr) == 0) { - priv->lowlat = 1; - } - - /* Enable Keep-alive by default. */ - priv->keepalive = 1; - priv->keepaliveintvl = GF_USE_DEFAULT_KEEPALIVE; - if (dict_get_str (this->xl->options, "transport.socket.keepalive", - &optstr) == 0) { - if (gf_string2boolean (optstr, &tmp_bool) == -1) { - gf_log (this->xl->name, GF_LOG_ERROR, - "'transport.socket.keepalive' takes only " - "boolean options, not taking any action"); - tmp_bool = 1; - } - - if (!tmp_bool) - priv->keepalive = 0; - - } - - if (dict_get_uint32 (this->xl->options, - "transport.socket.keepalive-interval", - &keepalive) == 0) { - priv->keepaliveintvl = keepalive; - } - - priv->windowsize = (int)windowsize; - this->private = priv; - - return 0; -} - - -void -fini (transport_t *this) -{ - socket_private_t *priv = this->private; - - if (!priv) - return; - this->private = NULL; - gf_log (this->xl->name, GF_LOG_TRACE, - "transport %p destroyed", this); - - pthread_mutex_destroy (&priv->lock); - GF_FREE (priv); -} - - -int32_t -init (transport_t *this) -{ - int ret = -1; - - ret = socket_init (this); - - if (ret == -1) { - gf_log (this->xl->name, GF_LOG_DEBUG, "socket_init() failed"); - } - - return ret; -} - -struct volume_options options[] = { - { .key = {"remote-port", - "transport.remote-port", - "transport.socket.remote-port"}, - .type = GF_OPTION_TYPE_INT - }, - { .key = {"transport.socket.listen-port", "listen-port"}, - .type = GF_OPTION_TYPE_INT - }, - { .key = {"transport.socket.bind-address", "bind-address" }, - .type = GF_OPTION_TYPE_INTERNET_ADDRESS - }, - { .key = {"transport.socket.connect-path", "connect-path"}, - .type = GF_OPTION_TYPE_ANY - }, - { .key = {"transport.socket.bind-path", "bind-path"}, - .type = GF_OPTION_TYPE_ANY - }, - { .key = {"transport.socket.listen-path", "listen-path"}, - .type = GF_OPTION_TYPE_ANY - }, - { .key = { "transport.address-family", - "address-family" }, - .value = {"inet", "inet6", "inet/inet6", "inet6/inet", - "unix", "inet-sdp" }, - .type = GF_OPTION_TYPE_STR - }, - - { .key = {"non-blocking-io"}, - .type = GF_OPTION_TYPE_BOOL - }, - { .key = {"transport.window-size"}, - .type = GF_OPTION_TYPE_SIZET, - .min = GF_MIN_SOCKET_WINDOW_SIZE, - .max = GF_MAX_SOCKET_WINDOW_SIZE, - }, - { .key = {"transport.socket.nodelay"}, - .type = GF_OPTION_TYPE_BOOL - }, - { .key = {"transport.socket.lowlat"}, - .type = GF_OPTION_TYPE_BOOL - }, - { .key = {"transport.socket.keepalive"}, - .type = GF_OPTION_TYPE_BOOL - }, - { .key = {"transport.socket.keepalive-interval"}, - .type = GF_OPTION_TYPE_INT - }, - { .key = {NULL} } -}; - diff --git a/xlators/protocol/legacy/transport/socket/src/socket.h b/xlators/protocol/legacy/transport/socket/src/socket.h deleted file mode 100644 index e1dc9a91e..000000000 --- a/xlators/protocol/legacy/transport/socket/src/socket.h +++ /dev/null @@ -1,129 +0,0 @@ -/* - Copyright (c) 2006-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 _SOCKET_H -#define _SOCKET_H - - -#ifndef _CONFIG_H -#define _CONFIG_H -#include "config.h" -#endif - -#include "event.h" -#include "transport.h" -#include "logging.h" -#include "dict.h" -#include "mem-pool.h" -#include "socket-mem-types.h" - -#ifndef MAX_IOVEC -#define MAX_IOVEC 16 -#endif /* MAX_IOVEC */ - -#define GF_DEFAULT_SOCKET_LISTEN_PORT 6996 - -/* This is the size set through setsockopt for - * both the TCP receive window size and the - * send buffer size. - * Till the time iobuf size becomes configurable, this size is set to include - * two iobufs + the GlusterFS protocol headers. - * Linux allows us to over-ride the max values for the system. - * Should we over-ride them? Because if we set a value larger than the default - * setsockopt will fail. Having larger values might be beneficial for - * IB links. - */ -#define GF_DEFAULT_SOCKET_WINDOW_SIZE (512 * GF_UNIT_KB) -#define GF_MAX_SOCKET_WINDOW_SIZE (1 * GF_UNIT_MB) -#define GF_MIN_SOCKET_WINDOW_SIZE (128 * GF_UNIT_KB) - -#define GF_USE_DEFAULT_KEEPALIVE (-1) - -typedef enum { - SOCKET_PROTO_STATE_NADA = 0, - SOCKET_PROTO_STATE_HEADER_COMING, - SOCKET_PROTO_STATE_HEADER_CAME, - SOCKET_PROTO_STATE_DATA_COMING, - SOCKET_PROTO_STATE_DATA_CAME, - SOCKET_PROTO_STATE_COMPLETE, -} socket_proto_state_t; - -struct socket_header { - char colonO[3]; - uint32_t size1; - uint32_t size2; - char version; -} __attribute__((packed)); - - -struct ioq { - union { - struct list_head list; - struct { - struct ioq *next; - struct ioq *prev; - }; - }; - struct socket_header header; - struct iovec vector[MAX_IOVEC]; - int count; - struct iovec *pending_vector; - int pending_count; - char *buf; - struct iobref *iobref; -}; - - -typedef struct { - int32_t sock; - int32_t idx; - unsigned char connected; // -1 = not connected. 0 = in progress. 1 = connected - char bio; - char connect_finish_log; - char submit_log; - union { - struct list_head ioq; - struct { - struct ioq *ioq_next; - struct ioq *ioq_prev; - }; - }; - struct { - int state; - struct socket_header header; - char *hdr_p; - size_t hdrlen; - struct iobuf *iobuf; - char *buf_p; - size_t buflen; - struct iovec vector[2]; - int count; - struct iovec *pending_vector; - int pending_count; - } incoming; - pthread_mutex_t lock; - int windowsize; - char lowlat; - char nodelay; - int keepalive; - int keepaliveintvl; -} socket_private_t; - - -#endif diff --git a/xlators/protocol/server/src/Makefile.am b/xlators/protocol/server/src/Makefile.am index 0df5894ec..6a18bf025 100644 --- a/xlators/protocol/server/src/Makefile.am +++ b/xlators/protocol/server/src/Makefile.am @@ -1,23 +1,26 @@ xlator_LTLIBRARIES = server.la xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/protocol -server_la_LDFLAGS = -module -avoidversion +server_la_LDFLAGS = -module -avoid-version server_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la \ $(top_builddir)/rpc/rpc-lib/src/libgfrpc.la \ $(top_builddir)/rpc/xdr/src/libgfxdr.la server_la_SOURCES = server.c server-resolve.c server-helpers.c \ - server3_1-fops.c server-handshake.c authenticate.c + server-rpc-fops.c server-handshake.c authenticate.c noinst_HEADERS = server.h server-helpers.h server-mem-types.h authenticate.h -AM_CFLAGS = -fPIC -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE -Wall \ - -I$(top_srcdir)/libglusterfs/src -shared -nostartfiles \ - -DCONFDIR=\"$(sysconfdir)/glusterfs\" -D$(GF_HOST_OS) \ +AM_CPPFLAGS = $(GF_CPPFLAGS) \ + -I$(top_srcdir)/libglusterfs/src \ + -DCONFDIR=\"$(sysconfdir)/glusterfs\" \ -DLIBDIR=\"$(libdir)/glusterfs/$(PACKAGE_VERSION)/auth\" \ - $(GF_CFLAGS) -I$(top_srcdir)/xlators/protocol/lib/src \ - -I$(top_srcdir)/rpc/rpc-lib/src/ \ - -I$(top_srcdir)/rpc/xdr/src/ + -I$(top_srcdir)/xlators/protocol/lib/src \ + -I$(top_srcdir)/rpc/rpc-lib/src \ + -I$(top_srcdir)/rpc/xdr/src + +AM_CFLAGS = -Wall $(GF_CFLAGS) \ + -DDATADIR=\"$(localstatedir)\" CLEANFILES = *~ diff --git a/xlators/protocol/server/src/authenticate.c b/xlators/protocol/server/src/authenticate.c index ffadf2e4d..d8d138a84 100644 --- a/xlators/protocol/server/src/authenticate.c +++ b/xlators/protocol/server/src/authenticate.c @@ -1,21 +1,14 @@ /* - Copyright (c) 2007-2011 Gluster, Inc. <http://www.gluster.com> + Copyright (c) 2007-2013 Red Hat, Inc. <http://www.redhat.com> This file is part of GlusterFS. - GlusterFS is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 3 of the License, - or (at your option) any later version. + 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. +*/ - 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 @@ -31,7 +24,7 @@ #include <errno.h> #include "authenticate.h" -static void +static int init (dict_t *this, char *key, data_t *value, void *data) { void *handle = NULL; @@ -59,7 +52,7 @@ init (dict_t *this, char *key, data_t *value, void *data) if (-1 == ret) { dict_set (this, key, data_from_dynptr (NULL, 0)); *error = -1; - return; + return -1; } handle = dlopen (auth_file, RTLD_LAZY); @@ -69,7 +62,7 @@ init (dict_t *this, char *key, data_t *value, void *data) dict_set (this, key, data_from_dynptr (NULL, 0)); GF_FREE (auth_file); *error = -1; - return; + return -1; } GF_FREE (auth_file); @@ -80,7 +73,7 @@ init (dict_t *this, char *key, data_t *value, void *data) dict_set (this, key, data_from_dynptr (NULL, 0)); dlclose (handle); *error = -1; - return; + return -1; } auth_handle = GF_CALLOC (1, sizeof (*auth_handle), @@ -89,15 +82,16 @@ init (dict_t *this, char *key, data_t *value, void *data) dict_set (this, key, data_from_dynptr (NULL, 0)); *error = -1; dlclose (handle); - return; + return -1; } auth_handle->vol_opt = GF_CALLOC (1, sizeof (volume_opt_list_t), gf_common_mt_volume_opt_list_t); if (!auth_handle->vol_opt) { dict_set (this, key, data_from_dynptr (NULL, 0)); *error = -1; + GF_FREE (auth_handle); dlclose (handle); - return; + return -1; } auth_handle->vol_opt->given_opt = dlsym (handle, "options"); if (auth_handle->vol_opt->given_opt == NULL) { @@ -110,47 +104,54 @@ init (dict_t *this, char *key, data_t *value, void *data) dict_set (this, key, data_from_dynptr (auth_handle, sizeof (*auth_handle))); + return 0; } -static void +static int fini (dict_t *this, char *key, data_t *value, void *data) { auth_handle_t *handle = data_to_ptr (value); if (handle) { dlclose (handle->handle); } + return 0; +} + +static int +_gf_auth_option_validate (dict_t *d, char *k, data_t *v, void *tmp) +{ + auth_handle_t *handle = NULL; + xlator_t *xl = NULL; + int ret = 0; + + xl = tmp; + + handle = data_to_ptr (v); + if (!handle) + return 0; + + list_add_tail (&(handle->vol_opt->list), &(xl->volume_options)); + + ret = xlator_options_validate_list (xl, xl->options, + handle->vol_opt, NULL); + if (ret) { + gf_log ("authenticate", GF_LOG_ERROR, + "volume option validation failed"); + return -1; + } + return 0; } int32_t gf_auth_init (xlator_t *xl, dict_t *auth_modules) { int ret = 0; - auth_handle_t *handle = NULL; - data_pair_t *pair = NULL; dict_foreach (auth_modules, init, &ret); if (ret) goto out; - pair = auth_modules->members_list; - while (pair) { - handle = data_to_ptr (pair->value); - if (!handle) { - pair = pair->next; - continue; - } - - list_add_tail (&(handle->vol_opt->list), - &(xl->volume_options)); - ret = xlator_options_validate_list (xl, xl->options, - handle->vol_opt, NULL); - - if (ret) - gf_log ("authenticate", GF_LOG_ERROR, - "volume option validation failed"); - - pair = pair->next; - } + ret = dict_foreach (auth_modules, _gf_auth_option_validate, xl); out: if (ret) { @@ -164,7 +165,7 @@ out: static dict_t *__input_params; static dict_t *__config_params; -void +int map (dict_t *this, char *key, data_t *value, void *data) { dict_t *res = data; @@ -179,15 +180,16 @@ map (dict_t *this, char *key, data_t *value, void *data) } else { dict_set (res, key, int_to_data (AUTH_DONT_CARE)); } + return 0; } -void +int reduce (dict_t *this, char *key, data_t *value, void *data) { int64_t val = 0; int64_t *res = data; if (!data) - return; + return 0; val = data_to_int64 (value); switch (val) @@ -204,6 +206,7 @@ reduce (dict_t *this, char *key, data_t *value, void *data) case AUTH_DONT_CARE: break; } + return 0; } diff --git a/xlators/protocol/server/src/authenticate.h b/xlators/protocol/server/src/authenticate.h index bb9f77e45..d4d43e498 100644 --- a/xlators/protocol/server/src/authenticate.h +++ b/xlators/protocol/server/src/authenticate.h @@ -1,20 +1,11 @@ /* - Copyright (c) 2007-2011 Gluster, Inc. <http://www.gluster.com> + Copyright (c) 2007-2013 Red Hat, Inc. <http://www.redhat.com> This file is part of GlusterFS. - GlusterFS is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 3 of the License, - or (at your option) any later version. - - GlusterFS is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see - <http://www.gnu.org/licenses/>. + This file is licensed to you under your choice of the GNU Lesser + General Public License, version 3 or any later version (LGPLv3 or + later), or the GNU General Public License, version 2 (GPLv2), in all + cases as published by the Free Software Foundation. */ #ifndef _AUTHENTICATE_H diff --git a/xlators/protocol/server/src/server-handshake.c b/xlators/protocol/server/src/server-handshake.c index 7761f78c4..d4941011d 100644 --- a/xlators/protocol/server/src/server-handshake.c +++ b/xlators/protocol/server/src/server-handshake.c @@ -1,20 +1,11 @@ /* - Copyright (c) 2010-2011 Gluster, Inc. <http://www.gluster.com> + Copyright (c) 2010-2013 Red Hat, Inc. <http://www.redhat.com> This file is part of GlusterFS. - GlusterFS is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 3 of the License, - or (at your option) any later version. - - GlusterFS is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see - <http://www.gnu.org/licenses/>. + This file is licensed to you under your choice of the GNU Lesser + General Public License, version 3 or any later version (LGPLv3 or + later), or the GNU General Public License, version 2 (GPLv2), in all + cases as published by the Free Software Foundation. */ @@ -40,7 +31,7 @@ gf_compare_client_version (rpcsvc_request_t *req, int fop_prognum, { int ret = -1; /* TODO: think.. */ - if (glusterfs3_1_fop_prog.prognum == fop_prognum) + if (glusterfs3_3_fop_prog.prognum == fop_prognum) ret = 0; return ret; @@ -103,9 +94,9 @@ _volfile_update_checksum (xlator_t *this, char *key, uint32_t checksum) if (temp_volfile->checksum != checksum) { gf_log (this->name, GF_LOG_INFO, - "the volume file got modified between earlier access " - "and now, this may lead to inconsistency between " - "clients, advised to remount client"); + "the volume file was modified between a prior access " + "and now. This may lead to inconsistency between " + "clients, you are advised to remount client"); temp_volfile->checksum = checksum; } @@ -118,10 +109,10 @@ static size_t getspec_build_volfile_path (xlator_t *this, const char *key, char *path, size_t path_len) { - int ret = -1; + char *filename = NULL; + server_conf_t *conf = NULL; + int ret = -1; int free_filename = 0; - char *filename = NULL; - server_conf_t *conf = NULL; char data_key[256] = {0,}; conf = this->private; @@ -264,7 +255,9 @@ server_getspec (rpcsvc_request_t *req) this = req->svc->mydata; conf = this->private; - if (!xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gf_getspec_req)) { + ret = xdr_to_generic (req->msg[0], &args, + (xdrproc_t)xdr_gf_getspec_req); + if (ret < 0) { //failed to decode msg; req->rpc_err = GARBAGE_ARGS; op_errno = EINVAL; @@ -311,8 +304,6 @@ server_getspec (rpcsvc_request_t *req) goto fail; } ret = read (spec_fd, rsp.spec, file_len); - - close (spec_fd); } /* convert to XDR */ @@ -323,6 +314,9 @@ fail: rsp.op_errno = gf_errno_to_error (op_errno); rsp.op_ret = ret; + if (spec_fd != -1) + close (spec_fd); + server_submit_reply (NULL, req, &rsp, NULL, 0, NULL, (xdrproc_t)xdr_gf_getspec_rsp); @@ -335,14 +329,15 @@ server_setvolume (rpcsvc_request_t *req) { gf_setvolume_req args = {{0,},}; gf_setvolume_rsp rsp = {0,}; - server_connection_t *conn = NULL; + client_t *client = NULL; + server_ctx_t *serv_ctx = NULL; server_conf_t *conf = NULL; peer_info_t *peerinfo = NULL; dict_t *reply = NULL; dict_t *config_params = NULL; dict_t *params = NULL; char *name = NULL; - char *process_uuid = NULL; + char *client_uid = NULL; char *clnt_version = NULL; xlator_t *xl = NULL; char *msg = NULL; @@ -360,7 +355,9 @@ server_setvolume (rpcsvc_request_t *req) params = dict_new (); reply = dict_new (); - if (!xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gf_setvolume_req)) { + ret = xdr_to_generic (req->msg[0], &args, + (xdrproc_t)xdr_gf_setvolume_req); + if (ret < 0) { //failed to decode msg; req->rpc_err = GARBAGE_ARGS; goto fail; @@ -397,7 +394,7 @@ server_setvolume (rpcsvc_request_t *req) params->extra_free = buf; buf = NULL; - ret = dict_get_str (params, "process-uuid", &process_uuid); + ret = dict_get_str (params, "process-uuid", &client_uid); if (ret < 0) { ret = dict_set_str (reply, "ERROR", "UUID not specified"); @@ -424,25 +421,32 @@ server_setvolume (rpcsvc_request_t *req) goto fail; } - conn = server_connection_get (this, process_uuid); - if (!conn) { + client = gf_client_get (this, &req->cred, client_uid); + if (client == NULL) { op_ret = -1; op_errno = ENOMEM; goto fail; } - gf_log (this->name, GF_LOG_DEBUG, "Connected to %s", conn->id); - cancelled = server_cancel_conn_timer (this, conn); - if (cancelled)//Do connection_put on behalf of grace-timer-handler. - server_connection_put (this, conn, NULL); - if (conn->lk_version != 0 && - conn->lk_version != lk_version) { - (void) server_connection_cleanup (this, conn, + gf_log (this->name, GF_LOG_DEBUG, "Connected to %s", client->client_uid); + cancelled = server_cancel_grace_timer (this, client); + if (cancelled)//Do gf_client_put on behalf of grace-timer-handler. + gf_client_put (client, NULL); + + serv_ctx = server_ctx_get (client, client->this); + if (serv_ctx == NULL) { + gf_log (this->name, GF_LOG_INFO, "server_ctx_get() failed"); + goto fail; + } + + if (serv_ctx->lk_version != 0 && + serv_ctx->lk_version != lk_version) { + (void) server_connection_cleanup (this, client, INTERNAL_LOCKS | POSIX_LOCKS); } - if (req->trans->xl_private != conn) - req->trans->xl_private = conn; + if (req->trans->xl_private != client) + req->trans->xl_private = client; ret = dict_get_int32 (params, "fops-version", &fop_version); if (ret < 0) { @@ -567,10 +571,10 @@ server_setvolume (rpcsvc_request_t *req) gf_log (this->name, GF_LOG_INFO, "accepted client from %s (version: %s)", - conn->id, + client->client_uid, (clnt_version) ? clnt_version : "old"); op_ret = 0; - conn->bound_xl = xl; + client->bound_xl = xl; ret = dict_set_str (reply, "ERROR", "Success"); if (ret < 0) gf_log (this->name, GF_LOG_DEBUG, @@ -578,7 +582,7 @@ server_setvolume (rpcsvc_request_t *req) } else { gf_log (this->name, GF_LOG_ERROR, "Cannot authenticate client from %s %s", - conn->id, + client->client_uid, (clnt_version) ? clnt_version : "old"); op_ret = -1; @@ -587,11 +591,10 @@ server_setvolume (rpcsvc_request_t *req) if (ret < 0) gf_log (this->name, GF_LOG_DEBUG, "failed to set error msg"); - goto fail; } - if (conn->bound_xl == NULL) { + if (client->bound_xl == NULL) { ret = dict_set_str (reply, "ERROR", "Check volfile and handshake " "options in protocol/client"); @@ -604,20 +607,21 @@ server_setvolume (rpcsvc_request_t *req) goto fail; } - if ((conn->bound_xl != NULL) && + if ((client->bound_xl != NULL) && (ret >= 0) && - (conn->bound_xl->itable == NULL)) { + (client->bound_xl->itable == NULL)) { /* create inode table for this bound_xl, if one doesn't already exist */ gf_log (this->name, GF_LOG_TRACE, "creating inode table with lru_limit=%"PRId32", " "xlator=%s", conf->inode_lru_limit, - conn->bound_xl->name); + client->bound_xl->name); /* TODO: what is this ? */ - conn->bound_xl->itable = inode_table_new (conf->inode_lru_limit, - conn->bound_xl); + client->bound_xl->itable = + inode_table_new (conf->inode_lru_limit, + client->bound_xl); } ret = dict_set_str (reply, "process-uuid", @@ -626,8 +630,7 @@ server_setvolume (rpcsvc_request_t *req) gf_log (this->name, GF_LOG_DEBUG, "failed to set 'process-uuid'"); - ret = dict_set_uint32 (reply, "clnt-lk-version", - conn->lk_version); + ret = dict_set_uint32 (reply, "clnt-lk-version", serv_ctx->lk_version); if (ret) gf_log (this->name, GF_LOG_WARNING, "failed to set 'clnt-lk-version'"); @@ -664,23 +667,34 @@ fail: rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error (op_errno); + /* if bound_xl is NULL or something fails, then put the connection + * back. Otherwise the connection would have been added to the + * list of connections the server is maintaining and might segfault + * during statedump when bound_xl of the connection is accessed. + */ + if (op_ret && !xl) { + /* We would have set the xl_private of the transport to the + * @conn. But if we have put the connection i.e shutting down + * the connection, then we should set xl_private to NULL as it + * would be pointing to a freed memory and would segfault when + * accessed upon getting DISCONNECT. + */ + gf_client_put (client, NULL); + req->trans->xl_private = NULL; + } server_submit_reply (NULL, req, &rsp, NULL, 0, NULL, (xdrproc_t)xdr_gf_setvolume_rsp); - if (args.dict.dict_val) - free (args.dict.dict_val); + free (args.dict.dict_val); - if (rsp.dict.dict_val) - GF_FREE (rsp.dict.dict_val); + GF_FREE (rsp.dict.dict_val); dict_unref (params); dict_unref (reply); dict_unref (config_params); - if (buf) { - GF_FREE (buf); - } + GF_FREE (buf); return 0; } @@ -703,12 +717,13 @@ server_ping (rpcsvc_request_t *req) int server_set_lk_version (rpcsvc_request_t *req) { - int op_ret = -1; - int op_errno = EINVAL; - gf_set_lk_ver_req args = {0, }; - gf_set_lk_ver_rsp rsp = {0,}; - server_connection_t *conn = NULL; - xlator_t *this = NULL; + int op_ret = -1; + int op_errno = EINVAL; + gf_set_lk_ver_req args = {0,}; + gf_set_lk_ver_rsp rsp = {0,}; + client_t *client = NULL; + server_ctx_t *serv_ctx = NULL; + xlator_t *this = NULL; this = req->svc->mydata; //TODO: Decide on an appropriate errno for the error-path @@ -716,16 +731,23 @@ server_set_lk_version (rpcsvc_request_t *req) if (!this) goto fail; - if (!xdr_to_generic (req->msg[0], &args, - (xdrproc_t)xdr_gf_set_lk_ver_req)) { + op_ret = xdr_to_generic (req->msg[0], &args, + (xdrproc_t)xdr_gf_set_lk_ver_req); + if (op_ret < 0) { //failed to decode msg; req->rpc_err = GARBAGE_ARGS; goto fail; } - conn = server_connection_get (this, args.uid); - conn->lk_version = args.lk_ver; - server_connection_put (this, conn, NULL); + client = gf_client_get (this, &req->cred, args.uid); + serv_ctx = server_ctx_get (client, client->this); + if (serv_ctx == NULL) { + gf_log (this->name, GF_LOG_INFO, "server_ctx_get() failed"); + goto fail; + } + + serv_ctx->lk_version = args.lk_ver; + gf_client_put (client, NULL); rsp.lk_ver = args.lk_ver; @@ -736,19 +758,17 @@ fail: server_submit_reply (NULL, req, &rsp, NULL, 0, NULL, (xdrproc_t)xdr_gf_set_lk_ver_rsp); - if (args.uid != NULL) { - free (args.uid); - } + free (args.uid); return 0; } rpcsvc_actor_t gluster_handshake_actors[] = { - [GF_HNDSK_NULL] = {"NULL", GF_HNDSK_NULL, server_null, NULL, NULL, 0}, - [GF_HNDSK_SETVOLUME] = {"SETVOLUME", GF_HNDSK_SETVOLUME, server_setvolume, NULL, NULL, 0}, - [GF_HNDSK_GETSPEC] = {"GETSPEC", GF_HNDSK_GETSPEC, server_getspec, NULL, NULL, 0}, - [GF_HNDSK_PING] = {"PING", GF_HNDSK_PING, server_ping, NULL, NULL, 0}, - [GF_HNDSK_SET_LK_VER] = {"SET_LK_VER", GF_HNDSK_SET_LK_VER, server_set_lk_version, NULL, NULL }, + [GF_HNDSK_NULL] = {"NULL", GF_HNDSK_NULL, server_null, NULL, 0, DRC_NA}, + [GF_HNDSK_SETVOLUME] = {"SETVOLUME", GF_HNDSK_SETVOLUME, server_setvolume, NULL, 0, DRC_NA}, + [GF_HNDSK_GETSPEC] = {"GETSPEC", GF_HNDSK_GETSPEC, server_getspec, NULL, 0, DRC_NA}, + [GF_HNDSK_PING] = {"PING", GF_HNDSK_PING, server_ping, NULL, 0, DRC_NA}, + [GF_HNDSK_SET_LK_VER] = {"SET_LK_VER", GF_HNDSK_SET_LK_VER, server_set_lk_version, NULL, 0, DRC_NA}, }; diff --git a/xlators/protocol/server/src/server-helpers.c b/xlators/protocol/server/src/server-helpers.c index 8827a48b0..f0b040c74 100644 --- a/xlators/protocol/server/src/server-helpers.c +++ b/xlators/protocol/server/src/server-helpers.c @@ -1,20 +1,11 @@ /* - Copyright (c) 2010-2011 Gluster, Inc. <http://www.gluster.com> + Copyright (c) 2010-2013 Red Hat, Inc. <http://www.redhat.com> This file is part of GlusterFS. - GlusterFS is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 3 of the License, - or (at your option) any later version. - - GlusterFS is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see - <http://www.gnu.org/licenses/>. + This file is licensed to you under your choice of the GNU Lesser + General Public License, version 3 or any later version (LGPLv3 or + later), or the GNU General Public License, version 2 (GPLv2), in all + cases as published by the Free Software Foundation. */ #ifndef _CONFIG_H @@ -35,6 +26,9 @@ server_decode_groups (call_frame_t *frame, rpcsvc_request_t *req) GF_VALIDATE_OR_GOTO ("server", frame, out); GF_VALIDATE_OR_GOTO ("server", req, out); + if (call_stack_alloc_groups (frame->root, req->auxgidcount) != 0) + return -1; + frame->root->ngrps = req->auxgidcount; if (frame->root->ngrps == 0) return 0; @@ -48,6 +42,7 @@ out: return 0; } + void server_loc_wipe (loc_t *loc) { @@ -61,19 +56,16 @@ server_loc_wipe (loc_t *loc) loc->inode = NULL; } - if (loc->path) - GF_FREE ((void *)loc->path); + GF_FREE ((void *)loc->path); } void server_resolve_wipe (server_resolve_t *resolve) { - if (resolve->path) - GF_FREE ((void *)resolve->path); + GF_FREE ((void *)resolve->path); - if (resolve->bname) - GF_FREE ((void *)resolve->bname); + GF_FREE ((void *)resolve->bname); loc_wipe (&resolve->resolve_loc); } @@ -82,11 +74,6 @@ server_resolve_wipe (server_resolve_t *resolve) void free_state (server_state_t *state) { - if (state->conn) { - //xprt_svc_unref (state->conn); - state->conn = NULL; - } - if (state->xprt) { rpc_transport_unref (state->xprt); state->xprt = NULL; @@ -121,11 +108,9 @@ free_state (server_state_t *state) state->xdata = NULL; } - if (state->volume) - GF_FREE ((void *)state->volume); + GF_FREE ((void *)state->volume); - if (state->name) - GF_FREE ((void *)state->name); + GF_FREE ((void *)state->name); server_loc_wipe (&state->loc); server_loc_wipe (&state->loc2); @@ -137,301 +122,26 @@ free_state (server_state_t *state) } -int -gf_add_locker (server_connection_t *conn, const char *volume, - loc_t *loc, fd_t *fd, pid_t pid, gf_lkowner_t *owner, - glusterfs_fop_t type) -{ - int32_t ret = -1; - struct _locker *new = NULL; - struct _lock_table *table = NULL; - - GF_VALIDATE_OR_GOTO ("server", volume, out); - - new = GF_CALLOC (1, sizeof (struct _locker), gf_server_mt_locker_t); - if (new == NULL) { - goto out; - } - INIT_LIST_HEAD (&new->lockers); - - new->volume = gf_strdup (volume); - - if (fd == NULL) { - loc_copy (&new->loc, loc); - } else { - new->fd = fd_ref (fd); - } - - new->pid = pid; - new->owner = *owner; - - pthread_mutex_lock (&conn->lock); - { - table = conn->ltable; - if (type == GF_FOP_ENTRYLK) - list_add_tail (&new->lockers, &table->entrylk_lockers); - else - list_add_tail (&new->lockers, &table->inodelk_lockers); - } - pthread_mutex_unlock (&conn->lock); -out: - return ret; -} - - -int -gf_del_locker (server_connection_t *conn, const char *volume, - loc_t *loc, fd_t *fd, gf_lkowner_t *owner, - glusterfs_fop_t type) -{ - struct _locker *locker = NULL; - struct _locker *tmp = NULL; - int32_t ret = -1; - struct list_head *head = NULL; - struct _lock_table *table = NULL; - int found = 0; - - GF_VALIDATE_OR_GOTO ("server", volume, out); - - pthread_mutex_lock (&conn->lock); - { - table = conn->ltable; - if (type == GF_FOP_ENTRYLK) { - head = &table->entrylk_lockers; - } else { - head = &table->inodelk_lockers; - } - - list_for_each_entry_safe (locker, tmp, head, lockers) { - if (!is_same_lkowner (&locker->owner, owner) || - strcmp (locker->volume, volume)) - continue; - - if (locker->fd && fd && (locker->fd == fd)) - found = 1; - else if (locker->loc.inode && loc && - (locker->loc.inode == loc->inode)) - found = 1; - if (found) { - list_del_init (&locker->lockers); - break; - } - } - if (!found) - locker = NULL; - } - pthread_mutex_unlock (&conn->lock); - - if (locker) { - if (locker->fd) - fd_unref (locker->fd); - else - loc_wipe (&locker->loc); - - GF_FREE (locker->volume); - GF_FREE (locker); - } - - ret = 0; -out: - return ret; -} - -static struct _lock_table * -gf_lock_table_new (void) -{ - struct _lock_table *new = NULL; - - new = GF_CALLOC (1, sizeof (struct _lock_table), gf_server_mt_lock_table_t); - if (new == NULL) { - goto out; - } - INIT_LIST_HEAD (&new->entrylk_lockers); - INIT_LIST_HEAD (&new->inodelk_lockers); -out: - return new; -} - -static int -server_nop_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, dict_t *xdata) -{ - int ret = -1; - server_state_t *state = NULL; - - GF_VALIDATE_OR_GOTO ("server", frame, out); - GF_VALIDATE_OR_GOTO ("server", cookie, out); - GF_VALIDATE_OR_GOTO ("server", this, out); - - if (frame->root->trans) - server_conn_unref (frame->root->trans); - state = CALL_STATE(frame); - - if (state) - free_state (state); - STACK_DESTROY (frame->root); - - ret = 0; -out: - return ret; -} - -int -do_lock_table_cleanup (xlator_t *this, server_connection_t *conn, - call_frame_t *frame, struct _lock_table *ltable) -{ - struct list_head inodelk_lockers, entrylk_lockers; - call_frame_t *tmp_frame = NULL; - struct gf_flock flock = {0, }; - xlator_t *bound_xl = NULL; - struct _locker *locker = NULL, *tmp = NULL; - int ret = -1; - char *path = NULL; - - GF_VALIDATE_OR_GOTO ("server", this, out); - GF_VALIDATE_OR_GOTO ("server", conn, out); - GF_VALIDATE_OR_GOTO ("server", frame, out); - GF_VALIDATE_OR_GOTO ("server", ltable, out); - - bound_xl = conn->bound_xl; - INIT_LIST_HEAD (&inodelk_lockers); - INIT_LIST_HEAD (&entrylk_lockers); - - list_splice_init (<able->inodelk_lockers, - &inodelk_lockers); - - list_splice_init (<able->entrylk_lockers, &entrylk_lockers); - GF_FREE (ltable); - - flock.l_type = F_UNLCK; - flock.l_start = 0; - flock.l_len = 0; - list_for_each_entry_safe (locker, - tmp, &inodelk_lockers, lockers) { - tmp_frame = copy_frame (frame); - if (tmp_frame == NULL) { - goto out; - } - /* - lock owner = 0 is a special case that tells posix-locks - to release all locks from this transport - */ - tmp_frame->root->pid = 0; - tmp_frame->root->trans = server_conn_ref (conn); - memset (&tmp_frame->root->lk_owner, 0, sizeof (gf_lkowner_t)); - - if (locker->fd) { - GF_ASSERT (locker->fd->inode); - - ret = inode_path (locker->fd->inode, NULL, &path); - - if (ret > 0) { - gf_log (this->name, GF_LOG_INFO, "finodelk " - "released on %s", path); - GF_FREE (path); - } else { - - gf_log (this->name, GF_LOG_INFO, "finodelk " - "released on inode with gfid %s", - uuid_utoa (locker->fd->inode->gfid)); - } - - STACK_WIND (tmp_frame, server_nop_cbk, bound_xl, - bound_xl->fops->finodelk, - locker->volume, - locker->fd, F_SETLK, &flock, NULL); - fd_unref (locker->fd); - } else { - gf_log (this->name, GF_LOG_INFO, "inodelk released " - "on %s", locker->loc.path); - - STACK_WIND (tmp_frame, server_nop_cbk, bound_xl, - bound_xl->fops->inodelk, - locker->volume, - &(locker->loc), F_SETLK, &flock, NULL); - loc_wipe (&locker->loc); - } - - GF_FREE (locker->volume); - - list_del_init (&locker->lockers); - GF_FREE (locker); - } - - tmp = NULL; - locker = NULL; - list_for_each_entry_safe (locker, tmp, &entrylk_lockers, lockers) { - tmp_frame = copy_frame (frame); - - tmp_frame->root->pid = 0; - tmp_frame->root->trans = server_conn_ref (conn); - memset (&tmp_frame->root->lk_owner, 0, sizeof (gf_lkowner_t)); - - if (locker->fd) { - GF_ASSERT (locker->fd->inode); - - ret = inode_path (locker->fd->inode, NULL, &path); - - if (ret > 0) { - gf_log (this->name, GF_LOG_INFO, "fentrylk " - "released on %s", path); - GF_FREE (path); - } else { - - gf_log (this->name, GF_LOG_INFO, "fentrylk " - "released on inode with gfid %s", - uuid_utoa (locker->fd->inode->gfid)); - } - - STACK_WIND (tmp_frame, server_nop_cbk, bound_xl, - bound_xl->fops->fentrylk, - locker->volume, - locker->fd, NULL, - ENTRYLK_UNLOCK, ENTRYLK_WRLCK, NULL); - fd_unref (locker->fd); - } else { - gf_log (this->name, GF_LOG_INFO, "entrylk released " - "on %s", locker->loc.path); - - STACK_WIND (tmp_frame, server_nop_cbk, bound_xl, - bound_xl->fops->entrylk, - locker->volume, - &(locker->loc), NULL, - ENTRYLK_UNLOCK, ENTRYLK_WRLCK, NULL); - loc_wipe (&locker->loc); - } - - GF_FREE (locker->volume); - - list_del_init (&locker->lockers); - GF_FREE (locker); - } - ret = 0; - -out: - return ret; -} - - static int server_connection_cleanup_flush_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { - int32_t ret = -1; - fd_t *fd = NULL; + int32_t ret = -1; + fd_t *fd = NULL; + client_t *client = NULL; GF_VALIDATE_OR_GOTO ("server", this, out); GF_VALIDATE_OR_GOTO ("server", cookie, out); GF_VALIDATE_OR_GOTO ("server", frame, out); fd = frame->local; + client = frame->root->client; fd_unref (fd); frame->local = NULL; - if (frame->root->trans) - server_conn_unref (frame->root->trans); + gf_client_unref (client); STACK_DESTROY (frame->root); ret = 0; @@ -440,9 +150,8 @@ out: } -int -do_fd_cleanup (xlator_t *this, server_connection_t *conn, call_frame_t *frame, - fdentry_t *fdentries, int fd_count) +static int +do_fd_cleanup (xlator_t *this, client_t* client, fdentry_t *fdentries, int fd_count) { fd_t *fd = NULL; int i = 0, ret = -1; @@ -451,16 +160,14 @@ do_fd_cleanup (xlator_t *this, server_connection_t *conn, call_frame_t *frame, char *path = NULL; GF_VALIDATE_OR_GOTO ("server", this, out); - GF_VALIDATE_OR_GOTO ("server", conn, out); - GF_VALIDATE_OR_GOTO ("server", frame, out); GF_VALIDATE_OR_GOTO ("server", fdentries, out); - bound_xl = conn->bound_xl; + bound_xl = client->bound_xl; for (i = 0;i < fd_count; i++) { fd = fdentries[i].fd; if (fd != NULL) { - tmp_frame = copy_frame (frame); + tmp_frame = create_frame (this, this->ctx->pool); if (tmp_frame == NULL) { goto out; } @@ -470,20 +177,20 @@ do_fd_cleanup (xlator_t *this, server_connection_t *conn, call_frame_t *frame, ret = inode_path (fd->inode, NULL, &path); if (ret > 0) { - gf_log (this->name, GF_LOG_INFO, "fd cleanup on " - "%s", path); + gf_log (this->name, GF_LOG_INFO, + "fd cleanup on %s", path); GF_FREE (path); } else { - gf_log (this->name, GF_LOG_INFO, "fd cleanup on" - " inode with gfid %s", + gf_log (this->name, GF_LOG_INFO, + "fd cleanup on inode with gfid %s", uuid_utoa (fd->inode->gfid)); } tmp_frame->local = fd; tmp_frame->root->pid = 0; - tmp_frame->root->trans = server_conn_ref (conn); + gf_client_ref (client); memset (&tmp_frame->root->lk_owner, 0, sizeof (gf_lkowner_t)); @@ -500,269 +207,72 @@ out: return ret; } -int -do_connection_cleanup (xlator_t *this, server_connection_t *conn, - struct _lock_table *ltable, fdentry_t *fdentries, int fd_count) -{ - int ret = 0; - int saved_ret = 0; - call_frame_t *frame = NULL; - server_state_t *state = NULL; - - GF_VALIDATE_OR_GOTO ("server", this, out); - GF_VALIDATE_OR_GOTO ("server", conn, out); - - if (!ltable && !fdentries) - goto out; - - frame = create_frame (this, this->ctx->pool); - if (frame == NULL) { - goto out; - } - - if (ltable) - saved_ret = do_lock_table_cleanup (this, conn, frame, ltable); - - if (fdentries != NULL) { - ret = do_fd_cleanup (this, conn, frame, fdentries, fd_count); - } - - state = CALL_STATE (frame); - if (state) - GF_FREE (state); - - STACK_DESTROY (frame->root); - - if (saved_ret || ret) { - ret = -1; - } - -out: - return ret; -} - int -server_connection_cleanup (xlator_t *this, server_connection_t *conn, +server_connection_cleanup (xlator_t *this, client_t *client, int32_t flags) { - struct _lock_table *ltable = NULL; - fdentry_t *fdentries = NULL; - uint32_t fd_count = 0; - int ret = 0; + server_ctx_t *serv_ctx = NULL; + fdentry_t *fdentries = NULL; + uint32_t fd_count = 0; + int cd_ret = 0; + int ret = 0; GF_VALIDATE_OR_GOTO (this->name, this, out); - GF_VALIDATE_OR_GOTO (this->name, conn, out); + GF_VALIDATE_OR_GOTO (this->name, client, out); GF_VALIDATE_OR_GOTO (this->name, flags, out); - pthread_mutex_lock (&conn->lock); - { - if (conn->ltable && (flags & INTERNAL_LOCKS)) { - ltable = conn->ltable; - conn->ltable = gf_lock_table_new (); - } - - if (conn->fdtable && (flags & POSIX_LOCKS)) - fdentries = gf_fd_fdtable_get_all_fds (conn->fdtable, - &fd_count); - } - pthread_mutex_unlock (&conn->lock); - - if (conn->bound_xl) - ret = do_connection_cleanup (this, conn, ltable, - fdentries, fd_count); - -out: - return ret; -} - - -int -server_connection_destroy (xlator_t *this, server_connection_t *conn) -{ - xlator_t *bound_xl = NULL; - int32_t ret = -1; - struct list_head inodelk_lockers; - struct list_head entrylk_lockers; - struct _lock_table *ltable = NULL; - fdtable_t *fdtable = NULL; - - GF_VALIDATE_OR_GOTO ("server", this, out); - GF_VALIDATE_OR_GOTO ("server", conn, out); - - bound_xl = (xlator_t *) (conn->bound_xl); - - if (bound_xl) { - pthread_mutex_lock (&(conn->lock)); - { - if (conn->ltable) { - ltable = conn->ltable; - conn->ltable = NULL; - } - if (conn->fdtable) { - fdtable = conn->fdtable; - conn->fdtable = NULL; - } - } - pthread_mutex_unlock (&conn->lock); + serv_ctx = server_ctx_get (client, client->this); - INIT_LIST_HEAD (&inodelk_lockers); - INIT_LIST_HEAD (&entrylk_lockers); - - if (ltable) { - list_splice_init (<able->inodelk_lockers, - &inodelk_lockers); - - list_splice_init (<able->entrylk_lockers, - &entrylk_lockers); - GF_FREE (ltable); - } - - GF_ASSERT (list_empty (&inodelk_lockers)); - GF_ASSERT (list_empty (&entrylk_lockers)); - - if (fdtable) - gf_fd_fdtable_destroy (fdtable); + if (serv_ctx == NULL) { + gf_log (this->name, GF_LOG_INFO, "server_ctx_get() failed"); + goto out; } - gf_log (this->name, GF_LOG_INFO, "destroyed connection of %s", - conn->id); - - pthread_mutex_destroy (&conn->lock); - GF_FREE (conn->id); - GF_FREE (conn); - ret = 0; -out: - return ret; -} - -server_connection_t* -server_conn_unref (server_connection_t *conn) -{ - server_connection_t *todel = NULL; - xlator_t *this = NULL; - - pthread_mutex_lock (&conn->lock); + LOCK (&serv_ctx->fdtable_lock); { - conn->ref--; - - if (!conn->ref) { - todel = conn; - } + if (serv_ctx->fdtable && (flags & POSIX_LOCKS)) + fdentries = gf_fd_fdtable_get_all_fds (serv_ctx->fdtable, + &fd_count); } - pthread_mutex_unlock (&conn->lock); + UNLOCK (&serv_ctx->fdtable_lock); - if (todel) { - this = THIS; - server_connection_destroy (this, todel); - conn = NULL; - } - return conn; -} + if (client->bound_xl == NULL) + goto out; -server_connection_t* -server_conn_ref (server_connection_t *conn) -{ - pthread_mutex_lock (&conn->lock); - { - conn->ref++; + if (flags & INTERNAL_LOCKS) { + cd_ret = gf_client_disconnect (client); } - pthread_mutex_unlock (&conn->lock); - - return conn; -} - -server_connection_t * -server_connection_get (xlator_t *this, const char *id) -{ - server_connection_t *conn = NULL; - server_connection_t *trav = NULL; - server_conf_t *conf = NULL; - GF_VALIDATE_OR_GOTO ("server", this, out); - GF_VALIDATE_OR_GOTO ("server", id, out); - - conf = this->private; + if (fdentries != NULL) + ret = do_fd_cleanup (this, client, fdentries, fd_count); + else + gf_log (this->name, GF_LOG_INFO, "no fdentries to clean"); - pthread_mutex_lock (&conf->mutex); - { - list_for_each_entry (trav, &conf->conns, list) { - if (!strcmp (trav->id, id)) { - conn = trav; - conn->bind_ref++; - goto unlock; - } - } - - conn = (void *) GF_CALLOC (1, sizeof (*conn), - gf_server_mt_conn_t); - if (!conn) - goto unlock; - - conn->id = gf_strdup (id); - /*'0' denotes uninitialised lock state*/ - conn->lk_version = 0; - conn->fdtable = gf_fd_fdtable_alloc (); - conn->ltable = gf_lock_table_new (); - conn->this = this; - conn->bind_ref = 1; - conn->ref = 1;//when bind_ref becomes 0 it calls conn_unref - pthread_mutex_init (&conn->lock, NULL); - list_add (&conn->list, &conf->conns); + if (cd_ret || ret) + ret = -1; - } -unlock: - pthread_mutex_unlock (&conf->mutex); out: - return conn; + return ret; } -server_connection_t* -server_connection_put (xlator_t *this, server_connection_t *conn, - gf_boolean_t *detached) -{ - server_conf_t *conf = NULL; - gf_boolean_t unref = _gf_false; - - if (detached) - *detached = _gf_false; - conf = this->private; - pthread_mutex_lock (&conf->mutex); - { - conn->bind_ref--; - if (!conn->bind_ref) { - list_del_init (&conn->list); - unref = _gf_true; - } - } - pthread_mutex_unlock (&conf->mutex); - if (unref) { - gf_log (this->name, GF_LOG_INFO, "Shutting down connection %s", - conn->id); - if (detached) - *detached = _gf_true; - server_conn_unref (conn); - conn = NULL; - } - return conn; -} static call_frame_t * server_alloc_frame (rpcsvc_request_t *req) { - call_frame_t *frame = NULL; - server_state_t *state = NULL; - server_connection_t *conn = NULL; + call_frame_t *frame = NULL; + server_state_t *state = NULL; + client_t *client = NULL; GF_VALIDATE_OR_GOTO ("server", req, out); GF_VALIDATE_OR_GOTO ("server", req->trans, out); GF_VALIDATE_OR_GOTO ("server", req->svc, out); GF_VALIDATE_OR_GOTO ("server", req->svc->ctx, out); - conn = (server_connection_t *)req->trans->xl_private; - GF_VALIDATE_OR_GOTO ("server", conn, out); + client = req->trans->xl_private; + GF_VALIDATE_OR_GOTO ("server", client, out); - frame = create_frame (conn->this, req->svc->ctx->pool); + frame = create_frame (client->this, req->svc->ctx->pool); if (!frame) goto out; @@ -770,45 +280,46 @@ server_alloc_frame (rpcsvc_request_t *req) if (!state) goto out; - if (conn->bound_xl) - state->itable = conn->bound_xl->itable; + if (client->bound_xl) + state->itable = client->bound_xl->itable; state->xprt = rpc_transport_ref (req->trans); - state->conn = conn; - state->resolve.fd_no = -1; state->resolve2.fd_no = -1; + frame->root->client = client; frame->root->state = state; /* which socket */ frame->root->unique = 0; /* which call */ - frame->this = conn->this; + frame->this = client->this; out: return frame; } - call_frame_t * get_frame_from_request (rpcsvc_request_t *req) { - call_frame_t *frame = NULL; + call_frame_t *frame = NULL; + client_t *client = NULL; GF_VALIDATE_OR_GOTO ("server", req, out); + client = req->trans->xl_private; + frame = server_alloc_frame (req); if (!frame) goto out; frame->root->op = req->procnum; - frame->root->type = req->type; frame->root->unique = req->xid; frame->root->uid = req->uid; frame->root->gid = req->gid; frame->root->pid = req->pid; - frame->root->trans = server_conn_ref (req->trans->xl_private); + gf_client_ref (client); + frame->root->client = client; frame->root->lk_owner = req->lk_owner; server_decode_groups (frame, req); @@ -893,84 +404,6 @@ out: return ret; } -void -put_server_conn_state (xlator_t *this, rpc_transport_t *xprt) -{ - GF_VALIDATE_OR_GOTO ("server", this, out); - GF_VALIDATE_OR_GOTO ("server", xprt, out); - - xprt->xl_private = NULL; -out: - return; -} - -server_connection_t * -get_server_conn_state (xlator_t *this, rpc_transport_t *xprt) -{ - GF_VALIDATE_OR_GOTO ("server", this, out); - GF_VALIDATE_OR_GOTO ("server", xprt, out); - - return (server_connection_t *)xprt->xl_private; -out: - return NULL; -} - -server_connection_t * -create_server_conn_state (xlator_t *this, rpc_transport_t *xprt) -{ - server_connection_t *conn = NULL; - int ret = -1; - - GF_VALIDATE_OR_GOTO ("server", this, out); - GF_VALIDATE_OR_GOTO ("server", xprt, out); - - conn = GF_CALLOC (1, sizeof (*conn), gf_server_mt_conn_t); - if (!conn) - goto out; - - pthread_mutex_init (&conn->lock, NULL); - - conn->fdtable = gf_fd_fdtable_alloc (); - if (!conn->fdtable) - goto out; - - conn->ltable = gf_lock_table_new (); - if (!conn->ltable) - goto out; - - conn->this = this; - - xprt->xl_private = conn; - - ret = 0; -out: - if (ret) - destroy_server_conn_state (conn); - - return conn; -} - -void -destroy_server_conn_state (server_connection_t *conn) -{ - GF_VALIDATE_OR_GOTO ("server", conn, out); - - if (conn->ltable) { - /* TODO */ - //FREE (conn->ltable); - ; - } - - if (conn->fdtable) - gf_fd_fdtable_destroy (conn->fdtable); - - pthread_mutex_destroy (&conn->lock); - - GF_FREE (conn); -out: - return; -} - void print_caller (char *str, int size, call_frame_t *frame) @@ -1097,12 +530,15 @@ server_print_params (char *str, int size, server_state_t *state) filled += snprintf (str + filled, size - filled, "volume=%s,", state->volume); +/* FIXME snprintf (str + filled, size - filled, - "bound_xl=%s}", state->conn->bound_xl->name); + "bound_xl=%s}", state->client->bound_xl->name); +*/ out: return; } + int server_resolve_is_empty (server_resolve_t *resolve) { @@ -1118,6 +554,7 @@ server_resolve_is_empty (server_resolve_t *resolve) return 1; } + void server_print_reply (call_frame_t *frame, int op_ret, int op_errno) { @@ -1142,10 +579,7 @@ server_print_reply (call_frame_t *frame, int op_ret, int op_errno) switch (frame->root->type) { case GF_OP_TYPE_FOP: - op = gf_fop_list[frame->root->op]; - break; - case GF_OP_TYPE_MGMT: - op = gf_mgmt_list[frame->root->op]; + op = (char *)gf_fop_list[frame->root->op]; break; default: op = ""; @@ -1166,16 +600,16 @@ out: void server_print_request (call_frame_t *frame) { - server_conf_t *conf = NULL; - xlator_t *this = NULL; + server_conf_t *conf = NULL; + xlator_t *this = NULL; server_state_t *state = NULL; + char *op = "UNKNOWN"; char resolve_vars[256]; char resolve2_vars[256]; char loc_vars[256]; char loc2_vars[256]; char other_vars[512]; char caller[512]; - char *op = "UNKNOWN"; GF_VALIDATE_OR_GOTO ("server", frame, out); @@ -1211,10 +645,7 @@ server_print_request (call_frame_t *frame) switch (frame->root->type) { case GF_OP_TYPE_FOP: - op = gf_fop_list[frame->root->op]; - break; - case GF_OP_TYPE_MGMT: - op = gf_mgmt_list[frame->root->op]; + op = (char *)gf_fop_list[frame->root->op]; break; default: op = ""; @@ -1229,13 +660,14 @@ out: return; } + int serialize_rsp_direntp (gf_dirent_t *entries, gfs3_readdirp_rsp *rsp) { gf_dirent_t *entry = NULL; - gfs3_dirplist *trav = NULL; - gfs3_dirplist *prev = NULL; - int ret = -1; + gfs3_dirplist *trav = NULL; + gfs3_dirplist *prev = NULL; + int ret = -1; GF_VALIDATE_OR_GOTO ("server", entries, out); GF_VALIDATE_OR_GOTO ("server", rsp, out); @@ -1289,10 +721,13 @@ serialize_rsp_direntp (gf_dirent_t *entries, gfs3_readdirp_rsp *rsp) rsp->reply = trav; prev = trav; + trav = NULL; } ret = 0; out: + GF_FREE (trav); + return ret; } @@ -1300,10 +735,10 @@ out: int serialize_rsp_dirent (gf_dirent_t *entries, gfs3_readdir_rsp *rsp) { - gf_dirent_t *entry = NULL; - gfs3_dirlist *trav = NULL; - gfs3_dirlist *prev = NULL; - int ret = -1; + gf_dirent_t *entry = NULL; + gfs3_dirlist *trav = NULL; + gfs3_dirlist *prev = NULL; + int ret = -1; GF_VALIDATE_OR_GOTO ("server", entries, out); GF_VALIDATE_OR_GOTO ("server", rsp, out); @@ -1330,11 +765,12 @@ out: return ret; } + int readdir_rsp_cleanup (gfs3_readdir_rsp *rsp) { - gfs3_dirlist *prev = NULL; - gfs3_dirlist *trav = NULL; + gfs3_dirlist *prev = NULL; + gfs3_dirlist *trav = NULL; trav = rsp->reply; prev = trav; @@ -1347,6 +783,7 @@ readdir_rsp_cleanup (gfs3_readdir_rsp *rsp) return 0; } + int readdirp_rsp_cleanup (gfs3_readdirp_rsp *rsp) { @@ -1357,8 +794,7 @@ readdirp_rsp_cleanup (gfs3_readdirp_rsp *rsp) prev = trav; while (trav) { trav = trav->nextentry; - if (prev->dict.dict_val) - GF_FREE (prev->dict.dict_val); + GF_FREE (prev->dict.dict_val); GF_FREE (prev); prev = trav; } @@ -1366,6 +802,7 @@ readdirp_rsp_cleanup (gfs3_readdirp_rsp *rsp) return 0; } + int gf_server_check_getxattr_cmd (call_frame_t *frame, const char *key) { @@ -1394,64 +831,431 @@ gf_server_check_getxattr_cmd (call_frame_t *frame, const char *key) return 0; } + int gf_server_check_setxattr_cmd (call_frame_t *frame, dict_t *dict) { - data_pair_t *pair = NULL; - server_conf_t *conf = NULL; - rpc_transport_t *xprt = NULL; - uint64_t total_read = 0; + server_conf_t *conf = NULL; + rpc_transport_t *xprt = NULL; + uint64_t total_read = 0; uint64_t total_write = 0; conf = frame->this->private; if (!conf || !dict) return 0; - for (pair = dict->members_list; pair; pair = pair->next) { - /* this exact key is used in 'io-stats' too. - * But this is better place for this information dump. - */ - if (fnmatch ("*io*stat*dump", pair->key, 0) == 0) { - list_for_each_entry (xprt, &conf->xprt_list, list) { - total_read += xprt->total_bytes_read; - total_write += xprt->total_bytes_write; - } - gf_log ("stats", GF_LOG_INFO, - "total-read %"PRIu64", total-write %"PRIu64, - total_read, total_write); + if (dict_foreach_fnmatch (dict, "*io*stat*dump", + dict_null_foreach_fn, NULL ) > 0) { + list_for_each_entry (xprt, &conf->xprt_list, list) { + total_read += xprt->total_bytes_read; + total_write += xprt->total_bytes_write; } + gf_log ("stats", GF_LOG_INFO, + "total-read %"PRIu64", total-write %"PRIu64, + total_read, total_write); } return 0; } + gf_boolean_t -server_cancel_conn_timer (xlator_t *this, server_connection_t *conn) +server_cancel_grace_timer (xlator_t *this, client_t *client) { - gf_timer_t *timer = NULL; - gf_boolean_t cancelled = _gf_false; + server_ctx_t *serv_ctx = NULL; + gf_timer_t *timer = NULL; + gf_boolean_t cancelled = _gf_false; - if (!this || !conn) { - gf_log (THIS->name, GF_LOG_ERROR, "Invalid arguments to " - "cancel connection timer"); + if (!this || !client) { + gf_log (THIS->name, GF_LOG_ERROR, + "Invalid arguments to cancel connection timer"); return cancelled; } - pthread_mutex_lock (&conn->lock); - { - if (!conn->timer) - goto unlock; + serv_ctx = server_ctx_get (client, client->this); - timer = conn->timer; - conn->timer = NULL; + if (serv_ctx == NULL) { + gf_log (this->name, GF_LOG_INFO, "server_ctx_get() failed"); + goto out; } -unlock: - pthread_mutex_unlock (&conn->lock); + + LOCK (&serv_ctx->fdtable_lock); + { + if (serv_ctx->grace_timer) { + timer = serv_ctx->grace_timer; + serv_ctx->grace_timer = NULL; + } + } + UNLOCK (&serv_ctx->fdtable_lock); if (timer) { gf_timer_call_cancel (this->ctx, timer); cancelled = _gf_true; } +out: return cancelled; } + +server_ctx_t* +server_ctx_get (client_t *client, xlator_t *xlator) +{ + void *tmp = NULL; + server_ctx_t *ctx = NULL; + + client_ctx_get (client, xlator, &tmp); + + ctx = tmp; + + if (ctx != NULL) + goto out; + + ctx = GF_CALLOC (1, sizeof (server_ctx_t), gf_server_mt_server_conf_t); + + if (ctx == NULL) + goto out; + + /* ctx->lk_version = 0; redundant */ + ctx->fdtable = gf_fd_fdtable_alloc (); + + if (ctx->fdtable == NULL) { + GF_FREE (ctx); + ctx = NULL; + goto out; + } + + LOCK_INIT (&ctx->fdtable_lock); + + if (client_ctx_set (client, xlator, ctx) != 0) { + LOCK_DESTROY (&ctx->fdtable_lock); + GF_FREE (ctx); + ctx = NULL; + } + +out: + return ctx; +} + +int32_t +gf_barrier_transmit (server_conf_t *conf, gf_barrier_payload_t *payload) +{ + gf_barrier_t *barrier = NULL; + int32_t ret = -1; + client_t *client = NULL; + gf_boolean_t lk_heal = _gf_false; + call_frame_t *frame = NULL; + server_state_t *state = NULL; + + GF_VALIDATE_OR_GOTO ("barrier", conf, out); + GF_VALIDATE_OR_GOTO ("barrier", conf->barrier, out); + GF_VALIDATE_OR_GOTO ("barrier", payload, out); + + barrier = conf->barrier; + + frame = payload->frame; + if (frame) { + state = CALL_STATE (frame); + frame->local = NULL; + client = frame->root->client; + } + /* currently lk fops are not barrier'ed. This is reflecting code in + * server_submit_reply */ + if (client) + lk_heal = ((server_conf_t *) client->this->private)->lk_heal; + + ret = rpcsvc_submit_generic (payload->req, &payload->rsp, 1, + payload->payload, payload->payload_count, + payload->iobref); + iobuf_unref (payload->iob); + if (ret == -1) { + gf_log_callingfn ("", GF_LOG_ERROR, "Reply submission failed"); + if (frame && client && !lk_heal) { + server_connection_cleanup (frame->this, client, + INTERNAL_LOCKS | POSIX_LOCKS); + } else { + /* TODO: Failure of open(dir), create, inodelk, entrylk + or lk fops send failure must be handled specially. */ + } + goto ret; + } + + ret = 0; +ret: + if (state) { + free_state (state); + } + + if (frame) { + gf_client_unref (client); + STACK_DESTROY (frame->root); + } + + if (payload->free_iobref) { + iobref_unref (payload->iobref); + } +out: + return ret; +} + +gf_barrier_payload_t * +gf_barrier_dequeue (gf_barrier_t *barrier) +{ + gf_barrier_payload_t *payload = NULL; + + if (!barrier || list_empty (&barrier->queue)) + return NULL; + + payload = list_entry (barrier->queue.next, + gf_barrier_payload_t, list); + if (payload) { + list_del_init (&payload->list); + barrier->cur_size--; + } + + return payload; +} + + +void* +gf_barrier_dequeue_start (void *data) +{ + server_conf_t *conf = NULL; + gf_barrier_t *barrier = NULL; + gf_barrier_payload_t *payload = NULL; + + conf = (server_conf_t *)data; + if (!conf || !conf->barrier) + return NULL; + barrier = conf->barrier; + + LOCK (&barrier->lock); + { + while (barrier->cur_size) { + payload = gf_barrier_dequeue (barrier); + if (payload) { + if (gf_barrier_transmit (conf, payload)) { + gf_log ("server", GF_LOG_WARNING, + "Failed to transmit"); + } + GF_FREE (payload); + } + } + } + UNLOCK (&barrier->lock); + return NULL; +} + +void +gf_barrier_timeout (void *data) +{ + server_conf_t *conf = NULL; + gf_barrier_t *barrier = NULL; + gf_boolean_t need_dequeue = _gf_false; + + conf = (server_conf_t *)data; + if (!conf || !conf->barrier) + goto out; + barrier = conf->barrier; + + gf_log ("", GF_LOG_INFO, "barrier timed-out"); + LOCK (&barrier->lock); + { + need_dequeue = barrier->on; + barrier->on = _gf_false; + } + UNLOCK (&barrier->lock); + + if (need_dequeue == _gf_true) + gf_barrier_dequeue_start (data); +out: + return; +} + + +int32_t +gf_barrier_start (xlator_t *this) +{ + server_conf_t *conf = NULL; + gf_barrier_t *barrier = NULL; + int32_t ret = -1; + struct timespec time = {0,}; + + conf = this->private; + + GF_VALIDATE_OR_GOTO ("server", this, out); + GF_VALIDATE_OR_GOTO (this->name, conf, out); + GF_VALIDATE_OR_GOTO (this->name, conf->barrier, out); + + barrier = conf->barrier; + + gf_log (this->name, GF_LOG_INFO, "barrier start called"); + LOCK (&barrier->lock); + { + /* if barrier is on, reset timer */ + if (barrier->on == _gf_true) { + ret = gf_timer_call_cancel (this->ctx, barrier->timer); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, "Failed to " + "unset timer, failing barrier start"); + goto unlock; + } + } + + barrier->on = _gf_true; + time.tv_sec = barrier->time_out; + time.tv_nsec = 0; + + barrier->timer = gf_timer_call_after (this->ctx, time, + gf_barrier_timeout, + (void *)conf); + if (!barrier->timer) { + gf_log (this->name, GF_LOG_ERROR, "Failed to set " + "timer, failing barrier start"); + barrier->on = _gf_false; + } + } +unlock: + UNLOCK (&barrier->lock); + + ret = 0; +out: + return ret; +} + +int32_t +gf_barrier_stop (xlator_t *this) +{ + server_conf_t *conf = NULL; + gf_barrier_t *barrier = NULL; + int32_t ret = -1; + gf_boolean_t need_dequeue = _gf_false; + + conf = this->private; + + GF_VALIDATE_OR_GOTO ("server", this, out); + GF_VALIDATE_OR_GOTO (this->name, conf, out); + GF_VALIDATE_OR_GOTO (this->name, conf->barrier, out); + + barrier = conf->barrier; + + gf_log (this->name, GF_LOG_INFO, "barrier stop called"); + LOCK (&barrier->lock); + { + need_dequeue = barrier->on; + barrier->on = _gf_false; + } + UNLOCK (&barrier->lock); + + if (need_dequeue == _gf_true) { + gf_timer_call_cancel (this->ctx, barrier->timer); + ret = gf_thread_create (&conf->barrier_th, NULL, + gf_barrier_dequeue_start, + conf); + if (ret) { + gf_log (this->name, GF_LOG_CRITICAL, + "Failed to start un-barriering"); + goto out; + } + } + ret = 0; +out: + return ret; +} + +int32_t +gf_barrier_fops_configure (xlator_t *this, gf_barrier_t *barrier, char *str) +{ + int32_t ret = -1; + char *dup_str = NULL; + char *str_tok = NULL; + char *save_ptr = NULL; + uint64_t fops = 0; + + /* by defaul fsync & flush needs to be barriered */ + + fops |= 1 << GFS3_OP_FSYNC; + fops |= 1 << GFS3_OP_FLUSH; + + if (!str) + goto done; + + dup_str = gf_strdup (str); + if (!dup_str) + goto done; + + str_tok = strtok_r (dup_str, ",", &save_ptr); + if (!str_tok) + goto done; + + fops = 0; + while (str_tok) { + if (!strcmp(str_tok, "writev")) { + fops |= ((uint64_t)1 << GFS3_OP_WRITE); + } else if (!strcmp(str_tok, "fsync")) { + fops |= ((uint64_t)1 << GFS3_OP_FSYNC); + } else if (!strcmp(str_tok, "read")) { + fops |= ((uint64_t)1 << GFS3_OP_READ); + } else if (!strcmp(str_tok, "rename")) { + fops |= ((uint64_t)1 << GFS3_OP_RENAME); + } else if (!strcmp(str_tok, "flush")) { + fops |= ((uint64_t)1 << GFS3_OP_FLUSH); + } else if (!strcmp(str_tok, "ftruncate")) { + fops |= ((uint64_t)1 << GFS3_OP_FTRUNCATE); + } else if (!strcmp(str_tok, "fallocate")) { + fops |= ((uint64_t)1 << GFS3_OP_FALLOCATE); + } else if (!strcmp(str_tok, "rmdir")) { + fops |= ((uint64_t)1 << GFS3_OP_RMDIR); + } else { + gf_log ("barrier", GF_LOG_ERROR, + "Invalid barrier fop %s", str_tok); + } + + str_tok = strtok_r (NULL, ",", &save_ptr); + } +done: + LOCK (&barrier->lock); + { + barrier->fops = fops; + } + UNLOCK (&barrier->lock); + ret = 0; + + GF_FREE (dup_str); + return ret; +} + +void +gf_barrier_enqueue (gf_barrier_t *barrier, gf_barrier_payload_t *payload) +{ + list_add_tail (&payload->list, &barrier->queue); + barrier->cur_size++; +} + +gf_barrier_payload_t * +gf_barrier_payload (rpcsvc_request_t *req, struct iovec *rsp, + call_frame_t *frame, struct iovec *payload_orig, + int payloadcount, struct iobref *iobref, + struct iobuf *iob, gf_boolean_t free_iobref) +{ + gf_barrier_payload_t *payload = NULL; + + if (!rsp) + return NULL; + + payload = GF_CALLOC (1, sizeof (*payload),1); + if (!payload) + return NULL; + + INIT_LIST_HEAD (&payload->list); + + payload->req = req; + memcpy (&payload->rsp, rsp, sizeof (struct iovec)); + payload->frame = frame; + payload->payload = payload_orig; + payload->payload_count = payloadcount; + payload->iobref = iobref; + payload->iob = iob; + payload->free_iobref = free_iobref; + + return payload; +} diff --git a/xlators/protocol/server/src/server-helpers.h b/xlators/protocol/server/src/server-helpers.h index 5ce5e36ac..b455aa6df 100644 --- a/xlators/protocol/server/src/server-helpers.h +++ b/xlators/protocol/server/src/server-helpers.h @@ -1,20 +1,11 @@ /* - Copyright (c) 2010-2011 Gluster, Inc. <http://www.gluster.com> + Copyright (c) 2010-2013 Red Hat, Inc. <http://www.redhat.com> This file is part of GlusterFS. - GlusterFS is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 3 of the License, - or (at your option) any later version. - - GlusterFS is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see - <http://www.gnu.org/licenses/>. + This file is licensed to you under your choice of the GNU Lesser + General Public License, version 3 or any later version (LGPLv3 or + later), or the GNU General Public License, version 2 (GPLv2), in all + cases as published by the Free Software Foundation. */ #ifndef _SERVER_HELPERS_H @@ -24,13 +15,8 @@ #define CALL_STATE(frame) ((server_state_t *)frame->root->state) -#define BOUND_XL(frame) ((xlator_t *) CALL_STATE(frame)->conn->bound_xl) - #define XPRT_FROM_FRAME(frame) ((rpc_transport_t *) CALL_STATE(frame)->xprt) -#define SERVER_CONNECTION(frame) \ - ((server_connection_t *) CALL_STATE(frame)->conn) - #define SERVER_CONF(frame) \ ((server_conf_t *)XPRT_FROM_FRAME(frame)->this->private) @@ -43,45 +29,26 @@ #define IS_NOT_ROOT(pathlen) ((pathlen > 2)? 1 : 0) +#define is_fop_barriered(fops, procnum) (fops & ((uint64_t)1 << procnum)) + +#define barrier_add_to_queue(barrier) (barrier->on || barrier->cur_size) + void free_state (server_state_t *state); void server_loc_wipe (loc_t *loc); -int32_t -gf_add_locker (server_connection_t *conn, const char *volume, - loc_t *loc, - fd_t *fd, - pid_t pid, - gf_lkowner_t *owner, - glusterfs_fop_t type); - -int32_t -gf_del_locker (server_connection_t *conn, const char *volume, - loc_t *loc, - fd_t *fd, - gf_lkowner_t *owner, - glusterfs_fop_t type); - void server_print_request (call_frame_t *frame); call_frame_t * get_frame_from_request (rpcsvc_request_t *req); -gf_boolean_t -server_cancel_conn_timer (xlator_t *this, server_connection_t *conn); - -void -put_server_conn_state (xlator_t *this, rpc_transport_t *xprt); - -server_connection_t * -get_server_conn_state (xlator_t *this, rpc_transport_t *xptr); - -server_connection_t * -create_server_conn_state (xlator_t *this, rpc_transport_t *xptr); +int +server_connection_cleanup (xlator_t *this, struct _client_t *client, + int32_t flags); -void -destroy_server_conn_state (server_connection_t *conn); +gf_boolean_t +server_cancel_grace_timer (xlator_t *this, struct _client_t *client); int server_build_config (xlator_t *this, server_conf_t *conf); @@ -91,4 +58,17 @@ int serialize_rsp_direntp (gf_dirent_t *entries, gfs3_readdirp_rsp *rsp); int readdirp_rsp_cleanup (gfs3_readdirp_rsp *rsp); int readdir_rsp_cleanup (gfs3_readdir_rsp *rsp); +server_ctx_t *server_ctx_get (client_t *client, xlator_t *xlator); + +int32_t gf_barrier_start (xlator_t *this); +int32_t gf_barrier_stop (xlator_t *this); +int32_t gf_barrier_fops_configure (xlator_t *this, gf_barrier_t *barrier, + char *str); +void gf_barrier_enqueue (gf_barrier_t *barrier, gf_barrier_payload_t *stub); +gf_barrier_payload_t * +gf_barrier_payload (rpcsvc_request_t *req, struct iovec *rsp, + call_frame_t *frame, struct iovec *payload, + int payloadcount, struct iobref *iobref, + struct iobuf *iob, gf_boolean_t free_iobref); + #endif /* !_SERVER_HELPERS_H */ diff --git a/xlators/protocol/server/src/server-mem-types.h b/xlators/protocol/server/src/server-mem-types.h index 5438ed6db..19c3466d3 100644 --- a/xlators/protocol/server/src/server-mem-types.h +++ b/xlators/protocol/server/src/server-mem-types.h @@ -1,20 +1,11 @@ /* - Copyright (c) 2010-2011 Gluster, Inc. <http://www.gluster.com> + Copyright (c) 2010-2013 Red Hat, Inc. <http://www.redhat.com> This file is part of GlusterFS. - GlusterFS is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 3 of the License, - or (at your option) any later version. - - GlusterFS is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see - <http://www.gnu.org/licenses/>. + This file is licensed to you under your choice of the GNU Lesser + General Public License, version 3 or any later version (LGPLv3 or + later), or the GNU General Public License, version 2 (GPLv2), in all + cases as published by the Free Software Foundation. */ diff --git a/xlators/protocol/server/src/server-resolve.c b/xlators/protocol/server/src/server-resolve.c index e44fc2de3..cc4686a03 100644 --- a/xlators/protocol/server/src/server-resolve.c +++ b/xlators/protocol/server/src/server-resolve.c @@ -1,20 +1,11 @@ /* - Copyright (c) 2010-2011 Gluster, Inc. <http://www.gluster.com> + Copyright (c) 2010-2013 Red Hat, Inc. <http://www.redhat.com> This file is part of GlusterFS. - GlusterFS is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 3 of the License, - or (at your option) any later version. - - GlusterFS is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see - <http://www.gnu.org/licenses/>. + This file is licensed to you under your choice of the GNU Lesser + General Public License, version 3 or any later version (LGPLv3 or + later), or the GNU General Public License, version 2 (GPLv2), in all + cases as published by the Free Software Foundation. */ #ifndef _CONFIG_H @@ -156,7 +147,8 @@ resolve_gfid_cbk (call_frame_t *frame, void *cookie, xlator_t *this, (char **) &resolve_loc->path); STACK_WIND (frame, resolve_gfid_entry_cbk, - BOUND_XL (frame), BOUND_XL (frame)->fops->lookup, + frame->root->client->bound_xl, + frame->root->client->bound_xl->fops->lookup, &resolve->resolve_loc, NULL); return 0; out: @@ -188,7 +180,8 @@ resolve_gfid (call_frame_t *frame) ret = loc_path (resolve_loc, NULL); STACK_WIND (frame, resolve_gfid_cbk, - BOUND_XL (frame), BOUND_XL (frame)->fops->lookup, + frame->root->client->bound_xl, + frame->root->client->bound_xl->fops->lookup, &resolve->resolve_loc, NULL); return 0; } @@ -422,6 +415,10 @@ out: if (inode) inode_unref (inode); + if (ret != 0) + gf_log ("server", GF_LOG_WARNING, "inode for the gfid (%s) is " + "not found. anonymous fd creation failed", + uuid_utoa (resolve->gfid)); return ret; } @@ -454,23 +451,34 @@ server_resolve_anonfd (call_frame_t *frame) int server_resolve_fd (call_frame_t *frame) { - server_state_t *state = NULL; - server_resolve_t *resolve = NULL; - server_connection_t *conn = NULL; - uint64_t fd_no = -1; + server_ctx_t *serv_ctx = NULL; + server_state_t *state = NULL; + client_t *client = NULL; + server_resolve_t *resolve = NULL; + uint64_t fd_no = -1; state = CALL_STATE (frame); resolve = state->resolve_now; - conn = SERVER_CONNECTION (frame); fd_no = resolve->fd_no; - if (fd_no == -2) { + if (fd_no == GF_ANON_FD_NO) { server_resolve_anonfd (frame); return 0; } - state->fd = gf_fd_fdptr_get (conn->fdtable, fd_no); + client = frame->root->client; + + serv_ctx = server_ctx_get (client, client->this); + + if (serv_ctx == NULL) { + gf_log ("", GF_LOG_INFO, "server_ctx_get() failed"); + resolve->op_ret = -1; + resolve->op_errno = ENOMEM; + return 0; + } + + state->fd = gf_fd_fdptr_get (serv_ctx->fdtable, fd_no); if (!state->fd) { gf_log ("", GF_LOG_INFO, "fd not found in context"); @@ -525,14 +533,12 @@ int server_resolve_done (call_frame_t *frame) { server_state_t *state = NULL; - xlator_t *bound_xl = NULL; state = CALL_STATE (frame); - bound_xl = BOUND_XL (frame); server_print_request (frame); - state->resume_fn (frame, bound_xl); + state->resume_fn (frame, frame->root->client->bound_xl); return 0; } diff --git a/xlators/protocol/server/src/server3_1-fops.c b/xlators/protocol/server/src/server-rpc-fops.c index 166f72094..138e601ce 100644 --- a/xlators/protocol/server/src/server3_1-fops.c +++ b/xlators/protocol/server/src/server-rpc-fops.c @@ -1,20 +1,11 @@ /* - Copyright (c) 2010-2011 Gluster, Inc. <http://www.gluster.com> + Copyright (c) 2010-2013 Red Hat, Inc. <http://www.redhat.com> This file is part of GlusterFS. - GlusterFS is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 3 of the License, - or (at your option) any later version. - - GlusterFS is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see - <http://www.gnu.org/licenses/>. + This file is licensed to you under your choice of the GNU Lesser + General Public License, version 3 or any later version (LGPLv3 or + later), or the GNU General Public License, version 2 (GPLv2), in all + cases as published by the Free Software Foundation. */ @@ -33,6 +24,11 @@ #include "xdr-nfs3.h" +#define SERVER_REQ_SET_ERROR(req, ret) \ + do { \ + rpcsvc_request_seterr (req, GARBAGE_ARGS); \ + ret = RPCSVC_ACTOR_ERROR; \ + } while (0) /* Callback function section */ int @@ -40,32 +36,29 @@ server_statfs_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct statvfs *buf, dict_t *xdata) { - gfs3_statfs_rsp rsp = {0,}; - rpcsvc_request_t *req = NULL; + gfs3_statfs_rsp rsp = {0,}; + rpcsvc_request_t *req = NULL; - req = frame->local; + GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val, + rsp.xdata.xdata_len, op_errno, out); - if (op_ret >= 0) { - gf_statfs_from_statfs (&rsp.statfs, buf); - } else { - gf_log (this->name, GF_LOG_INFO, - "%"PRId64": STATFS %"PRId32" (%s)", - frame->root->unique, op_ret, strerror (op_errno)); + if (op_ret < 0) { + gf_log (this->name, GF_LOG_WARNING, "%"PRId64": STATFS (%s)", + frame->root->unique, strerror (op_errno)); + goto out; } - GF_PROTOCOL_DICT_SERIALIZE (this, xdata, (&rsp.xdata.xdata_val), - rsp.xdata.xdata_len, op_errno, out); + gf_statfs_from_statfs (&rsp.statfs, buf); out: rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error (op_errno); - + req = frame->local; server_submit_reply (frame, req, &rsp, NULL, 0, NULL, (xdrproc_t)xdr_gfs3_statfs_rsp); - if (rsp.xdata.xdata_val) - GF_FREE (rsp.xdata.xdata_val); + GF_FREE (rsp.xdata.xdata_val); return 0; } @@ -76,17 +69,15 @@ server_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this, inode_t *inode, struct iatt *stbuf, dict_t *xdata, struct iatt *postparent) { - rpcsvc_request_t *req = NULL; - server_state_t *state = NULL; - inode_t *root_inode = NULL; - inode_t *link_inode = NULL; - loc_t fresh_loc = {0,}; - gfs3_lookup_rsp rsp = {0,}; - uuid_t rootgfid = {0,}; - - state = CALL_STATE(frame); + rpcsvc_request_t *req = NULL; + server_state_t *state = NULL; + inode_t *root_inode = NULL; + inode_t *link_inode = NULL; + loc_t fresh_loc = {0,}; + gfs3_lookup_rsp rsp = {0,}; + uuid_t rootgfid = {0,}; - req = frame->local; + state = CALL_STATE (frame); if (state->is_revalidate == 1 && op_ret == -1) { state->is_revalidate = 2; @@ -94,8 +85,9 @@ server_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this, inode_unref (fresh_loc.inode); fresh_loc.inode = inode_new (state->itable); - STACK_WIND (frame, server_lookup_cbk, BOUND_XL (frame), - BOUND_XL (frame)->fops->lookup, + STACK_WIND (frame, server_lookup_cbk, + frame->root->client->bound_xl, + frame->root->client->bound_xl->fops->lookup, &fresh_loc, state->xdata); loc_wipe (&fresh_loc); @@ -104,58 +96,70 @@ server_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this, gf_stat_from_iatt (&rsp.postparent, postparent); - if (op_ret == 0) { - root_inode = BOUND_XL(frame)->itable->root; - if (inode == root_inode) { - /* we just looked up root ("/") */ - stbuf->ia_ino = 1; - rootgfid[15] = 1; - uuid_copy (stbuf->ia_gfid, rootgfid); - if (inode->ia_type == 0) - inode->ia_type = stbuf->ia_type; - } - - gf_stat_from_iatt (&rsp.stat, stbuf); + GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val, + rsp.xdata.xdata_len, op_errno, out); - if (!__is_root_gfid (inode->gfid)) { - link_inode = inode_link (inode, state->loc.parent, - state->loc.name, stbuf); - if (link_inode) { - inode_lookup (link_inode); - inode_unref (link_inode); - } - } - } else { + if (op_ret) { if (state->is_revalidate && op_errno == ENOENT) { - if (!__is_root_gfid (state->loc.inode->gfid)) { + if (!__is_root_gfid (state->resolve.gfid)) { inode_unlink (state->loc.inode, state->loc.parent, state->loc.name); } } + goto out; } - GF_PROTOCOL_DICT_SERIALIZE (this, xdata, (&rsp.xdata.xdata_val), - rsp.xdata.xdata_len, op_errno, out); + root_inode = frame->root->client->bound_xl->itable->root; + if (inode == root_inode) { + /* we just looked up root ("/") */ + stbuf->ia_ino = 1; + rootgfid[15] = 1; + uuid_copy (stbuf->ia_gfid, rootgfid); + if (inode->ia_type == 0) + inode->ia_type = stbuf->ia_type; + } + + gf_stat_from_iatt (&rsp.stat, stbuf); + + if (!__is_root_gfid (inode->gfid)) { + link_inode = inode_link (inode, state->loc.parent, + state->loc.name, stbuf); + if (link_inode) { + inode_lookup (link_inode); + inode_unref (link_inode); + } + } out: rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error (op_errno); if (op_ret) { - gf_log (this->name, - ((op_errno == ENOENT) ? GF_LOG_TRACE : GF_LOG_INFO), - "%"PRId64": LOOKUP %s (%s) ==> %"PRId32" (%s)", - frame->root->unique, state->loc.path, - state->loc.inode ? uuid_utoa (state->loc.inode->gfid) : - "--", op_ret, strerror (op_errno)); + if (state->resolve.bname) { + gf_log (this->name, ((op_errno == ENOENT) ? + GF_LOG_TRACE : GF_LOG_INFO), + "%"PRId64": LOOKUP %s (%s/%s) ==> " + "(%s)", frame->root->unique, + state->loc.path, + uuid_utoa (state->resolve.pargfid), + state->resolve.bname, + strerror (op_errno)); + } else { + gf_log (this->name, ((op_errno == ENOENT) ? + GF_LOG_TRACE : GF_LOG_INFO), + "%"PRId64": LOOKUP %s (%s) ==> (%s)", + frame->root->unique, state->loc.path, + uuid_utoa (state->resolve.gfid), + strerror (op_errno)); + } } + req = frame->local; server_submit_reply (frame, req, &rsp, NULL, 0, NULL, (xdrproc_t)xdr_gfs3_lookup_rsp); - if (rsp.xdata.xdata_val) - GF_FREE (rsp.xdata.xdata_val); + GF_FREE (rsp.xdata.xdata_val); return 0; } @@ -166,52 +170,53 @@ server_lk_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct gf_flock *lock, dict_t *xdata) { - gfs3_lk_rsp rsp = {0,}; - rpcsvc_request_t *req = NULL; - server_state_t *state = NULL; - - req = frame->local; + gfs3_lk_rsp rsp = {0,}; + rpcsvc_request_t *req = NULL; + server_state_t *state = NULL; - GF_PROTOCOL_DICT_SERIALIZE (this, xdata, (&rsp.xdata.xdata_val), + GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val, rsp.xdata.xdata_len, op_errno, out); - state = CALL_STATE(frame); - - if (op_ret == 0) { - switch (lock->l_type) { - case F_RDLCK: - lock->l_type = GF_LK_F_RDLCK; - break; - case F_WRLCK: - lock->l_type = GF_LK_F_WRLCK; - break; - case F_UNLCK: - lock->l_type = GF_LK_F_UNLCK; - break; - default: - gf_log (this->name, GF_LOG_ERROR, - "Unknown lock type: %"PRId32"!", lock->l_type); - break; + if (op_ret) { + if ((op_errno != ENOSYS) && (op_errno != EAGAIN)) { + state = CALL_STATE (frame); + gf_log (this->name, GF_LOG_INFO, + "%"PRId64": LK %"PRId64" (%s) ==> " + "(%s)", frame->root->unique, + state->resolve.fd_no, + uuid_utoa (state->resolve.gfid), + strerror (op_errno)); } + goto out; + } - gf_proto_flock_from_flock (&rsp.flock, lock); - } else if ((op_errno != ENOSYS) && (op_errno != EAGAIN)) { - gf_log (this->name, GF_LOG_INFO, - "%"PRId64": LK %"PRId64" (%s) ==> %"PRId32" (%s)", - frame->root->unique, state->resolve.fd_no, - state->fd ? uuid_utoa (state->fd->inode->gfid) : "--", - op_ret, strerror (op_errno)); + switch (lock->l_type) { + case F_RDLCK: + lock->l_type = GF_LK_F_RDLCK; + break; + case F_WRLCK: + lock->l_type = GF_LK_F_WRLCK; + break; + case F_UNLCK: + lock->l_type = GF_LK_F_UNLCK; + break; + default: + gf_log (this->name, GF_LOG_ERROR, + "Unknown lock type: %"PRId32"!", lock->l_type); + break; } + gf_proto_flock_from_flock (&rsp.flock, lock); + out: rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error (op_errno); + req = frame->local; server_submit_reply (frame, req, &rsp, NULL, 0, NULL, (xdrproc_t)xdr_gfs3_lk_rsp); - if (rsp.xdata.xdata_val) - GF_FREE (rsp.xdata.xdata_val); + GF_FREE (rsp.xdata.xdata_val); return 0; } @@ -221,46 +226,36 @@ int server_inodelk_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { - gf_common_rsp rsp = {0,}; - server_connection_t *conn = NULL; - server_state_t *state = NULL; - rpcsvc_request_t *req = NULL; + gf_common_rsp rsp = {0,}; + server_state_t *state = NULL; + rpcsvc_request_t *req = NULL; - req = frame->local; - - GF_PROTOCOL_DICT_SERIALIZE (this, xdata, (&rsp.xdata.xdata_val), + GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val, rsp.xdata.xdata_len, op_errno, out); - conn = SERVER_CONNECTION(frame); - state = CALL_STATE(frame); + state = CALL_STATE (frame); - if (op_ret >= 0) { - if (state->flock.l_type == F_UNLCK) - gf_del_locker (conn, state->volume, - &state->loc, NULL, &frame->root->lk_owner, - GF_FOP_INODELK); - else - gf_add_locker (conn, state->volume, - &state->loc, NULL, frame->root->pid, - &frame->root->lk_owner, - GF_FOP_INODELK); - } else if ((op_errno != ENOSYS) && (op_errno != EAGAIN)) { - gf_log (this->name, GF_LOG_INFO, - "%"PRId64": INODELK %s (%s) ==> %"PRId32" (%s)", - frame->root->unique, state->loc.path, - state->loc.inode ? uuid_utoa (state->loc.inode->gfid) : - "--", op_ret, strerror (op_errno)); + if (op_ret < 0) { + if ((op_errno != ENOSYS) && (op_errno != EAGAIN)) { + gf_log (this->name, (op_errno == ENOENT)? + GF_LOG_DEBUG:GF_LOG_ERROR, + "%"PRId64": INODELK %s (%s) ==> (%s)", + frame->root->unique, state->loc.path, + uuid_utoa (state->resolve.gfid), + strerror (op_errno)); + } + goto out; } out: rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error (op_errno); + req = frame->local; server_submit_reply (frame, req, &rsp, NULL, 0, NULL, (xdrproc_t)xdr_gf_common_rsp); - if (rsp.xdata.xdata_val) - GF_FREE (rsp.xdata.xdata_val); + GF_FREE (rsp.xdata.xdata_val); return 0; } @@ -270,46 +265,36 @@ int server_finodelk_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { - gf_common_rsp rsp = {0,}; - server_state_t *state = NULL; - server_connection_t *conn = NULL; - rpcsvc_request_t *req = NULL; + gf_common_rsp rsp = {0,}; + server_state_t *state = NULL; + rpcsvc_request_t *req = NULL; - req = frame->local; + GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val, + rsp.xdata.xdata_len, op_errno, out); - conn = SERVER_CONNECTION(frame); - state = CALL_STATE(frame); + state = CALL_STATE (frame); - if (op_ret >= 0) { - if (state->flock.l_type == F_UNLCK) - gf_del_locker (conn, state->volume, - NULL, state->fd, - &frame->root->lk_owner, GF_FOP_INODELK); - else - gf_add_locker (conn, state->volume, - NULL, state->fd, - frame->root->pid, - &frame->root->lk_owner, GF_FOP_INODELK); - } else if ((op_errno != ENOSYS) && (op_errno != EAGAIN)) { - gf_log (this->name, GF_LOG_INFO, - "%"PRId64": FINODELK %"PRId64" (%s) ==> %"PRId32" (%s)", - frame->root->unique, state->resolve.fd_no, - state->fd ? uuid_utoa (state->fd->inode->gfid) : "--", - op_ret, strerror (op_errno)); + if (op_ret < 0) { + if ((op_errno != ENOSYS) && (op_errno != EAGAIN)) { + gf_log (this->name, GF_LOG_INFO, + "%"PRId64": FINODELK %"PRId64" (%s) " + "==> (%s)", frame->root->unique, + state->resolve.fd_no, + uuid_utoa (state->resolve.gfid), + strerror (op_errno)); + } + goto out; } - GF_PROTOCOL_DICT_SERIALIZE (this, xdata, (&rsp.xdata.xdata_val), - rsp.xdata.xdata_len, op_errno, out); - out: rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error (op_errno); + req = frame->local; server_submit_reply (frame, req, &rsp, NULL, 0, NULL, (xdrproc_t)xdr_gf_common_rsp); - if (rsp.xdata.xdata_val) - GF_FREE (rsp.xdata.xdata_val); + GF_FREE (rsp.xdata.xdata_val); return 0; } @@ -318,46 +303,35 @@ int server_entrylk_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { - server_connection_t *conn = NULL; - server_state_t *state = NULL; - rpcsvc_request_t *req = NULL; - gf_common_rsp rsp = {0,}; + gf_common_rsp rsp = {0,}; + server_state_t *state = NULL; + rpcsvc_request_t *req = NULL; - req = frame->local; + GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val, + rsp.xdata.xdata_len, op_errno, out); - conn = SERVER_CONNECTION(frame); - state = CALL_STATE(frame); + state = CALL_STATE (frame); - if (op_ret >= 0) { - if (state->cmd == ENTRYLK_UNLOCK) - gf_del_locker (conn, state->volume, - &state->loc, NULL, &frame->root->lk_owner, - GF_FOP_ENTRYLK); - else - gf_add_locker (conn, state->volume, - &state->loc, NULL, frame->root->pid, - &frame->root->lk_owner, - GF_FOP_ENTRYLK); - } else if ((op_errno != ENOSYS) && (op_errno != EAGAIN)) { - gf_log (this->name, GF_LOG_INFO, - "%"PRId64": ENTRYLK %s (%s) ==> %"PRId32" (%s)", - frame->root->unique, state->loc.path, - state->loc.inode ? uuid_utoa (state->loc.inode->gfid) : - "--", op_ret, strerror (op_errno)); + if (op_ret < 0) { + if ((op_errno != ENOSYS) && (op_errno != EAGAIN)) { + gf_log (this->name, GF_LOG_INFO, + "%"PRId64": ENTRYLK %s (%s) ==> (%s)", + frame->root->unique, state->loc.path, + uuid_utoa (state->resolve.gfid), + strerror (op_errno)); + } + goto out; } - GF_PROTOCOL_DICT_SERIALIZE (this, xdata, (&rsp.xdata.xdata_val), - rsp.xdata.xdata_len, op_errno, out); - out: rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error (op_errno); + req = frame->local; server_submit_reply (frame, req, &rsp, NULL, 0, NULL, (xdrproc_t)xdr_gf_common_rsp); - if (rsp.xdata.xdata_val) - GF_FREE (rsp.xdata.xdata_val); + GF_FREE (rsp.xdata.xdata_val); return 0; } @@ -367,44 +341,35 @@ int server_fentrylk_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { - gf_common_rsp rsp = {0,}; - server_connection_t *conn = NULL; - server_state_t *state = NULL; - rpcsvc_request_t *req = NULL; + gf_common_rsp rsp = {0,}; + server_state_t *state = NULL; + rpcsvc_request_t *req = NULL; - req = frame->local; - conn = SERVER_CONNECTION(frame); - state = CALL_STATE(frame); - if (op_ret >= 0) { - if (state->cmd == ENTRYLK_UNLOCK) - gf_del_locker (conn, state->volume, - NULL, state->fd, &frame->root->lk_owner, - GF_FOP_ENTRYLK); - else - gf_add_locker (conn, state->volume, - NULL, state->fd, frame->root->pid, - &frame->root->lk_owner, GF_FOP_ENTRYLK); - } else if ((op_errno != ENOSYS) && (op_errno != EAGAIN)) { - gf_log (this->name, GF_LOG_INFO, - "%"PRId64": FENTRYLK %"PRId64" (%s) " - " ==> %"PRId32" (%s)", - frame->root->unique, state->resolve.fd_no, - state->fd ? uuid_utoa (state->fd->inode->gfid) : "--", - op_ret, strerror (op_errno)); - } - - GF_PROTOCOL_DICT_SERIALIZE (this, xdata, (&rsp.xdata.xdata_val), + GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val, rsp.xdata.xdata_len, op_errno, out); + state = CALL_STATE (frame); + + if (op_ret < 0) { + if ((op_errno != ENOSYS) && (op_errno != EAGAIN)) { + gf_log (this->name, GF_LOG_INFO, + "%"PRId64": FENTRYLK %"PRId64" (%s) ==>(%s)", + frame->root->unique, state->resolve.fd_no, + uuid_utoa (state->resolve.gfid), + strerror (op_errno)); + } + goto out; + } + out: rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error (op_errno); + req = frame->local; server_submit_reply (frame, req, &rsp, NULL, 0, NULL, (xdrproc_t)xdr_gf_common_rsp); - if (rsp.xdata.xdata_val) - GF_FREE (rsp.xdata.xdata_val); + GF_FREE (rsp.xdata.xdata_val); return 0; } @@ -414,33 +379,32 @@ int server_access_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { - gf_common_rsp rsp = {0,}; - rpcsvc_request_t *req = NULL; - server_state_t *state = NULL; - - req = frame->local; + gf_common_rsp rsp = {0,}; + rpcsvc_request_t *req = NULL; + server_state_t *state = NULL; - state = CALL_STATE(frame); + GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val, + rsp.xdata.xdata_len, op_errno, out); - if (op_ret) + if (op_ret) { + state = CALL_STATE (frame); gf_log (this->name, GF_LOG_INFO, - "%"PRId64": ACCESS %s (%s) ==> %"PRId32" (%s)", + "%"PRId64": ACCESS %s (%s) ==> (%s)", frame->root->unique, state->loc.path, - state->loc.inode ? uuid_utoa (state->loc.inode->gfid) : - "--", op_ret, strerror (op_errno)); - - GF_PROTOCOL_DICT_SERIALIZE (this, xdata, (&rsp.xdata.xdata_val), - rsp.xdata.xdata_len, op_errno, out); + uuid_utoa (state->resolve.gfid), + strerror (op_errno)); + goto out; + } out: rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error (op_errno); + req = frame->local; server_submit_reply (frame, req, &rsp, NULL, 0, NULL, (xdrproc_t)xdr_gf_common_rsp); - if (rsp.xdata.xdata_val) - GF_FREE (rsp.xdata.xdata_val); + GF_FREE (rsp.xdata.xdata_val); return 0; } @@ -450,50 +414,49 @@ server_rmdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { - gfs3_rmdir_rsp rsp = {0,}; - server_state_t *state = NULL; - inode_t *parent = NULL; - rpcsvc_request_t *req = NULL; + gfs3_rmdir_rsp rsp = {0,}; + server_state_t *state = NULL; + inode_t *parent = NULL; + rpcsvc_request_t *req = NULL; - req = frame->local; + GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val, + rsp.xdata.xdata_len, op_errno, out); - state = CALL_STATE(frame); - - if (op_ret == 0) { - inode_unlink (state->loc.inode, state->loc.parent, - state->loc.name); - parent = inode_parent (state->loc.inode, 0, NULL); - if (parent) - /* parent should not be found for directories after - * inode_unlink, since directories cannot have - * hardlinks. - */ - inode_unref (parent); - else - inode_forget (state->loc.inode, 0); + state = CALL_STATE (frame); - gf_stat_from_iatt (&rsp.preparent, preparent); - gf_stat_from_iatt (&rsp.postparent, postparent); - } else { + if (op_ret) { gf_log (this->name, GF_LOG_INFO, - "%"PRId64": RMDIR %s (%s) ==> %"PRId32" (%s)", + "%"PRId64": RMDIR %s (%s/%s) ==> (%s)", frame->root->unique, state->loc.path, - state->loc.inode ? uuid_utoa (state->loc.inode->gfid) : - "--", op_ret, strerror (op_errno)); + uuid_utoa (state->resolve.pargfid), + state->resolve.bname, strerror (op_errno)); + goto out; } - GF_PROTOCOL_DICT_SERIALIZE (this, xdata, (&rsp.xdata.xdata_val), - rsp.xdata.xdata_len, op_errno, out); + inode_unlink (state->loc.inode, state->loc.parent, + state->loc.name); + parent = inode_parent (state->loc.inode, 0, NULL); + if (parent) + /* parent should not be found for directories after + * inode_unlink, since directories cannot have + * hardlinks. + */ + inode_unref (parent); + else + inode_forget (state->loc.inode, 0); + + gf_stat_from_iatt (&rsp.preparent, preparent); + gf_stat_from_iatt (&rsp.postparent, postparent); out: rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error (op_errno); + req = frame->local; server_submit_reply (frame, req, &rsp, NULL, 0, NULL, (xdrproc_t)xdr_gfs3_rmdir_rsp); - if (rsp.xdata.xdata_val) - GF_FREE (rsp.xdata.xdata_val); + GF_FREE (rsp.xdata.xdata_val); return 0; } @@ -504,43 +467,43 @@ server_mkdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this, struct iatt *stbuf, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { - gfs3_mkdir_rsp rsp = {0,}; - server_state_t *state = NULL; - inode_t *link_inode = NULL; - rpcsvc_request_t *req = NULL; + gfs3_mkdir_rsp rsp = {0,}; + server_state_t *state = NULL; + inode_t *link_inode = NULL; + rpcsvc_request_t *req = NULL; - req = frame->local; + GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val, + rsp.xdata.xdata_len, op_errno, out); - state = CALL_STATE(frame); - if (op_ret >= 0) { - gf_stat_from_iatt (&rsp.stat, stbuf); - gf_stat_from_iatt (&rsp.preparent, preparent); - gf_stat_from_iatt (&rsp.postparent, postparent); + state = CALL_STATE (frame); - link_inode = inode_link (inode, state->loc.parent, - state->loc.name, stbuf); - inode_lookup (link_inode); - inode_unref (link_inode); - } else { + if (op_ret < 0) { gf_log (this->name, GF_LOG_INFO, - "%"PRId64": MKDIR %s (%s) ==> %"PRId32" (%s)", + "%"PRId64": MKDIR %s (%s/%s) ==> (%s)", frame->root->unique, state->loc.path, - state->loc.inode ? uuid_utoa (state->loc.inode->gfid) : - "--",op_ret, strerror (op_errno)); + uuid_utoa (state->resolve.pargfid), + state->resolve.bname, strerror (op_errno)); + goto out; } - GF_PROTOCOL_DICT_SERIALIZE (this, xdata, (&rsp.xdata.xdata_val), - rsp.xdata.xdata_len, op_errno, out); + gf_stat_from_iatt (&rsp.stat, stbuf); + gf_stat_from_iatt (&rsp.preparent, preparent); + gf_stat_from_iatt (&rsp.postparent, postparent); + + link_inode = inode_link (inode, state->loc.parent, + state->loc.name, stbuf); + inode_lookup (link_inode); + inode_unref (link_inode); out: rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error (op_errno); + req = frame->local; server_submit_reply (frame, req, &rsp, NULL, 0, NULL, (xdrproc_t)xdr_gfs3_mkdir_rsp); - if (rsp.xdata.xdata_val) - GF_FREE (rsp.xdata.xdata_val); + GF_FREE (rsp.xdata.xdata_val); return 0; } @@ -551,43 +514,43 @@ server_mknod_cbk (call_frame_t *frame, void *cookie, xlator_t *this, inode_t *inode, struct iatt *stbuf, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { - gfs3_mknod_rsp rsp = {0,}; - server_state_t *state = NULL; - inode_t *link_inode = NULL; - rpcsvc_request_t *req = NULL; + gfs3_mknod_rsp rsp = {0,}; + server_state_t *state = NULL; + inode_t *link_inode = NULL; + rpcsvc_request_t *req = NULL; - req = frame->local; + GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val, + rsp.xdata.xdata_len, op_errno, out); - state = CALL_STATE(frame); - if (op_ret >= 0) { - gf_stat_from_iatt (&rsp.stat, stbuf); - gf_stat_from_iatt (&rsp.preparent, preparent); - gf_stat_from_iatt (&rsp.postparent, postparent); + state = CALL_STATE (frame); - link_inode = inode_link (inode, state->loc.parent, - state->loc.name, stbuf); - inode_lookup (link_inode); - inode_unref (link_inode); - } else { + if (op_ret < 0) { gf_log (this->name, GF_LOG_INFO, - "%"PRId64": MKNOD %s (%s) ==> %"PRId32" (%s)", + "%"PRId64": MKNOD %s (%s/%s) ==> (%s)", frame->root->unique, state->loc.path, - state->loc.inode ? uuid_utoa (state->loc.inode->gfid) : - "--",op_ret, strerror (op_errno)); + uuid_utoa (state->resolve.pargfid), + state->resolve.bname, strerror (op_errno)); + goto out; } - GF_PROTOCOL_DICT_SERIALIZE (this, xdata, (&rsp.xdata.xdata_val), - rsp.xdata.xdata_len, op_errno, out); + gf_stat_from_iatt (&rsp.stat, stbuf); + gf_stat_from_iatt (&rsp.preparent, preparent); + gf_stat_from_iatt (&rsp.postparent, postparent); + + link_inode = inode_link (inode, state->loc.parent, + state->loc.name, stbuf); + inode_lookup (link_inode); + inode_unref (link_inode); out: rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error (op_errno); + req = frame->local; server_submit_reply (frame, req, &rsp, NULL, 0, NULL, (xdrproc_t)xdr_gfs3_mknod_rsp); - if (rsp.xdata.xdata_val) - GF_FREE (rsp.xdata.xdata_val); + GF_FREE (rsp.xdata.xdata_val); return 0; } @@ -596,78 +559,78 @@ int server_fsyncdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { - gf_common_rsp rsp = {0,}; - server_state_t *state = NULL; - rpcsvc_request_t *req = NULL; - - req = frame->local; + gf_common_rsp rsp = {0,}; + server_state_t *state = NULL; + rpcsvc_request_t *req = NULL; - state = CALL_STATE(frame); + GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val, + rsp.xdata.xdata_len, op_errno, out); if (op_ret < 0) { + state = CALL_STATE (frame); gf_log (this->name, GF_LOG_INFO, - "%"PRId64": FSYNCDIR %"PRId64" (%s) ==> %"PRId32" (%s)", + "%"PRId64": FSYNCDIR %"PRId64" (%s) ==> (%s)", frame->root->unique, state->resolve.fd_no, - state->fd ? uuid_utoa (state->fd->inode->gfid) : "--", - op_ret, strerror (op_errno)); + uuid_utoa (state->resolve.gfid), + strerror (op_errno)); + goto out; } - GF_PROTOCOL_DICT_SERIALIZE (this, xdata, (&rsp.xdata.xdata_val), - rsp.xdata.xdata_len, op_errno, out); - out: rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error (op_errno); + req = frame->local; server_submit_reply (frame, req, &rsp, NULL, 0, NULL, (xdrproc_t)xdr_gf_common_rsp); - if (rsp.xdata.xdata_val) - GF_FREE (rsp.xdata.xdata_val); + GF_FREE (rsp.xdata.xdata_val); return 0; } int server_readdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, gf_dirent_t *entries, dict_t *xdata) + int32_t op_ret, int32_t op_errno, gf_dirent_t *entries, + dict_t *xdata) { - gfs3_readdir_rsp rsp = {0,}; - server_state_t *state = NULL; - rpcsvc_request_t *req = NULL; - int ret = 0; + gfs3_readdir_rsp rsp = {0,}; + server_state_t *state = NULL; + rpcsvc_request_t *req = NULL; + int ret = 0; - req = frame->local; + GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val, + rsp.xdata.xdata_len, op_errno, out); + + if (op_ret < 0) { + state = CALL_STATE (frame); + gf_log (this->name, GF_LOG_INFO, + "%"PRId64": READDIR %"PRId64" (%s) ==> (%s)", + frame->root->unique, state->resolve.fd_no, + uuid_utoa (state->resolve.gfid), + strerror (op_errno)); + goto out; + } - state = CALL_STATE(frame); - if (op_ret > 0) { + /* (op_ret == 0) is valid, and means EOF */ + if (op_ret) { ret = serialize_rsp_dirent (entries, &rsp); if (ret == -1) { op_ret = -1; op_errno = ENOMEM; goto out; } - } else { - /* (op_ret == 0) is valid, and means EOF, don't log for that */ - gf_log (this->name, (op_ret) ? GF_LOG_INFO : GF_LOG_TRACE, - "%"PRId64": READDIR %"PRId64" (%s) ==> %"PRId32 - " (%s)", frame->root->unique, state->resolve.fd_no, - state->fd ? uuid_utoa (state->fd->inode->gfid) : "--", - op_ret, strerror (op_errno)); } - GF_PROTOCOL_DICT_SERIALIZE (this, xdata, (&rsp.xdata.xdata_val), - rsp.xdata.xdata_len, op_errno, out); - out: rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error (op_errno); + req = frame->local; server_submit_reply (frame, req, &rsp, NULL, 0, NULL, (xdrproc_t)xdr_gfs3_readdir_rsp); - if (rsp.xdata.xdata_val) - GF_FREE (rsp.xdata.xdata_val); + GF_FREE (rsp.xdata.xdata_val); readdir_rsp_cleanup (&rsp); @@ -678,43 +641,45 @@ int server_opendir_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, fd_t *fd, dict_t *xdata) { - server_connection_t *conn = NULL; - server_state_t *state = NULL; - rpcsvc_request_t *req = NULL; - gfs3_opendir_rsp rsp = {0,}; - uint64_t fd_no = 0; - - conn = SERVER_CONNECTION (frame); - state = CALL_STATE (frame); + server_state_t *state = NULL; + server_ctx_t *serv_ctx = NULL; + rpcsvc_request_t *req = NULL; + gfs3_opendir_rsp rsp = {0,}; + uint64_t fd_no = 0; - if (op_ret >= 0) { - fd_bind (fd); + GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val, + rsp.xdata.xdata_len, op_errno, out); - fd_no = gf_fd_unused_get (conn->fdtable, fd); - fd_ref (fd); // on behalf of the client - } else { - gf_log (this->name, GF_LOG_INFO, - "%"PRId64": OPENDIR %s (%s) ==> %"PRId32" (%s)", + if (op_ret < 0) { + state = CALL_STATE (frame); + gf_log (this->name, (op_errno == ENOENT)? + GF_LOG_DEBUG:GF_LOG_ERROR, + "%"PRId64": OPENDIR %s (%s) ==> (%s)", frame->root->unique, state->loc.path, - state->loc.inode ? uuid_utoa (state->loc.inode->gfid) : - "--", op_ret, strerror (op_errno)); + uuid_utoa (state->resolve.gfid), strerror (op_errno)); + goto out; } - req = frame->local; + serv_ctx = server_ctx_get (frame->root->client, this); + if (serv_ctx == NULL) { + gf_log (this->name, GF_LOG_INFO, "server_ctx_get() failed"); + goto out; + } - GF_PROTOCOL_DICT_SERIALIZE (this, xdata, (&rsp.xdata.xdata_val), - rsp.xdata.xdata_len, op_errno, out); + fd_bind (fd); + fd_no = gf_fd_unused_get (serv_ctx->fdtable, fd); + fd_ref (fd); // on behalf of the client out: rsp.fd = fd_no; rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error (op_errno); + req = frame->local; server_submit_reply (frame, req, &rsp, NULL, 0, NULL, (xdrproc_t)xdr_gfs3_opendir_rsp); - if (rsp.xdata.xdata_val) - GF_FREE (rsp.xdata.xdata_val); + GF_FREE (rsp.xdata.xdata_val); return 0; } @@ -723,32 +688,32 @@ int server_removexattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { - gf_common_rsp rsp = {0,}; - rpcsvc_request_t *req = NULL; + gf_common_rsp rsp = {0,}; + rpcsvc_request_t *req = NULL; server_state_t *state = NULL; - req = frame->local; - state = CALL_STATE(frame); + GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val, + rsp.xdata.xdata_len, op_errno, out); - if (op_ret == -1) + if (op_ret == -1) { + state = CALL_STATE (frame); gf_log (this->name, GF_LOG_INFO, - "%"PRId64": REMOVEXATTR %s (%s) ==> %"PRId32" (%s)", + "%"PRId64": REMOVEXATTR %s (%s) of key %s ==> (%s)", frame->root->unique, state->loc.path, - state->loc.inode ? uuid_utoa (state->loc.inode->gfid) : - "--", op_ret, strerror (op_errno)); - - GF_PROTOCOL_DICT_SERIALIZE (this, xdata, (&rsp.xdata.xdata_val), - rsp.xdata.xdata_len, op_errno, out); + uuid_utoa (state->resolve.gfid), + state->name, strerror (op_errno)); + goto out; + } out: rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error (op_errno); + req = frame->local; server_submit_reply (frame, req, &rsp, NULL, 0, NULL, (xdrproc_t)xdr_gf_common_rsp); - if (rsp.xdata.xdata_val) - GF_FREE (rsp.xdata.xdata_val); + GF_FREE (rsp.xdata.xdata_val); return 0; } @@ -757,33 +722,32 @@ int server_fremovexattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { - gf_common_rsp rsp = {0,}; - rpcsvc_request_t *req = NULL; + gf_common_rsp rsp = {0,}; + rpcsvc_request_t *req = NULL; server_state_t *state = NULL; - req = frame->local; - state = CALL_STATE(frame); + GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val, + rsp.xdata.xdata_len, op_errno, out); - if (op_ret == -1) + if (op_ret == -1) { + state = CALL_STATE (frame); gf_log (this->name, GF_LOG_INFO, - "%"PRId64": FREMOVEXATTR (%s) ==> %"PRId32" (%s)", - frame->root->unique, ((state->fd->inode) ? - uuid_utoa (state->fd->inode->gfid) : - "--"), - op_ret, strerror (op_errno)); - - GF_PROTOCOL_DICT_SERIALIZE (this, xdata, (&rsp.xdata.xdata_val), - rsp.xdata.xdata_len, op_errno, out); + "%"PRId64": FREMOVEXATTR %"PRId64" (%s) (%s) ==> (%s)", + frame->root->unique, state->resolve.fd_no, + uuid_utoa (state->resolve.gfid), state->name, + strerror (op_errno)); + goto out; + } out: rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error (op_errno); + req = frame->local; server_submit_reply (frame, req, &rsp, NULL, 0, NULL, (xdrproc_t)xdr_gf_common_rsp); - if (rsp.xdata.xdata_val) - GF_FREE (rsp.xdata.xdata_val); + GF_FREE (rsp.xdata.xdata_val); return 0; } @@ -793,43 +757,40 @@ server_getxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *dict, dict_t *xdata) { - gfs3_getxattr_rsp rsp = {0,}; - rpcsvc_request_t *req = NULL; - server_state_t *state = NULL; + gfs3_getxattr_rsp rsp = {0,}; + rpcsvc_request_t *req = NULL; + server_state_t *state = NULL; - state = CALL_STATE (frame); + GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val, + rsp.xdata.xdata_len, op_errno, out); - if (op_ret >= 0) { - GF_PROTOCOL_DICT_SERIALIZE (this, dict, - (&rsp.dict.dict_val), - rsp.dict.dict_len, - op_errno, out); + if (op_ret == -1) { + state = CALL_STATE (frame); + gf_log (this->name, (((op_errno == ENOTSUP) || + (op_errno == ENODATA) || + (op_errno == ENOENT)) ? + GF_LOG_DEBUG : GF_LOG_INFO), + "%"PRId64": GETXATTR %s (%s) (%s) ==> (%s)", + frame->root->unique, state->loc.path, + uuid_utoa (state->resolve.gfid), + state->name, strerror (op_errno)); + goto out; } - GF_PROTOCOL_DICT_SERIALIZE (this, xdata, (&rsp.xdata.xdata_val), - rsp.xdata.xdata_len, op_errno, out); + GF_PROTOCOL_DICT_SERIALIZE (this, dict, &rsp.dict.dict_val, + rsp.dict.dict_len, op_errno, out); out: - req = frame->local; - rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error (op_errno); - if (op_ret == -1) - gf_log (this->name, ((op_errno == ENOTSUP) ? - GF_LOG_DEBUG : GF_LOG_INFO), - "%"PRId64": GETXATTR %s (%s) ==> %"PRId32" (%s)", - frame->root->unique, state->loc.path, - state->name, op_ret, strerror (op_errno)); - + req = frame->local; server_submit_reply (frame, req, &rsp, NULL, 0, NULL, (xdrproc_t)xdr_gfs3_getxattr_rsp); - if (rsp.dict.dict_val) - GF_FREE (rsp.dict.dict_val); + GF_FREE (rsp.dict.dict_val); - if (rsp.xdata.xdata_val) - GF_FREE (rsp.xdata.xdata_val); + GF_FREE (rsp.xdata.xdata_val); return 0; } @@ -840,44 +801,58 @@ server_fgetxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *dict, dict_t *xdata) { - gfs3_fgetxattr_rsp rsp = {0,}; - server_state_t *state = NULL; - rpcsvc_request_t *req = NULL; + gfs3_fgetxattr_rsp rsp = {0,}; + server_state_t *state = NULL; + rpcsvc_request_t *req = NULL; - state = CALL_STATE (frame); + GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val, + rsp.xdata.xdata_len, op_errno, out); - if (op_ret >= 0) { - GF_PROTOCOL_DICT_SERIALIZE (this, dict, - (&rsp.dict.dict_val), - rsp.dict.dict_len, - op_errno, out); + if (op_ret == -1) { + state = CALL_STATE (frame); + gf_log (this->name, ((op_errno == ENOTSUP) ? + GF_LOG_DEBUG : GF_LOG_INFO), + "%"PRId64": FGETXATTR %"PRId64" (%s) (%s) ==> (%s)", + frame->root->unique, state->resolve.fd_no, + uuid_utoa (state->resolve.gfid), + state->name, strerror (op_errno)); + goto out; } - GF_PROTOCOL_DICT_SERIALIZE (this, xdata, (&rsp.xdata.xdata_val), - rsp.xdata.xdata_len, op_errno, out); + GF_PROTOCOL_DICT_SERIALIZE (this, dict, &rsp.dict.dict_val, + rsp.dict.dict_len, op_errno, out); out: - req = frame->local; rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error (op_errno); - if (op_ret == -1) - gf_log (this->name, ((op_errno == ENOTSUP) ? - GF_LOG_DEBUG : GF_LOG_INFO), - "%"PRId64": FGETXATTR %"PRId64" (%s) ==> %"PRId32" (%s)", - frame->root->unique, state->resolve.fd_no, - state->name, op_ret, strerror (op_errno)); - + req = frame->local; server_submit_reply (frame, req, &rsp, NULL, 0, NULL, (xdrproc_t)xdr_gfs3_fgetxattr_rsp); - if (rsp.dict.dict_val) - GF_FREE (rsp.dict.dict_val); + GF_FREE (rsp.dict.dict_val); + + GF_FREE (rsp.xdata.xdata_val); + + return 0; +} + +/* print every key */ +static int +_gf_server_log_setxattr_failure (dict_t *d, char *k, data_t *v, + void *tmp) +{ + server_state_t *state = NULL; + call_frame_t *frame = NULL; - if (rsp.xdata.xdata_val) - GF_FREE (rsp.xdata.xdata_val); + frame = tmp; + state = CALL_STATE (frame); + gf_log (THIS->name, GF_LOG_INFO, + "%"PRId64": SETXATTR %s (%s) ==> %s", + frame->root->unique, state->loc.path, + uuid_utoa (state->resolve.gfid), k); return 0; } @@ -889,40 +864,53 @@ server_setxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, rpcsvc_request_t *req = NULL; server_state_t *state = NULL; - req = frame->local; - - state = CALL_STATE(frame); - rsp.op_ret = op_ret; - rsp.op_errno = gf_errno_to_error (op_errno); + GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val, + rsp.xdata.xdata_len, op_errno, out); if (op_ret == -1) { - gf_log (this->name, ((op_errno == ENOTSUP) ? + state = CALL_STATE (frame); + if (op_errno != ENOTSUP) + dict_foreach (state->dict, + _gf_server_log_setxattr_failure, + frame); + + gf_log (THIS->name, ((op_errno == ENOTSUP) ? GF_LOG_DEBUG : GF_LOG_INFO), - "%"PRId64": SETXATTR %s (%s) ==> %s (%s)", - frame->root->unique, state->loc.path, - state->loc.inode ? uuid_utoa (state->loc.inode->gfid) : - "--", ((state->dict) ? ((state->dict->members_list) ? - state->dict->members_list->key : - "(null)") : ("null")), - strerror (op_errno)); + "%s", strerror (op_errno)); + goto out; } - GF_PROTOCOL_DICT_SERIALIZE (this, xdata, (&rsp.xdata.xdata_val), - rsp.xdata.xdata_len, op_errno, out); - out: rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error (op_errno); + req = frame->local; server_submit_reply (frame, req, &rsp, NULL, 0, NULL, (xdrproc_t)xdr_gf_common_rsp); - if (rsp.xdata.xdata_val) - GF_FREE (rsp.xdata.xdata_val); + GF_FREE (rsp.xdata.xdata_val); return 0; } +/* print every key here */ +static int +_gf_server_log_fsetxattr_failure (dict_t *d, char *k, data_t *v, + void *tmp) +{ + call_frame_t *frame = NULL; + server_state_t *state = NULL; + + frame = tmp; + state = CALL_STATE (frame); + + gf_log (THIS->name, GF_LOG_INFO, + "%"PRId64": FSETXATTR %"PRId64" (%s) ==> %s", + frame->root->unique, state->resolve.fd_no, + uuid_utoa (state->resolve.gfid), k); + + return 0; +} int server_fsetxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, @@ -932,33 +920,31 @@ server_fsetxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, rpcsvc_request_t *req = NULL; server_state_t *state = NULL; - req = frame->local; - - state = CALL_STATE(frame); + GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val, + rsp.xdata.xdata_len, op_errno, out); - if (op_ret == -1) - gf_log (this->name, ((op_errno == ENOTSUP) ? + if (op_ret == -1) { + state = CALL_STATE (frame); + if (op_errno != ENOTSUP) { + dict_foreach (state->dict, + _gf_server_log_fsetxattr_failure, + frame); + } + gf_log (THIS->name, ((op_errno == ENOTSUP) ? GF_LOG_DEBUG : GF_LOG_INFO), - "%"PRId64": FSETXATTR %"PRId64" (%s) ==> %s (%s)", - frame->root->unique, state->resolve.fd_no, - state->fd ? uuid_utoa (state->fd->inode->gfid) : "--", - ((state->dict) ? ((state->dict->members_list) ? - state->dict->members_list->key : - "(null)") : "null"), - strerror (op_errno)); - - GF_PROTOCOL_DICT_SERIALIZE (this, xdata, (&rsp.xdata.xdata_val), - rsp.xdata.xdata_len, op_errno, out); + "%s", strerror (op_errno)); + goto out; + } out: rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error (op_errno); + req = frame->local; server_submit_reply (frame, req, &rsp, NULL, 0, NULL, (xdrproc_t)xdr_gf_common_rsp); - if (rsp.xdata.xdata_val) - GF_FREE (rsp.xdata.xdata_val); + GF_FREE (rsp.xdata.xdata_val); return 0; } @@ -970,77 +956,80 @@ server_rename_cbk (call_frame_t *frame, void *cookie, xlator_t *this, struct iatt *prenewparent, struct iatt *postnewparent, dict_t *xdata) { - gfs3_rename_rsp rsp = {0,}; - server_state_t *state = NULL; - rpcsvc_request_t *req = NULL; - inode_t *tmp_inode = NULL; - inode_t *tmp_parent = NULL; + gfs3_rename_rsp rsp = {0,}; + server_state_t *state = NULL; + rpcsvc_request_t *req = NULL; + inode_t *tmp_inode = NULL; + inode_t *tmp_parent = NULL; + char oldpar_str[50] = {0,}; + char newpar_str[50] = {0,}; - req = frame->local; - state = CALL_STATE(frame); - - if (op_ret == 0) { - stbuf->ia_type = state->loc.inode->ia_type; - - /* TODO: log gfid of the inodes */ - gf_log (state->conn->bound_xl->name, GF_LOG_TRACE, - "%"PRId64": RENAME_CBK %s ==> %s", - frame->root->unique, state->loc.name, state->loc2.name); - - /* Before renaming the inode, we have to get the inode for the - * destination entry (i.e. inode with state->loc2.parent as - * parent and state->loc2.name as name). If it exists, then - * unlink that inode, and send forget on that inode if the - * unlinked entry is the last entry. In case of fuse client - * the fuse kernel module itself sends the forget on the - * unlinked inode. - */ - tmp_inode = inode_grep (state->loc.inode->table, - state->loc2.parent, state->loc2.name); - if (tmp_inode) { - inode_unlink (tmp_inode, state->loc2.parent, - state->loc2.name); - tmp_parent = inode_parent (tmp_inode, 0, NULL); - if (tmp_parent) - inode_unref (tmp_parent); - else - inode_forget (tmp_inode, 0); - - inode_unref (tmp_inode); - } + GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val, + rsp.xdata.xdata_len, op_errno, out); - inode_rename (state->itable, - state->loc.parent, state->loc.name, - state->loc2.parent, state->loc2.name, - state->loc.inode, stbuf); - gf_stat_from_iatt (&rsp.stat, stbuf); + state = CALL_STATE (frame); - gf_stat_from_iatt (&rsp.preoldparent, preoldparent); - gf_stat_from_iatt (&rsp.postoldparent, postoldparent); + if (op_ret == -1) { + uuid_utoa_r (state->resolve.gfid, oldpar_str); + uuid_utoa_r (state->resolve2.gfid, newpar_str); + gf_log (this->name, GF_LOG_INFO, + "%"PRId64": RENAME %s (%s/%s) -> %s (%s/%s) ==> (%s)", + frame->root->unique, state->loc.path, + oldpar_str, state->resolve.bname, state->loc2.path, + newpar_str, state->resolve2.bname, strerror (op_errno)); + goto out; + } + + stbuf->ia_type = state->loc.inode->ia_type; - gf_stat_from_iatt (&rsp.prenewparent, prenewparent); - gf_stat_from_iatt (&rsp.postnewparent, postnewparent); + /* TODO: log gfid of the inodes */ + gf_log (frame->root->client->bound_xl->name, GF_LOG_TRACE, + "%"PRId64": RENAME_CBK %s ==> %s", + frame->root->unique, state->loc.name, state->loc2.name); + + /* Before renaming the inode, we have to get the inode for the + * destination entry (i.e. inode with state->loc2.parent as + * parent and state->loc2.name as name). If it exists, then + * unlink that inode, and send forget on that inode if the + * unlinked entry is the last entry. In case of fuse client + * the fuse kernel module itself sends the forget on the + * unlinked inode. + */ + tmp_inode = inode_grep (state->loc.inode->table, + state->loc2.parent, state->loc2.name); + if (tmp_inode) { + inode_unlink (tmp_inode, state->loc2.parent, + state->loc2.name); + tmp_parent = inode_parent (tmp_inode, 0, NULL); + if (tmp_parent) + inode_unref (tmp_parent); + else + inode_forget (tmp_inode, 0); + + inode_unref (tmp_inode); } - if (op_ret == -1) - gf_log (this->name, GF_LOG_INFO, - "%"PRId64": RENAME %s (%s) ==> %"PRId32" (%s)", - frame->root->unique, state->loc.path, - state->loc.inode ? uuid_utoa (state->loc.inode->gfid) : - "--", op_ret, strerror (op_errno)); + inode_rename (state->itable, + state->loc.parent, state->loc.name, + state->loc2.parent, state->loc2.name, + state->loc.inode, stbuf); + gf_stat_from_iatt (&rsp.stat, stbuf); - GF_PROTOCOL_DICT_SERIALIZE (this, xdata, (&rsp.xdata.xdata_val), - rsp.xdata.xdata_len, op_errno, out); + gf_stat_from_iatt (&rsp.preoldparent, preoldparent); + gf_stat_from_iatt (&rsp.postoldparent, postoldparent); + + gf_stat_from_iatt (&rsp.prenewparent, prenewparent); + gf_stat_from_iatt (&rsp.postnewparent, postnewparent); out: rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error (op_errno); + req = frame->local; server_submit_reply (frame, req, &rsp, NULL, 0, NULL, (xdrproc_t)xdr_gfs3_rename_rsp); - if (rsp.xdata.xdata_val) - GF_FREE (rsp.xdata.xdata_val); + GF_FREE (rsp.xdata.xdata_val); return 0; } @@ -1050,53 +1039,52 @@ server_unlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { - gfs3_unlink_rsp rsp = {0,}; - server_state_t *state = NULL; - inode_t *parent = NULL; - rpcsvc_request_t *req = NULL; - - req = frame->local; + gfs3_unlink_rsp rsp = {0,}; + server_state_t *state = NULL; + inode_t *parent = NULL; + rpcsvc_request_t *req = NULL; - state = CALL_STATE(frame); + GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val, + rsp.xdata.xdata_len, op_errno, out); - if (op_ret == 0) { - /* TODO: log gfid of the inodes */ - gf_log (state->conn->bound_xl->name, GF_LOG_TRACE, - "%"PRId64": UNLINK_CBK %s", - frame->root->unique, state->loc.name); + state = CALL_STATE (frame); - inode_unlink (state->loc.inode, state->loc.parent, - state->loc.name); + if (op_ret) { + gf_log (this->name, (op_errno == ENOENT)? + GF_LOG_DEBUG:GF_LOG_ERROR, + "%"PRId64": UNLINK %s (%s/%s) ==> (%s)", + frame->root->unique, state->loc.path, + uuid_utoa (state->resolve.pargfid), + state->resolve.bname, strerror (op_errno)); + goto out; + } - parent = inode_parent (state->loc.inode, 0, NULL); - if (parent) - inode_unref (parent); - else - inode_forget (state->loc.inode, 0); + /* TODO: log gfid of the inodes */ + gf_log (frame->root->client->bound_xl->name, GF_LOG_TRACE, + "%"PRId64": UNLINK_CBK %s", + frame->root->unique, state->loc.name); - gf_stat_from_iatt (&rsp.preparent, preparent); - gf_stat_from_iatt (&rsp.postparent, postparent); + inode_unlink (state->loc.inode, state->loc.parent, + state->loc.name); - } else { - gf_log (this->name, GF_LOG_INFO, - "%"PRId64": UNLINK %s (%s) ==> %"PRId32" (%s)", - frame->root->unique, state->loc.path, - state->loc.inode ? uuid_utoa (state->loc.inode->gfid) : - "--", op_ret, strerror (op_errno)); - } + parent = inode_parent (state->loc.inode, 0, NULL); + if (parent) + inode_unref (parent); + else + inode_forget (state->loc.inode, 0); - GF_PROTOCOL_DICT_SERIALIZE (this, xdata, (&rsp.xdata.xdata_val), - rsp.xdata.xdata_len, op_errno, out); + gf_stat_from_iatt (&rsp.preparent, preparent); + gf_stat_from_iatt (&rsp.postparent, postparent); out: rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error (op_errno); + req = frame->local; server_submit_reply (frame, req, &rsp, NULL, 0, NULL, (xdrproc_t)xdr_gfs3_unlink_rsp); - if (rsp.xdata.xdata_val) - GF_FREE (rsp.xdata.xdata_val); + GF_FREE (rsp.xdata.xdata_val); return 0; } @@ -1107,43 +1095,43 @@ server_symlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this, struct iatt *stbuf, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { - gfs3_symlink_rsp rsp = {0,}; - server_state_t *state = NULL; - inode_t *link_inode = NULL; - rpcsvc_request_t *req = NULL; + gfs3_symlink_rsp rsp = {0,}; + server_state_t *state = NULL; + inode_t *link_inode = NULL; + rpcsvc_request_t *req = NULL; - req = frame->local; + GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val, + rsp.xdata.xdata_len, op_errno, out); - state = CALL_STATE(frame); - if (op_ret >= 0) { - gf_stat_from_iatt (&rsp.stat, stbuf); - gf_stat_from_iatt (&rsp.preparent, preparent); - gf_stat_from_iatt (&rsp.postparent, postparent); + state = CALL_STATE (frame); - link_inode = inode_link (inode, state->loc.parent, - state->loc.name, stbuf); - inode_lookup (link_inode); - inode_unref (link_inode); - } else { + if (op_ret < 0) { gf_log (this->name, GF_LOG_INFO, - "%"PRId64": SYMLINK %s (%s) ==> %"PRId32" (%s)", + "%"PRId64": SYMLINK %s (%s/%s) ==> (%s)", frame->root->unique, state->loc.path, - state->loc.inode ? uuid_utoa (state->loc.inode->gfid) : - "--", op_ret, strerror (op_errno)); + uuid_utoa (state->resolve.pargfid), + state->resolve.bname, strerror (op_errno)); + goto out; } - GF_PROTOCOL_DICT_SERIALIZE (this, xdata, (&rsp.xdata.xdata_val), - rsp.xdata.xdata_len, op_errno, out); + gf_stat_from_iatt (&rsp.stat, stbuf); + gf_stat_from_iatt (&rsp.preparent, preparent); + gf_stat_from_iatt (&rsp.postparent, postparent); + + link_inode = inode_link (inode, state->loc.parent, + state->loc.name, stbuf); + inode_lookup (link_inode); + inode_unref (link_inode); out: rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error (op_errno); + req = frame->local; server_submit_reply (frame, req, &rsp, NULL, 0, NULL, (xdrproc_t)xdr_gfs3_symlink_rsp); - if (rsp.xdata.xdata_val) - GF_FREE (rsp.xdata.xdata_val); + GF_FREE (rsp.xdata.xdata_val); return 0; } @@ -1155,45 +1143,47 @@ server_link_cbk (call_frame_t *frame, void *cookie, xlator_t *this, struct iatt *stbuf, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { - gfs3_link_rsp rsp = {0,}; - server_state_t *state = NULL; - inode_t *link_inode = NULL; - rpcsvc_request_t *req = NULL; - - req = frame->local; + gfs3_link_rsp rsp = {0,}; + server_state_t *state = NULL; + inode_t *link_inode = NULL; + rpcsvc_request_t *req = NULL; + char gfid_str[50] = {0,}; + char newpar_str[50] = {0,}; - state = CALL_STATE(frame); - - if (op_ret == 0) { + GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val, + rsp.xdata.xdata_len, op_errno, out); - gf_stat_from_iatt (&rsp.stat, stbuf); - gf_stat_from_iatt (&rsp.preparent, preparent); - gf_stat_from_iatt (&rsp.postparent, postparent); + state = CALL_STATE (frame); - link_inode = inode_link (inode, state->loc2.parent, - state->loc2.name, stbuf); - inode_unref (link_inode); - } + if (op_ret) { + uuid_utoa_r (state->resolve.gfid, gfid_str); + uuid_utoa_r (state->resolve2.pargfid, newpar_str); - if (op_ret == -1) gf_log (this->name, GF_LOG_INFO, - "%"PRId64": LINK %s (%s) ==> %"PRId32" (%s)", + "%"PRId64": LINK %s (%s) -> %s/%s ==> (%s)", frame->root->unique, state->loc.path, - state->loc.inode ? uuid_utoa (state->loc.inode->gfid) : - "--", op_ret, strerror (op_errno)); + gfid_str, newpar_str, state->resolve2.bname, + strerror (op_errno)); + goto out; + } - GF_PROTOCOL_DICT_SERIALIZE (this, xdata, (&rsp.xdata.xdata_val), - rsp.xdata.xdata_len, op_errno, out); + gf_stat_from_iatt (&rsp.stat, stbuf); + gf_stat_from_iatt (&rsp.preparent, preparent); + gf_stat_from_iatt (&rsp.postparent, postparent); + + link_inode = inode_link (inode, state->loc2.parent, + state->loc2.name, stbuf); + inode_unref (link_inode); out: rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error (op_errno); + req = frame->local; server_submit_reply (frame, req, &rsp, NULL, 0, NULL, (xdrproc_t)xdr_gfs3_link_rsp); - if (rsp.xdata.xdata_val) - GF_FREE (rsp.xdata.xdata_val); + GF_FREE (rsp.xdata.xdata_val); return 0; } @@ -1203,75 +1193,70 @@ server_truncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata) { - gfs3_truncate_rsp rsp = {0,}; - server_state_t *state = NULL; - rpcsvc_request_t *req = NULL; - - req = frame->local; + gfs3_truncate_rsp rsp = {0,}; + server_state_t *state = NULL; + rpcsvc_request_t *req = NULL; - state = CALL_STATE (frame); + GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val, + rsp.xdata.xdata_len, op_errno, out); - if (op_ret == 0) { - gf_stat_from_iatt (&rsp.prestat, prebuf); - gf_stat_from_iatt (&rsp.poststat, postbuf); - } else { + if (op_ret) { + state = CALL_STATE (frame); gf_log (this->name, GF_LOG_INFO, - "%"PRId64": TRUNCATE %s (%s) ==> %"PRId32" (%s)", + "%"PRId64": TRUNCATE %s (%s) ==> (%s)", frame->root->unique, state->loc.path, - state->loc.inode ? uuid_utoa (state->loc.inode->gfid) : - "--", op_ret, strerror (op_errno)); + uuid_utoa (state->resolve.gfid), strerror (op_errno)); + goto out; } - GF_PROTOCOL_DICT_SERIALIZE (this, xdata, (&rsp.xdata.xdata_val), - rsp.xdata.xdata_len, op_errno, out); + gf_stat_from_iatt (&rsp.prestat, prebuf); + gf_stat_from_iatt (&rsp.poststat, postbuf); out: rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error (op_errno); + req = frame->local; server_submit_reply (frame, req, &rsp, NULL, 0, NULL, (xdrproc_t)xdr_gfs3_truncate_rsp); - if (rsp.xdata.xdata_val) - GF_FREE (rsp.xdata.xdata_val); + GF_FREE (rsp.xdata.xdata_val); return 0; } int server_fstat_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, struct iatt *stbuf, dict_t *xdata) + int32_t op_ret, int32_t op_errno, struct iatt *stbuf, + dict_t *xdata) { - gfs3_fstat_rsp rsp = {0,}; - server_state_t *state = NULL; - rpcsvc_request_t *req = NULL; - - req = frame->local; + gfs3_fstat_rsp rsp = {0,}; + server_state_t *state = NULL; + rpcsvc_request_t *req = NULL; - state = CALL_STATE(frame); + GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val, + rsp.xdata.xdata_len, op_errno, out); - if (op_ret == 0) { - gf_stat_from_iatt (&rsp.stat, stbuf); - } else { + if (op_ret) { + state = CALL_STATE (frame); gf_log (this->name, GF_LOG_INFO, - "%"PRId64": FSTAT %"PRId64" (%s) ==> %"PRId32" (%s)", + "%"PRId64": FSTAT %"PRId64" (%s) ==> (%s)", frame->root->unique, state->resolve.fd_no, - state->fd ? uuid_utoa (state->fd->inode->gfid) : "--", - op_ret, strerror (op_errno)); + uuid_utoa (state->resolve.gfid), strerror (op_errno)); + goto out; } - GF_PROTOCOL_DICT_SERIALIZE (this, xdata, (&rsp.xdata.xdata_val), - rsp.xdata.xdata_len, op_errno, out); + gf_stat_from_iatt (&rsp.stat, stbuf); out: rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error (op_errno); + req = frame->local; server_submit_reply (frame, req, &rsp, NULL, 0, NULL, (xdrproc_t)xdr_gfs3_fstat_rsp); - if (rsp.xdata.xdata_val) - GF_FREE (rsp.xdata.xdata_val); + GF_FREE (rsp.xdata.xdata_val); return 0; } @@ -1281,37 +1266,34 @@ server_ftruncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata) { - gfs3_ftruncate_rsp rsp = {0}; - server_state_t *state = NULL; - rpcsvc_request_t *req = NULL; - - req = frame->local; + gfs3_ftruncate_rsp rsp = {0}; + server_state_t *state = NULL; + rpcsvc_request_t *req = NULL; - state = CALL_STATE (frame); + GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val, + rsp.xdata.xdata_len, op_errno, out); - if (op_ret == 0) { - gf_stat_from_iatt (&rsp.prestat, prebuf); - gf_stat_from_iatt (&rsp.poststat, postbuf); - } else { + if (op_ret) { + state = CALL_STATE (frame); gf_log (this->name, GF_LOG_INFO, - "%"PRId64": FTRUNCATE %"PRId64" (%s)==> %"PRId32" (%s)", + "%"PRId64": FTRUNCATE %"PRId64" (%s)==> (%s)", frame->root->unique, state->resolve.fd_no, - state->fd ? uuid_utoa (state->fd->inode->gfid) : "--", - op_ret, strerror (op_errno)); + uuid_utoa (state->resolve.gfid), strerror (op_errno)); + goto out; } - GF_PROTOCOL_DICT_SERIALIZE (this, xdata, (&rsp.xdata.xdata_val), - rsp.xdata.xdata_len, op_errno, out); + gf_stat_from_iatt (&rsp.prestat, prebuf); + gf_stat_from_iatt (&rsp.poststat, postbuf); out: rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error (op_errno); + req = frame->local; server_submit_reply (frame, req, &rsp, NULL, 0, NULL, (xdrproc_t)xdr_gfs3_ftruncate_rsp); - if (rsp.xdata.xdata_val) - GF_FREE (rsp.xdata.xdata_val); + GF_FREE (rsp.xdata.xdata_val); return 0; } @@ -1320,33 +1302,32 @@ int server_flush_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) { - gf_common_rsp rsp = {0,}; - server_state_t *state = NULL; - rpcsvc_request_t *req = NULL; + gf_common_rsp rsp = {0,}; + server_state_t *state = NULL; + rpcsvc_request_t *req = NULL; - req = frame->local; + GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val, + rsp.xdata.xdata_len, op_errno, out); - state = CALL_STATE(frame); if (op_ret < 0) { - gf_log (this->name, GF_LOG_INFO, - "%"PRId64": FLUSH %"PRId64" (%s) ==> %"PRId32" (%s)", + state = CALL_STATE (frame); + gf_log (this->name, (op_errno == ENOENT)? + GF_LOG_DEBUG:GF_LOG_ERROR, + "%"PRId64": FLUSH %"PRId64" (%s) ==> (%s)", frame->root->unique, state->resolve.fd_no, - state->fd ? uuid_utoa (state->fd->inode->gfid) : "--", - op_ret, strerror (op_errno)); + uuid_utoa (state->resolve.gfid), strerror (op_errno)); + goto out; } - GF_PROTOCOL_DICT_SERIALIZE (this, xdata, (&rsp.xdata.xdata_val), - rsp.xdata.xdata_len, op_errno, out); - out: rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error (op_errno); + req = frame->local; server_submit_reply (frame, req, &rsp, NULL, 0, NULL, (xdrproc_t)xdr_gf_common_rsp); - if (rsp.xdata.xdata_val) - GF_FREE (rsp.xdata.xdata_val); + GF_FREE (rsp.xdata.xdata_val); return 0; } @@ -1356,37 +1337,34 @@ server_fsync_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata) { - gfs3_fsync_rsp rsp = {0,}; - server_state_t *state = NULL; - rpcsvc_request_t *req = NULL; - - req = frame->local; + gfs3_fsync_rsp rsp = {0,}; + server_state_t *state = NULL; + rpcsvc_request_t *req = NULL; - state = CALL_STATE(frame); + GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val, + rsp.xdata.xdata_len, op_errno, out); - if (op_ret >= 0) { - gf_stat_from_iatt (&(rsp.prestat), prebuf); - gf_stat_from_iatt (&(rsp.poststat), postbuf); - } else { + if (op_ret < 0) { + state = CALL_STATE (frame); gf_log (this->name, GF_LOG_INFO, - "%"PRId64": FSYNC %"PRId64" (%s) ==> %"PRId32" (%s)", + "%"PRId64": FSYNC %"PRId64" (%s) ==> (%s)", frame->root->unique, state->resolve.fd_no, - state->fd ? uuid_utoa (state->fd->inode->gfid) : "--", - op_ret, strerror (op_errno)); + uuid_utoa (state->resolve.gfid), strerror (op_errno)); + goto out; } - GF_PROTOCOL_DICT_SERIALIZE (this, xdata, (&rsp.xdata.xdata_val), - rsp.xdata.xdata_len, op_errno, out); + gf_stat_from_iatt (&(rsp.prestat), prebuf); + gf_stat_from_iatt (&(rsp.poststat), postbuf); out: rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error (op_errno); + req = frame->local; server_submit_reply (frame, req, &rsp, NULL, 0, NULL, (xdrproc_t)xdr_gfs3_fsync_rsp); - if (rsp.xdata.xdata_val) - GF_FREE (rsp.xdata.xdata_val); + GF_FREE (rsp.xdata.xdata_val); return 0; } @@ -1396,36 +1374,34 @@ server_writev_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata) { - gfs3_write_rsp rsp = {0,}; - server_state_t *state = NULL; - rpcsvc_request_t *req = NULL; + gfs3_write_rsp rsp = {0,}; + server_state_t *state = NULL; + rpcsvc_request_t *req = NULL; - req = frame->local; + GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val, + rsp.xdata.xdata_len, op_errno, out); - state = CALL_STATE(frame); - if (op_ret >= 0) { - gf_stat_from_iatt (&rsp.prestat, prebuf); - gf_stat_from_iatt (&rsp.poststat, postbuf); - } else { + if (op_ret < 0) { + state = CALL_STATE (frame); gf_log (this->name, GF_LOG_INFO, - "%"PRId64": WRITEV %"PRId64" (%s) ==> %"PRId32" (%s)", + "%"PRId64": WRITEV %"PRId64" (%s) ==> (%s)", frame->root->unique, state->resolve.fd_no, - state->fd ? uuid_utoa (state->fd->inode->gfid) : "--", - op_ret, strerror (op_errno)); + uuid_utoa (state->resolve.gfid), strerror (op_errno)); + goto out; } - GF_PROTOCOL_DICT_SERIALIZE (this, xdata, (&rsp.xdata.xdata_val), - rsp.xdata.xdata_len, op_errno, out); + gf_stat_from_iatt (&rsp.prestat, prebuf); + gf_stat_from_iatt (&rsp.poststat, postbuf); out: rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error (op_errno); + req = frame->local; server_submit_reply (frame, req, &rsp, NULL, 0, NULL, (xdrproc_t)xdr_gfs3_write_rsp); - if (rsp.xdata.xdata_val) - GF_FREE (rsp.xdata.xdata_val); + GF_FREE (rsp.xdata.xdata_val); return 0; } @@ -1437,23 +1413,9 @@ server_readv_cbk (call_frame_t *frame, void *cookie, xlator_t *this, struct iovec *vector, int32_t count, struct iatt *stbuf, struct iobref *iobref, dict_t *xdata) { - gfs3_read_rsp rsp = {0,}; - server_state_t *state = NULL; - rpcsvc_request_t *req = NULL; - - req = frame->local; - - state = CALL_STATE(frame); - if (op_ret >= 0) { - gf_stat_from_iatt (&rsp.stat, stbuf); - rsp.size = op_ret; - } else { - gf_log (this->name, GF_LOG_INFO, - "%"PRId64": READV %"PRId64" (%s) ==> %"PRId32" (%s)", - frame->root->unique, state->resolve.fd_no, - state->fd ? uuid_utoa (state->fd->inode->gfid) : "--", - op_ret, strerror (op_errno)); - } + gfs3_read_rsp rsp = {0,}; + server_state_t *state = NULL; + rpcsvc_request_t *req = NULL; #ifdef GF_TESTING_IO_XDATA { @@ -1465,18 +1427,30 @@ server_readv_cbk (call_frame_t *frame, void *cookie, xlator_t *this, "testing-xdata-value"); } #endif - GF_PROTOCOL_DICT_SERIALIZE (this, xdata, (&rsp.xdata.xdata_val), + GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val, rsp.xdata.xdata_len, op_errno, out); + if (op_ret < 0) { + state = CALL_STATE (frame); + gf_log (this->name, GF_LOG_INFO, + "%"PRId64": READV %"PRId64" (%s) ==> (%s)", + frame->root->unique, state->resolve.fd_no, + uuid_utoa (state->resolve.gfid), strerror (op_errno)); + goto out; + } + + gf_stat_from_iatt (&rsp.stat, stbuf); + rsp.size = op_ret; + out: rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error (op_errno); + req = frame->local; server_submit_reply (frame, req, &rsp, vector, count, iobref, (xdrproc_t)xdr_gfs3_read_rsp); - if (rsp.xdata.xdata_val) - GF_FREE (rsp.xdata.xdata_val); + GF_FREE (rsp.xdata.xdata_val); return 0; } @@ -1484,40 +1458,39 @@ out: int server_rchecksum_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, - uint32_t weak_checksum, uint8_t *strong_checksum, dict_t *xdata) + uint32_t weak_checksum, uint8_t *strong_checksum, + dict_t *xdata) { - gfs3_rchecksum_rsp rsp = {0,}; - rpcsvc_request_t *req = NULL; + gfs3_rchecksum_rsp rsp = {0,}; + rpcsvc_request_t *req = NULL; server_state_t *state = NULL; - req = frame->local; - - state = CALL_STATE(frame); - if (op_ret >= 0) { - rsp.weak_checksum = weak_checksum; + GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val, + rsp.xdata.xdata_len, op_errno, out); - rsp.strong_checksum.strong_checksum_val = (char *)strong_checksum; - rsp.strong_checksum.strong_checksum_len = MD5_DIGEST_LENGTH; - } - if (op_ret == -1) + if (op_ret < 0) { + state = CALL_STATE (frame); gf_log (this->name, GF_LOG_INFO, - "%"PRId64": RCHECKSUM %"PRId64" (%s)==> %"PRId32" (%s)", + "%"PRId64": RCHECKSUM %"PRId64" (%s)==> (%s)", frame->root->unique, state->resolve.fd_no, - state->fd ? uuid_utoa (state->fd->inode->gfid) : "--", - op_ret, strerror (op_errno)); + uuid_utoa (state->resolve.gfid), strerror (op_errno)); + goto out; + } - GF_PROTOCOL_DICT_SERIALIZE (this, xdata, (&rsp.xdata.xdata_val), - rsp.xdata.xdata_len, op_errno, out); + rsp.weak_checksum = weak_checksum; + + rsp.strong_checksum.strong_checksum_val = (char *)strong_checksum; + rsp.strong_checksum.strong_checksum_len = MD5_DIGEST_LENGTH; out: rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error (op_errno); + req = frame->local; server_submit_reply (frame, req, &rsp, NULL, 0, NULL, (xdrproc_t)xdr_gfs3_rchecksum_rsp); - if (rsp.xdata.xdata_val) - GF_FREE (rsp.xdata.xdata_val); + GF_FREE (rsp.xdata.xdata_val); return 0; } @@ -1527,41 +1500,45 @@ int server_open_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, fd_t *fd, dict_t *xdata) { - server_connection_t *conn = NULL; - server_state_t *state = NULL; - rpcsvc_request_t *req = NULL; - uint64_t fd_no = 0; - gfs3_open_rsp rsp = {0,}; + server_state_t *state = NULL; + server_ctx_t *serv_ctx = NULL; + rpcsvc_request_t *req = NULL; + uint64_t fd_no = 0; + gfs3_open_rsp rsp = {0,}; - conn = SERVER_CONNECTION (frame); - state = CALL_STATE (frame); + GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val, + rsp.xdata.xdata_len, op_errno, out); - if (op_ret >= 0) { - fd_bind (fd); - fd_no = gf_fd_unused_get (conn->fdtable, fd); - fd_ref (fd); - } else { - gf_log (this->name, GF_LOG_INFO, - "%"PRId64": OPEN %s (%s) ==> %"PRId32" (%s)", + if (op_ret < 0) { + state = CALL_STATE (frame); + gf_log (this->name, (op_errno == ENOENT)? + GF_LOG_DEBUG:GF_LOG_ERROR, + "%"PRId64": OPEN %s (%s) ==> (%s)", frame->root->unique, state->loc.path, - state->loc.inode ? uuid_utoa (state->loc.inode->gfid) : - "--", op_ret, strerror (op_errno)); + uuid_utoa (state->resolve.gfid), + strerror (op_errno)); + goto out; } - req = frame->local; - rsp.fd = fd_no; + serv_ctx = server_ctx_get (frame->root->client, this); + if (serv_ctx == NULL) { + gf_log (this->name, GF_LOG_INFO, "server_ctx_get() failed"); + goto out; + } - GF_PROTOCOL_DICT_SERIALIZE (this, xdata, (&rsp.xdata.xdata_val), - rsp.xdata.xdata_len, op_errno, out); + fd_bind (fd); + fd_no = gf_fd_unused_get (serv_ctx->fdtable, fd); + fd_ref (fd); + rsp.fd = fd_no; out: rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error (op_errno); + req = frame->local; server_submit_reply (frame, req, &rsp, NULL, 0, NULL, (xdrproc_t)xdr_gfs3_open_rsp); - if (rsp.xdata.xdata_val) - GF_FREE (rsp.xdata.xdata_val); + GF_FREE (rsp.xdata.xdata_val); return 0; } @@ -1569,85 +1546,88 @@ out: int server_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, - fd_t *fd, inode_t *inode, struct iatt *stbuf, - struct iatt *preparent, struct iatt *postparent, dict_t *xdata) + int32_t op_ret, int32_t op_errno, fd_t *fd, inode_t *inode, + struct iatt *stbuf, struct iatt *preparent, + struct iatt *postparent, dict_t *xdata) { - server_connection_t *conn = NULL; server_state_t *state = NULL; + server_ctx_t *serv_ctx = NULL; inode_t *link_inode = NULL; rpcsvc_request_t *req = NULL; uint64_t fd_no = 0; gfs3_create_rsp rsp = {0,}; - conn = SERVER_CONNECTION (frame); + GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val, + rsp.xdata.xdata_len, op_errno, out); + state = CALL_STATE (frame); - if (op_ret >= 0) { - /* TODO: log gfid too */ - gf_log (state->conn->bound_xl->name, GF_LOG_TRACE, - "%"PRId64": CREATE %s (%s)", - frame->root->unique, state->loc.name, - uuid_utoa (inode->gfid)); + if (op_ret < 0) { + gf_log (this->name, GF_LOG_INFO, + "%"PRId64": CREATE %s (%s/%s) ==> (%s)", + frame->root->unique, state->loc.path, + uuid_utoa (state->resolve.pargfid), + state->resolve.bname, strerror (op_errno)); + goto out; + } - link_inode = inode_link (inode, state->loc.parent, - state->loc.name, stbuf); + /* TODO: log gfid too */ + gf_log (frame->root->client->bound_xl->name, GF_LOG_TRACE, + "%"PRId64": CREATE %s (%s)", + frame->root->unique, state->loc.name, + uuid_utoa (stbuf->ia_gfid)); - if (!link_inode) { - op_ret = -1; - op_errno = ENOENT; - goto out; - } + link_inode = inode_link (inode, state->loc.parent, + state->loc.name, stbuf); - if (link_inode != inode) { - /* - VERY racy code (if used anywhere else) - -- don't do this without understanding - */ + if (!link_inode) { + op_ret = -1; + op_errno = ENOENT; + goto out; + } - inode_unref (fd->inode); - fd->inode = inode_ref (link_inode); - } + if (link_inode != inode) { + /* + VERY racy code (if used anywhere else) + -- don't do this without understanding + */ - inode_lookup (link_inode); - inode_unref (link_inode); + inode_unref (fd->inode); + fd->inode = inode_ref (link_inode); + } - fd_bind (fd); + inode_lookup (link_inode); + inode_unref (link_inode); - fd_no = gf_fd_unused_get (conn->fdtable, fd); - fd_ref (fd); + serv_ctx = server_ctx_get (frame->root->client, this); + if (serv_ctx == NULL) { + gf_log (this->name, GF_LOG_INFO, "server_ctx_get() failed"); + goto out; + } - if ((fd_no < 0) || (fd == 0)) { - op_ret = fd_no; - op_errno = errno; - } + fd_bind (fd); + fd_no = gf_fd_unused_get (serv_ctx->fdtable, fd); + fd_ref (fd); - gf_stat_from_iatt (&rsp.stat, stbuf); - gf_stat_from_iatt (&rsp.preparent, preparent); - gf_stat_from_iatt (&rsp.postparent, postparent); - } else { - gf_log (this->name, GF_LOG_INFO, - "%"PRId64": CREATE %s (%s) ==> %"PRId32" (%s)", - frame->root->unique, state->loc.path, - state->loc.inode ? uuid_utoa (state->loc.inode->gfid) : - "--", op_ret, strerror (op_errno)); + if ((fd_no < 0) || (fd == 0)) { + op_ret = fd_no; + op_errno = errno; } - GF_PROTOCOL_DICT_SERIALIZE (this, xdata, (&rsp.xdata.xdata_val), - rsp.xdata.xdata_len, op_errno, out); + gf_stat_from_iatt (&rsp.stat, stbuf); + gf_stat_from_iatt (&rsp.preparent, preparent); + gf_stat_from_iatt (&rsp.postparent, postparent); out: - req = frame->local; - rsp.fd = fd_no; rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error (op_errno); + req = frame->local; server_submit_reply (frame, req, &rsp, NULL, 0, NULL, (xdrproc_t)xdr_gfs3_create_rsp); - if (rsp.xdata.xdata_val) - GF_FREE (rsp.xdata.xdata_val); + GF_FREE (rsp.xdata.xdata_val); return 0; } @@ -1657,78 +1637,76 @@ server_readlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, const char *buf, struct iatt *stbuf, dict_t *xdata) { - gfs3_readlink_rsp rsp = {0,}; - server_state_t *state = NULL; - rpcsvc_request_t *req = NULL; - - req = frame->local; + gfs3_readlink_rsp rsp = {0,}; + server_state_t *state = NULL; + rpcsvc_request_t *req = NULL; - state = CALL_STATE(frame); + GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val, + rsp.xdata.xdata_len, op_errno, out); - if (op_ret >= 0) { - gf_stat_from_iatt (&rsp.buf, stbuf); - rsp.path = (char *)buf; - } else { + if (op_ret < 0) { + state = CALL_STATE (frame); gf_log (this->name, GF_LOG_INFO, - "%"PRId64": READLINK %s (%s) ==> %"PRId32" (%s)", + "%"PRId64": READLINK %s (%s) ==> (%s)", frame->root->unique, state->loc.path, - state->loc.inode ? uuid_utoa (state->loc.inode->gfid) : - "--", op_ret, strerror (op_errno)); + uuid_utoa (state->resolve.gfid), + strerror (op_errno)); + goto out; } - if (!rsp.path) - rsp.path = ""; - - GF_PROTOCOL_DICT_SERIALIZE (this, xdata, (&rsp.xdata.xdata_val), - rsp.xdata.xdata_len, op_errno, out); + gf_stat_from_iatt (&rsp.buf, stbuf); + rsp.path = (char *)buf; out: rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error (op_errno); + if (!rsp.path) + rsp.path = ""; + + req = frame->local; server_submit_reply (frame, req, &rsp, NULL, 0, NULL, (xdrproc_t)xdr_gfs3_readlink_rsp); - if (rsp.xdata.xdata_val) - GF_FREE (rsp.xdata.xdata_val); + GF_FREE (rsp.xdata.xdata_val); return 0; } int server_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, struct iatt *stbuf, dict_t *xdata) + int32_t op_ret, int32_t op_errno, struct iatt *stbuf, + dict_t *xdata) { - gfs3_stat_rsp rsp = {0,}; - server_state_t *state = NULL; - rpcsvc_request_t *req = NULL; - - req = frame->local; + gfs3_stat_rsp rsp = {0,}; + server_state_t *state = NULL; + rpcsvc_request_t *req = NULL; - state = CALL_STATE (frame); + GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val, + rsp.xdata.xdata_len, op_errno, out); - if (op_ret == 0) { - gf_stat_from_iatt (&rsp.stat, stbuf); - } else { - gf_log (this->name, GF_LOG_INFO, - "%"PRId64": STAT %s (%s) ==> %"PRId32" (%s)", + if (op_ret) { + state = CALL_STATE (frame); + gf_log (this->name, (op_errno == ENOENT)? + GF_LOG_DEBUG:GF_LOG_ERROR, + "%"PRId64": STAT %s (%s) ==> (%s)", frame->root->unique, state->loc.path, - state->loc.inode ? uuid_utoa (state->loc.inode->gfid) : - "--", op_ret, strerror (op_errno)); + uuid_utoa (state->resolve.gfid), + strerror (op_errno)); + goto out; } - GF_PROTOCOL_DICT_SERIALIZE (this, xdata, (&rsp.xdata.xdata_val), - rsp.xdata.xdata_len, op_errno, out); + gf_stat_from_iatt (&rsp.stat, stbuf); out: rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error (op_errno); + req = frame->local; server_submit_reply (frame, req, &rsp, NULL, 0, NULL, (xdrproc_t)xdr_gfs3_stat_rsp); - if (rsp.xdata.xdata_val) - GF_FREE (rsp.xdata.xdata_val); + GF_FREE (rsp.xdata.xdata_val); return 0; } @@ -1739,36 +1717,35 @@ server_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *statpre, struct iatt *statpost, dict_t *xdata) { - gfs3_setattr_rsp rsp = {0,}; - server_state_t *state = NULL; - rpcsvc_request_t *req = NULL; + gfs3_setattr_rsp rsp = {0,}; + server_state_t *state = NULL; + rpcsvc_request_t *req = NULL; - req = frame->local; - state = CALL_STATE (frame); + GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val, + rsp.xdata.xdata_len, op_errno, out); - if (op_ret == 0) { - gf_stat_from_iatt (&rsp.statpre, statpre); - gf_stat_from_iatt (&rsp.statpost, statpost); - } else { + if (op_ret) { + state = CALL_STATE (frame); gf_log (this->name, GF_LOG_INFO, - "%"PRId64": SETATTR %s (%s) ==> %"PRId32" (%s)", + "%"PRId64": SETATTR %s (%s) ==> (%s)", frame->root->unique, state->loc.path, - state->loc.inode ? uuid_utoa (state->loc.inode->gfid) : - "--", op_ret, strerror (op_errno)); + uuid_utoa (state->resolve.gfid), + strerror (op_errno)); + goto out; } - GF_PROTOCOL_DICT_SERIALIZE (this, xdata, (&rsp.xdata.xdata_val), - rsp.xdata.xdata_len, op_errno, out); + gf_stat_from_iatt (&rsp.statpre, statpre); + gf_stat_from_iatt (&rsp.statpost, statpost); out: rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error (op_errno); + req = frame->local; server_submit_reply (frame, req, &rsp, NULL, 0, NULL, (xdrproc_t)xdr_gfs3_setattr_rsp); - if (rsp.xdata.xdata_val) - GF_FREE (rsp.xdata.xdata_val); + GF_FREE (rsp.xdata.xdata_val); return 0; } @@ -1778,37 +1755,35 @@ server_fsetattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *statpre, struct iatt *statpost, dict_t *xdata) { - gfs3_fsetattr_rsp rsp = {0,}; - server_state_t *state = NULL; - rpcsvc_request_t *req = NULL; + gfs3_fsetattr_rsp rsp = {0,}; + server_state_t *state = NULL; + rpcsvc_request_t *req = NULL; - state = CALL_STATE (frame); + GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val, + rsp.xdata.xdata_len, op_errno, out); - if (op_ret == 0) { - gf_stat_from_iatt (&rsp.statpre, statpre); - gf_stat_from_iatt (&rsp.statpost, statpost); - } else { + if (op_ret) { + state = CALL_STATE (frame); gf_log (this->name, GF_LOG_INFO, - "%"PRId64": FSETATTR %"PRId64" (%s) ==> %"PRId32" (%s)", + "%"PRId64": FSETATTR %"PRId64" (%s) ==> (%s)", frame->root->unique, state->resolve.fd_no, - state->fd ? uuid_utoa (state->fd->inode->gfid) : "--", - op_ret, strerror (op_errno)); + uuid_utoa (state->resolve.gfid), + strerror (op_errno)); + goto out; } - req = frame->local; - - GF_PROTOCOL_DICT_SERIALIZE (this, xdata, (&rsp.xdata.xdata_val), - rsp.xdata.xdata_len, op_errno, out); + gf_stat_from_iatt (&rsp.statpre, statpre); + gf_stat_from_iatt (&rsp.statpost, statpost); out: rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error (op_errno); + req = frame->local; server_submit_reply (frame, req, &rsp, NULL, 0, NULL, (xdrproc_t)xdr_gfs3_fsetattr_rsp); - if (rsp.xdata.xdata_val) - GF_FREE (rsp.xdata.xdata_val); + GF_FREE (rsp.xdata.xdata_val); return 0; } @@ -1819,52 +1794,37 @@ server_xattrop_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *dict, dict_t *xdata) { - gfs3_xattrop_rsp rsp = {0,}; - server_state_t *state = NULL; - rpcsvc_request_t *req = NULL; + gfs3_xattrop_rsp rsp = {0,}; + server_state_t *state = NULL; + rpcsvc_request_t *req = NULL; - state = CALL_STATE (frame); + GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val, + rsp.xdata.xdata_len, op_errno, out); if (op_ret < 0) { - gf_log (this->name, GF_LOG_DEBUG, - "%"PRId64": XATTROP %s (%s) ==> %"PRId32" (%s)", + state = CALL_STATE (frame); + gf_log (this->name, GF_LOG_INFO, + "%"PRId64": XATTROP %s (%s) ==> (%s)", frame->root->unique, state->loc.path, - state->loc.inode ? uuid_utoa (state->loc.inode->gfid) : - "--", op_ret, strerror (op_errno)); + uuid_utoa (state->resolve.gfid), + strerror (op_errno)); goto out; } - if ((op_ret >= 0) && dict) { - GF_PROTOCOL_DICT_SERIALIZE (this, dict, - (&rsp.dict.dict_val), - rsp.dict.dict_len, - op_errno, out); - } - - GF_PROTOCOL_DICT_SERIALIZE (this, xdata, (&rsp.xdata.xdata_val), - rsp.xdata.xdata_len, op_errno, out); + GF_PROTOCOL_DICT_SERIALIZE (this, dict, &rsp.dict.dict_val, + rsp.dict.dict_len, op_errno, out); out: - req = frame->local; - rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error (op_errno); - if (op_ret == -1) - gf_log (this->name, GF_LOG_INFO, - "%"PRId64": XATTROP %s (%s) ==> %"PRId32" (%s)", - frame->root->unique, state->loc.path, - state->loc.inode ? uuid_utoa (state->loc.inode->gfid) : - "--", op_ret, strerror (op_errno)); - + req = frame->local; server_submit_reply (frame, req, &rsp, NULL, 0, NULL, (xdrproc_t)xdr_gfs3_xattrop_rsp); - if (rsp.dict.dict_val) - GF_FREE (rsp.dict.dict_val); + GF_FREE (rsp.dict.dict_val); - if (rsp.xdata.xdata_val) - GF_FREE (rsp.xdata.xdata_val); + GF_FREE (rsp.xdata.xdata_val); return 0; } @@ -1875,53 +1835,37 @@ server_fxattrop_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *dict, dict_t *xdata) { - gfs3_xattrop_rsp rsp = {0,}; - server_state_t *state = NULL; - rpcsvc_request_t *req = NULL; + gfs3_xattrop_rsp rsp = {0,}; + server_state_t *state = NULL; + rpcsvc_request_t *req = NULL; - state = CALL_STATE(frame); + GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val, + rsp.xdata.xdata_len, op_errno, out); if (op_ret < 0) { - gf_log (this->name, GF_LOG_DEBUG, - "%"PRId64": FXATTROP %"PRId64" (%s) ==> %"PRId32" (%s)", + state = CALL_STATE (frame); + gf_log (this->name, GF_LOG_INFO, + "%"PRId64": FXATTROP %"PRId64" (%s) ==> (%s)", frame->root->unique, state->resolve.fd_no, - state->fd ? uuid_utoa (state->fd->inode->gfid) : "--", - op_ret, strerror (op_errno)); + uuid_utoa (state->resolve.gfid), + strerror (op_errno)); goto out; } - if ((op_ret >= 0) && dict) { - GF_PROTOCOL_DICT_SERIALIZE (this, dict, - (&rsp.dict.dict_val), - rsp.dict.dict_len, - op_errno, out); - } - - GF_PROTOCOL_DICT_SERIALIZE (this, xdata, (&rsp.xdata.xdata_val), - rsp.xdata.xdata_len, op_errno, out); - + GF_PROTOCOL_DICT_SERIALIZE (this, dict, &rsp.dict.dict_val, + rsp.dict.dict_len, op_errno, out); out: - req = frame->local; - rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error (op_errno); - if (op_ret == -1) - gf_log (this->name, GF_LOG_INFO, - "%"PRId64": FXATTROP %"PRId64" (%s) ==> %"PRId32" (%s)", - frame->root->unique, state->resolve.fd_no, - state->fd ? uuid_utoa (state->fd->inode->gfid) : "--", - op_ret, strerror (op_errno)); - + req = frame->local; server_submit_reply (frame, req, &rsp, NULL, 0, NULL, (xdrproc_t)xdr_gfs3_fxattrop_rsp); - if (rsp.dict.dict_val) - GF_FREE (rsp.dict.dict_val); + GF_FREE (rsp.dict.dict_val); - if (rsp.xdata.xdata_val) - GF_FREE (rsp.xdata.xdata_val); + GF_FREE (rsp.xdata.xdata_val); return 0; } @@ -1929,54 +1873,171 @@ out: int server_readdirp_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, gf_dirent_t *entries, dict_t *xdata) + int32_t op_ret, int32_t op_errno, gf_dirent_t *entries, + dict_t *xdata) { - gfs3_readdirp_rsp rsp = {0,}; - server_state_t *state = NULL; - rpcsvc_request_t *req = NULL; - int ret = 0; + gfs3_readdirp_rsp rsp = {0,}; + server_state_t *state = NULL; + rpcsvc_request_t *req = NULL; + int ret = 0; - req = frame->local; + GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val, + rsp.xdata.xdata_len, op_errno, out); + + if (op_ret < 0) { + state = CALL_STATE (frame); + gf_log (this->name, GF_LOG_INFO, + "%"PRId64": READDIRP %"PRId64" (%s) ==> (%s)", + frame->root->unique, state->resolve.fd_no, + uuid_utoa (state->resolve.gfid), + strerror (op_errno)); + goto out; + } - state = CALL_STATE(frame); - if (op_ret > 0) { + /* (op_ret == 0) is valid, and means EOF */ + if (op_ret) { ret = serialize_rsp_direntp (entries, &rsp); if (ret == -1) { op_ret = -1; op_errno = ENOMEM; goto out; } + } - /* TODO: need more clear thoughts before calling this function. */ - /* gf_link_inodes_from_dirent (this, state->fd->inode, entries); */ + /* TODO: need more clear thoughts before calling this function. */ + /* gf_link_inodes_from_dirent (this, state->fd->inode, entries); */ - } else { - /* (op_ret == 0) is valid, and means EOF, don't log for that */ - gf_log (this->name, (op_ret) ? GF_LOG_INFO : GF_LOG_TRACE, - "%"PRId64": READDIRP %"PRId64" (%s) ==> %"PRId32" (%s)", +out: + rsp.op_ret = op_ret; + rsp.op_errno = gf_errno_to_error (op_errno); + + req = frame->local; + server_submit_reply (frame, req, &rsp, NULL, 0, NULL, + (xdrproc_t)xdr_gfs3_readdirp_rsp); + + GF_FREE (rsp.xdata.xdata_val); + + readdirp_rsp_cleanup (&rsp); + + return 0; +} + +int +server_fallocate_cbk(call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, + struct iatt *statpre, struct iatt *statpost, dict_t *xdata) +{ + gfs3_fallocate_rsp rsp = {0,}; + server_state_t *state = NULL; + rpcsvc_request_t *req = NULL; + + GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val, + rsp.xdata.xdata_len, op_errno, out); + + if (op_ret) { + state = CALL_STATE (frame); + gf_log (this->name, GF_LOG_INFO, + "%"PRId64": FALLOCATE %"PRId64" (%s) ==> (%s)", frame->root->unique, state->resolve.fd_no, - state->fd ? uuid_utoa (state->fd->inode->gfid) : "--", - op_ret, strerror (op_errno)); + uuid_utoa (state->resolve.gfid), + strerror (op_errno)); + goto out; } - GF_PROTOCOL_DICT_SERIALIZE (this, xdata, (&rsp.xdata.xdata_val), + gf_stat_from_iatt (&rsp.statpre, statpre); + gf_stat_from_iatt (&rsp.statpost, statpost); + +out: + rsp.op_ret = op_ret; + rsp.op_errno = gf_errno_to_error (op_errno); + + req = frame->local; + server_submit_reply(frame, req, &rsp, NULL, 0, NULL, + (xdrproc_t) xdr_gfs3_fallocate_rsp); + + GF_FREE (rsp.xdata.xdata_val); + + return 0; +} + +int +server_discard_cbk(call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, + struct iatt *statpre, struct iatt *statpost, dict_t *xdata) +{ + gfs3_discard_rsp rsp = {0,}; + server_state_t *state = NULL; + rpcsvc_request_t *req = NULL; + + GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val, rsp.xdata.xdata_len, op_errno, out); + if (op_ret) { + state = CALL_STATE (frame); + gf_log (this->name, GF_LOG_INFO, + "%"PRId64": DISCARD %"PRId64" (%s) ==> (%s)", + frame->root->unique, state->resolve.fd_no, + uuid_utoa (state->resolve.gfid), + strerror (op_errno)); + goto out; + } + + gf_stat_from_iatt (&rsp.statpre, statpre); + gf_stat_from_iatt (&rsp.statpost, statpost); + out: rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error (op_errno); - server_submit_reply (frame, req, &rsp, NULL, 0, NULL, - (xdrproc_t)xdr_gfs3_readdirp_rsp); + req = frame->local; + server_submit_reply(frame, req, &rsp, NULL, 0, NULL, + (xdrproc_t) xdr_gfs3_discard_rsp); - if (rsp.xdata.xdata_val) - GF_FREE (rsp.xdata.xdata_val); + GF_FREE (rsp.xdata.xdata_val); - readdirp_rsp_cleanup (&rsp); + return 0; +} + +int +server_zerofill_cbk(call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, + struct iatt *statpre, struct iatt *statpost, dict_t *xdata) +{ + gfs3_zerofill_rsp rsp = {0,}; + server_state_t *state = NULL; + rpcsvc_request_t *req = NULL; + + req = frame->local; + state = CALL_STATE (frame); + + GF_PROTOCOL_DICT_SERIALIZE (this, xdata, (&rsp.xdata.xdata_val), + rsp.xdata.xdata_len, op_errno, out); + + if (op_ret) { + gf_log (this->name, GF_LOG_INFO, + "%"PRId64": ZEROFILL%"PRId64" (%s) ==> (%s)", + frame->root->unique, state->resolve.fd_no, + uuid_utoa (state->resolve.gfid), + strerror (op_errno)); + goto out; + } + + gf_stat_from_iatt (&rsp.statpre, statpre); + gf_stat_from_iatt (&rsp.statpost, statpost); + +out: + rsp.op_ret = op_ret; + rsp.op_errno = gf_errno_to_error (op_errno); + + server_submit_reply(frame, req, &rsp, NULL, 0, NULL, + (xdrproc_t) xdr_gfs3_zerofill_rsp); + + GF_FREE (rsp.xdata.xdata_val); return 0; } + /* Resume function section */ int @@ -2140,6 +2201,7 @@ err: int server_fentrylk_resume (call_frame_t *frame, xlator_t *bound_xl) { + GF_UNUSED int ret = -1; server_state_t *state = NULL; state = CALL_STATE (frame); @@ -2147,6 +2209,13 @@ server_fentrylk_resume (call_frame_t *frame, xlator_t *bound_xl) if (state->resolve.op_ret != 0) goto err; + if (!state->xdata) + state->xdata = dict_new (); + + if (state->xdata) + ret = dict_set_str (state->xdata, "connection-id", + frame->root->client->client_uid); + STACK_WIND (frame, server_fentrylk_cbk, bound_xl, bound_xl->fops->fentrylk, state->volume, state->fd, state->name, @@ -2163,6 +2232,7 @@ err: int server_entrylk_resume (call_frame_t *frame, xlator_t *bound_xl) { + GF_UNUSED int ret = -1; server_state_t *state = NULL; state = CALL_STATE (frame); @@ -2170,6 +2240,13 @@ server_entrylk_resume (call_frame_t *frame, xlator_t *bound_xl) if (state->resolve.op_ret != 0) goto err; + if (!state->xdata) + state->xdata = dict_new (); + + if (state->xdata) + ret = dict_set_str (state->xdata, "connection-id", + frame->root->client->client_uid); + STACK_WIND (frame, server_entrylk_cbk, bound_xl, bound_xl->fops->entrylk, state->volume, &state->loc, state->name, @@ -2185,13 +2262,24 @@ err: int server_finodelk_resume (call_frame_t *frame, xlator_t *bound_xl) { + GF_UNUSED int ret = -1; server_state_t *state = NULL; + gf_log (bound_xl->name, GF_LOG_WARNING, "frame %p, xlator %p", + frame, bound_xl); + state = CALL_STATE (frame); if (state->resolve.op_ret != 0) goto err; + if (!state->xdata) + state->xdata = dict_new (); + + if (state->xdata) + ret = dict_set_str (state->xdata, "connection-id", + frame->root->client->client_uid); + STACK_WIND (frame, server_finodelk_cbk, bound_xl, bound_xl->fops->finodelk, state->volume, state->fd, state->cmd, &state->flock, state->xdata); @@ -2207,13 +2295,24 @@ err: int server_inodelk_resume (call_frame_t *frame, xlator_t *bound_xl) { + GF_UNUSED int ret = -1; server_state_t *state = NULL; + gf_log (bound_xl->name, GF_LOG_WARNING, "frame %p, xlator %p", + frame, bound_xl); + state = CALL_STATE (frame); if (state->resolve.op_ret != 0) goto err; + if (!state->xdata) + state->xdata = dict_new (); + + if (state->xdata) + ret = dict_set_str (state->xdata, "connection-id", + frame->root->client->client_uid); + STACK_WIND (frame, server_inodelk_cbk, bound_xl, bound_xl->fops->inodelk, state->volume, &state->loc, state->cmd, &state->flock, state->xdata); @@ -2327,6 +2426,8 @@ server_readdir_resume (call_frame_t *frame, xlator_t *bound_xl) if (state->resolve.op_ret != 0) goto err; + GF_ASSERT (state->fd); + STACK_WIND (frame, server_readdir_cbk, bound_xl, bound_xl->fops->readdir, @@ -2372,6 +2473,10 @@ server_opendir_resume (call_frame_t *frame, xlator_t *bound_xl) goto err; state->fd = fd_create (state->loc.inode, frame->root->pid); + if (!state->fd) { + gf_log ("server", GF_LOG_ERROR, "could not create the fd"); + goto err; + } STACK_WIND (frame, server_opendir_cbk, bound_xl, bound_xl->fops->opendir, @@ -2916,13 +3021,76 @@ err: return 0; } +int +server_fallocate_resume (call_frame_t *frame, xlator_t *bound_xl) +{ + server_state_t *state = NULL; + + state = CALL_STATE (frame); + + if (state->resolve.op_ret != 0) + goto err; + + STACK_WIND (frame, server_fallocate_cbk, + bound_xl, bound_xl->fops->fallocate, + state->fd, state->flags, state->offset, state->size, + state->xdata); + return 0; +err: + server_fallocate_cbk(frame, NULL, frame->this, state->resolve.op_ret, + state->resolve.op_errno, NULL, NULL, NULL); + + return 0; +} + +int +server_discard_resume (call_frame_t *frame, xlator_t *bound_xl) +{ + server_state_t *state = NULL; + + state = CALL_STATE (frame); + + if (state->resolve.op_ret != 0) + goto err; + + STACK_WIND (frame, server_discard_cbk, + bound_xl, bound_xl->fops->discard, + state->fd, state->offset, state->size, state->xdata); + return 0; +err: + server_discard_cbk(frame, NULL, frame->this, state->resolve.op_ret, + state->resolve.op_errno, NULL, NULL, NULL); + + return 0; +} + +int +server_zerofill_resume (call_frame_t *frame, xlator_t *bound_xl) +{ + server_state_t *state = NULL; + + state = CALL_STATE (frame); + + if (state->resolve.op_ret != 0) + goto err; + + STACK_WIND (frame, server_zerofill_cbk, + bound_xl, bound_xl->fops->zerofill, + state->fd, state->offset, state->size, state->xdata); + return 0; +err: + server_zerofill_cbk(frame, NULL, frame->this, state->resolve.op_ret, + state->resolve.op_errno, NULL, NULL, NULL); + + return 0; +} /* Fop section */ int -server_stat (rpcsvc_request_t *req) +server3_3_stat (rpcsvc_request_t *req) { server_state_t *state = NULL; call_frame_t *frame = NULL; @@ -2935,33 +3103,34 @@ server_stat (rpcsvc_request_t *req) /* Initialize args first, then decode */ - if (!xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_stat_req)) { + ret = xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_stat_req); + if (ret < 0) { //failed to decode msg; - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); goto out; } frame = get_frame_from_request (req); if (!frame) { - // something wrong, mostly insufficient memory - req->rpc_err = GARBAGE_ARGS; /* TODO */ + SERVER_REQ_SET_ERROR (req, ret); goto out; } frame->root->op = GF_FOP_STAT; state = CALL_STATE (frame); - if (!state->conn->bound_xl) { + if (!frame->root->client->bound_xl) { /* auth failure, request on subvolume without setvolume */ - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); goto out; } state->resolve.type = RESOLVE_MUST; memcpy (state->resolve.gfid, args.gfid, 16); - GF_PROTOCOL_DICT_UNSERIALIZE (state->conn->bound_xl, state->xdata, - (args.xdata.xdata_val), - (args.xdata.xdata_len), ret, + GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl, + state->xdata, + args.xdata.xdata_val, + args.xdata.xdata_len, ret, op_errno, out); @@ -2969,18 +3138,17 @@ server_stat (rpcsvc_request_t *req) resolve_and_resume (frame, server_stat_resume); out: - if (args.xdata.xdata_val) - free (args.xdata.xdata_val); + free (args.xdata.xdata_val); if (op_errno) - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); return ret; } int -server_setattr (rpcsvc_request_t *req) +server3_3_setattr (rpcsvc_request_t *req) { server_state_t *state = NULL; call_frame_t *frame = NULL; @@ -2991,24 +3159,26 @@ server_setattr (rpcsvc_request_t *req) if (!req) return 0; - if (!xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_setattr_req)) { + ret = xdr_to_generic (req->msg[0], &args, + (xdrproc_t)xdr_gfs3_setattr_req); + if (ret < 0) { //failed to decode msg; - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); goto out; } frame = get_frame_from_request (req); if (!frame) { // something wrong, mostly insufficient memory - req->rpc_err = GARBAGE_ARGS; /* TODO */ + SERVER_REQ_SET_ERROR (req, ret); goto out; } frame->root->op = GF_FOP_SETATTR; state = CALL_STATE (frame); - if (!state->conn->bound_xl) { + if (!frame->root->client->bound_xl) { /* auth failure, request on subvolume without setvolume */ - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); goto out; } @@ -3018,9 +3188,10 @@ server_setattr (rpcsvc_request_t *req) gf_stat_to_iatt (&args.stbuf, &state->stbuf); state->valid = args.valid; - GF_PROTOCOL_DICT_UNSERIALIZE (state->conn->bound_xl, state->xdata, - (args.xdata.xdata_val), - (args.xdata.xdata_len), ret, + GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl, + state->xdata, + args.xdata.xdata_val, + args.xdata.xdata_len, ret, op_errno, out); ret = 0; @@ -3028,17 +3199,16 @@ server_setattr (rpcsvc_request_t *req) out: if (op_errno) - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); - if (args.xdata.xdata_val) - free (args.xdata.xdata_val); + free (args.xdata.xdata_val); return ret; } int -server_fsetattr (rpcsvc_request_t *req) +server3_3_fsetattr (rpcsvc_request_t *req) { server_state_t *state = NULL; call_frame_t *frame = NULL; @@ -3049,24 +3219,25 @@ server_fsetattr (rpcsvc_request_t *req) if (!req) return ret; - if (!xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_fsetattr_req)) { + ret = xdr_to_generic (req->msg[0], &args, + (xdrproc_t)xdr_gfs3_fsetattr_req); + if (ret < 0) { //failed to decode msg; - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); goto out; } frame = get_frame_from_request (req); if (!frame) { - // something wrong, mostly insufficient memory - req->rpc_err = GARBAGE_ARGS; /* TODO */ + SERVER_REQ_SET_ERROR (req, ret); goto out; } frame->root->op = GF_FOP_FSETATTR; state = CALL_STATE (frame); - if (!state->conn->bound_xl) { + if (!frame->root->client->bound_xl) { /* auth failure, request on subvolume without setvolume */ - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); goto out; } @@ -3076,17 +3247,199 @@ server_fsetattr (rpcsvc_request_t *req) gf_stat_to_iatt (&args.stbuf, &state->stbuf); state->valid = args.valid; - GF_PROTOCOL_DICT_UNSERIALIZE (state->conn->bound_xl, state->xdata, + GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl, + state->xdata, + args.xdata.xdata_val, + args.xdata.xdata_len, ret, + op_errno, out); + + ret = 0; + resolve_and_resume (frame, server_fsetattr_resume); + +out: + free (args.xdata.xdata_val); + + if (op_errno) + SERVER_REQ_SET_ERROR (req, ret); + + return ret; +} + +int +server3_3_fallocate(rpcsvc_request_t *req) +{ + server_state_t *state = NULL; + call_frame_t *frame = NULL; + gfs3_fallocate_req args = {{0},}; + int ret = -1; + int op_errno = 0; + + if (!req) + return ret; + + ret = xdr_to_generic (req->msg[0], &args, + (xdrproc_t)xdr_gfs3_fallocate_req); + if (ret < 0) { + //failed to decode msg; + SERVER_REQ_SET_ERROR (req, ret); + goto out; + } + + frame = get_frame_from_request (req); + if (!frame) { + // something wrong, mostly insufficient memory + SERVER_REQ_SET_ERROR (req, ret); + goto out; + } + frame->root->op = GF_FOP_FALLOCATE; + + state = CALL_STATE (frame); + if (!frame->root->client->bound_xl) { + /* auth failure, request on subvolume without setvolume */ + SERVER_REQ_SET_ERROR (req, ret); + goto out; + } + + state->resolve.type = RESOLVE_MUST; + state->resolve.fd_no = args.fd; + + state->flags = args.flags; + state->offset = args.offset; + state->size = args.size; + memcpy(state->resolve.gfid, args.gfid, 16); + + GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl, + state->xdata, + args.xdata.xdata_val, + args.xdata.xdata_len, ret, + op_errno, out); + + ret = 0; + resolve_and_resume (frame, server_fallocate_resume); + +out: + free (args.xdata.xdata_val); + + if (op_errno) + SERVER_REQ_SET_ERROR (req, ret); + + return ret; +} + + +int +server3_3_discard(rpcsvc_request_t *req) +{ + server_state_t *state = NULL; + call_frame_t *frame = NULL; + gfs3_discard_req args = {{0},}; + int ret = -1; + int op_errno = 0; + + if (!req) + return ret; + + ret = xdr_to_generic (req->msg[0], &args, + (xdrproc_t)xdr_gfs3_discard_req); + if (ret < 0) { + //failed to decode msg; + SERVER_REQ_SET_ERROR (req, ret); + goto out; + } + + frame = get_frame_from_request (req); + if (!frame) { + // something wrong, mostly insufficient memory + SERVER_REQ_SET_ERROR (req, ret); + goto out; + } + frame->root->op = GF_FOP_DISCARD; + + state = CALL_STATE (frame); + if (!frame->root->client->bound_xl) { + /* auth failure, request on subvolume without setvolume */ + SERVER_REQ_SET_ERROR (req, ret); + goto out; + } + + state->resolve.type = RESOLVE_MUST; + state->resolve.fd_no = args.fd; + + state->offset = args.offset; + state->size = args.size; + memcpy(state->resolve.gfid, args.gfid, 16); + + GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl, + state->xdata, + args.xdata.xdata_val, + args.xdata.xdata_len, ret, + op_errno, out); + + ret = 0; + resolve_and_resume (frame, server_discard_resume); + +out: + free (args.xdata.xdata_val); + + if (op_errno) + SERVER_REQ_SET_ERROR (req, ret); + + return ret; +} + + +int +server3_3_zerofill(rpcsvc_request_t *req) +{ + server_state_t *state = NULL; + call_frame_t *frame = NULL; + gfs3_zerofill_req args = {{0},}; + int ret = -1; + int op_errno = 0; + + if (!req) + return ret; + + ret = xdr_to_generic (req->msg[0], &args, + (xdrproc_t)xdr_gfs3_zerofill_req); + if (ret < 0) { + /*failed to decode msg*/; + req->rpc_err = GARBAGE_ARGS; + goto out; + } + + frame = get_frame_from_request (req); + if (!frame) { + /* something wrong, mostly insufficient memory*/ + req->rpc_err = GARBAGE_ARGS; /* TODO */ + goto out; + } + frame->root->op = GF_FOP_ZEROFILL; + + state = CALL_STATE (frame); + if (!frame->root->client->bound_xl) { + /* auth failure, request on subvolume without setvolume */ + req->rpc_err = GARBAGE_ARGS; + goto out; + } + + state->resolve.type = RESOLVE_MUST; + state->resolve.fd_no = args.fd; + + state->offset = args.offset; + state->size = args.size; + memcpy(state->resolve.gfid, args.gfid, 16); + + GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl, state->xdata, (args.xdata.xdata_val), (args.xdata.xdata_len), ret, op_errno, out); ret = 0; - resolve_and_resume (frame, server_fsetattr_resume); + resolve_and_resume (frame, server_zerofill_resume); out: - if (args.xdata.xdata_val) - free (args.xdata.xdata_val); + free (args.xdata.xdata_val); if (op_errno) req->rpc_err = GARBAGE_ARGS; @@ -3094,9 +3447,8 @@ out: return ret; } - int -server_readlink (rpcsvc_request_t *req) +server3_3_readlink (rpcsvc_request_t *req) { server_state_t *state = NULL; call_frame_t *frame = NULL; @@ -3107,24 +3459,26 @@ server_readlink (rpcsvc_request_t *req) if (!req) return ret; - if (!xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_readlink_req)) { + ret = xdr_to_generic (req->msg[0], &args, + (xdrproc_t)xdr_gfs3_readlink_req); + if (ret < 0) { //failed to decode msg; - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); goto out; } frame = get_frame_from_request (req); if (!frame) { // something wrong, mostly insufficient memory - req->rpc_err = GARBAGE_ARGS; /* TODO */ + SERVER_REQ_SET_ERROR (req, ret); goto out; } frame->root->op = GF_FOP_READLINK; state = CALL_STATE (frame); - if (!state->conn->bound_xl) { + if (!frame->root->client->bound_xl) { /* auth failure, request on subvolume without setvolume */ - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); goto out; } @@ -3133,27 +3487,27 @@ server_readlink (rpcsvc_request_t *req) state->size = args.size; - GF_PROTOCOL_DICT_UNSERIALIZE (state->conn->bound_xl, state->xdata, - (args.xdata.xdata_val), - (args.xdata.xdata_len), ret, + GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl, + state->xdata, + args.xdata.xdata_val, + args.xdata.xdata_len, ret, op_errno, out); ret = 0; resolve_and_resume (frame, server_readlink_resume); out: - if (args.xdata.xdata_val) - free (args.xdata.xdata_val); + free (args.xdata.xdata_val); if (op_errno) - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); return ret; } int -server_create (rpcsvc_request_t *req) +server3_3_create (rpcsvc_request_t *req) { server_state_t *state = NULL; call_frame_t *frame = NULL; @@ -3166,24 +3520,26 @@ server_create (rpcsvc_request_t *req) args.bname = alloca (req->msg[0].iov_len); - if (!xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_create_req)) { + ret = xdr_to_generic (req->msg[0], &args, + (xdrproc_t)xdr_gfs3_create_req); + if (ret < 0) { //failed to decode msg; - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); goto out; } frame = get_frame_from_request (req); if (!frame) { // something wrong, mostly insufficient memory - req->rpc_err = GARBAGE_ARGS; /* TODO */ + SERVER_REQ_SET_ERROR (req, ret); goto out; } frame->root->op = GF_FOP_CREATE; state = CALL_STATE (frame); - if (!state->conn->bound_xl) { + if (!frame->root->client->bound_xl) { /* auth failure, request on subvolume without setvolume */ - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); goto out; } @@ -3201,9 +3557,10 @@ server_create (rpcsvc_request_t *req) } /* TODO: can do alloca for xdata field instead of stdalloc */ - GF_PROTOCOL_DICT_UNSERIALIZE (state->conn->bound_xl, state->xdata, - (args.xdata.xdata_val), - (args.xdata.xdata_len), ret, + GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl, + state->xdata, + args.xdata.xdata_val, + args.xdata.xdata_len, ret, op_errno, out); ret = 0; @@ -3211,18 +3568,17 @@ server_create (rpcsvc_request_t *req) out: /* memory allocated by libc, don't use GF_FREE */ - if (args.xdata.xdata_val) - free (args.xdata.xdata_val); + free (args.xdata.xdata_val); if (op_errno) - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); return ret; } int -server_open (rpcsvc_request_t *req) +server3_3_open (rpcsvc_request_t *req) { server_state_t *state = NULL; call_frame_t *frame = NULL; @@ -3233,24 +3589,25 @@ server_open (rpcsvc_request_t *req) if (!req) return ret; - if (!xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_open_req)) { + ret = xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_open_req); + if (ret < 0) { //failed to decode msg; - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); goto out; } frame = get_frame_from_request (req); if (!frame) { // something wrong, mostly insufficient memory - req->rpc_err = GARBAGE_ARGS; /* TODO */ + SERVER_REQ_SET_ERROR (req, ret); goto out; } frame->root->op = GF_FOP_OPEN; state = CALL_STATE (frame); - if (!state->conn->bound_xl) { + if (!frame->root->client->bound_xl) { /* auth failure, request on subvolume without setvolume */ - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); goto out; } @@ -3259,26 +3616,26 @@ server_open (rpcsvc_request_t *req) state->flags = gf_flags_to_flags (args.flags); - GF_PROTOCOL_DICT_UNSERIALIZE (state->conn->bound_xl, state->xdata, - (args.xdata.xdata_val), - (args.xdata.xdata_len), ret, + GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl, + state->xdata, + args.xdata.xdata_val, + args.xdata.xdata_len, ret, op_errno, out); ret = 0; resolve_and_resume (frame, server_open_resume); out: if (op_errno) - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); - if (args.xdata.xdata_val) - free (args.xdata.xdata_val); + free (args.xdata.xdata_val); return ret; } int -server_readv (rpcsvc_request_t *req) +server3_3_readv (rpcsvc_request_t *req) { server_state_t *state = NULL; call_frame_t *frame = NULL; @@ -3289,24 +3646,25 @@ server_readv (rpcsvc_request_t *req) if (!req) goto out; - if (!xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_read_req)) { + ret = xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_read_req); + if (ret < 0) { //failed to decode msg; - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); goto out; } frame = get_frame_from_request (req); if (!frame) { // something wrong, mostly insufficient memory - req->rpc_err = GARBAGE_ARGS; /* TODO */ + SERVER_REQ_SET_ERROR (req, ret); goto out; } frame->root->op = GF_FOP_READ; state = CALL_STATE (frame); - if (!state->conn->bound_xl) { + if (!frame->root->client->bound_xl) { /* auth failure, request on subvolume without setvolume */ - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); goto out; } @@ -3318,27 +3676,27 @@ server_readv (rpcsvc_request_t *req) memcpy (state->resolve.gfid, args.gfid, 16); - GF_PROTOCOL_DICT_UNSERIALIZE (state->conn->bound_xl, state->xdata, - (args.xdata.xdata_val), - (args.xdata.xdata_len), ret, + GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl, + state->xdata, + args.xdata.xdata_val, + args.xdata.xdata_len, ret, op_errno, out); ret = 0; resolve_and_resume (frame, server_readv_resume); out: /* memory allocated by libc, don't use GF_FREE */ - if (args.xdata.xdata_val) - free (args.xdata.xdata_val); + free (args.xdata.xdata_val); if (op_errno) - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); return ret; } int -server_writev (rpcsvc_request_t *req) +server3_3_writev (rpcsvc_request_t *req) { server_state_t *state = NULL; call_frame_t *frame = NULL; @@ -3351,25 +3709,26 @@ server_writev (rpcsvc_request_t *req) if (!req) return ret; - len = xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_write_req); - if (len == 0) { + len = xdr_to_generic (req->msg[0], &args, + (xdrproc_t)xdr_gfs3_write_req); + if (len < 0) { //failed to decode msg; - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); goto out; } frame = get_frame_from_request (req); if (!frame) { // something wrong, mostly insufficient memory - req->rpc_err = GARBAGE_ARGS; /* TODO */ + SERVER_REQ_SET_ERROR (req, ret); goto out; } frame->root->op = GF_FOP_WRITE; state = CALL_STATE (frame); - if (!state->conn->bound_xl) { + if (!frame->root->client->bound_xl) { /* auth failure, request on subvolume without setvolume */ - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); goto out; } @@ -3397,9 +3756,10 @@ server_writev (rpcsvc_request_t *req) state->size += state->payload_vector[i].iov_len; } - GF_PROTOCOL_DICT_UNSERIALIZE (state->conn->bound_xl, state->xdata, - (args.xdata.xdata_val), - (args.xdata.xdata_len), ret, + GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl, + state->xdata, + args.xdata.xdata_val, + args.xdata.xdata_len, ret, op_errno, out); #ifdef GF_TESTING_IO_XDATA @@ -3409,29 +3769,21 @@ server_writev (rpcsvc_request_t *req) ret = 0; resolve_and_resume (frame, server_writev_resume); out: - if (args.xdata.xdata_val) - free (args.xdata.xdata_val); + free (args.xdata.xdata_val); if (op_errno) - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); return ret; } -int -server_writev_vec (rpcsvc_request_t *req, struct iovec *payload, - int payload_count, struct iobref *iobref) -{ - return server_writev (req); -} - -#define SERVER3_1_VECWRITE_START 0 -#define SERVER3_1_VECWRITE_READING_HDR 1 -#define SERVER3_1_VECWRITE_READING_OPAQUE 2 +#define SERVER3_3_VECWRITE_START 0 +#define SERVER3_3_VECWRITE_READING_HDR 1 +#define SERVER3_3_VECWRITE_READING_OPAQUE 2 int -server_writev_vecsizer (int state, ssize_t *readsize, char *base_addr, +server3_3_writev_vecsizer (int state, ssize_t *readsize, char *base_addr, char *curr_addr) { ssize_t size = 0; @@ -3440,13 +3792,13 @@ server_writev_vecsizer (int state, ssize_t *readsize, char *base_addr, XDR xdr; switch (state) { - case SERVER3_1_VECWRITE_START: + case SERVER3_3_VECWRITE_START: size = xdr_sizeof ((xdrproc_t) xdr_gfs3_write_req, &write_req); *readsize = size; - nextstate = SERVER3_1_VECWRITE_READING_HDR; + nextstate = SERVER3_3_VECWRITE_READING_HDR; break; - case SERVER3_1_VECWRITE_READING_HDR: + case SERVER3_3_VECWRITE_READING_HDR: size = xdr_sizeof ((xdrproc_t) xdr_gfs3_write_req, &write_req); @@ -3463,18 +3815,17 @@ server_writev_vecsizer (int state, ssize_t *readsize, char *base_addr, *readsize = size; if (!size) - nextstate = SERVER3_1_VECWRITE_START; + nextstate = SERVER3_3_VECWRITE_START; else - nextstate = SERVER3_1_VECWRITE_READING_OPAQUE; + nextstate = SERVER3_3_VECWRITE_READING_OPAQUE; - if (write_req.xdata.xdata_val) - free (write_req.xdata.xdata_val); + free (write_req.xdata.xdata_val); break; - case SERVER3_1_VECWRITE_READING_OPAQUE: + case SERVER3_3_VECWRITE_READING_OPAQUE: *readsize = 0; - nextstate = SERVER3_1_VECWRITE_START; + nextstate = SERVER3_3_VECWRITE_START; break; default: gf_log ("server", GF_LOG_ERROR, "wrong state: %d", state); @@ -3485,25 +3836,38 @@ server_writev_vecsizer (int state, ssize_t *readsize, char *base_addr, int -server_release (rpcsvc_request_t *req) +server3_3_release (rpcsvc_request_t *req) { - server_connection_t *conn = NULL; - gfs3_release_req args = {{0,},}; - gf_common_rsp rsp = {0,}; - int ret = -1; + client_t *client = NULL; + server_ctx_t *serv_ctx = NULL; + gfs3_release_req args = {{0,},}; + gf_common_rsp rsp = {0,}; + int ret = -1; - if (!xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_release_req)) { + ret = xdr_to_generic (req->msg[0], &args, + (xdrproc_t)xdr_gfs3_release_req); + if (ret < 0) { //failed to decode msg; - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); goto out; } - conn = req->trans->xl_private; - if (!conn) { - req->rpc_err = GARBAGE_ARGS; + client = req->trans->xl_private; + if (!client) { + /* Handshake is not complete yet. */ + req->rpc_err = SYSTEM_ERR; goto out; } - gf_fd_put (conn->fdtable, args.fd); + + serv_ctx = server_ctx_get (client, client->this); + if (serv_ctx == NULL) { + gf_log (req->trans->name, GF_LOG_INFO, + "server_ctx_get() failed"); + req->rpc_err = SYSTEM_ERR; + goto out; + } + + gf_fd_put (serv_ctx->fdtable, args.fd); server_submit_reply (NULL, req, &rsp, NULL, 0, NULL, (xdrproc_t)xdr_gf_common_rsp); @@ -3514,26 +3878,37 @@ out: } int -server_releasedir (rpcsvc_request_t *req) +server3_3_releasedir (rpcsvc_request_t *req) { - server_connection_t *conn = NULL; - gfs3_releasedir_req args = {{0,},}; - gf_common_rsp rsp = {0,}; - int ret = -1; + client_t *client = NULL; + server_ctx_t *serv_ctx = NULL; + gfs3_releasedir_req args = {{0,},}; + gf_common_rsp rsp = {0,}; + int ret = -1; - if (!xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_release_req)) { + ret = xdr_to_generic (req->msg[0], &args, + (xdrproc_t)xdr_gfs3_release_req); + if (ret < 0) { //failed to decode msg; - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); goto out; } - conn = req->trans->xl_private; - if (!conn) { - req->rpc_err = GARBAGE_ARGS; + client = req->trans->xl_private; + if (!client) { + SERVER_REQ_SET_ERROR (req, ret); + goto out; + } + + serv_ctx = server_ctx_get (client, client->this); + if (serv_ctx == NULL) { + gf_log (req->trans->name, GF_LOG_INFO, + "server_ctx_get() failed"); + req->rpc_err = SYSTEM_ERR; goto out; } - gf_fd_put (conn->fdtable, args.fd); + gf_fd_put (serv_ctx->fdtable, args.fd); server_submit_reply (NULL, req, &rsp, NULL, 0, NULL, (xdrproc_t)xdr_gf_common_rsp); @@ -3545,7 +3920,7 @@ out: int -server_fsync (rpcsvc_request_t *req) +server3_3_fsync (rpcsvc_request_t *req) { server_state_t *state = NULL; call_frame_t *frame = NULL; @@ -3556,24 +3931,26 @@ server_fsync (rpcsvc_request_t *req) if (!req) return ret; - if (!xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_fsync_req)) { + ret = xdr_to_generic (req->msg[0], &args, + (xdrproc_t)xdr_gfs3_fsync_req); + if (ret < 0) { //failed to decode msg; - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); goto out; } frame = get_frame_from_request (req); if (!frame) { // something wrong, mostly insufficient memory - req->rpc_err = GARBAGE_ARGS; /* TODO */ + SERVER_REQ_SET_ERROR (req, ret); goto out; } frame->root->op = GF_FOP_FSYNC; state = CALL_STATE (frame); - if (!state->conn->bound_xl) { + if (!frame->root->client->bound_xl) { /* auth failure, request on subvolume without setvolume */ - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); goto out; } @@ -3582,19 +3959,19 @@ server_fsync (rpcsvc_request_t *req) state->flags = args.data; memcpy (state->resolve.gfid, args.gfid, 16); - GF_PROTOCOL_DICT_UNSERIALIZE (state->conn->bound_xl, state->xdata, - (args.xdata.xdata_val), - (args.xdata.xdata_len), ret, + GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl, + state->xdata, + args.xdata.xdata_val, + args.xdata.xdata_len, ret, op_errno, out); ret = 0; resolve_and_resume (frame, server_fsync_resume); out: - if (args.xdata.xdata_val) - free (args.xdata.xdata_val); + free (args.xdata.xdata_val); if (op_errno) - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); return ret; } @@ -3602,7 +3979,7 @@ out: int -server_flush (rpcsvc_request_t *req) +server3_3_flush (rpcsvc_request_t *req) { server_state_t *state = NULL; call_frame_t *frame = NULL; @@ -3613,24 +3990,26 @@ server_flush (rpcsvc_request_t *req) if (!req) return ret; - if (!xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_flush_req)) { + ret = xdr_to_generic (req->msg[0], &args, + (xdrproc_t)xdr_gfs3_flush_req); + if (ret < 0) { //failed to decode msg; - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); goto out; } frame = get_frame_from_request (req); if (!frame) { // something wrong, mostly insufficient memory - req->rpc_err = GARBAGE_ARGS; /* TODO */ + SERVER_REQ_SET_ERROR (req, ret); goto out; } frame->root->op = GF_FOP_FLUSH; state = CALL_STATE (frame); - if (!state->conn->bound_xl) { + if (!frame->root->client->bound_xl) { /* auth failure, request on subvolume without setvolume */ - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); goto out; } @@ -3638,19 +4017,19 @@ server_flush (rpcsvc_request_t *req) state->resolve.fd_no = args.fd; memcpy (state->resolve.gfid, args.gfid, 16); - GF_PROTOCOL_DICT_UNSERIALIZE (state->conn->bound_xl, state->xdata, - (args.xdata.xdata_val), - (args.xdata.xdata_len), ret, + GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl, + state->xdata, + args.xdata.xdata_val, + args.xdata.xdata_len, ret, op_errno, out); ret = 0; resolve_and_resume (frame, server_flush_resume); out: - if (args.xdata.xdata_val) - free (args.xdata.xdata_val); + free (args.xdata.xdata_val); if (op_errno) - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); return ret; } @@ -3658,7 +4037,7 @@ out: int -server_ftruncate (rpcsvc_request_t *req) +server3_3_ftruncate (rpcsvc_request_t *req) { server_state_t *state = NULL; call_frame_t *frame = NULL; @@ -3669,24 +4048,26 @@ server_ftruncate (rpcsvc_request_t *req) if (!req) return ret; - if (!xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_ftruncate_req)) { + ret = xdr_to_generic (req->msg[0], &args, + (xdrproc_t)xdr_gfs3_ftruncate_req); + if (ret < 0) { //failed to decode msg; - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); goto out; } frame = get_frame_from_request (req); if (!frame) { // something wrong, mostly insufficient memory - req->rpc_err = GARBAGE_ARGS; /* TODO */ + SERVER_REQ_SET_ERROR (req, ret); goto out; } frame->root->op = GF_FOP_FTRUNCATE; state = CALL_STATE (frame); - if (!state->conn->bound_xl) { + if (!frame->root->client->bound_xl) { /* auth failure, request on subvolume without setvolume */ - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); goto out; } @@ -3695,26 +4076,26 @@ server_ftruncate (rpcsvc_request_t *req) state->offset = args.offset; memcpy (state->resolve.gfid, args.gfid, 16); - GF_PROTOCOL_DICT_UNSERIALIZE (state->conn->bound_xl, state->xdata, - (args.xdata.xdata_val), - (args.xdata.xdata_len), ret, + GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl, + state->xdata, + args.xdata.xdata_val, + args.xdata.xdata_len, ret, op_errno, out); ret = 0; resolve_and_resume (frame, server_ftruncate_resume); out: - if (args.xdata.xdata_val) - free (args.xdata.xdata_val); + free (args.xdata.xdata_val); if (op_errno) - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); return ret; } int -server_fstat (rpcsvc_request_t *req) +server3_3_fstat (rpcsvc_request_t *req) { server_state_t *state = NULL; call_frame_t *frame = NULL; @@ -3725,24 +4106,26 @@ server_fstat (rpcsvc_request_t *req) if (!req) return ret; - if (!xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_fstat_req)) { + ret = xdr_to_generic (req->msg[0], &args, + (xdrproc_t)xdr_gfs3_fstat_req); + if (ret < 0) { //failed to decode msg; - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); goto out; } frame = get_frame_from_request (req); if (!frame) { // something wrong, mostly insufficient memory - req->rpc_err = GARBAGE_ARGS; /* TODO */ + SERVER_REQ_SET_ERROR (req, ret); goto out; } frame->root->op = GF_FOP_FSTAT; state = CALL_STATE (frame); - if (!state->conn->bound_xl) { + if (!frame->root->client->bound_xl) { /* auth failure, request on subvolume without setvolume */ - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); goto out; } @@ -3750,26 +4133,26 @@ server_fstat (rpcsvc_request_t *req) state->resolve.fd_no = args.fd; memcpy (state->resolve.gfid, args.gfid, 16); - GF_PROTOCOL_DICT_UNSERIALIZE (state->conn->bound_xl, state->xdata, - (args.xdata.xdata_val), - (args.xdata.xdata_len), ret, + GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl, + state->xdata, + args.xdata.xdata_val, + args.xdata.xdata_len, ret, op_errno, out); ret = 0; resolve_and_resume (frame, server_fstat_resume); out: - if (args.xdata.xdata_val) - free (args.xdata.xdata_val); + free (args.xdata.xdata_val); if (op_errno) - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); return ret; } int -server_truncate (rpcsvc_request_t *req) +server3_3_truncate (rpcsvc_request_t *req) { server_state_t *state = NULL; call_frame_t *frame = NULL; @@ -3780,24 +4163,26 @@ server_truncate (rpcsvc_request_t *req) if (!req) return ret; - if (!xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_truncate_req)) { + ret = xdr_to_generic (req->msg[0], &args, + (xdrproc_t)xdr_gfs3_truncate_req); + if (ret < 0) { //failed to decode msg; - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); goto out; } frame = get_frame_from_request (req); if (!frame) { // something wrong, mostly insufficient memory - req->rpc_err = GARBAGE_ARGS; /* TODO */ + SERVER_REQ_SET_ERROR (req, ret); goto out; } frame->root->op = GF_FOP_TRUNCATE; state = CALL_STATE (frame); - if (!state->conn->bound_xl) { + if (!frame->root->client->bound_xl) { /* auth failure, request on subvolume without setvolume */ - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); goto out; } @@ -3805,19 +4190,19 @@ server_truncate (rpcsvc_request_t *req) memcpy (state->resolve.gfid, args.gfid, 16); state->offset = args.offset; - GF_PROTOCOL_DICT_UNSERIALIZE (state->conn->bound_xl, state->xdata, - (args.xdata.xdata_val), - (args.xdata.xdata_len), ret, + GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl, + state->xdata, + args.xdata.xdata_val, + args.xdata.xdata_len, ret, op_errno, out); ret = 0; resolve_and_resume (frame, server_truncate_resume); out: - if (args.xdata.xdata_val) - free (args.xdata.xdata_val); + free (args.xdata.xdata_val); if (op_errno) - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); return ret; } @@ -3825,7 +4210,7 @@ out: int -server_unlink (rpcsvc_request_t *req) +server3_3_unlink (rpcsvc_request_t *req) { server_state_t *state = NULL; call_frame_t *frame = NULL; @@ -3838,24 +4223,26 @@ server_unlink (rpcsvc_request_t *req) args.bname = alloca (req->msg[0].iov_len); - if (!xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_unlink_req)) { + ret = xdr_to_generic (req->msg[0], &args, + (xdrproc_t)xdr_gfs3_unlink_req); + if (ret < 0) { //failed to decode msg; - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); goto out; } frame = get_frame_from_request (req); if (!frame) { // something wrong, mostly insufficient memory - req->rpc_err = GARBAGE_ARGS; /* TODO */ + SERVER_REQ_SET_ERROR (req, ret); goto out; } frame->root->op = GF_FOP_UNLINK; state = CALL_STATE (frame); - if (!state->conn->bound_xl) { + if (!frame->root->client->bound_xl) { /* auth failure, request on subvolume without setvolume */ - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); goto out; } @@ -3865,26 +4252,26 @@ server_unlink (rpcsvc_request_t *req) state->flags = args.xflags; - GF_PROTOCOL_DICT_UNSERIALIZE (state->conn->bound_xl, state->xdata, - (args.xdata.xdata_val), - (args.xdata.xdata_len), ret, + GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl, + state->xdata, + args.xdata.xdata_val, + args.xdata.xdata_len, ret, op_errno, out); ret = 0; resolve_and_resume (frame, server_unlink_resume); out: - if (args.xdata.xdata_val) - free (args.xdata.xdata_val); + free (args.xdata.xdata_val); if (op_errno) - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); return ret; } int -server_setxattr (rpcsvc_request_t *req) +server3_3_setxattr (rpcsvc_request_t *req) { server_state_t *state = NULL; dict_t *dict = NULL; @@ -3898,24 +4285,26 @@ server_setxattr (rpcsvc_request_t *req) args.dict.dict_val = alloca (req->msg[0].iov_len); - if (!xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_setxattr_req)) { + ret = xdr_to_generic (req->msg[0], &args, + (xdrproc_t)xdr_gfs3_setxattr_req); + if (ret < 0) { //failed to decode msg; - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); goto out; } frame = get_frame_from_request (req); if (!frame) { // something wrong, mostly insufficient memory - req->rpc_err = GARBAGE_ARGS; /* TODO */ + SERVER_REQ_SET_ERROR (req, ret); goto out; } frame->root->op = GF_FOP_SETXATTR; state = CALL_STATE (frame); - if (!state->conn->bound_xl) { + if (!frame->root->client->bound_xl) { /* auth failure, request on subvolume without setvolume */ - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); goto out; } @@ -3923,7 +4312,8 @@ server_setxattr (rpcsvc_request_t *req) state->flags = args.flags; memcpy (state->resolve.gfid, args.gfid, 16); - GF_PROTOCOL_DICT_UNSERIALIZE (state->conn->bound_xl, dict, + GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl, + dict, (args.dict.dict_val), (args.dict.dict_len), ret, op_errno, out); @@ -3933,9 +4323,10 @@ server_setxattr (rpcsvc_request_t *req) /* There can be some commands hidden in key, check and proceed */ gf_server_check_setxattr_cmd (frame, dict); - GF_PROTOCOL_DICT_UNSERIALIZE (state->conn->bound_xl, state->xdata, - (args.xdata.xdata_val), - (args.xdata.xdata_len), ret, + GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl, + state->xdata, + args.xdata.xdata_val, + args.xdata.xdata_len, ret, op_errno, out); ret = 0; @@ -3943,11 +4334,10 @@ server_setxattr (rpcsvc_request_t *req) return ret; out: - if (args.xdata.xdata_val) - free (args.xdata.xdata_val); + free (args.xdata.xdata_val); if (op_errno) - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); if (dict) dict_unref (dict); @@ -3958,7 +4348,7 @@ out: int -server_fsetxattr (rpcsvc_request_t *req) +server3_3_fsetxattr (rpcsvc_request_t *req) { server_state_t *state = NULL; dict_t *dict = NULL; @@ -3971,24 +4361,26 @@ server_fsetxattr (rpcsvc_request_t *req) return ret; args.dict.dict_val = alloca (req->msg[0].iov_len); - if (!xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_fsetxattr_req)) { + ret = xdr_to_generic (req->msg[0], &args, + (xdrproc_t)xdr_gfs3_fsetxattr_req); + if (ret < 0) { //failed to decode msg; - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); goto out; } frame = get_frame_from_request (req); if (!frame) { // something wrong, mostly insufficient memory - req->rpc_err = GARBAGE_ARGS; /* TODO */ + SERVER_REQ_SET_ERROR (req, ret); goto out; } frame->root->op = GF_FOP_FSETXATTR; state = CALL_STATE (frame); - if (!state->conn->bound_xl) { + if (!frame->root->client->bound_xl) { /* auth failure, request on subvolume without setvolume */ - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); goto out; } @@ -3997,16 +4389,18 @@ server_fsetxattr (rpcsvc_request_t *req) state->flags = args.flags; memcpy (state->resolve.gfid, args.gfid, 16); - GF_PROTOCOL_DICT_UNSERIALIZE (state->conn->bound_xl, dict, + GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl, + dict, (args.dict.dict_val), (args.dict.dict_len), ret, op_errno, out); state->dict = dict; - GF_PROTOCOL_DICT_UNSERIALIZE (state->conn->bound_xl, state->xdata, - (args.xdata.xdata_val), - (args.xdata.xdata_len), ret, + GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl, + state->xdata, + args.xdata.xdata_val, + args.xdata.xdata_len, ret, op_errno, out); ret = 0; @@ -4014,11 +4408,10 @@ server_fsetxattr (rpcsvc_request_t *req) return ret; out: - if (args.xdata.xdata_val) - free (args.xdata.xdata_val); + free (args.xdata.xdata_val); if (op_errno) - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); if (dict) dict_unref (dict); @@ -4029,7 +4422,7 @@ out: int -server_fxattrop (rpcsvc_request_t *req) +server3_3_fxattrop (rpcsvc_request_t *req) { dict_t *dict = NULL; server_state_t *state = NULL; @@ -4042,24 +4435,26 @@ server_fxattrop (rpcsvc_request_t *req) return ret; args.dict.dict_val = alloca (req->msg[0].iov_len); - if (!xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_fxattrop_req)) { + ret = xdr_to_generic (req->msg[0], &args, + (xdrproc_t)xdr_gfs3_fxattrop_req); + if (ret < 0) { //failed to decode msg; - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); goto out; } frame = get_frame_from_request (req); if (!frame) { // something wrong, mostly insufficient memory - req->rpc_err = GARBAGE_ARGS; /* TODO */ + SERVER_REQ_SET_ERROR (req, ret); goto out; } frame->root->op = GF_FOP_FXATTROP; - state = CALL_STATE(frame); - if (!state->conn->bound_xl) { + state = CALL_STATE (frame); + if (!frame->root->client->bound_xl) { /* auth failure, request on subvolume without setvolume */ - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); goto out; } @@ -4068,16 +4463,18 @@ server_fxattrop (rpcsvc_request_t *req) state->flags = args.flags; memcpy (state->resolve.gfid, args.gfid, 16); - GF_PROTOCOL_DICT_UNSERIALIZE (state->conn->bound_xl, dict, + GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl, + dict, (args.dict.dict_val), (args.dict.dict_len), ret, op_errno, out); state->dict = dict; - GF_PROTOCOL_DICT_UNSERIALIZE (state->conn->bound_xl, state->xdata, - (args.xdata.xdata_val), - (args.xdata.xdata_len), ret, + GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl, + state->xdata, + args.xdata.xdata_val, + args.xdata.xdata_len, ret, op_errno, out); ret = 0; @@ -4086,11 +4483,10 @@ server_fxattrop (rpcsvc_request_t *req) return ret; out: - if (args.xdata.xdata_val) - free (args.xdata.xdata_val); + free (args.xdata.xdata_val); if (op_errno) - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); if (dict) dict_unref (dict); @@ -4101,7 +4497,7 @@ out: int -server_xattrop (rpcsvc_request_t *req) +server3_3_xattrop (rpcsvc_request_t *req) { dict_t *dict = NULL; server_state_t *state = NULL; @@ -4115,24 +4511,26 @@ server_xattrop (rpcsvc_request_t *req) args.dict.dict_val = alloca (req->msg[0].iov_len); - if (!xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_xattrop_req)) { + ret = xdr_to_generic (req->msg[0], &args, + (xdrproc_t)xdr_gfs3_xattrop_req); + if (ret < 0) { //failed to decode msg; - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); goto out; } frame = get_frame_from_request (req); if (!frame) { // something wrong, mostly insufficient memory - req->rpc_err = GARBAGE_ARGS; /* TODO */ + SERVER_REQ_SET_ERROR (req, ret); goto out; } frame->root->op = GF_FOP_XATTROP; - state = CALL_STATE(frame); - if (!state->conn->bound_xl) { + state = CALL_STATE (frame); + if (!frame->root->client->bound_xl) { /* auth failure, request on subvolume without setvolume */ - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); goto out; } @@ -4140,16 +4538,18 @@ server_xattrop (rpcsvc_request_t *req) state->flags = args.flags; memcpy (state->resolve.gfid, args.gfid, 16); - GF_PROTOCOL_DICT_UNSERIALIZE (state->conn->bound_xl, dict, + GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl, + dict, (args.dict.dict_val), (args.dict.dict_len), ret, op_errno, out); state->dict = dict; - GF_PROTOCOL_DICT_UNSERIALIZE (state->conn->bound_xl, state->xdata, - (args.xdata.xdata_val), - (args.xdata.xdata_len), ret, + GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl, + state->xdata, + args.xdata.xdata_val, + args.xdata.xdata_len, ret, op_errno, out); ret = 0; @@ -4157,11 +4557,10 @@ server_xattrop (rpcsvc_request_t *req) return ret; out: - if (args.xdata.xdata_val) - free (args.xdata.xdata_val); + free (args.xdata.xdata_val); if (op_errno) - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); if (dict) dict_unref (dict); @@ -4171,7 +4570,7 @@ out: int -server_getxattr (rpcsvc_request_t *req) +server3_3_getxattr (rpcsvc_request_t *req) { server_state_t *state = NULL; call_frame_t *frame = NULL; @@ -4184,24 +4583,26 @@ server_getxattr (rpcsvc_request_t *req) args.name = alloca (256); - if (!xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_getxattr_req)) { + ret = xdr_to_generic (req->msg[0], &args, + (xdrproc_t)xdr_gfs3_getxattr_req); + if (ret < 0) { //failed to decode msg; - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); goto out; } frame = get_frame_from_request (req); if (!frame) { // something wrong, mostly insufficient memory - req->rpc_err = GARBAGE_ARGS; /* TODO */ + SERVER_REQ_SET_ERROR (req, ret); goto out; } frame->root->op = GF_FOP_GETXATTR; state = CALL_STATE (frame); - if (!state->conn->bound_xl) { + if (!frame->root->client->bound_xl) { /* auth failure, request on subvolume without setvolume */ - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); goto out; } @@ -4214,26 +4615,26 @@ server_getxattr (rpcsvc_request_t *req) gf_server_check_getxattr_cmd (frame, state->name); } - GF_PROTOCOL_DICT_UNSERIALIZE (state->conn->bound_xl, state->xdata, - (args.xdata.xdata_val), - (args.xdata.xdata_len), ret, + GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl, + state->xdata, + args.xdata.xdata_val, + args.xdata.xdata_len, ret, op_errno, out); ret = 0; resolve_and_resume (frame, server_getxattr_resume); out: - if (args.xdata.xdata_val) - free (args.xdata.xdata_val); + free (args.xdata.xdata_val); if (op_errno) - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); return ret; } int -server_fgetxattr (rpcsvc_request_t *req) +server3_3_fgetxattr (rpcsvc_request_t *req) { server_state_t *state = NULL; call_frame_t *frame = NULL; @@ -4245,24 +4646,26 @@ server_fgetxattr (rpcsvc_request_t *req) return ret; args.name = alloca (256); - if (!xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_fgetxattr_req)) { + ret = xdr_to_generic (req->msg[0], &args, + (xdrproc_t)xdr_gfs3_fgetxattr_req); + if (ret < 0) { //failed to decode msg; - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); goto out; } frame = get_frame_from_request (req); if (!frame) { // something wrong, mostly insufficient memory - req->rpc_err = GARBAGE_ARGS; /* TODO */ + SERVER_REQ_SET_ERROR (req, ret); goto out; } frame->root->op = GF_FOP_FGETXATTR; state = CALL_STATE (frame); - if (!state->conn->bound_xl) { + if (!frame->root->client->bound_xl) { /* auth failure, request on subvolume without setvolume */ - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); goto out; } @@ -4273,19 +4676,19 @@ server_fgetxattr (rpcsvc_request_t *req) if (args.namelen) state->name = gf_strdup (args.name); - GF_PROTOCOL_DICT_UNSERIALIZE (state->conn->bound_xl, state->xdata, - (args.xdata.xdata_val), - (args.xdata.xdata_len), ret, + GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl, + state->xdata, + args.xdata.xdata_val, + args.xdata.xdata_len, ret, op_errno, out); ret = 0; resolve_and_resume (frame, server_fgetxattr_resume); out: - if (args.xdata.xdata_val) - free (args.xdata.xdata_val); + free (args.xdata.xdata_val); if (op_errno) - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); return ret; } @@ -4293,7 +4696,7 @@ out: int -server_removexattr (rpcsvc_request_t *req) +server3_3_removexattr (rpcsvc_request_t *req) { server_state_t *state = NULL; call_frame_t *frame = NULL; @@ -4306,24 +4709,26 @@ server_removexattr (rpcsvc_request_t *req) args.name = alloca (256); - if (!xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_removexattr_req)) { + ret = xdr_to_generic (req->msg[0], &args, + (xdrproc_t)xdr_gfs3_removexattr_req); + if (ret < 0) { //failed to decode msg; - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); goto out; } frame = get_frame_from_request (req); if (!frame) { // something wrong, mostly insufficient memory - req->rpc_err = GARBAGE_ARGS; /* TODO */ + SERVER_REQ_SET_ERROR (req, ret); goto out; } frame->root->op = GF_FOP_REMOVEXATTR; state = CALL_STATE (frame); - if (!state->conn->bound_xl) { + if (!frame->root->client->bound_xl) { /* auth failure, request on subvolume without setvolume */ - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); goto out; } @@ -4331,25 +4736,25 @@ server_removexattr (rpcsvc_request_t *req) memcpy (state->resolve.gfid, args.gfid, 16); state->name = gf_strdup (args.name); - GF_PROTOCOL_DICT_UNSERIALIZE (state->conn->bound_xl, state->xdata, - (args.xdata.xdata_val), - (args.xdata.xdata_len), ret, + GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl, + state->xdata, + args.xdata.xdata_val, + args.xdata.xdata_len, ret, op_errno, out); ret = 0; resolve_and_resume (frame, server_removexattr_resume); out: - if (args.xdata.xdata_val) - free (args.xdata.xdata_val); + free (args.xdata.xdata_val); if (op_errno) - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); return ret; } int -server_fremovexattr (rpcsvc_request_t *req) +server3_3_fremovexattr (rpcsvc_request_t *req) { server_state_t *state = NULL; call_frame_t *frame = NULL; @@ -4362,25 +4767,26 @@ server_fremovexattr (rpcsvc_request_t *req) args.name = alloca (4096); - if (!xdr_to_generic (req->msg[0], &args, - (xdrproc_t)xdr_gfs3_fremovexattr_req)) { + ret = xdr_to_generic (req->msg[0], &args, + (xdrproc_t)xdr_gfs3_fremovexattr_req); + if (ret < 0) { //failed to decode msg; - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); goto out; } frame = get_frame_from_request (req); if (!frame) { // something wrong, mostly insufficient memory - req->rpc_err = GARBAGE_ARGS; /* TODO */ + SERVER_REQ_SET_ERROR (req, ret); goto out; } frame->root->op = GF_FOP_FREMOVEXATTR; state = CALL_STATE (frame); - if (!state->conn->bound_xl) { + if (!frame->root->client->bound_xl) { /* auth failure, request on subvolume without setvolume */ - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); goto out; } @@ -4389,19 +4795,19 @@ server_fremovexattr (rpcsvc_request_t *req) memcpy (state->resolve.gfid, args.gfid, 16); state->name = gf_strdup (args.name); - GF_PROTOCOL_DICT_UNSERIALIZE (state->conn->bound_xl, state->xdata, - (args.xdata.xdata_val), - (args.xdata.xdata_len), ret, + GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl, + state->xdata, + args.xdata.xdata_val, + args.xdata.xdata_len, ret, op_errno, out); ret = 0; resolve_and_resume (frame, server_fremovexattr_resume); out: - if (args.xdata.xdata_val) - free (args.xdata.xdata_val); + free (args.xdata.xdata_val); if (op_errno) - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); return ret; } @@ -4410,7 +4816,7 @@ out: int -server_opendir (rpcsvc_request_t *req) +server3_3_opendir (rpcsvc_request_t *req) { server_state_t *state = NULL; call_frame_t *frame = NULL; @@ -4421,50 +4827,52 @@ server_opendir (rpcsvc_request_t *req) if (!req) return ret; - if (!xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_opendir_req)) { + ret = xdr_to_generic (req->msg[0], &args, + (xdrproc_t)xdr_gfs3_opendir_req); + if (ret < 0) { //failed to decode msg; - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); goto out; } frame = get_frame_from_request (req); if (!frame) { // something wrong, mostly insufficient memory - req->rpc_err = GARBAGE_ARGS; /* TODO */ + SERVER_REQ_SET_ERROR (req, ret); goto out; } frame->root->op = GF_FOP_OPENDIR; state = CALL_STATE (frame); - if (!state->conn->bound_xl) { + if (!frame->root->client->bound_xl) { /* auth failure, request on subvolume without setvolume */ - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); goto out; } state->resolve.type = RESOLVE_MUST; memcpy (state->resolve.gfid, args.gfid, 16); - GF_PROTOCOL_DICT_UNSERIALIZE (state->conn->bound_xl, state->xdata, - (args.xdata.xdata_val), - (args.xdata.xdata_len), ret, + GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl, + state->xdata, + args.xdata.xdata_val, + args.xdata.xdata_len, ret, op_errno, out); ret = 0; resolve_and_resume (frame, server_opendir_resume); out: - if (args.xdata.xdata_val) - free (args.xdata.xdata_val); + free (args.xdata.xdata_val); if (op_errno) - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); return ret; } int -server_readdirp (rpcsvc_request_t *req) +server3_3_readdirp (rpcsvc_request_t *req) { server_state_t *state = NULL; call_frame_t *frame = NULL; @@ -4476,24 +4884,26 @@ server_readdirp (rpcsvc_request_t *req) if (!req) return ret; - if (!xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_readdirp_req)) { + ret = xdr_to_generic (req->msg[0], &args, + (xdrproc_t)xdr_gfs3_readdirp_req); + if (ret < 0) { //failed to decode msg; - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); goto out; } frame = get_frame_from_request (req); if (!frame) { // something wrong, mostly insufficient memory - req->rpc_err = GARBAGE_ARGS; /* TODO */ + SERVER_REQ_SET_ERROR (req, ret); goto out; } frame->root->op = GF_FOP_READDIRP; - state = CALL_STATE(frame); - if (!state->conn->bound_xl) { + state = CALL_STATE (frame); + if (!frame->root->client->bound_xl) { /* auth failure, request on subvolume without setvolume */ - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); goto out; } @@ -4514,7 +4924,8 @@ server_readdirp (rpcsvc_request_t *req) memcpy (state->resolve.gfid, args.gfid, 16); /* here, dict itself works as xdata */ - GF_PROTOCOL_DICT_UNSERIALIZE (state->conn->bound_xl, state->dict, + GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl, + state->dict, (args.dict.dict_val), (args.dict.dict_len), ret, op_errno, out); @@ -4524,16 +4935,15 @@ server_readdirp (rpcsvc_request_t *req) resolve_and_resume (frame, server_readdirp_resume); out: if (op_errno) - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); - if (args.dict.dict_val) - free (args.dict.dict_val); + free (args.dict.dict_val); return ret; } int -server_readdir (rpcsvc_request_t *req) +server3_3_readdir (rpcsvc_request_t *req) { server_state_t *state = NULL; call_frame_t *frame = NULL; @@ -4545,24 +4955,26 @@ server_readdir (rpcsvc_request_t *req) if (!req) return ret; - if (!xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_readdir_req)) { + ret = xdr_to_generic (req->msg[0], &args, + (xdrproc_t)xdr_gfs3_readdir_req); + if (ret < 0) { //failed to decode msg; - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); goto out; } frame = get_frame_from_request (req); if (!frame) { // something wrong, mostly insufficient memory - req->rpc_err = GARBAGE_ARGS; /* TODO */ + SERVER_REQ_SET_ERROR (req, ret); goto out; } frame->root->op = GF_FOP_READDIR; - state = CALL_STATE(frame); - if (!state->conn->bound_xl) { + state = CALL_STATE (frame); + if (!frame->root->client->bound_xl) { /* auth failure, request on subvolume without setvolume */ - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); goto out; } @@ -4582,25 +4994,25 @@ server_readdir (rpcsvc_request_t *req) state->offset = args.offset; memcpy (state->resolve.gfid, args.gfid, 16); - GF_PROTOCOL_DICT_UNSERIALIZE (state->conn->bound_xl, state->xdata, - (args.xdata.xdata_val), - (args.xdata.xdata_len), ret, + GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl, + state->xdata, + args.xdata.xdata_val, + args.xdata.xdata_len, ret, op_errno, out); ret = 0; resolve_and_resume (frame, server_readdir_resume); out: - if (args.xdata.xdata_val) - free (args.xdata.xdata_val); + free (args.xdata.xdata_val); if (op_errno) - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); return ret; } int -server_fsyncdir (rpcsvc_request_t *req) +server3_3_fsyncdir (rpcsvc_request_t *req) { server_state_t *state = NULL; call_frame_t *frame = NULL; @@ -4611,24 +5023,26 @@ server_fsyncdir (rpcsvc_request_t *req) if (!req) return ret; - if (!xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_fsyncdir_req)) { + ret = xdr_to_generic (req->msg[0], &args, + (xdrproc_t)xdr_gfs3_fsyncdir_req); + if (ret < 0) { //failed to decode msg; - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); goto out; } frame = get_frame_from_request (req); if (!frame) { // something wrong, mostly insufficient memory - req->rpc_err = GARBAGE_ARGS; /* TODO */ + SERVER_REQ_SET_ERROR (req, ret); goto out; } frame->root->op = GF_FOP_FSYNCDIR; - state = CALL_STATE(frame); - if (!state->conn->bound_xl) { + state = CALL_STATE (frame); + if (!frame->root->client->bound_xl) { /* auth failure, request on subvolume without setvolume */ - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); goto out; } @@ -4637,19 +5051,19 @@ server_fsyncdir (rpcsvc_request_t *req) state->flags = args.data; memcpy (state->resolve.gfid, args.gfid, 16); - GF_PROTOCOL_DICT_UNSERIALIZE (state->conn->bound_xl, state->xdata, - (args.xdata.xdata_val), - (args.xdata.xdata_len), ret, + GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl, + state->xdata, + args.xdata.xdata_val, + args.xdata.xdata_len, ret, op_errno, out); ret = 0; resolve_and_resume (frame, server_fsyncdir_resume); out: - if (args.xdata.xdata_val) - free (args.xdata.xdata_val); + free (args.xdata.xdata_val); if (op_errno) - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); return ret; } @@ -4657,7 +5071,7 @@ out: int -server_mknod (rpcsvc_request_t *req) +server3_3_mknod (rpcsvc_request_t *req) { server_state_t *state = NULL; call_frame_t *frame = NULL; @@ -4670,24 +5084,26 @@ server_mknod (rpcsvc_request_t *req) args.bname = alloca (req->msg[0].iov_len); - if (!xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_mknod_req)) { + ret = xdr_to_generic (req->msg[0], &args, + (xdrproc_t)xdr_gfs3_mknod_req); + if (ret < 0) { //failed to decode msg; - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); goto out; } frame = get_frame_from_request (req); if (!frame) { // something wrong, mostly insufficient memory - req->rpc_err = GARBAGE_ARGS; /* TODO */ + SERVER_REQ_SET_ERROR (req, ret); goto out; } frame->root->op = GF_FOP_MKNOD; state = CALL_STATE (frame); - if (!state->conn->bound_xl) { + if (!frame->root->client->bound_xl) { /* auth failure, request on subvolume without setvolume */ - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); goto out; } @@ -4699,9 +5115,10 @@ server_mknod (rpcsvc_request_t *req) state->dev = args.dev; state->umask = args.umask; - GF_PROTOCOL_DICT_UNSERIALIZE (state->conn->bound_xl, state->xdata, - (args.xdata.xdata_val), - (args.xdata.xdata_len), ret, + GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl, + state->xdata, + args.xdata.xdata_val, + args.xdata.xdata_len, ret, op_errno, out); ret = 0; @@ -4709,11 +5126,10 @@ server_mknod (rpcsvc_request_t *req) out: if (op_errno) - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); /* memory allocated by libc, don't use GF_FREE */ - if (args.xdata.xdata_val) - free (args.xdata.xdata_val); + free (args.xdata.xdata_val); return ret; @@ -4721,7 +5137,7 @@ out: int -server_mkdir (rpcsvc_request_t *req) +server3_3_mkdir (rpcsvc_request_t *req) { server_state_t *state = NULL; call_frame_t *frame = NULL; @@ -4734,24 +5150,26 @@ server_mkdir (rpcsvc_request_t *req) args.bname = alloca (req->msg[0].iov_len); - if (!xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_mkdir_req)) { + ret = xdr_to_generic (req->msg[0], &args, + (xdrproc_t)xdr_gfs3_mkdir_req); + if (ret < 0) { //failed to decode msg; - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); goto out; } frame = get_frame_from_request (req); if (!frame) { // something wrong, mostly insufficient memory - req->rpc_err = GARBAGE_ARGS; /* TODO */ + SERVER_REQ_SET_ERROR (req, ret); goto out; } frame->root->op = GF_FOP_MKDIR; state = CALL_STATE (frame); - if (!state->conn->bound_xl) { + if (!frame->root->client->bound_xl) { /* auth failure, request on subvolume without setvolume */ - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); goto out; } @@ -4763,9 +5181,10 @@ server_mkdir (rpcsvc_request_t *req) state->umask = args.umask; /* TODO: can do alloca for xdata field instead of stdalloc */ - GF_PROTOCOL_DICT_UNSERIALIZE (state->conn->bound_xl, state->xdata, - (args.xdata.xdata_val), - (args.xdata.xdata_len), ret, + GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl, + state->xdata, + args.xdata.xdata_val, + args.xdata.xdata_len, ret, op_errno, out); ret = 0; @@ -4773,17 +5192,16 @@ server_mkdir (rpcsvc_request_t *req) out: if (op_errno) - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); - if (args.xdata.xdata_val) - free (args.xdata.xdata_val); + free (args.xdata.xdata_val); return ret; } int -server_rmdir (rpcsvc_request_t *req) +server3_3_rmdir (rpcsvc_request_t *req) { server_state_t *state = NULL; call_frame_t *frame = NULL; @@ -4796,24 +5214,26 @@ server_rmdir (rpcsvc_request_t *req) args.bname = alloca (req->msg[0].iov_len); - if (!xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_rmdir_req)) { + ret = xdr_to_generic (req->msg[0], &args, + (xdrproc_t)xdr_gfs3_rmdir_req); + if (ret < 0) { //failed to decode msg; - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); goto out; } frame = get_frame_from_request (req); if (!frame) { // something wrong, mostly insufficient memory - req->rpc_err = GARBAGE_ARGS; /* TODO */ + SERVER_REQ_SET_ERROR (req, ret); goto out; } frame->root->op = GF_FOP_RMDIR; state = CALL_STATE (frame); - if (!state->conn->bound_xl) { + if (!frame->root->client->bound_xl) { /* auth failure, request on subvolume without setvolume */ - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); goto out; } @@ -4823,19 +5243,19 @@ server_rmdir (rpcsvc_request_t *req) state->flags = args.xflags; - GF_PROTOCOL_DICT_UNSERIALIZE (state->conn->bound_xl, state->xdata, - (args.xdata.xdata_val), - (args.xdata.xdata_len), ret, + GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl, + state->xdata, + args.xdata.xdata_val, + args.xdata.xdata_len, ret, op_errno, out); ret = 0; resolve_and_resume (frame, server_rmdir_resume); out: - if (args.xdata.xdata_val) - free (args.xdata.xdata_val); + free (args.xdata.xdata_val); if (op_errno) - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); return ret; } @@ -4843,7 +5263,7 @@ out: int -server_inodelk (rpcsvc_request_t *req) +server3_3_inodelk (rpcsvc_request_t *req) { server_state_t *state = NULL; call_frame_t *frame = NULL; @@ -4857,24 +5277,26 @@ server_inodelk (rpcsvc_request_t *req) args.volume = alloca (256); - if (!xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_inodelk_req)) { + ret = xdr_to_generic (req->msg[0], &args, + (xdrproc_t)xdr_gfs3_inodelk_req); + if (ret < 0) { //failed to decode msg; - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); goto out; } frame = get_frame_from_request (req); if (!frame) { // something wrong, mostly insufficient memory - req->rpc_err = GARBAGE_ARGS; /* TODO */ + SERVER_REQ_SET_ERROR (req, ret); goto out; } frame->root->op = GF_FOP_INODELK; state = CALL_STATE (frame); - if (!state->conn->bound_xl) { + if (!frame->root->client->bound_xl) { /* auth failure, request on subvolume without setvolume */ - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); goto out; } @@ -4911,28 +5333,27 @@ server_inodelk (rpcsvc_request_t *req) break; } - GF_PROTOCOL_DICT_UNSERIALIZE (state->conn->bound_xl, state->xdata, - (args.xdata.xdata_val), - (args.xdata.xdata_len), ret, + GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl, + state->xdata, + args.xdata.xdata_val, + args.xdata.xdata_len, ret, op_errno, out); ret = 0; resolve_and_resume (frame, server_inodelk_resume); out: - if (args.xdata.xdata_val) - free (args.xdata.xdata_val); + free (args.xdata.xdata_val); - if (args.flock.lk_owner.lk_owner_val) - free (args.flock.lk_owner.lk_owner_val); + free (args.flock.lk_owner.lk_owner_val); if (op_errno) - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); return ret; } int -server_finodelk (rpcsvc_request_t *req) +server3_3_finodelk (rpcsvc_request_t *req) { server_state_t *state = NULL; call_frame_t *frame = NULL; @@ -4944,24 +5365,26 @@ server_finodelk (rpcsvc_request_t *req) return ret; args.volume = alloca (256); - if (!xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_finodelk_req)) { + ret = xdr_to_generic (req->msg[0], &args, + (xdrproc_t)xdr_gfs3_finodelk_req); + if (ret < 0) { //failed to decode msg; - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); goto out; } frame = get_frame_from_request (req); if (!frame) { // something wrong, mostly insufficient memory - req->rpc_err = GARBAGE_ARGS; /* TODO */ + SERVER_REQ_SET_ERROR (req, ret); goto out; } frame->root->op = GF_FOP_FINODELK; - state = CALL_STATE(frame); - if (!state->conn->bound_xl) { + state = CALL_STATE (frame); + if (!frame->root->client->bound_xl) { /* auth failure, request on subvolume without setvolume */ - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); goto out; } @@ -4999,29 +5422,28 @@ server_finodelk (rpcsvc_request_t *req) break; } - GF_PROTOCOL_DICT_UNSERIALIZE (state->conn->bound_xl, state->xdata, - (args.xdata.xdata_val), - (args.xdata.xdata_len), ret, + GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl, + state->xdata, + args.xdata.xdata_val, + args.xdata.xdata_len, ret, op_errno, out); ret = 0; resolve_and_resume (frame, server_finodelk_resume); out: - if (args.xdata.xdata_val) - free (args.xdata.xdata_val); + free (args.xdata.xdata_val); - if (args.flock.lk_owner.lk_owner_val) - free (args.flock.lk_owner.lk_owner_val); + free (args.flock.lk_owner.lk_owner_val); if (op_errno) - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); return ret; } int -server_entrylk (rpcsvc_request_t *req) +server3_3_entrylk (rpcsvc_request_t *req) { server_state_t *state = NULL; call_frame_t *frame = NULL; @@ -5035,24 +5457,26 @@ server_entrylk (rpcsvc_request_t *req) args.volume = alloca (256); args.name = alloca (256); - if (!xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_entrylk_req)) { + ret = xdr_to_generic (req->msg[0], &args, + (xdrproc_t)xdr_gfs3_entrylk_req); + if (ret < 0) { //failed to decode msg; - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); goto out; } frame = get_frame_from_request (req); if (!frame) { // something wrong, mostly insufficient memory - req->rpc_err = GARBAGE_ARGS; /* TODO */ + SERVER_REQ_SET_ERROR (req, ret); goto out; } frame->root->op = GF_FOP_ENTRYLK; state = CALL_STATE (frame); - if (!state->conn->bound_xl) { + if (!frame->root->client->bound_xl) { /* auth failure, request on subvolume without setvolume */ - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); goto out; } @@ -5066,25 +5490,25 @@ server_entrylk (rpcsvc_request_t *req) state->cmd = args.cmd; state->type = args.type; - GF_PROTOCOL_DICT_UNSERIALIZE (state->conn->bound_xl, state->xdata, - (args.xdata.xdata_val), - (args.xdata.xdata_len), ret, + GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl, + state->xdata, + args.xdata.xdata_val, + args.xdata.xdata_len, ret, op_errno, out); ret = 0; resolve_and_resume (frame, server_entrylk_resume); out: - if (args.xdata.xdata_val) - free (args.xdata.xdata_val); + free (args.xdata.xdata_val); if (op_errno) - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); return ret; } int -server_fentrylk (rpcsvc_request_t *req) +server3_3_fentrylk (rpcsvc_request_t *req) { server_state_t *state = NULL; call_frame_t *frame = NULL; @@ -5098,24 +5522,26 @@ server_fentrylk (rpcsvc_request_t *req) args.name = alloca (256); args.volume = alloca (256); - if (!xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_fentrylk_req)) { + ret = xdr_to_generic (req->msg[0], &args, + (xdrproc_t)xdr_gfs3_fentrylk_req); + if (ret < 0) { //failed to decode msg; - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); goto out; } frame = get_frame_from_request (req); if (!frame) { // something wrong, mostly insufficient memory - req->rpc_err = GARBAGE_ARGS; /* TODO */ + SERVER_REQ_SET_ERROR (req, ret); goto out; } frame->root->op = GF_FOP_FENTRYLK; - state = CALL_STATE(frame); - if (!state->conn->bound_xl) { + state = CALL_STATE (frame); + if (!frame->root->client->bound_xl) { /* auth failure, request on subvolume without setvolume */ - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); goto out; } @@ -5129,25 +5555,25 @@ server_fentrylk (rpcsvc_request_t *req) state->name = gf_strdup (args.name); state->volume = gf_strdup (args.volume); - GF_PROTOCOL_DICT_UNSERIALIZE (state->conn->bound_xl, state->xdata, - (args.xdata.xdata_val), - (args.xdata.xdata_len), ret, + GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl, + state->xdata, + args.xdata.xdata_val, + args.xdata.xdata_len, ret, op_errno, out); ret = 0; resolve_and_resume (frame, server_fentrylk_resume); out: - if (args.xdata.xdata_val) - free (args.xdata.xdata_val); + free (args.xdata.xdata_val); if (op_errno) - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); return ret; } int -server_access (rpcsvc_request_t *req) +server3_3_access (rpcsvc_request_t *req) { server_state_t *state = NULL; call_frame_t *frame = NULL; @@ -5158,24 +5584,26 @@ server_access (rpcsvc_request_t *req) if (!req) return ret; - if (!xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_access_req)) { + ret = xdr_to_generic (req->msg[0], &args, + (xdrproc_t)xdr_gfs3_access_req); + if (ret < 0) { //failed to decode msg; - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); goto out; } frame = get_frame_from_request (req); if (!frame) { // something wrong, mostly insufficient memory - req->rpc_err = GARBAGE_ARGS; /* TODO */ + SERVER_REQ_SET_ERROR (req, ret); goto out; } frame->root->op = GF_FOP_ACCESS; state = CALL_STATE (frame); - if (!state->conn->bound_xl) { + if (!frame->root->client->bound_xl) { /* auth failure, request on subvolume without setvolume */ - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); goto out; } @@ -5183,19 +5611,19 @@ server_access (rpcsvc_request_t *req) memcpy (state->resolve.gfid, args.gfid, 16); state->mask = args.mask; - GF_PROTOCOL_DICT_UNSERIALIZE (state->conn->bound_xl, state->xdata, - (args.xdata.xdata_val), - (args.xdata.xdata_len), ret, + GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl, + state->xdata, + args.xdata.xdata_val, + args.xdata.xdata_len, ret, op_errno, out); ret = 0; resolve_and_resume (frame, server_access_resume); out: - if (args.xdata.xdata_val) - free (args.xdata.xdata_val); + free (args.xdata.xdata_val); if (op_errno) - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); return ret; } @@ -5203,7 +5631,7 @@ out: int -server_symlink (rpcsvc_request_t *req) +server3_3_symlink (rpcsvc_request_t *req) { server_state_t *state = NULL; call_frame_t *frame = NULL; @@ -5217,24 +5645,26 @@ server_symlink (rpcsvc_request_t *req) args.bname = alloca (req->msg[0].iov_len); args.linkname = alloca (4096); - if (!xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_symlink_req)) { + ret = xdr_to_generic (req->msg[0], &args, + (xdrproc_t)xdr_gfs3_symlink_req); + if (ret < 0) { //failed to decode msg; - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); goto out; } frame = get_frame_from_request (req); if (!frame) { // something wrong, mostly insufficient memory - req->rpc_err = GARBAGE_ARGS; /* TODO */ + SERVER_REQ_SET_ERROR (req, ret); goto out; } frame->root->op = GF_FOP_SYMLINK; state = CALL_STATE (frame); - if (!state->conn->bound_xl) { + if (!frame->root->client->bound_xl) { /* auth failure, request on subvolume without setvolume */ - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); goto out; } @@ -5244,9 +5674,10 @@ server_symlink (rpcsvc_request_t *req) state->name = gf_strdup (args.linkname); state->umask = args.umask; - GF_PROTOCOL_DICT_UNSERIALIZE (state->conn->bound_xl, state->xdata, - (args.xdata.xdata_val), - (args.xdata.xdata_len), ret, + GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl, + state->xdata, + args.xdata.xdata_val, + args.xdata.xdata_len, ret, op_errno, out); ret = 0; @@ -5254,11 +5685,10 @@ server_symlink (rpcsvc_request_t *req) out: if (op_errno) - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); /* memory allocated by libc, don't use GF_FREE */ - if (args.xdata.xdata_val) - free (args.xdata.xdata_val); + free (args.xdata.xdata_val); return ret; } @@ -5266,7 +5696,7 @@ out: int -server_link (rpcsvc_request_t *req) +server3_3_link (rpcsvc_request_t *req) { server_state_t *state = NULL; call_frame_t *frame = NULL; @@ -5279,24 +5709,25 @@ server_link (rpcsvc_request_t *req) args.newbname = alloca (req->msg[0].iov_len); - if (!xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_link_req)) { + ret = xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_link_req); + if (ret < 0) { //failed to decode msg; - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); goto out; } frame = get_frame_from_request (req); if (!frame) { // something wrong, mostly insufficient memory - req->rpc_err = GARBAGE_ARGS; /* TODO */ + SERVER_REQ_SET_ERROR (req, ret); goto out; } frame->root->op = GF_FOP_LINK; state = CALL_STATE (frame); - if (!state->conn->bound_xl) { + if (!frame->root->client->bound_xl) { /* auth failure, request on subvolume without setvolume */ - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); goto out; } @@ -5307,26 +5738,26 @@ server_link (rpcsvc_request_t *req) state->resolve2.bname = gf_strdup (args.newbname); memcpy (state->resolve2.pargfid, args.newgfid, 16); - GF_PROTOCOL_DICT_UNSERIALIZE (state->conn->bound_xl, state->xdata, - (args.xdata.xdata_val), - (args.xdata.xdata_len), ret, + GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl, + state->xdata, + args.xdata.xdata_val, + args.xdata.xdata_len, ret, op_errno, out); ret = 0; resolve_and_resume (frame, server_link_resume); out: - if (args.xdata.xdata_val) - free (args.xdata.xdata_val); + free (args.xdata.xdata_val); if (op_errno) - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); return ret; } int -server_rename (rpcsvc_request_t *req) +server3_3_rename (rpcsvc_request_t *req) { server_state_t *state = NULL; call_frame_t *frame = NULL; @@ -5340,24 +5771,26 @@ server_rename (rpcsvc_request_t *req) args.oldbname = alloca (req->msg[0].iov_len); args.newbname = alloca (req->msg[0].iov_len); - if (!xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_rename_req)) { + ret = xdr_to_generic (req->msg[0], &args, + (xdrproc_t)xdr_gfs3_rename_req); + if (ret < 0) { //failed to decode msg; - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); goto out; } frame = get_frame_from_request (req); if (!frame) { // something wrong, mostly insufficient memory - req->rpc_err = GARBAGE_ARGS; /* TODO */ + SERVER_REQ_SET_ERROR (req, ret); goto out; } frame->root->op = GF_FOP_RENAME; state = CALL_STATE (frame); - if (!state->conn->bound_xl) { + if (!frame->root->client->bound_xl) { /* auth failure, request on subvolume without setvolume */ - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); goto out; } @@ -5369,25 +5802,25 @@ server_rename (rpcsvc_request_t *req) state->resolve2.bname = gf_strdup (args.newbname); memcpy (state->resolve2.pargfid, args.newgfid, 16); - GF_PROTOCOL_DICT_UNSERIALIZE (state->conn->bound_xl, state->xdata, - (args.xdata.xdata_val), - (args.xdata.xdata_len), ret, + GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl, + state->xdata, + args.xdata.xdata_val, + args.xdata.xdata_len, ret, op_errno, out); ret = 0; resolve_and_resume (frame, server_rename_resume); out: - if (args.xdata.xdata_val) - free (args.xdata.xdata_val); + free (args.xdata.xdata_val); if (op_errno) - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); return ret; } int -server_lk (rpcsvc_request_t *req) +server3_3_lk (rpcsvc_request_t *req) { server_state_t *state = NULL; call_frame_t *frame = NULL; @@ -5398,24 +5831,25 @@ server_lk (rpcsvc_request_t *req) if (!req) return ret; - if (!xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_lk_req)) { + ret = xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_lk_req); + if (ret < 0) { //failed to decode msg; - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); goto out; } frame = get_frame_from_request (req); if (!frame) { // something wrong, mostly insufficient memory - req->rpc_err = GARBAGE_ARGS; /* TODO */ + SERVER_REQ_SET_ERROR (req, ret); goto out; } frame->root->op = GF_FOP_LK; state = CALL_STATE (frame); - if (!state->conn->bound_xl) { + if (!frame->root->client->bound_xl) { /* auth failure, request on subvolume without setvolume */ - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); goto out; } @@ -5463,7 +5897,7 @@ server_lk (rpcsvc_request_t *req) state->flock.l_type = F_UNLCK; break; default: - gf_log (state->conn->bound_xl->name, GF_LOG_ERROR, + gf_log (frame->root->client->bound_xl->name, GF_LOG_ERROR, "fd - %"PRId64" (%s): Unknown lock type: %"PRId32"!", state->resolve.fd_no, uuid_utoa (state->fd->inode->gfid), state->type); @@ -5471,29 +5905,28 @@ server_lk (rpcsvc_request_t *req) } - GF_PROTOCOL_DICT_UNSERIALIZE (state->conn->bound_xl, state->xdata, - (args.xdata.xdata_val), - (args.xdata.xdata_len), ret, + GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl, + state->xdata, + args.xdata.xdata_val, + args.xdata.xdata_len, ret, op_errno, out); ret = 0; resolve_and_resume (frame, server_lk_resume); out: - if (args.xdata.xdata_val) - free (args.xdata.xdata_val); + free (args.xdata.xdata_val); - if (args.flock.lk_owner.lk_owner_val) - free (args.flock.lk_owner.lk_owner_val); + free (args.flock.lk_owner.lk_owner_val); if (op_errno) - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); return ret; } int -server_rchecksum (rpcsvc_request_t *req) +server3_3_rchecksum (rpcsvc_request_t *req) { server_state_t *state = NULL; call_frame_t *frame = NULL; @@ -5504,24 +5937,26 @@ server_rchecksum (rpcsvc_request_t *req) if (!req) return ret; - if (!xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_rchecksum_req)) { + ret = xdr_to_generic (req->msg[0], &args, + (xdrproc_t)xdr_gfs3_rchecksum_req); + if (ret < 0) { //failed to decode msg; - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); goto out; } frame = get_frame_from_request (req); if (!frame) { // something wrong, mostly insufficient memory - req->rpc_err = GARBAGE_ARGS; /* TODO */ + SERVER_REQ_SET_ERROR (req, ret); goto out; } frame->root->op = GF_FOP_RCHECKSUM; - state = CALL_STATE(frame); - if (!state->conn->bound_xl) { + state = CALL_STATE (frame); + if (!frame->root->client->bound_xl) { /* auth failure, request on subvolume without setvolume */ - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); goto out; } @@ -5530,19 +5965,19 @@ server_rchecksum (rpcsvc_request_t *req) state->offset = args.offset; state->size = args.len; - GF_PROTOCOL_DICT_UNSERIALIZE (state->conn->bound_xl, state->xdata, - (args.xdata.xdata_val), - (args.xdata.xdata_len), ret, + GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl, + state->xdata, + args.xdata.xdata_val, + args.xdata.xdata_len, ret, op_errno, out); ret = 0; resolve_and_resume (frame, server_rchecksum_resume); out: - if (args.xdata.xdata_val) - free (args.xdata.xdata_val); + free (args.xdata.xdata_val); if (op_errno) - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); return ret; } @@ -5562,7 +5997,7 @@ server_null (rpcsvc_request_t *req) } int -server_lookup (rpcsvc_request_t *req) +server3_3_lookup (rpcsvc_request_t *req) { call_frame_t *frame = NULL; server_state_t *state = NULL; @@ -5575,16 +6010,18 @@ server_lookup (rpcsvc_request_t *req) args.bname = alloca (req->msg[0].iov_len); args.xdata.xdata_val = alloca (req->msg[0].iov_len); - if (!xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_lookup_req)) { + ret = xdr_to_generic (req->msg[0], &args, + (xdrproc_t)xdr_gfs3_lookup_req); + if (ret < 0) { //failed to decode msg; - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); goto err; } frame = get_frame_from_request (req); if (!frame) { // something wrong, mostly insufficient memory - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); goto err; } frame->root->op = GF_FOP_LOOKUP; @@ -5594,9 +6031,9 @@ server_lookup (rpcsvc_request_t *req) */ state = CALL_STATE (frame); - if (!state->conn->bound_xl) { + if (!frame->root->client->bound_xl) { /* auth failure, request on subvolume without setvolume */ - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); goto out; } @@ -5609,9 +6046,10 @@ server_lookup (rpcsvc_request_t *req) memcpy (state->resolve.gfid, args.gfid, 16); } - GF_PROTOCOL_DICT_UNSERIALIZE (state->conn->bound_xl, state->xdata, - (args.xdata.xdata_val), - (args.xdata.xdata_len), ret, + GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl, + state->xdata, + args.xdata.xdata_val, + args.xdata.xdata_len, ret, op_errno, out); ret = 0; @@ -5628,7 +6066,7 @@ err: } int -server_statfs (rpcsvc_request_t *req) +server3_3_statfs (rpcsvc_request_t *req) { server_state_t *state = NULL; call_frame_t *frame = NULL; @@ -5639,97 +6077,103 @@ server_statfs (rpcsvc_request_t *req) if (!req) return ret; - if (!xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_statfs_req)) { + ret = xdr_to_generic (req->msg[0], &args, + (xdrproc_t)xdr_gfs3_statfs_req); + if (ret < 0) { //failed to decode msg; - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); goto out; } frame = get_frame_from_request (req); if (!frame) { // something wrong, mostly insufficient memory - req->rpc_err = GARBAGE_ARGS; /* TODO */ + SERVER_REQ_SET_ERROR (req, ret); goto out; } frame->root->op = GF_FOP_STATFS; state = CALL_STATE (frame); - if (!state->conn->bound_xl) { + if (!frame->root->client->bound_xl) { /* auth failure, request on subvolume without setvolume */ - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); goto out; } state->resolve.type = RESOLVE_MUST; memcpy (state->resolve.gfid, args.gfid, 16); - GF_PROTOCOL_DICT_UNSERIALIZE (state->conn->bound_xl, state->xdata, - (args.xdata.xdata_val), - (args.xdata.xdata_len), ret, + GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl, + state->xdata, + args.xdata.xdata_val, + args.xdata.xdata_len, ret, op_errno, out); ret = 0; resolve_and_resume (frame, server_statfs_resume); out: if (op_errno) - req->rpc_err = GARBAGE_ARGS; + SERVER_REQ_SET_ERROR (req, ret); return ret; } -rpcsvc_actor_t glusterfs3_1_fop_actors[] = { - [GFS3_OP_NULL] = { "NULL", GFS3_OP_NULL, server_null, NULL, NULL, 0}, - [GFS3_OP_STAT] = { "STAT", GFS3_OP_STAT, server_stat, NULL, NULL, 0}, - [GFS3_OP_READLINK] = { "READLINK", GFS3_OP_READLINK, server_readlink, NULL, NULL, 0}, - [GFS3_OP_MKNOD] = { "MKNOD", GFS3_OP_MKNOD, server_mknod, NULL, NULL, 0}, - [GFS3_OP_MKDIR] = { "MKDIR", GFS3_OP_MKDIR, server_mkdir, NULL, NULL, 0}, - [GFS3_OP_UNLINK] = { "UNLINK", GFS3_OP_UNLINK, server_unlink, NULL, NULL, 0}, - [GFS3_OP_RMDIR] = { "RMDIR", GFS3_OP_RMDIR, server_rmdir, NULL, NULL, 0}, - [GFS3_OP_SYMLINK] = { "SYMLINK", GFS3_OP_SYMLINK, server_symlink, NULL, NULL, 0}, - [GFS3_OP_RENAME] = { "RENAME", GFS3_OP_RENAME, server_rename, NULL, NULL, 0}, - [GFS3_OP_LINK] = { "LINK", GFS3_OP_LINK, server_link, NULL, NULL, 0}, - [GFS3_OP_TRUNCATE] = { "TRUNCATE", GFS3_OP_TRUNCATE, server_truncate, NULL, NULL, 0}, - [GFS3_OP_OPEN] = { "OPEN", GFS3_OP_OPEN, server_open, NULL, NULL, 0}, - [GFS3_OP_READ] = { "READ", GFS3_OP_READ, server_readv, NULL, NULL, 0}, - [GFS3_OP_WRITE] = { "WRITE", GFS3_OP_WRITE, server_writev, server_writev_vec, server_writev_vecsizer, 0}, - [GFS3_OP_STATFS] = { "STATFS", GFS3_OP_STATFS, server_statfs, NULL, NULL, 0}, - [GFS3_OP_FLUSH] = { "FLUSH", GFS3_OP_FLUSH, server_flush, NULL, NULL, 0}, - [GFS3_OP_FSYNC] = { "FSYNC", GFS3_OP_FSYNC, server_fsync, NULL, NULL, 0}, - [GFS3_OP_SETXATTR] = { "SETXATTR", GFS3_OP_SETXATTR, server_setxattr, NULL, NULL, 0}, - [GFS3_OP_GETXATTR] = { "GETXATTR", GFS3_OP_GETXATTR, server_getxattr, NULL, NULL, 0}, - [GFS3_OP_REMOVEXATTR] = { "REMOVEXATTR", GFS3_OP_REMOVEXATTR, server_removexattr, NULL, NULL, 0}, - [GFS3_OP_OPENDIR] = { "OPENDIR", GFS3_OP_OPENDIR, server_opendir, NULL, NULL, 0}, - [GFS3_OP_FSYNCDIR] = { "FSYNCDIR", GFS3_OP_FSYNCDIR, server_fsyncdir, NULL, NULL, 0}, - [GFS3_OP_ACCESS] = { "ACCESS", GFS3_OP_ACCESS, server_access, NULL, NULL, 0}, - [GFS3_OP_CREATE] = { "CREATE", GFS3_OP_CREATE, server_create, NULL, NULL, 0}, - [GFS3_OP_FTRUNCATE] = { "FTRUNCATE", GFS3_OP_FTRUNCATE, server_ftruncate, NULL, NULL, 0}, - [GFS3_OP_FSTAT] = { "FSTAT", GFS3_OP_FSTAT, server_fstat, NULL, NULL, 0}, - [GFS3_OP_LK] = { "LK", GFS3_OP_LK, server_lk, NULL, NULL, 0}, - [GFS3_OP_LOOKUP] = { "LOOKUP", GFS3_OP_LOOKUP, server_lookup, NULL, NULL, 0}, - [GFS3_OP_READDIR] = { "READDIR", GFS3_OP_READDIR, server_readdir, NULL, NULL, 0}, - [GFS3_OP_INODELK] = { "INODELK", GFS3_OP_INODELK, server_inodelk, NULL, NULL, 0}, - [GFS3_OP_FINODELK] = { "FINODELK", GFS3_OP_FINODELK, server_finodelk, NULL, NULL, 0}, - [GFS3_OP_ENTRYLK] = { "ENTRYLK", GFS3_OP_ENTRYLK, server_entrylk, NULL, NULL, 0}, - [GFS3_OP_FENTRYLK] = { "FENTRYLK", GFS3_OP_FENTRYLK, server_fentrylk, NULL, NULL, 0}, - [GFS3_OP_XATTROP] = { "XATTROP", GFS3_OP_XATTROP, server_xattrop, NULL, NULL, 0}, - [GFS3_OP_FXATTROP] = { "FXATTROP", GFS3_OP_FXATTROP, server_fxattrop, NULL, NULL, 0}, - [GFS3_OP_FGETXATTR] = { "FGETXATTR", GFS3_OP_FGETXATTR, server_fgetxattr, NULL, NULL, 0}, - [GFS3_OP_FSETXATTR] = { "FSETXATTR", GFS3_OP_FSETXATTR, server_fsetxattr, NULL, NULL, 0}, - [GFS3_OP_RCHECKSUM] = { "RCHECKSUM", GFS3_OP_RCHECKSUM, server_rchecksum, NULL, NULL, 0}, - [GFS3_OP_SETATTR] = { "SETATTR", GFS3_OP_SETATTR, server_setattr, NULL, NULL, 0}, - [GFS3_OP_FSETATTR] = { "FSETATTR", GFS3_OP_FSETATTR, server_fsetattr, NULL, NULL, 0}, - [GFS3_OP_READDIRP] = { "READDIRP", GFS3_OP_READDIRP, server_readdirp, NULL, NULL, 0}, - [GFS3_OP_RELEASE] = { "RELEASE", GFS3_OP_RELEASE, server_release, NULL, NULL, 0}, - [GFS3_OP_RELEASEDIR] = { "RELEASEDIR", GFS3_OP_RELEASEDIR, server_releasedir, NULL, NULL, 0}, - [GFS3_OP_FREMOVEXATTR] = { "FREMOVEXATTR", GFS3_OP_FREMOVEXATTR, server_fremovexattr, NULL, NULL, 0}, +rpcsvc_actor_t glusterfs3_3_fop_actors[] = { + [GFS3_OP_NULL] = {"NULL", GFS3_OP_NULL, server_null, NULL, 0, DRC_NA}, + [GFS3_OP_STAT] = {"STAT", GFS3_OP_STAT, server3_3_stat, NULL, 0, DRC_NA}, + [GFS3_OP_READLINK] = {"READLINK", GFS3_OP_READLINK, server3_3_readlink, NULL, 0, DRC_NA}, + [GFS3_OP_MKNOD] = {"MKNOD", GFS3_OP_MKNOD, server3_3_mknod, NULL, 0, DRC_NA}, + [GFS3_OP_MKDIR] = {"MKDIR", GFS3_OP_MKDIR, server3_3_mkdir, NULL, 0, DRC_NA}, + [GFS3_OP_UNLINK] = {"UNLINK", GFS3_OP_UNLINK, server3_3_unlink, NULL, 0, DRC_NA}, + [GFS3_OP_RMDIR] = {"RMDIR", GFS3_OP_RMDIR, server3_3_rmdir, NULL, 0, DRC_NA}, + [GFS3_OP_SYMLINK] = {"SYMLINK", GFS3_OP_SYMLINK, server3_3_symlink, NULL, 0, DRC_NA}, + [GFS3_OP_RENAME] = {"RENAME", GFS3_OP_RENAME, server3_3_rename, NULL, 0, DRC_NA}, + [GFS3_OP_LINK] = {"LINK", GFS3_OP_LINK, server3_3_link, NULL, 0, DRC_NA}, + [GFS3_OP_TRUNCATE] = {"TRUNCATE", GFS3_OP_TRUNCATE, server3_3_truncate, NULL, 0, DRC_NA}, + [GFS3_OP_OPEN] = {"OPEN", GFS3_OP_OPEN, server3_3_open, NULL, 0, DRC_NA}, + [GFS3_OP_READ] = {"READ", GFS3_OP_READ, server3_3_readv, NULL, 0, DRC_NA}, + [GFS3_OP_WRITE] = {"WRITE", GFS3_OP_WRITE, server3_3_writev, server3_3_writev_vecsizer, 0, DRC_NA}, + [GFS3_OP_STATFS] = {"STATFS", GFS3_OP_STATFS, server3_3_statfs, NULL, 0, DRC_NA}, + [GFS3_OP_FLUSH] = {"FLUSH", GFS3_OP_FLUSH, server3_3_flush, NULL, 0, DRC_NA}, + [GFS3_OP_FSYNC] = {"FSYNC", GFS3_OP_FSYNC, server3_3_fsync, NULL, 0, DRC_NA}, + [GFS3_OP_SETXATTR] = {"SETXATTR", GFS3_OP_SETXATTR, server3_3_setxattr, NULL, 0, DRC_NA}, + [GFS3_OP_GETXATTR] = {"GETXATTR", GFS3_OP_GETXATTR, server3_3_getxattr, NULL, 0, DRC_NA}, + [GFS3_OP_REMOVEXATTR] = {"REMOVEXATTR", GFS3_OP_REMOVEXATTR, server3_3_removexattr, NULL, 0, DRC_NA}, + [GFS3_OP_OPENDIR] = {"OPENDIR", GFS3_OP_OPENDIR, server3_3_opendir, NULL, 0, DRC_NA}, + [GFS3_OP_FSYNCDIR] = {"FSYNCDIR", GFS3_OP_FSYNCDIR, server3_3_fsyncdir, NULL, 0, DRC_NA}, + [GFS3_OP_ACCESS] = {"ACCESS", GFS3_OP_ACCESS, server3_3_access, NULL, 0, DRC_NA}, + [GFS3_OP_CREATE] = {"CREATE", GFS3_OP_CREATE, server3_3_create, NULL, 0, DRC_NA}, + [GFS3_OP_FTRUNCATE] = {"FTRUNCATE", GFS3_OP_FTRUNCATE, server3_3_ftruncate, NULL, 0, DRC_NA}, + [GFS3_OP_FSTAT] = {"FSTAT", GFS3_OP_FSTAT, server3_3_fstat, NULL, 0, DRC_NA}, + [GFS3_OP_LK] = {"LK", GFS3_OP_LK, server3_3_lk, NULL, 0, DRC_NA}, + [GFS3_OP_LOOKUP] = {"LOOKUP", GFS3_OP_LOOKUP, server3_3_lookup, NULL, 0, DRC_NA}, + [GFS3_OP_READDIR] = {"READDIR", GFS3_OP_READDIR, server3_3_readdir, NULL, 0, DRC_NA}, + [GFS3_OP_INODELK] = {"INODELK", GFS3_OP_INODELK, server3_3_inodelk, NULL, 0, DRC_NA}, + [GFS3_OP_FINODELK] = {"FINODELK", GFS3_OP_FINODELK, server3_3_finodelk, NULL, 0, DRC_NA}, + [GFS3_OP_ENTRYLK] = {"ENTRYLK", GFS3_OP_ENTRYLK, server3_3_entrylk, NULL, 0, DRC_NA}, + [GFS3_OP_FENTRYLK] = {"FENTRYLK", GFS3_OP_FENTRYLK, server3_3_fentrylk, NULL, 0, DRC_NA}, + [GFS3_OP_XATTROP] = {"XATTROP", GFS3_OP_XATTROP, server3_3_xattrop, NULL, 0, DRC_NA}, + [GFS3_OP_FXATTROP] = {"FXATTROP", GFS3_OP_FXATTROP, server3_3_fxattrop, NULL, 0, DRC_NA}, + [GFS3_OP_FGETXATTR] = {"FGETXATTR", GFS3_OP_FGETXATTR, server3_3_fgetxattr, NULL, 0, DRC_NA}, + [GFS3_OP_FSETXATTR] = {"FSETXATTR", GFS3_OP_FSETXATTR, server3_3_fsetxattr, NULL, 0, DRC_NA}, + [GFS3_OP_RCHECKSUM] = {"RCHECKSUM", GFS3_OP_RCHECKSUM, server3_3_rchecksum, NULL, 0, DRC_NA}, + [GFS3_OP_SETATTR] = {"SETATTR", GFS3_OP_SETATTR, server3_3_setattr, NULL, 0, DRC_NA}, + [GFS3_OP_FSETATTR] = {"FSETATTR", GFS3_OP_FSETATTR, server3_3_fsetattr, NULL, 0, DRC_NA}, + [GFS3_OP_READDIRP] = {"READDIRP", GFS3_OP_READDIRP, server3_3_readdirp, NULL, 0, DRC_NA}, + [GFS3_OP_RELEASE] = {"RELEASE", GFS3_OP_RELEASE, server3_3_release, NULL, 0, DRC_NA}, + [GFS3_OP_RELEASEDIR] = {"RELEASEDIR", GFS3_OP_RELEASEDIR, server3_3_releasedir, NULL, 0, DRC_NA}, + [GFS3_OP_FREMOVEXATTR] = {"FREMOVEXATTR", GFS3_OP_FREMOVEXATTR, server3_3_fremovexattr, NULL, 0, DRC_NA}, + [GFS3_OP_FALLOCATE] = {"FALLOCATE", GFS3_OP_FALLOCATE, server3_3_fallocate, NULL, 0, DRC_NA}, + [GFS3_OP_DISCARD] = {"DISCARD", GFS3_OP_DISCARD, server3_3_discard, NULL, 0, DRC_NA}, + [GFS3_OP_ZEROFILL] = {"ZEROFILL", GFS3_OP_ZEROFILL, server3_3_zerofill, NULL, 0, DRC_NA}, }; -struct rpcsvc_program glusterfs3_1_fop_prog = { - .progname = "GlusterFS " PACKAGE_VERSION, - .prognum = GLUSTER3_1_FOP_PROGRAM, - .progver = GLUSTER3_1_FOP_VERSION, - .numactors = GLUSTER3_1_FOP_PROCCNT, - .actors = glusterfs3_1_fop_actors, +struct rpcsvc_program glusterfs3_3_fop_prog = { + .progname = "GlusterFS 3.3", + .prognum = GLUSTER_FOP_PROGRAM, + .progver = GLUSTER_FOP_VERSION, + .numactors = GLUSTER_FOP_PROCCNT, + .actors = glusterfs3_3_fop_actors, }; diff --git a/xlators/protocol/server/src/server.c b/xlators/protocol/server/src/server.c index a99ba817e..589bd7b36 100644 --- a/xlators/protocol/server/src/server.c +++ b/xlators/protocol/server/src/server.c @@ -1,20 +1,11 @@ /* - Copyright (c) 2010-2011 Gluster, Inc. <http://www.gluster.com> + Copyright (c) 2010-2013 Red Hat, Inc. <http://www.redhat.com> This file is part of GlusterFS. - GlusterFS is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 3 of the License, - or (at your option) any later version. - - GlusterFS is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see - <http://www.gnu.org/licenses/>. + This file is licensed to you under your choice of the GNU Lesser + General Public License, version 3 or any later version (LGPLv3 or + later), or the GNU General Public License, version 2 (GPLv2), in all + cases as published by the Free Software Foundation. */ @@ -34,33 +25,56 @@ #include "statedump.h" #include "defaults.h" #include "authenticate.h" -#include "rpcsvc.h" void grace_time_handler (void *data) { - server_connection_t *conn = NULL; - xlator_t *this = NULL; - gf_boolean_t cancelled = _gf_false; - gf_boolean_t detached = _gf_false; + client_t *client = NULL; + xlator_t *this = NULL; + gf_timer_t *timer = NULL; + server_ctx_t *serv_ctx = NULL; + gf_boolean_t cancelled = _gf_false; + gf_boolean_t detached = _gf_false; - conn = data; - this = conn->this; + client = data; + this = client->this; - GF_VALIDATE_OR_GOTO (THIS->name, conn, out); GF_VALIDATE_OR_GOTO (THIS->name, this, out); - gf_log (this->name, GF_LOG_INFO, "grace timer expired for %s", conn->id); + gf_log (this->name, GF_LOG_INFO, "grace timer expired for %s", + client->client_uid); - cancelled = server_cancel_conn_timer (this, conn); + serv_ctx = server_ctx_get (client, this); + + if (serv_ctx == NULL) { + gf_log (this->name, GF_LOG_INFO, "server_ctx_get() failed"); + goto out; + } + + LOCK (&serv_ctx->fdtable_lock); + { + if (serv_ctx->grace_timer) { + timer = serv_ctx->grace_timer; + serv_ctx->grace_timer = NULL; + } + } + UNLOCK (&serv_ctx->fdtable_lock); + if (timer) { + gf_timer_call_cancel (this->ctx, timer); + cancelled = _gf_true; + } if (cancelled) { - //conn should not be destroyed in conn_put, so take a ref. - server_conn_ref (conn); - server_connection_put (this, conn, &detached); + + /* + * client must not be destroyed in gf_client_put(), + * so take a ref. + */ + gf_client_ref (client); + gf_client_put (client, &detached); if (detached)//reconnection did not happen :-( - server_connection_cleanup (this, conn, - INTERNAL_LOCKS | POSIX_LOCKS); - server_conn_unref (conn); + server_connection_cleanup (this, client, + INTERNAL_LOCKS | POSIX_LOCKS); + gf_client_unref (client); } out: return; @@ -116,8 +130,6 @@ ret: return iob; } - - int server_submit_reply (call_frame_t *frame, rpcsvc_request_t *req, void *arg, struct iovec *payload, int payloadcount, @@ -128,19 +140,24 @@ server_submit_reply (call_frame_t *frame, rpcsvc_request_t *req, void *arg, struct iovec rsp = {0,}; server_state_t *state = NULL; char new_iobref = 0; - server_connection_t *conn = NULL; + client_t *client = NULL; gf_boolean_t lk_heal = _gf_false; + server_conf_t *conf = NULL; + gf_barrier_t *barrier = NULL; + gf_barrier_payload_t *stub = NULL; + gf_boolean_t barriered = _gf_false; GF_VALIDATE_OR_GOTO ("server", req, ret); if (frame) { state = CALL_STATE (frame); frame->local = NULL; - conn = SERVER_CONNECTION(frame); + client = frame->root->client; + conf = (server_conf_t *) client->this->private; } - if (conn) - lk_heal = ((server_conf_t *) conn->this->private)->lk_heal; + if (client) + lk_heal = ((server_conf_t *) client->this->private)->lk_heal; if (!iobref) { iobref = iobref_new (); @@ -159,6 +176,32 @@ server_submit_reply (call_frame_t *frame, rpcsvc_request_t *req, void *arg, iobref_add (iobref, iob); + if (conf) + barrier = conf->barrier; + if (barrier) { + /* todo: write's with fd flags set to O_SYNC and O_DIRECT */ + LOCK (&barrier->lock); + { + if (is_fop_barriered (barrier->fops, req->procnum) && + (barrier_add_to_queue (barrier))) { + stub = gf_barrier_payload (req, &rsp, frame, + payload, + payloadcount, iobref, + iob, new_iobref); + if (stub) { + gf_barrier_enqueue (barrier, stub); + barriered = _gf_true; + } else { + gf_log ("", GF_LOG_ERROR, "Failed to " + " barrier fop %"PRIu64, + ((uint64_t)1 << req->procnum)); + } + } + } + UNLOCK (&barrier->lock); + if (barriered == _gf_true) + goto out; + } /* Then, submit the message for transmission. */ ret = rpcsvc_submit_generic (req, &rsp, 1, payload, payloadcount, iobref); @@ -174,13 +217,14 @@ server_submit_reply (call_frame_t *frame, rpcsvc_request_t *req, void *arg, iobuf_unref (iob); if (ret == -1) { gf_log_callingfn ("", GF_LOG_ERROR, "Reply submission failed"); - if (frame && conn && !lk_heal) { - server_connection_cleanup (frame->this, conn, + if (frame && client && !lk_heal) { + server_connection_cleanup (frame->this, client, INTERNAL_LOCKS | POSIX_LOCKS); } else { + gf_log_callingfn ("", GF_LOG_ERROR, + "Reply submission failed"); /* TODO: Failure of open(dir), create, inodelk, entrylk or lk fops send failure must be handled specially. */ - ; } goto ret; } @@ -192,104 +236,17 @@ ret: } if (frame) { - if (frame->root->trans) - server_conn_unref (frame->root->trans); + gf_client_unref (client); STACK_DESTROY (frame->root); } if (new_iobref) { iobref_unref (iobref); } - - return ret; -} - -/* */ -int -server_fd_to_dict (xlator_t *this, dict_t *dict) -{ - server_conf_t *conf = NULL; - server_connection_t *trav = NULL; - char key[GF_DUMP_MAX_BUF_LEN] = {0,}; - int count = 0; - int ret = -1; - - GF_VALIDATE_OR_GOTO (THIS->name, this, out); - GF_VALIDATE_OR_GOTO (this->name, dict, out); - - conf = this->private; - if (!conf) - return -1; - - ret = pthread_mutex_trylock (&conf->mutex); - if (ret) - return -1; - - list_for_each_entry (trav, &conf->conns, list) { - memset (key, 0, sizeof (key)); - snprintf (key, sizeof (key), "conn%d", count++); - fdtable_dump_to_dict (trav->fdtable, key, dict); - } - pthread_mutex_unlock (&conf->mutex); - - ret = dict_set_int32 (dict, "conncount", count); out: return ret; } -int -server_fd (xlator_t *this) -{ - server_conf_t *conf = NULL; - server_connection_t *trav = NULL; - char key[GF_DUMP_MAX_BUF_LEN]; - int i = 1; - int ret = -1; - - GF_VALIDATE_OR_GOTO ("server", this, out); - - conf = this->private; - if (!conf) { - gf_log (this->name, GF_LOG_WARNING, - "conf null in xlator"); - return -1; - } - - gf_proc_dump_add_section("xlator.protocol.server.conn"); - - ret = pthread_mutex_trylock (&conf->mutex); - if (ret) { - gf_log("", GF_LOG_WARNING, "Unable to dump fdtable" - " errno: %d", errno); - return -1; - } - - list_for_each_entry (trav, &conf->conns, list) { - if (trav->id) { - gf_proc_dump_build_key(key, - "conn","%d.id", i); - gf_proc_dump_write(key, "%s", trav->id); - } - - gf_proc_dump_build_key(key,"conn","%d.ref",i) - gf_proc_dump_write(key, "%d", trav->ref); - if (trav->bound_xl) { - gf_proc_dump_build_key(key, - "conn","%d.bound_xl", i); - gf_proc_dump_write(key, "%s", trav->bound_xl->name); - } - - gf_proc_dump_build_key(key, - "conn","%d.id", i); - fdtable_dump(trav->fdtable,key); - i++; - } - pthread_mutex_unlock (&conf->mutex); - - ret = 0; -out: - return ret; -} int server_priv_to_dict (xlator_t *this, dict_t *dict) @@ -366,7 +323,12 @@ server_priv (xlator_t *this) if (!conf) return 0; - pthread_mutex_lock (&conf->mutex); + gf_proc_dump_build_key (key, "xlator.protocol.server", "priv"); + gf_proc_dump_add_section (key); + + ret = pthread_mutex_trylock (&conf->mutex); + if (ret != 0) + goto out; { list_for_each_entry (xprt, &conf->xprt_list, list) { total_read += xprt->total_bytes_read; @@ -383,115 +345,16 @@ server_priv (xlator_t *this) ret = 0; out: - return ret; -} - -int -server_inode_to_dict (xlator_t *this, dict_t *dict) -{ - server_conf_t *conf = NULL; - server_connection_t *trav = NULL; - char key[32] = {0,}; - int count = 0; - int ret = -1; - xlator_t *prev_bound_xl = NULL; - - GF_VALIDATE_OR_GOTO (THIS->name, this, out); - GF_VALIDATE_OR_GOTO (this->name, dict, out); - - conf = this->private; - if (!conf) - return -1; - - ret = pthread_mutex_trylock (&conf->mutex); if (ret) - return -1; - - list_for_each_entry (trav, &conf->conns, list) { - if (trav->bound_xl && trav->bound_xl->itable) { - /* Presently every brick contains only one - * bound_xl for all connections. This will lead - * to duplicating of the inode lists, if listing - * is done for every connection. This simple check - * prevents duplication in the present case. If - * need arises the check can be improved. - */ - if (trav->bound_xl == prev_bound_xl) - continue; - prev_bound_xl = trav->bound_xl; - - memset (key, 0, sizeof (key)); - snprintf (key, sizeof (key), "conn%d", count); - inode_table_dump_to_dict (trav->bound_xl->itable, - key, dict); - count++; - } - } - pthread_mutex_unlock (&conf->mutex); - - ret = dict_set_int32 (dict, "conncount", count); - -out: - if (prev_bound_xl) - prev_bound_xl = NULL; - return ret; -} - -int -server_inode (xlator_t *this) -{ - server_conf_t *conf = NULL; - server_connection_t *trav = NULL; - char key[GF_DUMP_MAX_BUF_LEN]; - int i = 1; - int ret = -1; - xlator_t *prev_bound_xl = NULL; - - GF_VALIDATE_OR_GOTO ("server", this, out); - - conf = this->private; - if (!conf) { - gf_log (this->name, GF_LOG_WARNING, - "conf null in xlator"); - return -1; - } - - ret = pthread_mutex_trylock (&conf->mutex); - if (ret) { - gf_log("", GF_LOG_WARNING, "Unable to dump itable" - " errno: %d", errno); - return -1; - } + gf_proc_dump_write ("Unable to print priv", + "(Lock acquisition failed) %s", + this?this->name:"server"); - list_for_each_entry (trav, &conf->conns, list) { - if (trav->bound_xl && trav->bound_xl->itable) { - /* Presently every brick contains only one - * bound_xl for all connections. This will lead - * to duplicating of the inode lists, if listing - * is done for every connection. This simple check - * prevents duplication in the present case. If - * need arises the check can be improved. - */ - if (trav->bound_xl == prev_bound_xl) - continue; - prev_bound_xl = trav->bound_xl; - - gf_proc_dump_build_key(key, - "conn","%d.bound_xl.%s", - i, trav->bound_xl->name); - inode_table_dump(trav->bound_xl->itable,key); - i++; - } - } - pthread_mutex_unlock (&conf->mutex); - - ret = 0; -out: return ret; } -static void +static int get_auth_types (dict_t *this, char *key, data_t *value, void *data) { dict_t *auth_dict = NULL; @@ -528,85 +391,88 @@ get_auth_types (dict_t *this, char *key, data_t *value, void *data) GF_FREE (key_cpy); out: - return; + return 0; } +int +_check_for_auth_option (dict_t *d, char *k, data_t *v, + void *tmp) +{ + int ret = 0; + xlator_t *xl = NULL; + char *tail = NULL; + char *tmp_addr_list = NULL; + char *addr = NULL; + char *tmp_str = NULL; + + xl = tmp; + + tail = strtail (k, "auth."); + if (!tail) + goto out; + + /* fast fwd thru module type */ + tail = strchr (tail, '.'); + if (!tail) + goto out; + tail++; + + tail = strtail (tail, xl->name); + if (!tail) + goto out; + + if (*tail == '.') { + /* when we are here, the key is checked for + * valid auth.allow.<xlator> + * Now we verify the ip address + */ + if (!strcmp (v->data, "*")) { + ret = 0; + goto out; + } + + tmp_addr_list = gf_strdup (v->data); + addr = strtok_r (tmp_addr_list, ",", &tmp_str); + if (!addr) + addr = v->data; + + while (addr) { + if (valid_internet_address (addr, _gf_true)) { + ret = 0; + } else { + ret = -1; + gf_log (xl->name, GF_LOG_ERROR, + "internet address '%s'" + " does not conform to" + " standards.", addr); + goto out; + } + if (tmp_str) + addr = strtok_r (NULL, ",", &tmp_str); + else + addr = NULL; + } + + GF_FREE (tmp_addr_list); + tmp_addr_list = NULL; + } +out: + return ret; +} int validate_auth_options (xlator_t *this, dict_t *dict) { int error = -1; xlator_list_t *trav = NULL; - data_pair_t *pair = NULL; - char *tail = NULL; - char *tmp_addr_list = NULL; - char *addr = NULL; - char *tmp_str = NULL; GF_VALIDATE_OR_GOTO ("server", this, out); GF_VALIDATE_OR_GOTO ("server", dict, out); trav = this->children; while (trav) { - error = -1; - for (pair = dict->members_list; pair; pair = pair->next) { - tail = strtail (pair->key, "auth."); - if (!tail) - continue; - /* fast fwd thru module type */ - tail = strchr (tail, '.'); - if (!tail) - continue; - tail++; - - tail = strtail (tail, trav->xlator->name); - if (!tail) - continue; - - if (*tail == '.') { - error = 0; - - /* when we are here, the key is checked for - * valid auth.allow.<xlator> - * Now we verify the ip address - */ - if (!strcmp (pair->value->data, "*")) { - error = 0; - goto out; - } - - tmp_addr_list = gf_strdup (pair->value->data); - addr = strtok_r (tmp_addr_list, ",", - &tmp_str); - if (!addr) - addr = pair->value->data; - - while (addr) { - - if (valid_internet_address - (addr, _gf_true)) { - error = 0; - } else { - error = -1; - gf_log (this->name, GF_LOG_ERROR, - "internet address '%s'" - " does not conform to" - " standards.", addr); - goto out; - - } - if (tmp_str) - addr = strtok_r (NULL, ",", - &tmp_str); - else - addr = NULL; - } - - GF_FREE (tmp_addr_list); - tmp_addr_list = NULL; - } - - } + error = dict_foreach (dict, _check_for_auth_option, + trav->xlator); if (-1 == error) { gf_log (this->name, GF_LOG_ERROR, @@ -619,8 +485,6 @@ validate_auth_options (xlator_t *this, dict_t *dict) } out: - if (tmp_addr_list) - GF_FREE (tmp_addr_list); return error; } @@ -631,9 +495,10 @@ server_rpc_notify (rpcsvc_t *rpc, void *xl, rpcsvc_event_t event, { gf_boolean_t detached = _gf_false; xlator_t *this = NULL; - rpc_transport_t *xprt = NULL; - server_connection_t *conn = NULL; + rpc_transport_t *trans = NULL; server_conf_t *conf = NULL; + client_t *client = NULL; + server_ctx_t *serv_ctx = NULL; if (!xl || !data) { gf_log_callingfn ("server", GF_LOG_WARNING, @@ -642,7 +507,7 @@ server_rpc_notify (rpcsvc_t *rpc, void *xl, rpcsvc_event_t event, } this = xl; - xprt = data; + trans = data; conf = this->private; switch (event) { @@ -650,17 +515,17 @@ server_rpc_notify (rpcsvc_t *rpc, void *xl, rpcsvc_event_t event, { /* Have a structure per new connection */ /* TODO: Should we create anything here at all ? * / - conn = create_server_conn_state (this, xprt); - if (!conn) + client->conn = create_server_conn_state (this, trans); + if (!client->conn) goto out; - xprt->protocol_private = conn; + trans->protocol_private = client->conn; */ - INIT_LIST_HEAD (&xprt->list); + INIT_LIST_HEAD (&trans->list); pthread_mutex_lock (&conf->mutex); { - list_add_tail (&xprt->list, &conf->xprt_list); + list_add_tail (&trans->list, &conf->xprt_list); } pthread_mutex_unlock (&conf->mutex); @@ -673,50 +538,58 @@ server_rpc_notify (rpcsvc_t *rpc, void *xl, rpcsvc_event_t event, */ pthread_mutex_lock (&conf->mutex); { - list_del_init (&xprt->list); + list_del_init (&trans->list); } pthread_mutex_unlock (&conf->mutex); - conn = get_server_conn_state (this, xprt); - if (!conn) + client = trans->xl_private; + if (!client) break; gf_log (this->name, GF_LOG_INFO, "disconnecting connection" - "from %s", conn->id); + "from %s", client->client_uid); /* If lock self heal is off, then destroy the conn object, else register a grace timer event */ if (!conf->lk_heal) { - server_conn_ref (conn); - server_connection_put (this, conn, &detached); + gf_client_ref (client); + gf_client_put (client, &detached); if (detached) - server_connection_cleanup (this, conn, - INTERNAL_LOCKS | - POSIX_LOCKS); - server_conn_unref (conn); - } else { - put_server_conn_state (this, xprt); - server_connection_cleanup (this, conn, INTERNAL_LOCKS); + server_connection_cleanup (this, client, + INTERNAL_LOCKS | POSIX_LOCKS); + gf_client_unref (client); + break; + } + trans->xl_private = NULL; + server_connection_cleanup (this, client, INTERNAL_LOCKS); - pthread_mutex_lock (&conn->lock); - { - if (conn->timer) - goto unlock; + serv_ctx = server_ctx_get (client, this); - gf_log (this->name, GF_LOG_INFO, "starting a grace " - "timer for %s", conn->id); + if (serv_ctx == NULL) { + gf_log (this->name, GF_LOG_INFO, + "server_ctx_get() failed"); + goto out; + } + + LOCK (&serv_ctx->fdtable_lock); + { + if (!serv_ctx->grace_timer) { - conn->timer = gf_timer_call_after (this->ctx, - conf->grace_tv, - grace_time_handler, - conn); + gf_log (this->name, GF_LOG_INFO, + "starting a grace timer for %s", + client->client_uid); + + serv_ctx->grace_timer = + gf_timer_call_after (this->ctx, + conf->grace_ts, + grace_time_handler, + client); } - unlock: - pthread_mutex_unlock (&conn->lock); } + UNLOCK (&serv_ctx->fdtable_lock); break; case RPCSVC_EVENT_TRANSPORT_DESTROY: - /*- conn obj has been disassociated from xprt on first + /*- conn obj has been disassociated from trans on first * disconnect. * conn cleanup and destruction is handed over to * grace_time_handler or the subsequent handler that 'owns' @@ -749,39 +622,41 @@ out: } -static void -_delete_auth_opt (dict_t *this, - char *key, - data_t *value, - void *data) +static int +_delete_auth_opt (dict_t *this, char *key, data_t *value, void *data) { char *auth_option_pattern[] = { "auth.addr.*.allow", - "auth.addr.*.reject"}; - if (fnmatch ( auth_option_pattern[0], key, 0) != 0) { - dict_del (this, key); - return; - } + "auth.addr.*.reject", + NULL}; + int i = 0; - if (fnmatch ( auth_option_pattern[1], key, 0) != 0) { - dict_del (this, key); - return; + for (i = 0; auth_option_pattern[i]; i++) { + if (fnmatch (auth_option_pattern[i], key, 0) == 0) { + dict_del (this, key); + break; + } } + + return 0; } -static void -_copy_auth_opt (dict_t *unused, - char *key, - data_t *value, - void *xl_dict) +static int +_copy_auth_opt (dict_t *unused, char *key, data_t *value, void *xl_dict) { char *auth_option_pattern[] = { "auth.addr.*.allow", - "auth.addr.*.reject"}; - if (fnmatch ( auth_option_pattern[0], key, 0) != 0) - dict_set ((dict_t *)xl_dict, key, (value)); + "auth.addr.*.reject", + NULL}; + int i = 0; + + for (i = 0; auth_option_pattern [i]; i++) { + if (fnmatch (auth_option_pattern[i], key, 0) == 0) { + dict_set ((dict_t *)xl_dict, key, value); + break; + } + } - if (fnmatch ( auth_option_pattern[1], key, 0) != 0) - dict_set ((dict_t *)xl_dict, key, (value)); + return 0; } @@ -808,14 +683,14 @@ server_init_grace_timer (xlator_t *this, dict_t *options, ret = dict_get_int32 (options, "grace-timeout", &grace_timeout); if (!ret) - conf->grace_tv.tv_sec = grace_timeout; + conf->grace_ts.tv_sec = grace_timeout; else - conf->grace_tv.tv_sec = 10; + conf->grace_ts.tv_sec = 10; gf_log (this->name, GF_LOG_DEBUG, "Server grace timeout " - "value = %"PRIu64, conf->grace_tv.tv_sec); + "value = %"PRIu64, conf->grace_ts.tv_sec); - conf->grace_tv.tv_usec = 0; + conf->grace_ts.tv_nsec = 0; ret = 0; out: @@ -853,22 +728,15 @@ reconfigure (xlator_t *this, dict_t *options) gf_log (this->name, GF_LOG_WARNING, "'trace' takes on only boolean values. " "Neglecting option"); - ret = -1; + ret = -1; goto out; - } - conf->trace = trace; - gf_log (this->name, GF_LOG_TRACE, "Reconfigured trace" - " to %d", conf->trace); + } + conf->trace = trace; + gf_log (this->name, GF_LOG_TRACE, "Reconfigured trace" + " to %d", conf->trace); - } + } - /*ret = dict_get_str (options, "statedump-path", &statedump_path); - if (!ret) { - gf_path_strip_trailing_slashes (statedump_path); - if (this->ctx->statedump_path) - GF_FREE (this->ctx->statedump_path); - this->ctx->statedump_path = gf_strdup (statedump_path); - }*/ GF_OPTION_RECONF ("statedump-path", statedump_path, options, path, out); if (!statedump_path) { @@ -878,8 +746,7 @@ reconfigure (xlator_t *this, dict_t *options) goto out; } gf_path_strip_trailing_slashes (statedump_path); - if (this->ctx->statedump_path) - GF_FREE (this->ctx->statedump_path); + GF_FREE (this->ctx->statedump_path); this->ctx->statedump_path = gf_strdup (statedump_path); if (!conf->auth_modules) @@ -907,6 +774,8 @@ reconfigure (xlator_t *this, dict_t *options) } (void) rpcsvc_set_allow_insecure (rpc_conf, options); + (void) rpcsvc_set_root_squash (rpc_conf, options); + (void) rpcsvc_set_outstanding_rpc_limit (rpc_conf, options); list_for_each_entry (listeners, &(rpc_conf->listeners), list) { if (listeners->trans != NULL) { if (listeners->trans->reconfigure ) @@ -923,6 +792,26 @@ out: return ret; } +static int32_t +client_destroy_cbk (xlator_t *this, client_t *client) +{ + void *tmp = NULL; + server_ctx_t *ctx = NULL; + + client_ctx_del (client, this, &tmp); + + ctx = tmp; + + if (ctx == NULL) + return 0; + + gf_fd_fdtable_destroy (ctx->fdtable); + LOCK_DESTROY (&ctx->fdtable_lock); + GF_FREE (ctx); + + return 0; +} + int init (xlator_t *this) { @@ -930,6 +819,8 @@ init (xlator_t *this) server_conf_t *conf = NULL; rpcsvc_listener_t *listener = NULL; char *statedump_path = NULL; + gf_barrier_t *barrier = NULL; + char *str = NULL; GF_VALIDATE_OR_GOTO ("init", this, out); if (this->children == NULL) { @@ -949,7 +840,6 @@ init (xlator_t *this) GF_VALIDATE_OR_GOTO(this->name, conf, out); - INIT_LIST_HEAD (&conf->conns); INIT_LIST_HEAD (&conf->xprt_list); pthread_mutex_init (&conf->mutex, NULL); @@ -1023,14 +913,14 @@ init (xlator_t *this) goto out; } - glusterfs3_1_fop_prog.options = this->options; - ret = rpcsvc_program_register (conf->rpc, &glusterfs3_1_fop_prog); + glusterfs3_3_fop_prog.options = this->options; + ret = rpcsvc_program_register (conf->rpc, &glusterfs3_3_fop_prog); if (ret) { gf_log (this->name, GF_LOG_WARNING, "registration of program (name:%s, prognum:%d, " - "progver:%d) failed", glusterfs3_1_fop_prog.progname, - glusterfs3_1_fop_prog.prognum, - glusterfs3_1_fop_prog.progver); + "progver:%d) failed", glusterfs3_3_fop_prog.progname, + glusterfs3_3_fop_prog.prognum, + glusterfs3_3_fop_prog.progver); goto out; } @@ -1042,7 +932,7 @@ init (xlator_t *this) "progver:%d) failed", gluster_handshake_prog.progname, gluster_handshake_prog.prognum, gluster_handshake_prog.progver); - rpcsvc_program_unregister (conf->rpc, &glusterfs3_1_fop_prog); + rpcsvc_program_unregister (conf->rpc, &glusterfs3_3_fop_prog); goto out; } @@ -1071,6 +961,37 @@ init (xlator_t *this) } } #endif + /* barrier related */ + barrier = GF_CALLOC (1, sizeof (*barrier),1); + if (!barrier) { + gf_log (this->name, GF_LOG_WARNING, + "WARNING: Failed to allocate barrier"); + ret = -1; + goto out; + } + + LOCK_INIT (&barrier->lock); + INIT_LIST_HEAD (&barrier->queue); + barrier->on = _gf_false; + + GF_OPTION_INIT ("barrier-queue-length", barrier->max_size, + int64, out); + GF_OPTION_INIT ("barrier-timeout", barrier->time_out, + uint64, out); + + ret = dict_get_str (this->options, "barrier-fops", &str); + if (ret) { + gf_log (this->name, GF_LOG_DEBUG, + "setting barrier fops to default value"); + } + ret = gf_barrier_fops_configure (this, barrier, str); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, + "invalid barrier fops specified"); + goto out; + } + + conf->barrier = barrier; this->private = conf; ret = 0; @@ -1124,29 +1045,65 @@ int notify (xlator_t *this, int32_t event, void *data, ...) { int ret = 0; + int32_t val = 0; + dict_t *dict = NULL; + dict_t *output = NULL; + va_list ap; + + dict = data; + va_start (ap, data); + output = va_arg (ap, dict_t*); + va_end (ap); + switch (event) { + case GF_EVENT_VOLUME_BARRIER_OP: + ret = dict_get_int32 (dict, "barrier", &val); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, + "Wrong BARRIER event"); + goto out; + } + /* !val un-barrier, if val, barrier */ + if (val) { + ret = gf_barrier_start (this); + if (ret) + gf_log (this->name, GF_LOG_ERROR, + "Barrier start failed"); + } else { + ret = gf_barrier_stop (this); + if (ret) + gf_log (this->name, GF_LOG_ERROR, + "Barrier stop failed"); + } + ret = dict_set_int32 (output, "barrier-status", ret); + if (ret) + gf_log (this->name, GF_LOG_ERROR, + "Failed to set barrier-status in dict"); + break; + + /* todo: call default_notify to make other xlators handle it.*/ default: default_notify (this, event, data); break; } - +out: return ret; } -struct xlator_fops fops = { -}; +struct xlator_fops fops; struct xlator_cbks cbks = { + .client_destroy = client_destroy_cbk, }; struct xlator_dumpops dumpops = { .priv = server_priv, - .fd = server_fd, - .inode = server_inode, + .fd = gf_client_dump_fdtables, + .inode = gf_client_dump_inodes, .priv_to_dict = server_priv_to_dict, - .fd_to_dict = server_fd_to_dict, - .inode_to_dict = server_inode_to_dict, + .fd_to_dict = gf_client_dump_fdtables_to_dict, + .inode_to_dict = gf_client_dump_inodes_to_dict, }; @@ -1174,6 +1131,8 @@ struct volume_options options[] = { .min = 0, .max = (1 * GF_UNIT_MB), .default_value = "16384", + .description = "Specifies the maximum megabytes of memory to be " + "used in the inode cache." }, { .key = {"verify-volfile-checksum"}, .type = GF_OPTION_TYPE_BOOL @@ -1188,9 +1147,17 @@ struct volume_options options[] = { { .key = {"rpc-auth-allow-insecure"}, .type = GF_OPTION_TYPE_BOOL, }, + { .key = {"root-squash"}, + .type = GF_OPTION_TYPE_BOOL, + .default_value = "off", + .description = "Map requests from uid/gid 0 to the anonymous " + "uid/gid. Note that this does not apply to any other" + "uids or gids that might be equally sensitive, such as" + "user bin or group staff." + }, { .key = {"statedump-path"}, .type = GF_OPTION_TYPE_PATH, - .default_value = "/tmp", + .default_value = DEFAULT_VAR_RUN_DIRECTORY, .description = "Specifies directory in which gluster should save its" " statedumps. By default it is the /tmp directory" }, @@ -1206,7 +1173,8 @@ struct volume_options options[] = { {.key = {"tcp-window-size"}, .type = GF_OPTION_TYPE_SIZET, .min = GF_MIN_SOCKET_WINDOW_SIZE, - .max = GF_MAX_SOCKET_WINDOW_SIZE + .max = GF_MAX_SOCKET_WINDOW_SIZE, + .description = "Specifies the window size for tcp socket." }, /* The following two options are defined in addr.c, redifined here * @@ -1224,6 +1192,23 @@ struct volume_options options[] = { "hostnames to connect to the server. By default, all" " connections are allowed." }, - + {.key = {"barrier-timeout"}, + .type = GF_OPTION_TYPE_INT, + .default_value = "60", + .min = 0, + .max = 360, + .description = "Barrier timeout in seconds", + }, + {.key = {"barrier-queue-length"}, + .type = GF_OPTION_TYPE_INT, + .default_value = "4096", + .min = 0, + .max = 16384, + .description = "Barrier queue length", + }, + {.key = {"barrier-fops"}, + .type = GF_OPTION_TYPE_STR, + .description = "Allow a comma seperated fop lists", + }, { .key = {NULL} }, }; diff --git a/xlators/protocol/server/src/server.h b/xlators/protocol/server/src/server.h index 94ceafd10..782327d77 100644 --- a/xlators/protocol/server/src/server.h +++ b/xlators/protocol/server/src/server.h @@ -1,20 +1,11 @@ /* - Copyright (c) 2010-2011 Gluster, Inc. <http://www.gluster.com> + Copyright (c) 2010-2013 Red Hat, Inc. <http://www.redhat.com> This file is part of GlusterFS. - GlusterFS is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 3 of the License, - or (at your option) any later version. - - GlusterFS is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see - <http://www.gnu.org/licenses/>. + This file is licensed to you under your choice of the GNU Lesser + General Public License, version 3 or any later version (LGPLv3 or + later), or the GNU General Public License, version 2 (GPLv2), in all + cases as published by the Free Software Foundation. */ #ifndef _SERVER_H @@ -22,6 +13,7 @@ #include <pthread.h> +#include "fd.h" #include "rpcsvc.h" #include "fd.h" @@ -29,70 +21,47 @@ #include "server-mem-types.h" #include "glusterfs3.h" #include "timer.h" +#include "client_t.h" #define DEFAULT_BLOCK_SIZE 4194304 /* 4MB */ #define DEFAULT_VOLUME_FILE_PATH CONFDIR "/glusterfs.vol" #define GF_MAX_SOCKET_WINDOW_SIZE (1 * GF_UNIT_MB) #define GF_MIN_SOCKET_WINDOW_SIZE (0) -typedef enum { - INTERNAL_LOCKS = 1, - POSIX_LOCKS = 2, -} server_lock_flags_t; - -typedef struct _server_state server_state_t; - -struct _locker { - struct list_head lockers; - char *volume; - loc_t loc; - fd_t *fd; - gf_lkowner_t owner; - pid_t pid; -}; - -struct _lock_table { - struct list_head inodelk_lockers; - struct list_head entrylk_lockers; - size_t count; +struct _gf_barrier_payload { + rpcsvc_request_t *req; + struct iovec rsp; + call_frame_t *frame; + struct iovec *payload; + struct iobref *iobref; + struct iobuf *iob; + int payload_count; + gf_boolean_t free_iobref; + struct list_head list; }; -/* private structure per connection (transport object) - * used as transport_t->xl_private - */ -struct _server_connection { - struct list_head list; - char *id; - int ref; - int bind_ref; - pthread_mutex_t lock; - fdtable_t *fdtable; - struct _lock_table *ltable; - gf_timer_t *timer; - xlator_t *bound_xl; - xlator_t *this; - uint32_t lk_version; +typedef struct _gf_barrier_payload gf_barrier_payload_t; + +struct _gf_barrier { + gf_lock_t lock; + gf_boolean_t on; + gf_boolean_t force; + size_t cur_size; + int64_t max_size; + uint64_t fops; + gf_timer_t *timer; + uint64_t time_out; + struct list_head queue; }; -typedef struct _server_connection server_connection_t; +typedef struct _gf_barrier gf_barrier_t; +typedef enum { + INTERNAL_LOCKS = 1, + POSIX_LOCKS = 2, +} server_lock_flags_t; -server_connection_t * -server_connection_get (xlator_t *this, const char *id); - -server_connection_t * -server_connection_put (xlator_t *this, server_connection_t *conn, - gf_boolean_t *detached); - -server_connection_t* -server_conn_unref (server_connection_t *conn); - -server_connection_t* -server_conn_ref (server_connection_t *conn); - -int -server_connection_cleanup (xlator_t *this, server_connection_t *conn, - int32_t flags); +typedef struct _server_state server_state_t; int server_null (rpcsvc_request_t *req); @@ -112,11 +81,12 @@ struct server_conf { heal is on else off. */ char *conf_dir; struct _volfile_ctx *volfile; - struct timeval grace_tv; + struct timespec grace_ts; dict_t *auth_modules; pthread_mutex_t mutex; - struct list_head conns; + gf_barrier_t *barrier; struct list_head xprt_list; + pthread_t barrier_th; }; typedef struct server_conf server_conf_t; @@ -137,7 +107,7 @@ struct resolve_comp { typedef struct { server_resolve_type_t type; - uint64_t fd_no; + int64_t fd_no; u_char gfid[16]; u_char pargfid[16]; char *path; @@ -154,11 +124,10 @@ int resolve_and_resume (call_frame_t *frame, server_resume_fn_t fn); struct _server_state { - server_connection_t *conn; - rpc_transport_t *xprt; - inode_table_t *itable; + rpc_transport_t *xprt; + inode_table_t *itable; - server_resume_fn_t resume_fn; + server_resume_fn_t resume_fn; loc_t loc; loc_t loc2; @@ -194,7 +163,7 @@ struct _server_state { int mask; char is_revalidate; dict_t *dict; - struct gf_flock flock; + struct gf_flock flock; const char *volume; dir_entry_t *entry; @@ -202,10 +171,20 @@ struct _server_state { mode_t umask; }; + extern struct rpcsvc_program gluster_handshake_prog; -extern struct rpcsvc_program glusterfs3_1_fop_prog; +extern struct rpcsvc_program glusterfs3_3_fop_prog; extern struct rpcsvc_program gluster_ping_prog; + +typedef struct _server_ctx { + gf_lock_t fdtable_lock; + fdtable_t *fdtable; + struct _gf_timer *grace_timer; + uint32_t lk_version; +} server_ctx_t; + + int server_submit_reply (call_frame_t *frame, rpcsvc_request_t *req, void *arg, struct iovec *payload, int payloadcount, |
