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