d2787b
From 4c47d6dd7c5ddcaa2a1e159427c0f6713fd33907 Mon Sep 17 00:00:00 2001
d2787b
From: karthik-us <ksubrahm@redhat.com>
d2787b
Date: Wed, 23 Dec 2020 14:57:51 +0530
d2787b
Subject: [PATCH 514/517] afr: event gen changes
d2787b
d2787b
The general idea of the changes is to prevent resetting event generation
d2787b
to zero in the inode ctx, since event gen is something that should
d2787b
follow 'causal order'.
d2787b
d2787b
Change #1:
d2787b
For a read txn, in inode refresh cbk, if event_generation is
d2787b
found zero, we are failing the read fop. This is not needed
d2787b
because change in event gen is only a marker for the next inode refresh to
d2787b
happen and should not be taken into account by the current read txn.
d2787b
d2787b
Change #2:
d2787b
The event gen being zero above can happen if there is a racing lookup,
d2787b
which resets even get (in afr_lookup_done) if there are non zero afr
d2787b
xattrs. The resetting is done only to trigger an inode refresh and a
d2787b
possible client side heal on the next lookup. That can be acheived by
d2787b
setting the need_refresh flag in the inode ctx. So replaced all
d2787b
occurences of resetting even gen to zero with a call to
d2787b
afr_inode_need_refresh_set().
d2787b
d2787b
Change #3:
d2787b
In both lookup and discover path, we are doing an inode refresh which is
d2787b
not required since all 3 essentially do the same thing- update the inode
d2787b
ctx with the good/bad copies from the brick replies. Inode refresh also
d2787b
triggers background heals, but I think it is okay to do it when we call
d2787b
refresh during the read and write txns and not in the lookup path.
d2787b
d2787b
The .ts which relied on inode refresh in lookup path to trigger heals are
d2787b
now changed to do read txn so that inode refresh and the heal happens.
d2787b
d2787b
Upstream patch details:
d2787b
> Change-Id: Iebf39a9be6ffd7ffd6e4046c96b0fa78ade6c5ec
d2787b
> Fixes: #1179
d2787b
> Signed-off-by: Ravishankar N <ravishankar@redhat.com>
d2787b
> Reported-by: Erik Jacobson <erik.jacobson at hpe.com>
d2787b
Upstream patch: https://review.gluster.org/#/c/glusterfs/+/24316/
d2787b
d2787b
BUG: 1640148
d2787b
Change-Id: Iebf39a9be6ffd7ffd6e4046c96b0fa78ade6c5ec
d2787b
Signed-off-by: karthik-us <ksubrahm@redhat.com>
d2787b
Reviewed-on: https://code.engineering.redhat.com/gerrit/222074
d2787b
Tested-by: RHGS Build Bot <nigelb@redhat.com>
d2787b
Reviewed-by: Ravishankar Narayanankutty <ravishankar@redhat.com>
d2787b
---
d2787b
 ...fid-mismatch-resolution-with-fav-child-policy.t |  8 +-
d2787b
 xlators/cluster/afr/src/afr-common.c               | 92 +++++-----------------
d2787b
 xlators/cluster/afr/src/afr-dir-write.c            |  6 +-
d2787b
 xlators/cluster/afr/src/afr.h                      |  5 +-
d2787b
 4 files changed, 29 insertions(+), 82 deletions(-)
d2787b
d2787b
diff --git a/tests/basic/afr/gfid-mismatch-resolution-with-fav-child-policy.t b/tests/basic/afr/gfid-mismatch-resolution-with-fav-child-policy.t
d2787b
index f4aa351..12af0c8 100644
d2787b
--- a/tests/basic/afr/gfid-mismatch-resolution-with-fav-child-policy.t
d2787b
+++ b/tests/basic/afr/gfid-mismatch-resolution-with-fav-child-policy.t
d2787b
@@ -168,8 +168,8 @@ TEST [ "$gfid_1" != "$gfid_2" ]
d2787b
 #We know that second brick has the bigger size file
d2787b
 BIGGER_FILE_MD5=$(md5sum $B0/${V0}1/f3 | cut -d\  -f1)
d2787b
 
