diff options
author | Vikas Gorur <vikas@gluster.com> | 2009-12-02 14:02:44 +0000 |
---|---|---|
committer | Anand V. Avati <avati@dev.gluster.com> | 2009-12-03 02:00:39 -0800 |
commit | be762405e773ac25054cd08ba7f5760389db3bdd (patch) | |
tree | 28c2fd6b9c008c230445656c554a23347fde887b | |
parent | 9cc2207e2ffc23e88c23a95bb0783156a85b57c4 (diff) |
cluster/afr: Don't do transactional flush if pre-op has been nowhere done.
If a pre-op has not been done on any subvolume at all, there
is no reason to make flush a transaction call.
Signed-off-by: Vikas Gorur <vikas@gluster.com>
Signed-off-by: Anand V. Avati <avati@dev.gluster.com>
BUG: 427 (flush on a file opened read-only should not hold locks)
URL: http://bugs.gluster.com/cgi-bin/bugzilla3/show_bug.cgi?id=427
-rw-r--r-- | xlators/cluster/afr/src/afr.c | 124 |
1 files changed, 106 insertions, 18 deletions
diff --git a/xlators/cluster/afr/src/afr.c b/xlators/cluster/afr/src/afr.c index 33cd70cd478..f81b8005da0 100644 --- a/xlators/cluster/afr/src/afr.c +++ b/xlators/cluster/afr/src/afr.c @@ -1250,6 +1250,73 @@ afr_flush_done (call_frame_t *frame, xlator_t *this) int +afr_plain_flush_cbk (call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno) + +{ + afr_local_t *local = NULL; + + int call_count = -1; + + local = frame->local; + + LOCK (&frame->lock); + { + if (op_ret == 0) + local->op_ret = 0; + + local->op_errno = op_errno; + } + UNLOCK (&frame->lock); + + call_count = afr_frame_return (frame); + + if (call_count == 0) + AFR_STACK_UNWIND (flush, frame, local->op_ret, local->op_errno); + + return 0; +} + + +static int +__no_pre_op_done (xlator_t *this, fd_t *fd) +{ + int i = 0; + int op_ret = 1; + + int _ret = 0; + uint64_t ctx; + afr_fd_ctx_t * fd_ctx = NULL; + + afr_private_t *priv = NULL; + + priv = this->private; + + LOCK (&fd->lock); + { + _ret = __fd_ctx_get (fd, this, &ctx); + + if (_ret < 0) { + goto out; + } + + fd_ctx = (afr_fd_ctx_t *)(long) ctx; + + for (i = 0; i < priv->child_count; i++) { + if (fd_ctx->pre_op_done[i]) { + op_ret = 0; + break; + } + } + } +out: + UNLOCK (&fd->lock); + + return op_ret; +} + + +int afr_flush (call_frame_t *frame, xlator_t *this, fd_t *fd) { afr_private_t * priv = NULL; @@ -1262,20 +1329,15 @@ afr_flush (call_frame_t *frame, xlator_t *this, fd_t *fd) int op_ret = -1; int op_errno = 0; + int i = 0; + int call_count = 0; + VALIDATE_OR_GOTO (frame, out); VALIDATE_OR_GOTO (this, out); VALIDATE_OR_GOTO (this->private, out); priv = this->private; - transaction_frame = copy_frame (frame); - if (!transaction_frame) { - op_errno = ENOMEM; - 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); @@ -1284,21 +1346,47 @@ afr_flush (call_frame_t *frame, xlator_t *this, fd_t *fd) goto out; } - transaction_frame->local = local; + call_count = afr_up_children_count (priv->child_count, local->child_up); + + if (__no_pre_op_done (this, fd)) { + frame->local = local; - local->op = GF_FOP_FLUSH; + for (i = 0; i < priv->child_count; i++) { + if (local->child_up[i]) { + STACK_WIND_COOKIE (frame, afr_plain_flush_cbk, + (void *) (long) i, + priv->children[i], + priv->children[i]->fops->flush, + fd); + if (!--call_count) + break; + } + } + } else { + transaction_frame = copy_frame (frame); + if (!transaction_frame) { + op_errno = ENOMEM; + gf_log (this->name, GF_LOG_ERROR, + "Out of memory."); + goto out; + } + + 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->transaction.fop = afr_flush_wind; + local->transaction.done = afr_flush_done; + local->transaction.unwind = afr_flush_unwind; - local->fd = fd_ref (fd); + local->fd = fd_ref (fd); - local->transaction.main_frame = frame; - local->transaction.start = LLONG_MAX - 1; - local->transaction.len = 0; + local->transaction.main_frame = frame; + local->transaction.start = LLONG_MAX - 1; + local->transaction.len = 0; - afr_transaction (transaction_frame, this, AFR_FLUSH_TRANSACTION); + afr_transaction (transaction_frame, this, AFR_FLUSH_TRANSACTION); + } op_ret = 0; out: |