diff options
author | Vikas Gorur <vikas@gluster.com> | 2009-05-04 10:50:48 -0700 |
---|---|---|
committer | Anand V. Avati <avati@amp.gluster.com> | 2009-05-05 12:11:49 +0530 |
commit | 1a5bcf508b22c1f9f5bd2f555e290f6725035cd2 (patch) | |
tree | 135f7ea9636e00fa9f8a138c532bdddbc21342f6 | |
parent | 9aea45a0e1338a10558c4f3f434d172c4bc8c209 (diff) |
Made afr_flush a 'quick-unwind' transaction.
Signed-off-by: Anand V. Avati <avati@amp.gluster.com>
-rw-r--r-- | xlators/cluster/afr/src/afr.c | 73 |
1 files changed, 67 insertions, 6 deletions
diff --git a/xlators/cluster/afr/src/afr.c b/xlators/cluster/afr/src/afr.c index 8e3229e09b5..a20cf792170 100644 --- a/xlators/cluster/afr/src/afr.c +++ b/xlators/cluster/afr/src/afr.c @@ -898,24 +898,68 @@ out: /* {{{ flush */ int +afr_flush_unwind (call_frame_t *frame, xlator_t *this) +{ + afr_local_t * local = NULL; + afr_private_t * priv = NULL; + call_frame_t *main_frame = NULL; + + local = frame->local; + priv = this->private; + + LOCK (&frame->lock); + { + if (local->transaction.main_frame) + main_frame = local->transaction.main_frame; + local->transaction.main_frame = NULL; + } + UNLOCK (&frame->lock); + + if (main_frame) { + AFR_STACK_UNWIND (main_frame, local->op_ret, local->op_errno); + } + + return 0; +} + + +int afr_flush_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno) { - afr_local_t * local = NULL; + afr_local_t * local = NULL; + afr_private_t * priv = NULL; int call_count = -1; + int child_index = (long) cookie; + int need_unwind = 0; local = frame->local; + priv = this->private; LOCK (&frame->lock); { - if (op_ret == 0) - local->op_ret = 0; + if (afr_fop_failed (op_ret, op_errno)) + afr_transaction_fop_failed (frame, this, child_index); + + if (op_ret != -1) { + if (local->success_count == 0) { + local->op_ret = op_ret; + } + local->success_count++; + + if (local->success_count == priv->wait_count) { + need_unwind = 1; + } + } local->op_errno = op_errno; } UNLOCK (&frame->lock); + if (need_unwind) + afr_flush_unwind (frame, this); + call_count = afr_frame_return (frame); if (call_count == 0) { @@ -971,7 +1015,9 @@ afr_flush_done (call_frame_t *frame, xlator_t *this) local = frame->local; - AFR_STACK_UNWIND (frame, local->op_ret, local->op_errno); + local->transaction.unwind (frame, this); + + AFR_STACK_DESTROY (frame); return 0; } @@ -983,6 +1029,8 @@ afr_flush (call_frame_t *frame, xlator_t *this, fd_t *fd) afr_private_t * priv = NULL; afr_local_t * local = NULL; + call_frame_t * transaction_frame = NULL; + int ret = -1; int op_ret = -1; @@ -994,6 +1042,13 @@ afr_flush (call_frame_t *frame, xlator_t *this, fd_t *fd) priv = this->private; + transaction_frame = copy_frame (frame); + if (!transaction_frame) { + gf_log (this->name, GF_LOG_ERROR, + "Out of memory."); + goto out; + } + ALLOC_OR_GOTO (local, afr_local_t, out); ret = AFR_LOCAL_INIT (local, priv); @@ -1002,22 +1057,28 @@ afr_flush (call_frame_t *frame, xlator_t *this, fd_t *fd) goto out; } - frame->local = local; + transaction_frame->local = local; local->op = GF_FOP_FLUSH; + local->transaction.fop = afr_flush_wind; local->transaction.done = afr_flush_done; + local->transaction.unwind = afr_flush_unwind; local->fd = fd_ref (fd); + local->transaction.main_frame = frame; local->transaction.start = 0; local->transaction.len = 0; - afr_transaction (frame, this, AFR_FLUSH_TRANSACTION); + afr_transaction (transaction_frame, this, AFR_FLUSH_TRANSACTION); op_ret = 0; out: if (op_ret == -1) { + if (transaction_frame) + AFR_STACK_DESTROY (transaction_frame); + AFR_STACK_UNWIND (frame, op_ret, op_errno, NULL); } |