d2787b
-TEST ls $M0/f3
d2787b
-TEST cat $M0/f3
d2787b
+TEST ls $M0 #Trigger entry heal via readdir inode refresh
d2787b
+TEST cat $M0/f3 #Trigger data heal via readv inode refresh
d2787b
 EXPECT_WITHIN $HEAL_TIMEOUT "^0$" get_pending_heal_count $V0
d2787b
 
d2787b
 #gfid split-brain should be resolved
d2787b
@@ -215,8 +215,8 @@ TEST $CLI volume start $V0 force
d2787b
 EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" brick_up_status $V0 $H0 $B0/${V0}2
d2787b
 EXPECT_WITHIN $CHILD_UP_TIMEOUT "1" afr_child_up_status $V0 2
d2787b
 
d2787b
-TEST ls $M0/f4
d2787b
-TEST cat $M0/f4
d2787b
+TEST ls $M0 #Trigger entry heal via readdir inode refresh
d2787b
+TEST cat $M0/f4  #Trigger data heal via readv inode refresh
d2787b
 EXPECT_WITHIN $HEAL_TIMEOUT "^0$" get_pending_heal_count $V0
d2787b
 
d2787b
 #gfid split-brain should be resolved
d2787b
diff --git a/xlators/cluster/afr/src/afr-common.c b/xlators/cluster/afr/src/afr-common.c
d2787b
index fca2cd5..90b4f14 100644
d2787b
--- a/xlators/cluster/afr/src/afr-common.c
d2787b
+++ b/xlators/cluster/afr/src/afr-common.c
d2787b
@@ -284,7 +284,7 @@ __afr_set_in_flight_sb_status(xlator_t *this, afr_local_t *local,
d2787b
                 metadatamap |= (1 << index);
d2787b
             }
d2787b
             if (metadatamap_old != metadatamap) {
d2787b
-                event = 0;
d2787b
+                __afr_inode_need_refresh_set(inode, this);
d2787b
             }
d2787b
             break;
d2787b
 
d2787b
@@ -297,7 +297,7 @@ __afr_set_in_flight_sb_status(xlator_t *this, afr_local_t *local,
d2787b
                 datamap |= (1 << index);
d2787b
             }
d2787b
             if (datamap_old != datamap)
d2787b
-                event = 0;
d2787b
+                __afr_inode_need_refresh_set(inode, this);
d2787b
             break;
d2787b
 
d2787b
         default:
d2787b
@@ -461,34 +461,6 @@ out:
d2787b
 }
d2787b
 
d2787b
 int
