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