3604df
From d1b1a5186903cf9166a2aba7a2eadafd83038708 Mon Sep 17 00:00:00 2001
3604df
From: Pranith Kumar K <pkarampu@redhat.com>
3604df
Date: Thu, 1 Dec 2016 09:42:19 +0530
3604df
Subject: [PATCH 229/235] cluster/afr: Serialize conflicting locks on all
3604df
 subvols
3604df
3604df
Problem:
3604df
1) When a blocking lock is issued and the parallel lock phase fails
3604df
on all subvolumes with EAGAIN, it is not switching to serialized
3604df
locking phase.
3604df
2) When quorum is enabled and locks fail partially it is better
3604df
to give errno returned by brick rather than the default
3604df
quorum errno.
3604df
3604df
Fix:
3604df
Handled this error case and changed op_errno to reflect the actual
3604df
errno in case of quorum error.
3604df
3604df
 >BUG: 1369077
3604df
 >Change-Id: Ifac2e4a13686e9fde601873012700966d56a7f31
3604df
 >Signed-off-by: Pranith Kumar K <pkarampu@redhat.com>
3604df
 >Reviewed-on: http://review.gluster.org/15984
3604df
 >Smoke: Gluster Build System <jenkins@build.gluster.org>
3604df
 >NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org>
3604df
 >CentOS-regression: Gluster Build System <jenkins@build.gluster.org>
3604df
 >Reviewed-by: Ravishankar N <ravishankar@redhat.com>
3604df
3604df
BUG: 1393694
3604df
Change-Id: Id8ab11e633400383097d4487c8dc2f440afe43e7
3604df
Signed-off-by: Pranith Kumar K <pkarampu@redhat.com>
3604df
Reviewed-on: https://code.engineering.redhat.com/gerrit/92316
3604df
Tested-by: Ravishankar Narayanankutty <ravishankar@redhat.com>
3604df
Reviewed-by: Ravishankar Narayanankutty <ravishankar@redhat.com>
3604df
---
3604df
 xlators/cluster/afr/src/afr-common.c      | 82 +++++++++++++++++++------------
3604df
 xlators/cluster/afr/src/afr-transaction.c |  4 +-
3604df
 2 files changed, 53 insertions(+), 33 deletions(-)
3604df
3604df
diff --git a/xlators/cluster/afr/src/afr-common.c b/xlators/cluster/afr/src/afr-common.c
3604df
index a87428a..55f10e7 100644
3604df
--- a/xlators/cluster/afr/src/afr-common.c
3604df
+++ b/xlators/cluster/afr/src/afr-common.c
3604df
@@ -3510,43 +3510,19 @@ afr_fop_lock_wind (call_frame_t *frame, xlator_t *this, int child_index,
3604df
         }
3604df
 }
3604df
 
