b7d4d7
From 8c366f34a279a5ab2a6301bfd93534fe746a23e8 Mon Sep 17 00:00:00 2001
b7d4d7
From: Ravishankar N <ravishankar@redhat.com>
b7d4d7
Date: Mon, 7 Dec 2020 09:53:27 +0530
b7d4d7
Subject: [PATCH 483/511] afr: more quorum checks in lookup and new entry
b7d4d7
 marking
b7d4d7
b7d4d7
Problem: See upstream github issue for details.
b7d4d7
b7d4d7
Fix:
b7d4d7
-In lookup if the entry exists in 2 out of 3 bricks, don't fail the
b7d4d7
lookup with ENOENT just because there is an entrylk on the parent.
b7d4d7
Consider quorum before deciding.
b7d4d7
b7d4d7
-If entry FOP does not succeed on quorum no. of bricks, do not perform
b7d4d7
new entry mark.
b7d4d7
b7d4d7
Upstream patch details:
b7d4d7
> Reviewed-on: https://review.gluster.org/#/c/glusterfs/+/24499/
b7d4d7
> Fixes: #1303
b7d4d7
> Change-Id: I56df8c89ad53b29fa450c7930a7b7ccec9f4a6c5
b7d4d7
> Signed-off-by: Ravishankar N <ravishankar@redhat.com>
b7d4d7
b7d4d7
BUG: 1821599
b7d4d7
Change-Id: If513e8a7d6088a676288927630d8e616269bf5d5
b7d4d7
Signed-off-by: Ravishankar N <ravishankar@redhat.com>
b7d4d7
Reviewed-on: https://code.engineering.redhat.com/gerrit/220363
b7d4d7
Tested-by: RHGS Build Bot <nigelb@redhat.com>
b7d4d7
Reviewed-by: Sunil Kumar Heggodu Gopala Acharya <sheggodu@redhat.com>
b7d4d7
---
b7d4d7
 ...20-mark-dirty-for-entry-txn-on-quorum-failure.t |  2 --
b7d4d7
 xlators/cluster/afr/src/afr-common.c               | 24 ++++++++++++----------
b7d4d7
 xlators/cluster/afr/src/afr-dir-write.c            |  8 ++++++++
b7d4d7
 xlators/cluster/afr/src/afr.h                      |  4 ++++
b7d4d7
 4 files changed, 25 insertions(+), 13 deletions(-)
b7d4d7
b7d4d7
diff --git a/tests/bugs/replicate/bug-1586020-mark-dirty-for-entry-txn-on-quorum-failure.t b/tests/bugs/replicate/bug-1586020-mark-dirty-for-entry-txn-on-quorum-failure.t
b7d4d7
index 26f9049..49c4dea 100644
b7d4d7
--- a/tests/bugs/replicate/bug-1586020-mark-dirty-for-entry-txn-on-quorum-failure.t
b7d4d7
+++ b/tests/bugs/replicate/bug-1586020-mark-dirty-for-entry-txn-on-quorum-failure.t
b7d4d7
@@ -53,8 +53,6 @@ TEST ! ls $B0/${V0}1/file$i
b7d4d7
 TEST ls $B0/${V0}2/file$i
b7d4d7
 dirty=$(get_hex_xattr trusted.afr.dirty $B0/${V0}2)
b7d4d7
 TEST [ "$dirty" != "000000000000000000000000" ]
b7d4d7
-EXPECT "000000010000000100000000" get_hex_xattr trusted.afr.$V0-client-0 $B0/${V0}2/file$i
b7d4d7
-EXPECT "000000010000000100000000" get_hex_xattr trusted.afr.$V0-client-1 $B0/${V0}2/file$i
b7d4d7
 
b7d4d7
 TEST $CLI volume set $V0 self-heal-daemon on
b7d4d7
 EXPECT_WITHIN $PROCESS_UP_TIMEOUT "Y" glustershd_up_status
b7d4d7
diff --git a/xlators/cluster/afr/src/afr-common.c b/xlators/cluster/afr/src/afr-common.c
b7d4d7
index 89e2483..851ccad 100644
b7d4d7
--- a/xlators/cluster/afr/src/afr-common.c
b7d4d7
+++ b/xlators/cluster/afr/src/afr-common.c
b7d4d7
@@ -1236,7 +1236,7 @@ refresh_done:
b7d4d7
     return 0;
b7d4d7
 }
b7d4d7
 
b7d4d7
-static void
b7d4d7
+void
b7d4d7
 afr_fill_success_replies(afr_local_t *local, afr_private_t *priv,
b7d4d7
                          unsigned char *replies)
b7d4d7
 {
b7d4d7
@@ -2290,6 +2290,7 @@ afr_lookup_done(call_frame_t *frame, xlator_t *this)
b7d4d7
         0,
b7d4d7
     };
b7d4d7
     gf_boolean_t locked_entry = _gf_false;