d2787b
-__afr_inode_event_gen_reset_small(inode_t *inode, xlator_t *this)
d2787b
-{
d2787b
-    int ret = -1;
d2787b
-    uint16_t datamap = 0;
d2787b
-    uint16_t metadatamap = 0;
d2787b
-    uint32_t event = 0;
d2787b
-    uint64_t val = 0;
d2787b
-    afr_inode_ctx_t *ctx = NULL;
d2787b
-
d2787b
-    ret = __afr_inode_ctx_get(this, inode, &ctx;;
d2787b
-    if (ret)
d2787b
-        return ret;
d2787b
-
d2787b
-    val = ctx->read_subvol;
d2787b
-
d2787b
-    metadatamap = (val & 0x000000000000ffff) >> 0;
d2787b
-    datamap = (val & 0x00000000ffff0000) >> 16;
d2787b
-    event = 0;
d2787b
-
d2787b
-    val = ((uint64_t)metadatamap) | (((uint64_t)datamap) << 16) |
d2787b
-          (((uint64_t)event) << 32);
d2787b
-
d2787b
-    ctx->read_subvol = val;
d2787b
-
d2787b
-    return ret;
d2787b
-}
d2787b
-
d2787b
-int
d2787b
 __afr_inode_read_subvol_get(inode_t *inode, xlator_t *this, unsigned char *data,
d2787b
                             unsigned char *metadata, int *event_p)
d2787b
 {
d2787b
@@ -559,22 +531,6 @@ out:
d2787b
 }
d2787b
 
d2787b
 int
d2787b
-__afr_inode_event_gen_reset(inode_t *inode, xlator_t *this)
d2787b
-{
d2787b
-    afr_private_t *priv = NULL;
d2787b
-    int ret = -1;
d2787b
-
d2787b
-    priv = this->private;
d2787b
-
d2787b
-    if (priv->child_count <= 16)
d2787b
-        ret = __afr_inode_event_gen_reset_small(inode, this);
d2787b
-    else
d2787b
-        ret = -1;
d2787b
-
d2787b
-    return ret;
d2787b
-}
d2787b
-
d2787b
-int
d2787b
 afr_inode_read_subvol_get(inode_t *inode, xlator_t *this, unsigned char *data,
d2787b
                           unsigned char *metadata, int *event_p)
d2787b
 {
d2787b
@@ -723,30 +679,22 @@ out:
d2787b
     return need_refresh;
d2787b
 }
d2787b
 
d2787b
-static int
d2787b
-afr_inode_need_refresh_set(inode_t *inode, xlator_t *this)
d2787b
+int
d2787b
+__afr_inode_need_refresh_set(inode_t *inode, xlator_t *this)
d2787b
 {
d2787b
     int ret = -1;
d2787b
     afr_inode_ctx_t *ctx = NULL;
d2787b
 
d2787b
-    GF_VALIDATE_OR_GOTO(this->name, inode, out);
d2787b
-
d2787b
-    LOCK(&inode->lock);
d2787b
-    {
d2787b
-        ret = __afr_inode_ctx_get(this, inode, &ctx;;
d2787b
-        if (ret)
d2787b
-            goto unlock;
d2787b
-
d2787b
+    ret = __afr_inode_ctx_get(this, inode, &ctx;;
d2787b
+    if (ret == 0) {
d2787b
         ctx->need_refresh = _gf_true;
d2787b
     }
d2787b
-unlock:
d2787b
-    UNLOCK(&inode->lock);
d2787b
-out:
d2787b
+
d2787b
     return ret;
d2787b
 }
d2787b
 
d2787b
 int
d2787b
-afr_inode_event_gen_reset(inode_t *inode, xlator_t *this)
d2787b
+afr_inode_need_refresh_set(inode_t *inode, xlator_t *this)
d2787b
 {
d2787b
     int ret = -1;
d2787b
 
d2787b
@@ -754,7 +702,7 @@ afr_inode_event_gen_reset(inode_t *inode, xlator_t *this)
d2787b
 
d2787b
     LOCK(&inode->lock);
d2787b
     {
d2787b
-        ret = __afr_inode_event_gen_reset(inode, this);
d2787b
+        ret = __afr_inode_need_refresh_set(inode, this);
d2787b
     }
d2787b
     UNLOCK(&inode->lock);
d2787b
 out:
d2787b
@@ -1191,7 +1139,7 @@ afr_txn_refresh_done(call_frame_t *frame, xlator_t *this, int err)
d2787b
     ret = afr_inode_get_readable(frame, inode, this, local->readable,
d2787b
                                  &event_generation, local->transaction.type);
d2787b
 
d2787b
-    if (ret == -EIO || (local->is_read_txn && !event_generation)) {
d2787b
+    if (ret == -EIO) {
d2787b
         /* No readable subvolume even after refresh ==> splitbrain.*/
d2787b
         if (!priv->fav_child_policy) {
d2787b
             err = EIO;
d2787b
@@ -2413,7 +2361,7 @@ afr_lookup_done(call_frame_t *frame, xlator_t *this)
d2787b
         if (read_subvol == -1)
d2787b
             goto cant_interpret;
d2787b
         if (ret) {
d2787b
-            afr_inode_event_gen_reset(local->inode, this);
d2787b
+            afr_inode_need_refresh_set(local->inode, this);
d2787b
             dict_del_sizen(local->replies[read_subvol].xdata, GF_CONTENT_KEY);
d2787b
         }
d2787b
     } else {
d2787b
@@ -2971,6 +2919,7 @@ afr_discover_unwind(call_frame_t *frame, xlator_t *this)
d2787b
     afr_private_t *priv = NULL;
d2787b
     afr_local_t *local = NULL;
d2787b
     int read_subvol = -1;
d2787b
+    int ret = 0;
d2787b
     unsigned char *data_readable = NULL;
d2787b
     unsigned char *success_replies = NULL;
d2787b
 
d2787b
@@ -2992,7 +2941,10 @@ afr_discover_unwind(call_frame_t *frame, xlator_t *this)
d2787b
     if (!afr_has_quorum(success_replies, this, frame))
d2787b
         goto unwind;
d2787b
 
d2787b
-    afr_replies_interpret(frame, this, local->inode, NULL);
d2787b
+    ret = afr_replies_interpret(frame, this, local->inode, NULL);
d2787b
+    if (ret) {
d2787b
+        afr_inode_need_refresh_set(local->inode, this);
d2787b
+    }
d2787b
 
d2787b
     read_subvol = afr_read_subvol_decide(local->inode, this, NULL,
d2787b
                                          data_readable);
d2787b
@@ -3248,11 +3200,7 @@ afr_discover(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xattr_req)
d2787b
     afr_read_subvol_get(loc->inode, this, NULL, NULL, &event,
d2787b
                         AFR_DATA_TRANSACTION, NULL);
d2787b
 
d2787b
-    if (afr_is_inode_refresh_reqd(loc->inode, this, event,
d2787b
-                                  local->event_generation))
d2787b
-        afr_inode_refresh(frame, this, loc->inode, NULL, afr_discover_do);
d2787b
-    else
d2787b
-        afr_discover_do(frame, this, 0);
d2787b
+    afr_discover_do(frame, this, 0);
d2787b
 
d2787b
     return 0;
d2787b
 out:
d2787b
@@ -3393,11 +3341,7 @@ afr_lookup(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xattr_req)
d2787b
     afr_read_subvol_get(loc->parent, this, NULL, NULL, &event,
d2787b
                         AFR_DATA_TRANSACTION, NULL);
d2787b
 
d2787b
-    if (afr_is_inode_refresh_reqd(loc->inode, this, event,
d2787b
-                                  local->event_generation))
d2787b
-        afr_inode_refresh(frame, this, loc->parent, NULL, afr_lookup_do);
d2787b
-    else
d2787b
-        afr_lookup_do(frame, this, 0);
d2787b
+    afr_lookup_do(frame, this, 0);
d2787b
 
d2787b
     return 0;
d2787b
 out:
d2787b
diff --git a/xlators/cluster/afr/src/afr-dir-write.c b/xlators/cluster/afr/src/afr-dir-write.c
d2787b
index 416c19d..d419bfc 100644
d2787b
--- a/xlators/cluster/afr/src/afr-dir-write.c
d2787b
+++ b/xlators/cluster/afr/src/afr-dir-write.c
d2787b
@@ -123,11 +123,11 @@ __afr_dir_write_finalize(call_frame_t *frame, xlator_t *this)
d2787b
             continue;
d2787b
         if (local->replies[i].op_ret < 0) {
d2787b
             if (local->inode)
d2787b
-                afr_inode_event_gen_reset(local->inode, this);
d2787b
+                afr_inode_need_refresh_set(local->inode, this);
d2787b
             if (local->parent)
d2787b
-                afr_inode_event_gen_reset(local->parent, this);
d2787b
+                afr_inode_need_refresh_set(local->parent, this);
d2787b
             if (local->parent2)
d2787b
-                afr_inode_event_gen_reset(local->parent2, this);
d2787b
+                afr_inode_need_refresh_set(local->parent2, this);
d2787b
             continue;
d2787b
         }
d2787b
 
d2787b
diff --git a/xlators/cluster/afr/src/afr.h b/xlators/cluster/afr/src/afr.h
d2787b
index ed5096e..3a2b26d 100644
d2787b
--- a/xlators/cluster/afr/src/afr.h
d2787b
+++ b/xlators/cluster/afr/src/afr.h
d2787b
@@ -948,7 +948,10 @@ afr_inode_read_subvol_set(inode_t *inode, xlator_t *this,
d2787b
                           int event_generation);
d2787b
 
d2787b
 int
d2787b
-afr_inode_event_gen_reset(inode_t *inode, xlator_t *this);
d2787b
+__afr_inode_need_refresh_set(inode_t *inode, xlator_t *this);
d2787b
+
d2787b
+int
d2787b
+afr_inode_need_refresh_set(inode_t *inode, xlator_t *this);
d2787b
 
d2787b
 int
d2787b
 afr_read_subvol_select_by_policy(inode_t *inode, xlator_t *this,
d2787b
-- 
d2787b
1.8.3.1
d2787b