3604df
-static int32_t
3604df
-afr_unlock_partial_lock_cbk (call_frame_t *frame, void *cookie,
3604df
-                             xlator_t *this, int32_t op_ret,
3604df
-                             int32_t op_errno, dict_t *xdata)
3604df
-
3604df
+void
3604df
+afr_fop_lock_proceed (call_frame_t *frame)
3604df
 {
3604df
         afr_local_t *local = NULL;
3604df
         afr_private_t *priv = NULL;
3604df
-        int call_count = -1;
3604df
-        int child_index = (long)cookie;
3604df
-        uuid_t  gfid = {0};
3604df
 
3604df
         local = frame->local;
3604df
-        priv = this->private;
3604df
-
3604df
-        if (op_ret < 0 && op_errno != ENOTCONN) {
3604df
-                if (local->fd)
3604df
-                        gf_uuid_copy (gfid, local->fd->inode->gfid);
3604df
-                else
3604df
-                        loc_gfid (&local->loc, gfid);
3604df
-                gf_msg (this->name, GF_LOG_ERROR, op_errno,
3604df
-                        AFR_MSG_UNLOCK_FAIL,
3604df
-                        "%s: Failed to unlock %s on %s "
3604df
-                        "with lk_owner: %s", uuid_utoa (gfid),
3604df
-                        gf_fop_list[local->op],
3604df
-                        priv->children[child_index]->name,
3604df
-                        lkowner_utoa (&frame->root->lk_owner));
3604df
-        }
3604df
-
3604df
-        call_count = afr_frame_return (frame);
3604df
-        if (call_count)
3604df
-                goto out;
3604df
+        priv = frame->this->private;
3604df
 
3604df
         if (local->fop_lock_state != AFR_FOP_LOCK_PARALLEL) {
3604df
                 afr_fop_lock_unwind (frame, local->op, local->op_ret,
3604df
                                      local->op_errno, local->xdata_rsp);
3604df
-                goto out;
3604df
+                return;
3604df
         }
3604df
         /* At least one child is up */
3604df
         /*
3604df
@@ -3590,8 +3566,42 @@ afr_unlock_partial_lock_cbk (call_frame_t *frame, void *cookie,
3604df
         default:
3604df
                 break;
3604df
         }
3604df
-        afr_serialized_lock_wind (frame, this);
3604df
-out:
3604df
+        afr_serialized_lock_wind (frame, frame->this);
3604df
+}
3604df
+
3604df
+static int32_t
3604df
+afr_unlock_partial_lock_cbk (call_frame_t *frame, void *cookie,
3604df
+                             xlator_t *this, int32_t op_ret,
3604df
+                             int32_t op_errno, dict_t *xdata)
3604df
+
3604df
+{
3604df
+        afr_local_t *local = NULL;
3604df
+        afr_private_t *priv = NULL;
3604df
+        int call_count = -1;
3604df
+        int child_index = (long)cookie;
3604df
+        uuid_t  gfid = {0};
3604df
+
3604df
+        local = frame->local;
3604df
+        priv = this->private;
3604df
+
3604df
+        if (op_ret < 0 && op_errno != ENOTCONN) {
3604df
+                if (local->fd)
3604df
+                        gf_uuid_copy (gfid, local->fd->inode->gfid);
3604df
+                else
3604df
+                        loc_gfid (&local->loc, gfid);
3604df
+                gf_msg (this->name, GF_LOG_ERROR, op_errno,
3604df
+                        AFR_MSG_UNLOCK_FAIL,
3604df
+                        "%s: Failed to unlock %s on %s "
3604df
+                        "with lk_owner: %s", uuid_utoa (gfid),
3604df
+                        gf_fop_list[local->op],
3604df
+                        priv->children[child_index]->name,
3604df
+                        lkowner_utoa (&frame->root->lk_owner));
3604df
+        }
3604df
+
3604df
+        call_count = afr_frame_return (frame);
3604df
+        if (call_count == 0)
3604df
+                afr_fop_lock_proceed (frame);
3604df
+
3604df
         return 0;
3604df
 }
3604df
 
3604df
@@ -3603,6 +3613,11 @@ afr_unlock_locks_and_proceed (call_frame_t *frame, xlator_t *this,
3604df
         afr_private_t *priv = NULL;
3604df
         afr_local_t *local = NULL;
3604df
 
3604df
+        if (call_count == 0) {
3604df
+                afr_fop_lock_proceed (frame);
3604df
+                goto out;
3604df
+        }
3604df
+
3604df
         local = frame->local;
3604df
         priv = this->private;
3604df
         local->call_count = call_count;
3604df
@@ -3639,6 +3654,7 @@ afr_unlock_locks_and_proceed (call_frame_t *frame, xlator_t *this,
3604df
                         break;
3604df
         }
3604df
 
3604df
+out:
3604df
         return 0;
3604df
 }
3604df
 
3604df
@@ -3681,7 +3697,7 @@ afr_fop_lock_done (call_frame_t *frame, xlator_t *this)
3604df
                 local->op_errno = local->replies[i].op_errno;
3604df
         }
3604df
 
3604df
-        if (afr_fop_lock_is_unlock (frame) || (lock_count == 0))
3604df
+        if (afr_fop_lock_is_unlock (frame))
3604df
                 goto unwind;
3604df
 
3604df
         if (afr_is_conflicting_lock_present (local->op_ret, local->op_errno)) {
3604df
@@ -3689,7 +3705,9 @@ afr_fop_lock_done (call_frame_t *frame, xlator_t *this)
3604df
         } else if (priv->quorum_count && !afr_has_quorum (success, this)) {
3604df
                 local->fop_lock_state = AFR_FOP_LOCK_QUORUM_FAILED;
3604df
                 local->op_ret = -1;
3604df
-                local->op_errno = afr_quorum_errno (priv);
3604df
+                local->op_errno = afr_final_errno (local, priv);
3604df
+                if (local->op_errno == 0)
3604df
+                        local->op_errno = afr_quorum_errno (priv);
3604df
                 afr_unlock_locks_and_proceed (frame, this, lock_count);
3604df
         } else {
3604df
                 goto unwind;
3604df
diff --git a/xlators/cluster/afr/src/afr-transaction.c b/xlators/cluster/afr/src/afr-transaction.c
3604df
index 479f71f..f397ae7 100644
3604df
--- a/xlators/cluster/afr/src/afr-transaction.c
3604df
+++ b/xlators/cluster/afr/src/afr-transaction.c
3604df
@@ -1666,7 +1666,9 @@ afr_changelog_pre_op (call_frame_t *frame, xlator_t *this)
3604df
          * quorum number of nodes.
3604df
          */
3604df
         if (priv->quorum_count && !afr_has_fop_quorum (frame)) {
3604df
-                op_errno = afr_quorum_errno (priv);
3604df
+                op_errno = int_lock->lock_op_errno;
3604df
+                if (op_errno == 0)
3604df
+                        op_errno = afr_quorum_errno (priv);
3604df
                 goto err;
3604df
         }
3604df
 
3604df
-- 
3604df
2.9.3
3604df