3604df
From fd75683b1e1334d60fbbca97f7d35dd50d61b404 Mon Sep 17 00:00:00 2001
3604df
From: Pranith Kumar K <pkarampu@redhat.com>
3604df
Date: Mon, 7 Nov 2016 14:47:34 +0530
3604df
Subject: [PATCH 195/206] cluster/afr: Fix bugs in [f]inodelk/[f]entrylk
3604df
3604df
Problems:
3604df
1) Inodelk is not taking quorum into account
3604df
2) finodelk, [f]entrylk are not implemented correctly
3604df
3) By default afr doesn't go for non-blocking parallel locks.
3604df
3604df
Fix:
3604df
Implemented a common framework which can be used by
3604df
[f]inodelk/[f]entrylk.  Used quorum for the same.
3604df
3604df
 >Change-Id: I239f13875a065298630d266941df10cfa3addc85
3604df
 >BUG: 1369077
3604df
 >Signed-off-by: Pranith Kumar K <pkarampu@redhat.com>
3604df
 >Reviewed-on: http://review.gluster.org/15802
3604df
 >Tested-by: Krutika Dhananjay <kdhananj@redhat.com>
3604df
 >Reviewed-by: Krutika Dhananjay <kdhananj@redhat.com>
3604df
 >Smoke: Gluster Build System <jenkins@build.gluster.org>
3604df
 >Reviewed-by: Ravishankar N <ravishankar@redhat.com>
3604df
 >CentOS-regression: Gluster Build System <jenkins@build.gluster.org>
3604df
 >NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org>
3604df
3604df
BUG: 1393694
3604df
Change-Id: If36907dad803b4774372036a54f8a034cd4155f5
3604df
Signed-off-by: Pranith Kumar K <pkarampu@redhat.com>
3604df
Reviewed-on: https://code.engineering.redhat.com/gerrit/91346
3604df
---
3604df
 tests/basic/afr/inodelk.t                 |  87 ++++
3604df
 xlators/cluster/afr/src/afr-common.c      | 676 ++++++++++++++++--------------
3604df
 xlators/cluster/afr/src/afr-lk-common.c   |   2 +-
3604df
 xlators/cluster/afr/src/afr-messages.h    |   4 +-
3604df
 xlators/cluster/afr/src/afr-transaction.c |   8 -
3604df
 xlators/cluster/afr/src/afr.h             |  21 +
3604df
 6 files changed, 483 insertions(+), 315 deletions(-)
3604df
 create mode 100644 tests/basic/afr/inodelk.t
3604df
3604df
diff --git a/tests/basic/afr/inodelk.t b/tests/basic/afr/inodelk.t
3604df
new file mode 100644
3604df
index 0000000..a32aa85
3604df
--- /dev/null
3604df
+++ b/tests/basic/afr/inodelk.t
3604df
@@ -0,0 +1,87 @@
3604df
+#!/bin/bash
3604df
+
3604df
+. $(dirname $0)/../../include.rc
3604df
+. $(dirname $0)/../../volume.rc
3604df
+cleanup;
3604df
+
3604df
+#This test tests that inodelk fails when quorum is not met. Also tests the
3604df
+#success case where inodelk is obtained and unlocks are done correctly.
3604df
+
3604df
+TEST glusterd;
3604df
+TEST pidof glusterd
3604df
+
3604df
+TEST $CLI volume create $V0 replica 3 arbiter 1 $H0:$B0/${V0}{0..5}
3604df
+TEST $CLI volume start $V0
3604df
+TEST $GFS -s $H0 --volfile-id=$V0 $M0
3604df
+
3604df
+#Test success case
3604df
+TEST mkdir $M0/dir1
3604df
+TEST mv $M0/dir1 $M0/dir2
3604df
+
3604df
+#If there is a problem with inodelk unlocking the following would hang.
3604df
+TEST mv $M0/dir2 $M0/dir1
3604df
+
3604df
+#Test failure case by bringing two of the bricks down
3604df
+#Test that the directory is not moved partially on some bricks but successful
3604df
+#on other subvol where quorum meets. Do that for both set of bricks
3604df
+
3604df
+TEST kill_brick $V0 $H0 $B0/${V0}0
3604df
+TEST kill_brick $V0 $H0 $B0/${V0}1
3604df
+TEST ! mv $M0/dir1 $M0/dir2
3604df
+
3604df
+TEST stat $B0/${V0}0/dir1
3604df
+TEST stat $B0/${V0}1/dir1
3604df
+TEST stat $B0/${V0}2/dir1
3604df
+TEST stat $B0/${V0}3/dir1
3604df
+TEST stat $B0/${V0}4/dir1
3604df
+TEST stat $B0/${V0}5/dir1
3604df
+TEST ! stat $B0/${V0}0/dir2
3604df
+TEST ! stat $B0/${V0}1/dir2
3604df
+TEST ! stat $B0/${V0}2/dir2
3604df
+TEST ! stat $B0/${V0}3/dir2
3604df
+TEST ! stat $B0/${V0}4/dir2
3604df
+TEST ! stat $B0/${V0}5/dir2
3604df
+
3604df
+TEST $CLI volume start $V0 force
3604df
+TEST kill_brick $V0 $H0 $B0/${V0}3
3604df
+TEST kill_brick $V0 $H0 $B0/${V0}4
3604df
+EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" afr_child_up_status $V0 0
3604df
+EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" afr_child_up_status $V0 1
3604df
+TEST ! mv $M0/dir1 $M0/dir2
3604df
+TEST stat $B0/${V0}0/dir1
3604df
+TEST stat $B0/${V0}1/dir1
3604df
+TEST stat $B0/${V0}2/dir1
3604df
+TEST stat $B0/${V0}3/dir1
3604df
+TEST stat $B0/${V0}4/dir1
3604df
+TEST stat $B0/${V0}5/dir1
3604df
+TEST ! stat $B0/${V0}0/dir2
3604df
+TEST ! stat $B0/${V0}1/dir2
3604df
+TEST ! stat $B0/${V0}2/dir2
3604df
+TEST ! stat $B0/${V0}3/dir2
3604df
+TEST ! stat $B0/${V0}4/dir2
3604df
+TEST ! stat $B0/${V0}5/dir2
3604df
+
3604df
+#Bring the bricks back up and try mv once more, it should succeed.
3604df
+TEST $CLI volume start $V0 force
3604df
+EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" afr_child_up_status $V0 3
3604df
+EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" afr_child_up_status $V0 4
3604df
+TEST mv $M0/dir1 $M0/dir2
3604df
+cleanup;
3604df
+#Do similar tests on replica 2
3604df
+TEST glusterd;
3604df
+TEST pidof glusterd
3604df
+TEST $CLI volume create $V0 replica 2 $H0:$B0/${V0}{0..3}
3604df
+TEST $CLI volume start $V0
3604df
+TEST $GFS -s $H0 --volfile-id=$V0 $M0
3604df
+TEST mkdir $M0/dir1
3604df
+TEST mv $M0/dir1 $M0/dir2
3604df
+#Because we don't know hashed subvol, do the same test twice bringing 1 brick
3604df
+#from each down, quorum calculation should allow it.
3604df
+TEST kill_brick $V0 $H0 $B0/${V0}0
3604df
+TEST mv $M0/dir2 $M0/dir1
3604df
+TEST $CLI volume start $V0 force
3604df
+TEST kill_brick $V0 $H0 $B0/${V0}2
3604df
+TEST mv $M0/dir1 $M0/dir2
3604df
+TEST kill_brick $V0 $H0 $B0/${V0}0
3604df
+TEST mv $M0/dir2 $M0/dir1
3604df
+cleanup
3604df
diff --git a/xlators/cluster/afr/src/afr-common.c b/xlators/cluster/afr/src/afr-common.c
3604df
index dec6026..ab60406 100644
3604df
--- a/xlators/cluster/afr/src/afr-common.c
3604df
+++ b/xlators/cluster/afr/src/afr-common.c
3604df
@@ -45,6 +45,14 @@
3604df
 #include "afr-messages.h"
