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