From 273ab81002930fc93f0f118ef266848ed26d1f98 Mon Sep 17 00:00:00 2001 From: Poornima G Date: Mon, 22 Aug 2016 12:30:43 +0530 Subject: [PATCH 133/141] afr: Implement IPC fop Currently ipc() is not implemented in afr. md-cache and upcall uses ipc to register the list of xattrs, [1] for more details. For the ipc op GF_IPC_TARGET_UPCALL, it has to be wound to all the replica subvolumes. ipc() is failed when any of the subvolumes fails with other than ENOTCONN or all of the subvolumes are down. [1] http://review.gluster.org/#/c/15002/ Change-Id: I0f651330eafda64e4d922043fe53bd0014536247 BUG: 1284873 Signed-off-by: Poornima G Reviewed-on: http://review.gluster.org/15378 Tested-by: Pranith Kumar Karampuri Smoke: Gluster Build System NetBSD-regression: NetBSD Build System CentOS-regression: Gluster Build System Reviewed-by: Pranith Kumar Karampuri Reviewed-on: https://code.engineering.redhat.com/gerrit/87046 Reviewed-by: Rajesh Joseph Tested-by: Rajesh Joseph --- xlators/cluster/afr/src/afr-common.c | 120 ++++++++++++++++++++++++++++++++++ xlators/cluster/afr/src/afr.c | 1 + 2 files changed, 121 insertions(+), 0 deletions(-) diff --git a/xlators/cluster/afr/src/afr-common.c b/xlators/cluster/afr/src/afr-common.c index a743446..d819a22 100644 --- a/xlators/cluster/afr/src/afr-common.c +++ b/xlators/cluster/afr/src/afr-common.c @@ -4010,6 +4010,126 @@ out: } int +afr_ipc_cbk (call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, dict_t *xdata) +{ + afr_local_t *local = NULL; + int child_index = (long)cookie; + int call_count = 0; + gf_boolean_t failed = _gf_false; + gf_boolean_t succeded = _gf_false; + int i = 0; + afr_private_t *priv = NULL; + + local = frame->local; + priv = this->private; + + local->replies[child_index].valid = 1; + local->replies[child_index].op_ret = op_ret; + local->replies[child_index].op_errno = op_errno; + if (xdata) + local->replies[child_index].xdata = dict_ref (xdata); + + call_count = afr_frame_return (frame); + if (call_count) + goto out; + /* If any of the subvolumes failed with other than ENOTCONN + * return error else return success unless all the subvolumes + * failed. + * TODO: In case of failure, we need to unregister the xattrs + * from the other subvolumes where it succeded (once upcall + * fixes the Bz-1371622)*/ + for (i = 0; i < priv->child_count; i++) { + if (!local->replies[i].valid) + continue; + if (local->replies[i].op_ret < 0 && + local->replies[i].op_errno != ENOTCONN) { + local->op_ret = local->replies[i].op_ret; + local->op_errno = local->replies[i].op_errno; + if (local->xdata_rsp) + dict_unref (local->xdata_rsp); + local->xdata_rsp = NULL; + if (local->replies[i].xdata) { + local->xdata_rsp = + dict_ref (local->replies[i].xdata); + } + failed = _gf_true; + break; + } + if (local->replies[i].op_ret == 0) { + succeded = _gf_true; + local->op_ret = 0; + local->op_errno = 0; + if (!local->xdata_rsp && local->replies[i].xdata) { + local->xdata_rsp = + dict_ref (local->replies[i].xdata); + } + } + } + + if (!succeded && !failed) { + local->op_ret = -1; + local->op_errno = ENOTCONN; + } + + AFR_STACK_UNWIND (ipc, frame, local->op_ret, local->op_errno, + local->xdata_rsp); + +out: + return 0; +} + +int +afr_ipc (call_frame_t *frame, xlator_t *this, int32_t op, dict_t *xdata) +{ + afr_local_t *local = NULL; + int32_t op_errno = -1; + afr_private_t *priv = NULL; + int i = 0; + int call_cnt = -1; + + VALIDATE_OR_GOTO (frame, err); + VALIDATE_OR_GOTO (this, err); + + if (op != GF_IPC_TARGET_UPCALL) + goto wind_default; + + VALIDATE_OR_GOTO (this->private, err); + priv = this->private; + + local = AFR_FRAME_INIT (frame, op_errno); + if (!local) + goto err; + + call_cnt = local->call_count; + for (i = 0; i < priv->child_count; i++) { + if (!local->child_up[i]) + continue; + + STACK_WIND_COOKIE (frame, afr_ipc_cbk, + (void *) (long) i, + priv->children[i], + priv->children[i]->fops->ipc, + op, xdata); + if (!--call_cnt) + break; + } + return 0; + +err: + if (op_errno == -1) + op_errno = errno; + AFR_STACK_UNWIND (ipc, frame, -1, op_errno, NULL); + + return 0; + +wind_default: + STACK_WIND (frame, default_ipc_cbk, FIRST_CHILD (this), + FIRST_CHILD (this)->fops->ipc, op, xdata); + return 0; +} + +int afr_forget (xlator_t *this, inode_t *inode) { uint64_t ctx_int = 0; diff --git a/xlators/cluster/afr/src/afr.c b/xlators/cluster/afr/src/afr.c index c30e7ec..bca9e90 100644 --- a/xlators/cluster/afr/src/afr.c +++ b/xlators/cluster/afr/src/afr.c @@ -563,6 +563,7 @@ struct xlator_fops fops = { .finodelk = afr_finodelk, .entrylk = afr_entrylk, .fentrylk = afr_fentrylk, + .ipc = afr_ipc, /* inode read */ .access = afr_access, -- 1.7.1