b7d4d7
+    gf_boolean_t in_flight_create = _gf_false;
b7d4d7
     gf_boolean_t can_interpret = _gf_true;
b7d4d7
     inode_t *parent = NULL;
b7d4d7
     ia_type_t ia_type = IA_INVAL;
b7d4d7
@@ -2333,17 +2334,12 @@ afr_lookup_done(call_frame_t *frame, xlator_t *this)
b7d4d7
         if (!replies[i].valid)
b7d4d7
             continue;
b7d4d7
 
b7d4d7
-        if (locked_entry && replies[i].op_ret == -1 &&
b7d4d7
-            replies[i].op_errno == ENOENT) {
b7d4d7
-            /* Second, check entry is still
b7d4d7
-               "underway" in creation */
b7d4d7
-            local->op_ret = -1;
b7d4d7
-            local->op_errno = ENOENT;
b7d4d7
-            goto error;
b7d4d7
-        }
b7d4d7
-
b7d4d7
-        if (replies[i].op_ret == -1)
b7d4d7
+        if (replies[i].op_ret == -1) {
b7d4d7
+            if (locked_entry && replies[i].op_errno == ENOENT) {
b7d4d7
+                in_flight_create = _gf_true;
b7d4d7
+            }
b7d4d7
             continue;
b7d4d7
+        }
b7d4d7
 
b7d4d7
         if (read_subvol == -1 || !readable[read_subvol]) {
b7d4d7
             read_subvol = i;
b7d4d7
@@ -2353,6 +2349,12 @@ afr_lookup_done(call_frame_t *frame, xlator_t *this)
b7d4d7
         }
b7d4d7
     }
b7d4d7
 
b7d4d7
+    if (in_flight_create && !afr_has_quorum(success_replies, this, NULL)) {
b7d4d7
+        local->op_ret = -1;
b7d4d7
+        local->op_errno = ENOENT;
b7d4d7
+        goto error;
b7d4d7
+    }
b7d4d7
+
b7d4d7
     if (read_subvol == -1)
b7d4d7
         goto error;
b7d4d7
     /* We now have a read_subvol, which is readable[] (if there
b7d4d7
diff --git a/xlators/cluster/afr/src/afr-dir-write.c b/xlators/cluster/afr/src/afr-dir-write.c
b7d4d7
index 84e2a34..416c19d 100644
b7d4d7
--- a/xlators/cluster/afr/src/afr-dir-write.c
b7d4d7
+++ b/xlators/cluster/afr/src/afr-dir-write.c
b7d4d7
@@ -349,6 +349,7 @@ afr_mark_entry_pending_changelog(call_frame_t *frame, xlator_t *this)
b7d4d7
     afr_private_t *priv = NULL;
b7d4d7
     int pre_op_count = 0;
b7d4d7
     int failed_count = 0;
b7d4d7
+    unsigned char *success_replies = NULL;
b7d4d7
 
b7d4d7
     local = frame->local;
b7d4d7
     priv = this->private;
b7d4d7
@@ -364,9 +365,16 @@ afr_mark_entry_pending_changelog(call_frame_t *frame, xlator_t *this)
b7d4d7
     failed_count = AFR_COUNT(local->transaction.failed_subvols,
b7d4d7
                              priv->child_count);
b7d4d7
 
b7d4d7
+    /* FOP succeeded on all bricks. */
b7d4d7
     if (pre_op_count == priv->child_count && !failed_count)
b7d4d7
         return;
b7d4d7
 
b7d4d7
+    /* FOP did not suceed on quorum no. of bricks. */
b7d4d7
+    success_replies = alloca0(priv->child_count);
b7d4d7
+    afr_fill_success_replies(local, priv, success_replies);
b7d4d7
+    if (!afr_has_quorum(success_replies, this, NULL))
b7d4d7
+        return;
b7d4d7
+
b7d4d7
     if (priv->thin_arbiter_count) {
b7d4d7
         /*Mark new entry using ta file*/
b7d4d7
         local->is_new_entry = _gf_true;
b7d4d7
diff --git a/xlators/cluster/afr/src/afr.h b/xlators/cluster/afr/src/afr.h
b7d4d7
index ff96246..ed5096e 100644
b7d4d7
--- a/xlators/cluster/afr/src/afr.h
b7d4d7
+++ b/xlators/cluster/afr/src/afr.h
b7d4d7
@@ -1334,4 +1334,8 @@ afr_mark_new_entry_changelog(call_frame_t *frame, xlator_t *this);
b7d4d7
 
b7d4d7
 void
b7d4d7
 afr_selfheal_childup(xlator_t *this, afr_private_t *priv);
b7d4d7
+
b7d4d7
+void
b7d4d7
+afr_fill_success_replies(afr_local_t *local, afr_private_t *priv,
b7d4d7
+                         unsigned char *replies);
b7d4d7
 #endif /* __AFR_H__ */
b7d4d7
-- 
b7d4d7
1.8.3.1
b7d4d7