3604df
 #include "compound-fop-utils.h"
3604df
 
3604df
+int32_t
3604df
+afr_quorum_errno (afr_private_t *priv)
3604df
+{
3604df
+        if (priv->quorum_reads)
3604df
+                return ENOTCONN;
3604df
+        return EROFS;
3604df
+}
3604df
+
3604df
 call_frame_t *
3604df
 afr_copy_frame (call_frame_t *base)
3604df
 {
3604df
@@ -1558,6 +1566,29 @@ afr_remove_eager_lock_stub (afr_local_t *local)
3604df
         UNLOCK (&local->fd->lock);
3604df
 }
3604df
 
3604df
+static gf_boolean_t
3604df
+afr_fop_lock_is_unlock (call_frame_t *frame)
3604df
+{
3604df
+        afr_local_t *local = frame->local;
3604df
+        switch (local->op) {
3604df
+        case GF_FOP_INODELK:
3604df
+        case GF_FOP_FINODELK:
3604df
+                if ((F_UNLCK == local->cont.inodelk.in_flock.l_type) &&
3604df
+                   (local->cont.inodelk.in_cmd == F_SETLKW ||
3604df
+                    local->cont.inodelk.in_cmd == F_SETLK))
3604df
+                        return _gf_true;
3604df
+                break;
3604df
+        case GF_FOP_ENTRYLK:
3604df
+        case GF_FOP_FENTRYLK:
3604df
+                if (ENTRYLK_UNLOCK == local->cont.entrylk.in_cmd)
3604df
+                                 return _gf_true;
3604df
+                 break;
3604df
+        default:
3604df
+                 break;
3604df
+        }
3604df
+        return _gf_false;
3604df
+}
3604df
+
3604df
 void
3604df
 afr_local_cleanup (afr_local_t *local, xlator_t *this)
