f338ef
From 87d8070f80487322a1736846a78725fd88f8de34 Mon Sep 17 00:00:00 2001
f338ef
From: Pranith Kumar K <pkarampu@redhat.com>
f338ef
Date: Tue, 20 Aug 2019 13:27:24 +0530
f338ef
Subject: [PATCH 291/297] cluster/ec: Mark release only when it is acquired
f338ef
f338ef
Problem:
f338ef
Mount-1                                Mount-2
f338ef
1)Tries to acquire lock on 'dir1'   1)Tries to acquire lock on 'dir1'
f338ef
2)Lock is granted on brick-0        2)Lock gets EAGAIN on brick-0 and
f338ef
				      leads to blocking lock on brick-0
f338ef
3)Gets a lock-contention            3) Doesn't matter what happens on mount-2
f338ef
  notification, marks lock->release    from here on.
f338ef
  to true.
f338ef
4)New fop comes on 'dir1' which will
f338ef
  be put in frozen list as lock->release
f338ef
  is set to true.
f338ef
5) Lock acquisition from step-2 fails because
f338ef
3 bricks went down in 4+2 setup.
f338ef
f338ef
Fop on mount-1 which is put in frozen list will hang because no codepath will
f338ef
move it from frozen list to any other list and the lock will not be retried.
f338ef
f338ef
Fix:
f338ef
Don't set lock->release to true if lock is not acquired at the time of
f338ef
lock-contention-notification
f338ef
f338ef
Upstream-patch: https://review.gluster.org/c/glusterfs/+/23272
f338ef
fixes: bz#1731896
f338ef
Change-Id: Ie6630db8735ccf372cc54b873a3a3aed7a6082b7
f338ef
Signed-off-by: Pranith Kumar K <pkarampu@redhat.com>
f338ef
Reviewed-on: https://code.engineering.redhat.com/gerrit/180870
f338ef
Tested-by: RHGS Build Bot <nigelb@redhat.com>
f338ef
Reviewed-by: Ashish Pandey <aspandey@redhat.com>
f338ef
Reviewed-by: Sunil Kumar Heggodu Gopala Acharya <sheggodu@redhat.com>
f338ef
---
f338ef
 xlators/cluster/ec/src/ec-common.c | 20 ++++++++++++++++++--
f338ef
 xlators/cluster/ec/src/ec-types.h  |  1 +
f338ef
 2 files changed, 19 insertions(+), 2 deletions(-)
f338ef
f338ef
diff --git a/xlators/cluster/ec/src/ec-common.c b/xlators/cluster/ec/src/ec-common.c
f338ef
index 2e59180..5cae37b 100644
f338ef
--- a/xlators/cluster/ec/src/ec-common.c
f338ef
+++ b/xlators/cluster/ec/src/ec-common.c
f338ef
@@ -1867,6 +1867,10 @@ ec_lock_acquired(ec_lock_link_t *link)
f338ef
     LOCK(&lock->loc.inode->lock);
f338ef
 
f338ef
     lock->acquired = _gf_true;
f338ef
+    if (lock->contention) {
f338ef
+        lock->release = _gf_true;
f338ef
+        lock->contention = _gf_false;
f338ef
+    }
f338ef
 
f338ef
     ec_lock_update_fd(lock, fop);
f338ef
     ec_lock_wake_shared(lock, &list);
f338ef
@@ -1892,15 +1896,20 @@ ec_locked(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret,
f338ef
     ec_lock_link_t *link = NULL;
f338ef
     ec_lock_t *lock = NULL;
f338ef
 
f338ef
+    link = fop->data;
f338ef
+    lock = link->lock;
f338ef
     if (op_ret >= 0) {
f338ef
-        link = fop->data;
f338ef
-        lock = link->lock;
f338ef
         lock->mask = lock->good_mask = fop->good;
f338ef
         lock->healing = 0;
f338ef
 
f338ef
         ec_lock_acquired(link);
f338ef
         ec_lock(fop->parent);
f338ef
     } else {
f338ef
+        LOCK(&lock->loc.inode->lock);
f338ef
+        {
f338ef
+            lock->contention = _gf_false;
f338ef
+        }
f338ef
+        UNLOCK(&lock->loc.inode->lock);
f338ef
         gf_msg(this->name, GF_LOG_WARNING, op_errno, EC_MSG_PREOP_LOCK_FAILED,
f338ef
                "Failed to complete preop lock");
f338ef
     }
f338ef
@@ -2547,6 +2556,13 @@ ec_lock_release(ec_t *ec, inode_t *inode)
f338ef
     gf_msg_debug(ec->xl->name, 0, "Releasing inode %p due to lock contention",
f338ef
                  inode);
f338ef
 
f338ef
+    if (!lock->acquired) {
f338ef
+        /* This happens if some bricks already got the lock while inodelk is in
f338ef
+         * progress.  Set release to true after lock is acquired*/
f338ef
+        lock->contention = _gf_true;
f338ef
+        goto done;
f338ef
+    }
f338ef
+
f338ef
     /* The lock is not marked to be released, so the frozen list should be
f338ef
      * empty. */
f338ef
     GF_ASSERT(list_empty(&lock->frozen));
f338ef
diff --git a/xlators/cluster/ec/src/ec-types.h b/xlators/cluster/ec/src/ec-types.h
f338ef
index ea4f6ad..34a9768 100644
f338ef
--- a/xlators/cluster/ec/src/ec-types.h
f338ef
+++ b/xlators/cluster/ec/src/ec-types.h
f338ef
@@ -267,6 +267,7 @@ struct _ec_lock {
f338ef
     uint32_t refs_pending;  /* Refs assigned to fops being prepared */
f338ef
     uint32_t waiting_flags; /*Track xattrop/dirty marking*/
f338ef
     gf_boolean_t acquired;
f338ef
+    gf_boolean_t contention;
f338ef
     gf_boolean_t unlock_now;
f338ef
     gf_boolean_t release;
f338ef
     gf_boolean_t query;
f338ef
-- 
f338ef
1.8.3.1
f338ef