diff options
Diffstat (limited to 'xlators/cluster/afr/src')
-rw-r--r-- | xlators/cluster/afr/src/afr-common.c | 149 | ||||
-rw-r--r-- | xlators/cluster/afr/src/afr.c | 1 | ||||
-rw-r--r-- | xlators/cluster/afr/src/afr.h | 7 |
3 files changed, 157 insertions, 0 deletions
diff --git a/xlators/cluster/afr/src/afr-common.c b/xlators/cluster/afr/src/afr-common.c index 8752e98c8df..c313294961f 100644 --- a/xlators/cluster/afr/src/afr-common.c +++ b/xlators/cluster/afr/src/afr-common.c @@ -4552,6 +4552,155 @@ out: return 0; } +int32_t +afr_lease_unlock_cbk (call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, struct gf_lease *lease, + dict_t *xdata) +{ + afr_local_t *local = NULL; + int call_count = -1; + + local = frame->local; + call_count = afr_frame_return (frame); + + if (call_count == 0) + AFR_STACK_UNWIND (lease, frame, local->op_ret, local->op_errno, + lease, xdata); + + return 0; +} + +int32_t +afr_lease_unlock (call_frame_t *frame, xlator_t *this) +{ + afr_local_t *local = NULL; + afr_private_t *priv = NULL; + int i = 0; + int call_count = 0; + + local = frame->local; + priv = this->private; + + call_count = afr_locked_nodes_count (local->cont.lease.locked_nodes, + priv->child_count); + + if (call_count == 0) { + AFR_STACK_UNWIND (lease, frame, local->op_ret, local->op_errno, + &local->cont.lease.ret_lease, NULL); + return 0; + } + + local->call_count = call_count; + + local->cont.lease.user_lease.cmd = GF_UNLK_LEASE; + + for (i = 0; i < priv->child_count; i++) { + if (local->cont.lease.locked_nodes[i]) { + STACK_WIND (frame, afr_lease_unlock_cbk, + priv->children[i], + priv->children[i]->fops->lease, + &local->loc, &local->cont.lease.user_lease, NULL); + + if (!--call_count) + break; + } + } + + return 0; +} + +int32_t +afr_lease_cbk (call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, struct gf_lease *lease, + dict_t *xdata) +{ + afr_local_t *local = NULL; + afr_private_t *priv = NULL; + int child_index = -1; + + local = frame->local; + priv = this->private; + + child_index = (long) cookie; + + afr_common_lock_cbk (frame, cookie, this, op_ret, op_errno, xdata); + if (op_ret < 0 && op_errno == EAGAIN) { + local->op_ret = -1; + local->op_errno = EAGAIN; + + afr_lease_unlock (frame, this); + return 0; + } + + if (op_ret == 0) { + local->op_ret = 0; + local->op_errno = 0; + local->cont.lease.locked_nodes[child_index] = 1; + local->cont.lease.ret_lease = *lease; + } + + child_index++; + if (child_index < priv->child_count) { + STACK_WIND_COOKIE (frame, afr_lease_cbk, (void *) (long) child_index, + priv->children[child_index], + priv->children[child_index]->fops->lease, + &local->loc, &local->cont.lease.user_lease, xdata); + } else if (priv->quorum_count && + !afr_has_quorum (local->cont.lk.locked_nodes, this)) { + local->op_ret = -1; + local->op_errno = afr_final_errno (local, priv); + + afr_lease_unlock (frame, this); + } else { + if (local->op_ret < 0) + local->op_errno = afr_final_errno (local, priv); + AFR_STACK_UNWIND (lease, frame, local->op_ret, local->op_errno, + &local->cont.lease.ret_lease, NULL); + } + + return 0; +} + +int +afr_lease (call_frame_t *frame, xlator_t *this, + loc_t *loc, struct gf_lease *lease, dict_t *xdata) +{ + afr_private_t *priv = NULL; + afr_local_t *local = NULL; + int32_t op_errno = ENOMEM; + + priv = this->private; + + local = AFR_FRAME_INIT (frame, op_errno); + if (!local) + goto out; + + local->op = GF_FOP_LEASE; + local->cont.lease.locked_nodes = GF_CALLOC (priv->child_count, + sizeof (*local->cont.lease.locked_nodes), + gf_afr_mt_char); + + if (!local->cont.lease.locked_nodes) { + op_errno = ENOMEM; + goto out; + } + + loc_copy (&local->loc, loc); + local->cont.lease.user_lease = *lease; + local->cont.lease.ret_lease = *lease; + + STACK_WIND_COOKIE (frame, afr_lease_cbk, (void *) (long) 0, + priv->children[0], + priv->children[0]->fops->lease, + loc, lease, xdata); + + return 0; +out: + AFR_STACK_UNWIND (lease, frame, -1, op_errno, NULL, NULL); + + return 0; +} + int afr_ipc_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) diff --git a/xlators/cluster/afr/src/afr.c b/xlators/cluster/afr/src/afr.c index 27cee590b4b..0d6773c96e8 100644 --- a/xlators/cluster/afr/src/afr.c +++ b/xlators/cluster/afr/src/afr.c @@ -638,6 +638,7 @@ struct xlator_fops fops = { .entrylk = afr_entrylk, .fentrylk = afr_fentrylk, .ipc = afr_ipc, + .lease = afr_lease, /* inode read */ .access = afr_access, diff --git a/xlators/cluster/afr/src/afr.h b/xlators/cluster/afr/src/afr.h index fd75de45341..c76b0c1c485 100644 --- a/xlators/cluster/afr/src/afr.h +++ b/xlators/cluster/afr/src/afr.h @@ -689,6 +689,13 @@ typedef struct _afr_local { int32_t datasync; } fsync; + struct { + struct gf_lease user_lease; + struct gf_lease ret_lease; + unsigned char *locked_nodes; + } lease; + + } cont; struct { |