3604df
 {
3604df
@@ -1681,6 +1712,15 @@ afr_local_cleanup (afr_local_t *local, xlator_t *this)
3604df
 
3604df
         { /* inodelk */
3604df
                 GF_FREE (local->cont.inodelk.volume);
3604df
+                if (local->cont.inodelk.xdata)
3604df
+                        dict_unref (local->cont.inodelk.xdata);
3604df
+        }
3604df
+
3604df
+        { /* entrylk */
3604df
+                GF_FREE (local->cont.entrylk.volume);
3604df
+                GF_FREE (local->cont.entrylk.basename);
3604df
+                if (local->cont.entrylk.xdata)
3604df
+                        dict_unref (local->cont.entrylk.xdata);
3604df
         }
3604df
 
3604df
         if (local->xdata_req)
3604df
@@ -3242,10 +3282,96 @@ out:
3604df
 
3604df
 /* }}} */
3604df
 
3604df
-int32_t
3604df
-afr_unlock_partial_inodelk_cbk (call_frame_t *frame, void *cookie,
3604df
-                                xlator_t *this, int32_t op_ret,
3604df
-                                int32_t op_errno, dict_t *xdata)
3604df
+static int
3604df
+afr_serialized_lock_wind (call_frame_t *frame, xlator_t *this);
3604df
+
3604df
+static gf_boolean_t
3604df
+afr_is_conflicting_lock_present (int32_t op_ret, int32_t op_errno)
3604df
+{
3604df
+        if (op_ret == -1 && op_errno == EAGAIN)
3604df
+                return _gf_true;
3604df
+        return _gf_false;
3604df
+}
3604df
+
3604df
+static void
3604df
+afr_fop_lock_unwind (call_frame_t *frame, glusterfs_fop_t op, int32_t op_ret,
3604df
+                     int32_t op_errno, dict_t *xdata)
3604df
+{
3604df
+        switch (op) {
3604df
+        case GF_FOP_INODELK:
3604df
+                AFR_STACK_UNWIND (inodelk, frame, op_ret, op_errno, xdata);
3604df
+                break;
3604df
+        case GF_FOP_FINODELK:
3604df
+                AFR_STACK_UNWIND (finodelk, frame, op_ret, op_errno, xdata);
3604df
+                break;
3604df
+        case GF_FOP_ENTRYLK:
3604df
+                AFR_STACK_UNWIND (entrylk, frame, op_ret, op_errno, xdata);
3604df
+                break;
3604df
+        case GF_FOP_FENTRYLK:
3604df
+                AFR_STACK_UNWIND (fentrylk, frame, op_ret, op_errno, xdata);
3604df
+                break;
3604df
+        default:
3604df
+                break;
3604df
+        }
3604df
+}
3604df
+
3604df
+static void
3604df
+afr_fop_lock_wind (call_frame_t *frame, xlator_t *this, int child_index,
3604df
+                   int32_t (*lock_cbk) (call_frame_t *, void *, xlator_t *,
3604df
+                                        int32_t, int32_t, dict_t *))
3604df
+{
3604df
+        afr_local_t *local = frame->local;
3604df
+        afr_private_t *priv = this->private;
3604df
+        int i = child_index;
3604df
+
3604df
+        switch (local->op) {
3604df
+        case GF_FOP_INODELK:
3604df
+                STACK_WIND_COOKIE (frame, lock_cbk, (void *) (long) i,
3604df
+                                   priv->children[i],
3604df
+                                   priv->children[i]->fops->inodelk,
3604df
+                                   (const char *)local->cont.inodelk.volume,
3604df
+                                   &local->loc, local->cont.inodelk.cmd,
3604df
+                                   &local->cont.inodelk.flock,
3604df
+                                   local->cont.inodelk.xdata);
3604df
+                break;
3604df
+        case GF_FOP_FINODELK:
3604df
+                STACK_WIND_COOKIE (frame, lock_cbk, (void *) (long) i,
3604df
+                                   priv->children[i],
3604df
+                                   priv->children[i]->fops->finodelk,
3604df
+                                   (const char *)local->cont.inodelk.volume,
3604df
+                                   local->fd, local->cont.inodelk.cmd,
3604df
+                                   &local->cont.inodelk.flock,
3604df
+                                   local->cont.inodelk.xdata);
3604df
+                break;
3604df
+        case GF_FOP_ENTRYLK:
3604df
+                STACK_WIND_COOKIE (frame, lock_cbk, (void *) (long) i,
3604df
+                                   priv->children[i],
3604df
+                                   priv->children[i]->fops->entrylk,
3604df
+                                   local->cont.entrylk.volume, &local->loc,
3604df
+                                   local->cont.entrylk.basename,
3604df
+                                   local->cont.entrylk.cmd,
3604df
+                                   local->cont.entrylk.type,
3604df
+                                   local->cont.entrylk.xdata);
3604df
+                break;
3604df
+        case GF_FOP_FENTRYLK:
3604df
+                STACK_WIND_COOKIE (frame, lock_cbk, (void *) (long) i,
3604df
+                                   priv->children[i],
3604df
+                                   priv->children[i]->fops->fentrylk,
3604df
+                                   local->cont.entrylk.volume, local->fd,
3604df
+                                   local->cont.entrylk.basename,
3604df
+                                   local->cont.entrylk.cmd,
3604df
+                                   local->cont.entrylk.type,
3604df
+                                   local->cont.entrylk.xdata);
3604df
+                break;
3604df
+        default:
3604df
+                break;
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
 {
3604df
         afr_local_t *local = NULL;
3604df
@@ -3258,28 +3384,78 @@ afr_unlock_partial_inodelk_cbk (call_frame_t *frame, void *cookie,
3604df
         priv = this->private;
3604df
 
3604df
         if (op_ret < 0 && op_errno != ENOTCONN) {
3604df
-                loc_gfid (&local->loc, gfid);
3604df
-                gf_msg (this->name, GF_LOG_ERROR, 0,
3604df
-                        AFR_MSG_INODE_UNLOCK_FAIL,
3604df
-                        "%s: Failed to unlock %s "
3604df
-                        "with lk_owner: %s (%s)", uuid_utoa (gfid),
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
-                        strerror (op_errno));
3604df
+                        lkowner_utoa (&frame->root->lk_owner));
3604df
         }
3604df
 
3604df
         call_count = afr_frame_return (frame);
3604df
-        if (call_count == 0) {
3604df
-                AFR_STACK_UNWIND (inodelk, frame, local->op_ret,
3604df
-                                  local->op_errno, local->xdata_rsp);
3604df
-        }
3604df
+        if (call_count)
3604df
+                goto out;
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
+        }
3604df
+        /* At least one child is up */
3604df
+        /*
3604df
+         * Non-blocking locks also need to be serialized.  Otherwise there is
3604df
+         * a chance that both the mounts which issued same non-blocking inodelk
3604df
+         * may endup not acquiring the lock on any-brick.
3604df
+         * Ex: Mount1 and Mount2
3604df
+         * request for full length lock on file f1.  Mount1 afr may acquire the
3604df
+         * partial lock on brick-1 and may not acquire the lock on brick-2
3604df
+         * because Mount2 already got the lock on brick-2, vice versa.  Since
3604df
+         * both the mounts only got partial locks, afr treats them as failure in
3604df
+         * gaining the locks and unwinds with EAGAIN errno.
3604df
+         */
3604df
+        local->op_ret = -1;
3604df
+        local->op_ret = EUCLEAN;
3604df
+        local->fop_lock_state = AFR_FOP_LOCK_SERIAL;
3604df
+        afr_local_replies_wipe (local, priv);
3604df
+        if (local->xdata_rsp)
3604df
+                dict_unref (local->xdata_rsp);
3604df
+        local->xdata_rsp = NULL;
3604df
+        switch (local->op) {
3604df
+        case GF_FOP_INODELK:
3604df
+        case GF_FOP_FINODELK:
3604df
+                local->cont.inodelk.cmd = local->cont.inodelk.in_cmd;
3604df
+                local->cont.inodelk.flock = local->cont.inodelk.in_flock;
3604df
+                if (local->cont.inodelk.xdata)
3604df
+                        dict_unref (local->cont.inodelk.xdata);
3604df
+                local->cont.inodelk.xdata = NULL;
3604df
+                if (local->xdata_req)
3604df
+                        local->cont.inodelk.xdata = dict_ref (local->xdata_req);
3604df
+                break;
3604df
+        case GF_FOP_ENTRYLK:
3604df
+        case GF_FOP_FENTRYLK:
3604df
+                local->cont.entrylk.cmd = local->cont.entrylk.in_cmd;
3604df
+                if (local->cont.entrylk.xdata)
3604df
+                        dict_unref (local->cont.entrylk.xdata);
3604df
+                local->cont.entrylk.xdata = NULL;
3604df
+                if (local->xdata_req)
3604df
+                        local->cont.entrylk.xdata = dict_ref (local->xdata_req);
3604df
+                break;
3604df
+        default:
3604df
+                break;
3604df
+        }
3604df
+        afr_serialized_lock_wind (frame, this);
3604df
+out:
3604df
         return 0;
3604df
 }
3604df
 
3604df
-int32_t
3604df
-afr_unlock_inodelks_and_unwind (call_frame_t *frame, xlator_t *this,
3604df
-                                int call_count)
3604df
+static int32_t
3604df
+afr_unlock_locks_and_proceed (call_frame_t *frame, xlator_t *this,
3604df
+                             int call_count)
3604df
 {
3604df
         int i = 0;
3604df
         afr_private_t *priv = NULL;
3604df
@@ -3288,7 +3464,25 @@ afr_unlock_inodelks_and_unwind (call_frame_t *frame, xlator_t *this,
3604df
         local = frame->local;
3604df
         priv = this->private;
3604df
         local->call_count = call_count;
3604df
-        local->cont.inodelk.flock.l_type = F_UNLCK;
3604df
+        switch (local->op) {
3604df
+        case GF_FOP_INODELK:
3604df
+        case GF_FOP_FINODELK:
3604df
+                local->cont.inodelk.flock.l_type = F_UNLCK;
3604df
+                local->cont.inodelk.cmd = F_SETLK;
3604df
+                if (local->cont.inodelk.xdata)
3604df
+                        dict_unref (local->cont.inodelk.xdata);
3604df
+                local->cont.inodelk.xdata = NULL;
3604df
+                break;
3604df
+        case GF_FOP_ENTRYLK:
3604df
+        case GF_FOP_FENTRYLK:
3604df
+                local->cont.entrylk.cmd = ENTRYLK_UNLOCK;
3604df
+                if (local->cont.entrylk.xdata)
3604df
+                        dict_unref (local->cont.entrylk.xdata);
3604df
+                local->cont.entrylk.xdata = NULL;
3604df
+                break;
3604df
+        default:
3604df
+                break;
3604df
+        }
3604df
 
3604df
         for (i = 0; i < priv->child_count; i++) {
3604df
                 if (!local->replies[i].valid)
3604df
@@ -3297,13 +3491,7 @@ afr_unlock_inodelks_and_unwind (call_frame_t *frame, xlator_t *this,
3604df
                 if (local->replies[i].op_ret == -1)
3604df
                         continue;
3604df
 
3604df
-                STACK_WIND_COOKIE (frame, afr_unlock_partial_inodelk_cbk,
3604df
-                                   (void*) (long) i,
3604df
-                                   priv->children[i],
3604df
-                                   priv->children[i]->fops->inodelk,
3604df
-                                   local->cont.inodelk.volume,
3604df
-                                   &local->loc, local->cont.inodelk.cmd,
3604df
-                                   &local->cont.inodelk.flock, 0);
3604df
+                afr_fop_lock_wind (frame, this, i, afr_unlock_partial_lock_cbk);
3604df
 
3604df
                 if (!--call_count)
3604df
                         break;
3604df
@@ -3313,23 +3501,27 @@ afr_unlock_inodelks_and_unwind (call_frame_t *frame, xlator_t *this,
3604df
 }
3604df
 
3604df
 int32_t
3604df
-afr_inodelk_done (call_frame_t *frame, xlator_t *this)
3604df
+afr_fop_lock_done (call_frame_t *frame, xlator_t *this)
3604df
 {
3604df
         int i = 0;
3604df
         int lock_count = 0;
3604df
+        unsigned char *success = NULL;
3604df
 
3604df
         afr_local_t *local = NULL;
3604df
         afr_private_t *priv = NULL;
3604df
 
3604df
         local = frame->local;
3604df
         priv = this->private;
3604df
+        success = alloca0(priv->child_count);
3604df
 
3604df
         for (i = 0; i < priv->child_count; i++) {
3604df
                 if (!local->replies[i].valid)
3604df
                         continue;
3604df
 
3604df
-                if (local->replies[i].op_ret == 0)
3604df
+                if (local->replies[i].op_ret == 0) {
3604df
                         lock_count++;
3604df
+                        success[i] = 1;
3604df
+                }
3604df
 
3604df
                 if (local->op_ret == -1 && local->op_errno == EAGAIN)
3604df
                         continue;
3604df
@@ -3347,20 +3539,29 @@ afr_inodelk_done (call_frame_t *frame, xlator_t *this)
3604df
                 local->op_errno = local->replies[i].op_errno;
3604df
         }
3604df
 
3604df
-        if (lock_count && local->cont.inodelk.flock.l_type != F_UNLCK &&
3604df
-            (local->op_ret == -1 && local->op_errno == EAGAIN)) {
3604df
-                afr_unlock_inodelks_and_unwind (frame, this,
3604df
-                                                lock_count);
3604df
+        if (afr_fop_lock_is_unlock (frame) || (lock_count == 0))
3604df
+                goto unwind;
3604df
+
3604df
+        if (afr_is_conflicting_lock_present (local->op_ret, local->op_errno)) {
3604df
+                afr_unlock_locks_and_proceed (frame, this, lock_count);
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
+                afr_unlock_locks_and_proceed (frame, this, lock_count);
3604df
         } else {
3604df
-                AFR_STACK_UNWIND (inodelk, frame, local->op_ret,
3604df
-                                  local->op_errno, local->xdata_rsp);
3604df
+                goto unwind;
3604df
         }
3604df
 
3604df
         return 0;
3604df
+unwind:
3604df
+        afr_fop_lock_unwind (frame, local->op, local->op_ret,
3604df
+                             local->op_errno, local->xdata_rsp);
3604df
+        return 0;
3604df
 }
3604df
 
3604df
-int
3604df
-afr_common_inodelk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
3604df
+static int
3604df
+afr_common_lock_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
3604df
                         int32_t op_ret, int32_t op_errno, dict_t *xdata)
3604df
 {
3604df
         afr_local_t *local = NULL;
3604df
@@ -3384,32 +3585,8 @@ afr_common_inodelk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
3604df
 }
3604df
 
3604df
 static int32_t
3604df
-afr_parallel_inodelk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
3604df
-                          int32_t op_ret, int32_t op_errno, dict_t *xdata)
3604df
-
3604df
-{
3604df
-        int     call_count = 0;
3604df
-
3604df
-        afr_common_inodelk_cbk (frame, cookie, this, op_ret, op_errno, xdata);
3604df
-
3604df
-        call_count = afr_frame_return (frame);
3604df
-        if (call_count == 0)
3604df
-                afr_inodelk_done (frame, this);
3604df
-
3604df
-        return 0;
3604df
-}
3604df
-
3604df
-static gf_boolean_t
3604df
-afr_is_conflicting_lock_present (int32_t op_ret, int32_t op_errno)
3604df
-{
3604df
-        if (op_ret == -1 && op_errno == EAGAIN)
3604df
-                return _gf_true;
3604df
-        return _gf_false;
3604df
-}
3604df
-
3604df
-static int32_t
3604df
-afr_serialized_inodelk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
3604df
-		            int32_t op_ret, int32_t op_errno, dict_t *xdata)
3604df
+afr_serialized_lock_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
3604df
+                         int32_t op_ret, int32_t op_errno, dict_t *xdata)
3604df
 
3604df
 {
3604df
         afr_local_t *local = NULL;
3604df
@@ -3420,7 +3597,7 @@ afr_serialized_inodelk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
3604df
         local = frame->local;
3604df
         priv = this->private;
3604df
 
3604df
-        afr_common_inodelk_cbk (frame, cookie, this, op_ret, op_errno, xdata);
3604df
+        afr_common_lock_cbk (frame, cookie, this, op_ret, op_errno, xdata);
3604df
 
3604df
         for (next_child = child_index + 1; next_child < priv->child_count;
3604df
              next_child++) {
3604df
@@ -3430,80 +3607,117 @@ afr_serialized_inodelk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
3604df
 
3604df
         if (afr_is_conflicting_lock_present (op_ret, op_errno) ||
3604df
             (next_child == priv->child_count)) {
3604df
-                afr_inodelk_done (frame, this);
3604df
+                afr_fop_lock_done (frame, this);
3604df
         } else {
3604df
-                STACK_WIND_COOKIE (frame, afr_serialized_inodelk_cbk,
3604df
-                                   (void *) (long) next_child,
3604df
-                                   priv->children[next_child],
3604df
-                                   priv->children[next_child]->fops->inodelk,
3604df
-                                   (const char *)local->cont.inodelk.volume,
3604df
-                                   &local->loc, local->cont.inodelk.cmd,
3604df
-                                   &local->cont.inodelk.flock,
3604df
-                                   local->xdata_req);
3604df
+                afr_fop_lock_wind (frame, this, next_child,
3604df
+                                   afr_serialized_lock_cbk);
3604df
         }
3604df
 
3604df
         return 0;
3604df
 }
3604df
 
3604df
 static int
3604df
-afr_parallel_inodelk_wind (call_frame_t *frame, xlator_t *this)
3604df
+afr_serialized_lock_wind (call_frame_t *frame, xlator_t *this)
3604df
 {
3604df
         afr_private_t *priv = NULL;
3604df
         afr_local_t *local  = NULL;
3604df
-        int         call_count = 0;
3604df
         int i = 0;
3604df
 
3604df
         priv = this->private;
3604df
         local = frame->local;
3604df
-        call_count = local->call_count;
3604df
 
3604df
         for (i = 0; i < priv->child_count; i++) {
3604df
-                if (!local->child_up[i])
3604df
-                        continue;
3604df
-                STACK_WIND_COOKIE (frame, afr_parallel_inodelk_cbk,
3604df
-                                   (void *) (long) i,
3604df
-                                   priv->children[i],
3604df
-                                   priv->children[i]->fops->inodelk,
3604df
-                                   (const char *)local->cont.inodelk.volume,
3604df
-                                   &local->loc, local->cont.inodelk.cmd,
3604df
-                                   &local->cont.inodelk.flock,
3604df
-                                   local->xdata_req);
3604df
-                if (!--call_count)
3604df
+                if (local->child_up[i]) {
3604df
+                        afr_fop_lock_wind (frame, this, i,
3604df
+                                           afr_serialized_lock_cbk);
3604df
                         break;
3604df
+                }
3604df
         }
3604df
         return 0;
3604df
 }
3604df
 
3604df
+static int32_t
3604df
+afr_parallel_lock_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
3604df
+                       int32_t op_ret, int32_t op_errno, dict_t *xdata)
3604df
+
3604df
+{
3604df
+        int     call_count = 0;
3604df
+
3604df
+        afr_common_lock_cbk (frame, cookie, this, op_ret, op_errno, xdata);
3604df
+
3604df
+        call_count = afr_frame_return (frame);
3604df
+        if (call_count == 0)
3604df
+                afr_fop_lock_done (frame, this);
3604df
+
3604df
+        return 0;
3604df
+}
3604df
+
3604df
 static int
3604df
-afr_serialized_inodelk_wind (call_frame_t *frame, xlator_t *this)
3604df
+afr_parallel_lock_wind (call_frame_t *frame, xlator_t *this)
3604df
 {
3604df
         afr_private_t *priv = NULL;
3604df
         afr_local_t *local  = NULL;
3604df
+        int         call_count = 0;
3604df
         int i = 0;
3604df
 
3604df
         priv = this->private;
3604df
         local = frame->local;
3604df
+        call_count = local->call_count;
3604df
 
3604df
         for (i = 0; i < priv->child_count; i++) {
3604df
-                if (local->child_up[i]) {
3604df
-                        STACK_WIND_COOKIE (frame, afr_serialized_inodelk_cbk,
3604df
-                                           (void *) (long) i,
3604df
-                                           priv->children[i],
3604df
-                                           priv->children[i]->fops->inodelk,
3604df
-                                       (const char *)local->cont.inodelk.volume,
3604df
-                                           &local->loc, local->cont.inodelk.cmd,
3604df
-                                           &local->cont.inodelk.flock,
3604df
-                                           local->xdata_req);
3604df
+                if (!local->child_up[i])
3604df
+                        continue;
3604df
+                afr_fop_lock_wind (frame, this, i, afr_parallel_lock_cbk);
3604df
+                if (!--call_count)
3604df
+                        break;
3604df
+        }
3604df
+        return 0;
3604df
+}
3604df
+
3604df
+static int
3604df
+afr_fop_handle_lock (call_frame_t *frame, xlator_t *this)
3604df
+{
3604df
+        afr_local_t *local = frame->local;
3604df
+
3604df
+        if (!afr_fop_lock_is_unlock (frame)) {
3604df
+                switch (local->op) {
3604df
+                case GF_FOP_INODELK:
3604df
+                case GF_FOP_FINODELK:
3604df
+                        local->cont.inodelk.cmd = F_SETLK;
3604df
+                        break;
3604df
+                case GF_FOP_ENTRYLK:
3604df
+                case GF_FOP_FENTRYLK:
3604df
+                        local->cont.entrylk.cmd = ENTRYLK_LOCK_NB;
3604df
+                        break;
3604df
+                default:
3604df
                         break;
3604df
                 }
3604df
         }
3604df
+
3604df
+        if (local->xdata_req) {
3604df
+                switch (local->op) {
3604df
+                case GF_FOP_INODELK:
3604df
+                case GF_FOP_FINODELK:
3604df
+                        local->cont.inodelk.xdata = dict_ref (local->xdata_req);
3604df
+                        break;
3604df
+                case GF_FOP_ENTRYLK:
3604df
+                case GF_FOP_FENTRYLK:
3604df
+                        local->cont.entrylk.xdata = dict_ref (local->xdata_req);
3604df
+                        break;
3604df
+                default:
3604df
+                        break;
3604df
+                }
3604df
+        }
3604df
+
3604df
+        local->fop_lock_state = AFR_FOP_LOCK_PARALLEL;
3604df
+        afr_parallel_lock_wind (frame, this);
3604df
         return 0;
3604df
 }
3604df
 
3604df
-int32_t
3604df
-afr_inodelk (call_frame_t *frame, xlator_t *this,
3604df
-             const char *volume, loc_t *loc, int32_t cmd,
3604df
-             struct gf_flock *flock, dict_t *xdata)
3604df
+static int32_t
3604df
+afr_handle_inodelk (call_frame_t *frame, glusterfs_fop_t fop,
3604df
+                    const char *volume, loc_t *loc, fd_t *fd, int32_t cmd,
3604df
+                    struct gf_flock *flock, dict_t *xdata)
3604df
 {
3604df
         afr_local_t *local  = NULL;
3604df
         int32_t op_errno = ENOMEM;
3604df
@@ -3512,259 +3726,113 @@ afr_inodelk (call_frame_t *frame, xlator_t *this,
3604df
         if (!local)
3604df
                 goto out;
3604df
 
3604df
-        loc_copy (&local->loc, loc);
3604df
+        local->op = fop;
3604df
+        if (loc)
3604df
+                loc_copy (&local->loc, loc);
3604df
+        if (fd)
3604df
+                local->fd = fd_ref (fd);
3604df
+
3604df
         local->cont.inodelk.volume = gf_strdup (volume);
3604df
         if (!local->cont.inodelk.volume) {
3604df
                 op_errno = ENOMEM;
3604df
                 goto out;
3604df
         }
3604df
 
3604df
+        local->cont.inodelk.in_cmd = cmd;
3604df
         local->cont.inodelk.cmd = cmd;
3604df
+        local->cont.inodelk.in_flock = *flock;
3604df
         local->cont.inodelk.flock = *flock;
3604df
         if (xdata)
3604df
                 local->xdata_req = dict_ref (xdata);
3604df
 
3604df
-        /* At least one child is up */
3604df
-        /*
3604df
-         * Non-blocking locks also need to be serialized.  Otherwise there is
3604df
-         * a chance that both the mounts which issued same non-blocking inodelk
3604df
-         * may endup not acquiring the lock on any-brick.
3604df
-         * Ex: Mount1 and Mount2
3604df
-         * request for full length lock on file f1.  Mount1 afr may acquire the
3604df
-         * partial lock on brick-1 and may not acquire the lock on brick-2
3604df
-         * because Mount2 already got the lock on brick-2, vice versa.  Since
3604df
-         * both the mounts only got partial locks, afr treats them as failure in
3604df
-         * gaining the locks and unwinds with EAGAIN errno.
3604df
-         */
3604df
-        if (flock->l_type == F_UNLCK) {
3604df
-                afr_parallel_inodelk_wind (frame, this);
3604df
-        } else {
3604df
-                afr_serialized_inodelk_wind (frame, this);
3604df
-        }
3604df
-
3604df
-	return 0;
3604df
+        op_errno = -afr_fop_handle_lock (frame, frame->this);
3604df
+        if (op_errno)
3604df
+                goto out;
3604df
+        return 0;
3604df
 out:
3604df
-	AFR_STACK_UNWIND (inodelk, frame, -1, op_errno, NULL);
3604df
+        afr_fop_lock_unwind (frame, fop, -1, op_errno, NULL);
3604df
 
3604df
         return 0;
3604df
 }
3604df
 
3604df
-
3604df
 int32_t
3604df
-afr_finodelk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
3604df
-		  int32_t op_ret, int32_t op_errno, dict_t *xdata)
3604df
-
3604df
+afr_inodelk (call_frame_t *frame, xlator_t *this,
3604df
+             const char *volume, loc_t *loc, int32_t cmd,
3604df
+             struct gf_flock *flock, dict_t *xdata)
3604df
 {
3604df
-        afr_local_t *local = NULL;
3604df
-        int call_count = -1;
3604df
-
3604df
-        local = frame->local;
3604df
-
3604df
-        LOCK (&frame->lock);
3604df
-        {
3604df
-                if (op_ret == 0)
3604df
-                        local->op_ret = 0;
3604df
-
3604df
-                local->op_errno = op_errno;
3604df
-        }
3604df
-        UNLOCK (&frame->lock);
3604df
-
3604df
-        call_count = afr_frame_return (frame);
3604df
-
3604df
-        if (call_count == 0)
3604df
-                AFR_STACK_UNWIND (finodelk, frame, local->op_ret,
3604df
-                                  local->op_errno, xdata);
3604df
-
3604df
+        afr_handle_inodelk (frame, GF_FOP_INODELK, volume, loc, NULL, cmd,
3604df
+                            flock, xdata);
3604df
         return 0;
3604df
 }
3604df
 
3604df
-
3604df
 int32_t
3604df
 afr_finodelk (call_frame_t *frame, xlator_t *this, const char *volume, fd_t *fd,
3604df
-	      int32_t cmd, struct gf_flock *flock, dict_t *xdata)
3604df
-{
3604df
-        afr_private_t *priv = NULL;
3604df
-        afr_local_t *local  = NULL;
3604df
-        int i = 0;
3604df
-        int32_t call_count = 0;
3604df
-        int32_t op_errno = ENOMEM;
3604df
-
3604df
-        priv = this->private;
3604df
-
3604df
-	local = AFR_FRAME_INIT (frame, op_errno);
3604df
-	if (!local)
3604df
-		goto out;
3604df
-
3604df
-        call_count = local->call_count;
3604df
-	if (!call_count) {
3604df
-		op_errno = ENOTCONN;
3604df
-		goto out;
3604df
-	}
3604df
-
3604df
-        for (i = 0; i < priv->child_count; i++) {
3604df
-                if (local->child_up[i]) {
3604df
-                        STACK_WIND (frame, afr_finodelk_cbk,
3604df
-                                    priv->children[i],
3604df
-                                    priv->children[i]->fops->finodelk,
3604df
-                                    volume, fd, cmd, flock, xdata);
3604df
-
3604df
-                        if (!--call_count)
3604df
-                                break;
3604df
-                }
3604df
-        }
3604df
-
3604df
-	return 0;
3604df
-out:
3604df
-	AFR_STACK_UNWIND (finodelk, frame, -1, op_errno, NULL);
3604df
-
3604df
-        return 0;
3604df
-}
3604df
-
3604df
-
3604df
-int32_t
3604df
-afr_entrylk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
3604df
-                 int32_t op_ret, int32_t op_errno, dict_t *xdata)
3604df
+              int32_t cmd, struct gf_flock *flock, dict_t *xdata)
3604df
 {
3604df
-        afr_local_t *local = NULL;
3604df
-        int call_count = -1;
3604df
-
3604df
-        local = frame->local;
3604df
-
3604df
-        LOCK (&frame->lock);
3604df
-        {
3604df
-                if (op_ret == 0)
3604df
-                        local->op_ret = 0;
3604df
-
3604df
-                local->op_errno = op_errno;
3604df
-        }
3604df
-        UNLOCK (&frame->lock);
3604df
-
3604df
-        call_count = afr_frame_return (frame);
3604df
-
3604df
-        if (call_count == 0)
3604df
-                AFR_STACK_UNWIND (entrylk, frame, local->op_ret,
3604df
-                                  local->op_errno, xdata);
3604df
-
3604df
+        afr_handle_inodelk (frame, GF_FOP_FINODELK, volume, NULL, fd, cmd,
3604df
+                            flock, xdata);
3604df
         return 0;
3604df
 }
3604df
 
3604df
-
3604df
-int
3604df
-afr_entrylk (call_frame_t *frame, xlator_t *this, const char *volume,
3604df
-	     loc_t *loc, const char *basename, entrylk_cmd cmd,
3604df
-	     entrylk_type type, dict_t *xdata)
3604df
+static int
3604df
+afr_handle_entrylk (call_frame_t *frame, glusterfs_fop_t fop,
3604df
+                    const char *volume, loc_t *loc, fd_t *fd,
3604df
+                    const char *basename, entrylk_cmd cmd,
3604df
+                    entrylk_type type, dict_t *xdata)
3604df
 {
3604df
-        afr_private_t *priv = NULL;
3604df
         afr_local_t *local  = NULL;
3604df
-        int i = 0;
3604df
-        int32_t call_count = 0;
3604df
-        int32_t op_errno = 0;
3604df
-
3604df
-        priv = this->private;
3604df
-
3604df
-	local = AFR_FRAME_INIT (frame, op_errno);
3604df
-	if (!local)
3604df
-		goto out;
3604df
-
3604df
-        call_count = local->call_count;
3604df
-	if (!call_count) {
3604df
-		op_errno = ENOTCONN;
3604df
-		goto out;
3604df
-	}
3604df
+        int32_t op_errno = ENOMEM;
3604df
 
3604df
-        for (i = 0; i < priv->child_count; i++) {
3604df
-                if (local->child_up[i]) {
3604df
-                        STACK_WIND (frame, afr_entrylk_cbk,
3604df
-                                    priv->children[i],
3604df
-                                    priv->children[i]->fops->entrylk,
3604df
-                                    volume, loc, basename, cmd, type, xdata);
3604df
+        local = AFR_FRAME_INIT (frame, op_errno);
3604df
+        if (!local)
3604df
+                goto out;
3604df
 
3604df
-                        if (!--call_count)
3604df
-                                break;
3604df
-                }
3604df
+        local->op = fop;
3604df
+        if (loc)
3604df
+                loc_copy (&local->loc, loc);
3604df
+        if (fd)
3604df
+                local->fd = fd_ref (fd);
3604df
+        local->cont.entrylk.cmd = cmd;
3604df
+        local->cont.entrylk.in_cmd = cmd;
3604df
+        local->cont.entrylk.type = type;
3604df
+        local->cont.entrylk.volume = gf_strdup (volume);
3604df
+        local->cont.entrylk.basename = gf_strdup (basename);
3604df
+        if (!local->cont.entrylk.volume || !local->cont.entrylk.basename) {
3604df
+                op_errno = ENOMEM;
3604df
+                goto out;
3604df
         }
3604df
+        if (xdata)
3604df
+                local->xdata_req = dict_ref (xdata);
3604df
+        op_errno = -afr_fop_handle_lock (frame, frame->this);
3604df
+        if (op_errno)
3604df
+                goto out;
3604df
 
3604df
-	return 0;
3604df
+        return 0;
3604df
 out:
3604df
-	AFR_STACK_UNWIND (entrylk, frame, -1, op_errno, NULL);
3604df
-
3604df
+        afr_fop_lock_unwind (frame, fop, -1, op_errno, NULL);
3604df
         return 0;
3604df
 }
3604df
 
3604df
-
3604df
-
3604df
 int
3604df
-afr_fentrylk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
3604df
-		  int32_t op_ret, int32_t op_errno, dict_t *xdata)
3604df
-
3604df
+afr_entrylk (call_frame_t *frame, xlator_t *this, const char *volume,
3604df
+             loc_t *loc, const char *basename, entrylk_cmd cmd,
3604df
+             entrylk_type type, dict_t *xdata)
3604df
 {
3604df
-        afr_local_t *local = NULL;
3604df
-        int call_count = -1;
3604df
-
3604df
-        local = frame->local;
3604df
-
3604df
-        LOCK (&frame->lock);
3604df
-        {
3604df
-                if (op_ret == 0)
3604df
-                        local->op_ret = 0;
3604df
-
3604df
-                local->op_errno = op_errno;
3604df
-        }
3604df
-        UNLOCK (&frame->lock);
3604df
-
3604df
-        call_count = afr_frame_return (frame);
3604df
-
3604df
-        if (call_count == 0)
3604df
-                AFR_STACK_UNWIND (fentrylk, frame, local->op_ret,
3604df
-                                  local->op_errno, xdata);
3604df
-
3604df
+        afr_handle_entrylk (frame, GF_FOP_ENTRYLK, volume, loc, NULL, basename,
3604df
+                            cmd, type, xdata);
3604df
         return 0;
3604df
 }
3604df
 
3604df
-
3604df
 int
3604df
 afr_fentrylk (call_frame_t *frame, xlator_t *this, const char *volume, fd_t *fd,
3604df
               const char *basename, entrylk_cmd cmd, entrylk_type type,
3604df
-	      dict_t *xdata)
3604df
+              dict_t *xdata)
3604df
 {
3604df
-        afr_private_t *priv = NULL;
3604df
-        afr_local_t *local  = NULL;
3604df
-        int i = 0;
3604df
-        int32_t call_count = 0;
3604df
-        int32_t op_errno = ENOMEM;
3604df
-
3604df
-        priv = this->private;
3604df
-
3604df
-        local = AFR_FRAME_INIT (frame, op_errno);
3604df
-	if (!local)
3604df
-		goto out;
3604df
-
3604df
-        call_count = local->call_count;
3604df
-	if (!call_count) {
3604df
-		op_errno = ENOTCONN;
3604df
-		goto out;
3604df
-	}
3604df
-
3604df
-        for (i = 0; i < priv->child_count; i++) {
3604df
-                if (local->child_up[i]) {
3604df
-                        STACK_WIND (frame, afr_fentrylk_cbk,
3604df
-                                    priv->children[i],
3604df
-                                    priv->children[i]->fops->fentrylk,
3604df
-                                    volume, fd, basename, cmd, type, xdata);
3604df
-
3604df
-                        if (!--call_count)
3604df
-                                break;
3604df
-                }
3604df
-        }
3604df
-
3604df
-	return 0;
3604df
-out:
3604df
-	AFR_STACK_UNWIND (fentrylk, frame, -1, op_errno, NULL);
3604df
-
3604df
+        afr_handle_entrylk (frame, GF_FOP_FENTRYLK, volume, NULL, fd, basename,
3604df
+                            cmd, type, xdata);
3604df
         return 0;
3604df
 }
3604df
 
3604df
-
3604df
 int
3604df
 afr_statfs_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int op_ret,
3604df
 		int op_errno, struct statvfs *statvfs, dict_t *xdata)
3604df
diff --git a/xlators/cluster/afr/src/afr-lk-common.c b/xlators/cluster/afr/src/afr-lk-common.c
3604df
index 0bd9ffe..6019454 100644
3604df
--- a/xlators/cluster/afr/src/afr-lk-common.c
3604df
+++ b/xlators/cluster/afr/src/afr-lk-common.c
3604df
@@ -669,7 +669,7 @@ afr_unlock_inodelk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
3604df
 
3604df
         if (op_ret < 0 && op_errno != ENOTCONN && op_errno != EBADFD) {
3604df
                 gf_msg (this->name, GF_LOG_ERROR, op_errno,
3604df
-                        AFR_MSG_INODE_UNLOCK_FAIL,
3604df
+                        AFR_MSG_UNLOCK_FAIL,
3604df
                         "path=%s gfid=%s: unlock failed on subvolume %s "
3604df
                         "with lock owner %s", local->loc.path,
3604df
                         loc_gfid_utoa (&(local->loc)),
3604df
diff --git a/xlators/cluster/afr/src/afr-messages.h b/xlators/cluster/afr/src/afr-messages.h
3604df
index c7af18d..00e689b 100644
3604df
--- a/xlators/cluster/afr/src/afr-messages.h
3604df
+++ b/xlators/cluster/afr/src/afr-messages.h
3604df
@@ -130,11 +130,11 @@
3604df
 
3604df
 /*!
3604df
  * @messageid 108010
3604df
- * @diagnosis Inode unlocks failed on a brick.
3604df
+ * @diagnosis unlocks failed on a brick.
3604df
  * @recommendedaction Error number in the log should give the reason why it
3604df
  * failed. Also observe brick logs for more information.
3604df
 */
3604df
-#define AFR_MSG_INODE_UNLOCK_FAIL       (GLFS_COMP_BASE_AFR + 10)
3604df
+#define AFR_MSG_UNLOCK_FAIL       (GLFS_COMP_BASE_AFR + 10)
3604df
 
3604df
 /*!
3604df
  * @messageid 108011
3604df
diff --git a/xlators/cluster/afr/src/afr-transaction.c b/xlators/cluster/afr/src/afr-transaction.c
3604df
index bff8226..1ed327c 100644
3604df
--- a/xlators/cluster/afr/src/afr-transaction.c
3604df
+++ b/xlators/cluster/afr/src/afr-transaction.c
3604df
@@ -136,14 +136,6 @@ afr_needs_changelog_update (afr_local_t *local)
3604df
         return _gf_false;
3604df
 }
3604df
 
3604df
-static int32_t
3604df
-afr_quorum_errno (afr_private_t *priv)
3604df
-{
3604df
-        if (priv->quorum_reads)
3604df
-                return ENOTCONN;
3604df
-        return EROFS;
3604df
-}
3604df
-
3604df
 int
3604df
 __afr_txn_write_fop (call_frame_t *frame, xlator_t *this)
3604df
 {
3604df
diff --git a/xlators/cluster/afr/src/afr.h b/xlators/cluster/afr/src/afr.h
3604df
index 17b997e..a9cab13 100644
3604df
--- a/xlators/cluster/afr/src/afr.h
3604df
+++ b/xlators/cluster/afr/src/afr.h
3604df
@@ -348,6 +348,11 @@ typedef struct {
3604df
 	int readdir_subvol;
3604df
 } afr_fd_ctx_t;
3604df
 
3604df
+typedef enum {
3604df
+        AFR_FOP_LOCK_PARALLEL,
3604df
+        AFR_FOP_LOCK_SERIAL,
3604df
+        AFR_FOP_LOCK_QUORUM_FAILED,
3604df
+} afr_fop_lock_state_t;
3604df
 
3604df
 typedef struct _afr_local {
3604df
 	glusterfs_fop_t  op;
3604df
@@ -665,10 +670,22 @@ typedef struct _afr_local {
3604df
                 struct {
3604df
                         char *volume;
3604df
                         int32_t cmd;
3604df
+                        int32_t in_cmd;
3604df
+                        struct gf_flock in_flock;
3604df
                         struct gf_flock flock;
3604df
+                        void *xdata;
3604df
                 } inodelk;
3604df
 
3604df
                 struct {
3604df
+                        char *volume;
3604df
+                        char *basename;
3604df
+                        entrylk_cmd in_cmd;
3604df
+                        entrylk_cmd cmd;
3604df
+                        entrylk_type type;
3604df
+                        void *xdata;
3604df
+                } entrylk;
3604df
+
3604df
+                struct {
3604df
                         off_t offset;
3604df
                         gf_seek_what_t what;
3604df
                 } seek;
3604df
@@ -788,6 +805,7 @@ typedef struct _afr_local {
3604df
 
3604df
         gf_boolean_t need_full_crawl;
3604df
         gf_boolean_t compound;
3604df
+        afr_fop_lock_state_t fop_lock_state;
3604df
 } afr_local_t;
3604df
 
3604df
 
3604df
@@ -1200,4 +1218,7 @@ void
3604df
 afr_compound_cleanup (compound_args_t *args, dict_t *xdata,
3604df
                       dict_t *newloc_xdata);
3604df
 
3604df
+int32_t
3604df
+afr_quorum_errno (afr_private_t *priv);
3604df
+
3604df
 #endif /* __AFR_H__ */
3604df
-- 
3604df
2.9.3
3604df