b7d4d7
From 8d24d891aade910b0bb86b27c25a8d2382e19ba0 Mon Sep 17 00:00:00 2001
b7d4d7
From: karthik-us <ksubrahm@redhat.com>
b7d4d7
Date: Tue, 15 Dec 2020 15:04:19 +0530
b7d4d7
Subject: [PATCH 516/517] afr: return -EIO for gfid split-brains.
b7d4d7
b7d4d7
Problem:
b7d4d7
entry-self-heal-anon-dir-off.t was failing occasionally because
b7d4d7
afr_gfid_split_brain_source() returned -1 instead of -EIO for
b7d4d7
split-brains, causing the code to proceed to afr_lookup_done(), which
b7d4d7
in turn succeeded the lookup if there was a parallel client side heal
b7d4d7
going on.
b7d4d7
b7d4d7
Fix:
b7d4d7
Return -EIO instead of -1 so that lookp fails.
b7d4d7
b7d4d7
Also, afr_selfheal_name() was using the same dict to get and set values. This
b7d4d7
could be problematic if the caller passed local->xdata_req, since
b7d4d7
setting a response in a request dict can lead to bugs.So changed it to use
b7d4d7
separate request and response dicts.
b7d4d7
b7d4d7
Upstream patch details:
b7d4d7
> Fixes: #1739
b7d4d7
> Credits Pranith Karampuri <pranith.karampuri@phonepe.com>
b7d4d7
> Signed-off-by: Ravishankar N <ravishankar@redhat.com>
b7d4d7
>Change-Id: I5cb4c547fb25e6bfc8bec1740f7eb64e1a5ad443
b7d4d7
Upstream patch: https://github.com/gluster/glusterfs/pull/1819/
b7d4d7
b7d4d7
BUG: 1640148
b7d4d7
Signed-off-by: karthik-us <ksubrahm@redhat.com>
b7d4d7
Change-Id: I5cb4c547fb25e6bfc8bec1740f7eb64e1a5ad443
b7d4d7
Reviewed-on: https://code.engineering.redhat.com/gerrit/221209
b7d4d7
Tested-by: RHGS Build Bot <nigelb@redhat.com>
b7d4d7
Reviewed-by: Ravishankar Narayanankutty <ravishankar@redhat.com>
b7d4d7
---
b7d4d7
 xlators/cluster/afr/src/afr-common.c           | 12 ++++++++----
b7d4d7
 xlators/cluster/afr/src/afr-self-heal-common.c | 27 +++++++++++++-------------
b7d4d7
 xlators/cluster/afr/src/afr-self-heal-entry.c  |  8 ++++----
b7d4d7
 xlators/cluster/afr/src/afr-self-heal-name.c   | 23 +++++++++++-----------
b7d4d7
 xlators/cluster/afr/src/afr-self-heal.h        |  5 +++--
b7d4d7
 xlators/cluster/afr/src/afr-self-heald.c       |  2 +-
b7d4d7
 6 files changed, 42 insertions(+), 35 deletions(-)
b7d4d7
b7d4d7
diff --git a/xlators/cluster/afr/src/afr-common.c b/xlators/cluster/afr/src/afr-common.c
b7d4d7
index 6f2da11..416012c 100644
b7d4d7
--- a/xlators/cluster/afr/src/afr-common.c
b7d4d7
+++ b/xlators/cluster/afr/src/afr-common.c
b7d4d7
@@ -2366,7 +2366,7 @@ afr_lookup_done(call_frame_t *frame, xlator_t *this)
b7d4d7
         /* If we were called from glfsheal and there is still a gfid
b7d4d7
          * mismatch, succeed the lookup and let glfsheal print the
b7d4d7
          * response via gfid-heal-msg.*/
b7d4d7
-        if (!dict_get_str_sizen(local->xattr_req, "gfid-heal-msg",
b7d4d7
+        if (!dict_get_str_sizen(local->xattr_rsp, "gfid-heal-msg",
b7d4d7
                                 &gfid_heal_msg))
b7d4d7
             goto cant_interpret;
b7d4d7
 
b7d4d7
@@ -2421,7 +2421,7 @@ afr_lookup_done(call_frame_t *frame, xlator_t *this)
b7d4d7
         goto error;
b7d4d7
     }
b7d4d7
 
b7d4d7
-    ret = dict_get_str_sizen(local->xattr_req, "gfid-heal-msg", &gfid_heal_msg);
b7d4d7
+    ret = dict_get_str_sizen(local->xattr_rsp, "gfid-heal-msg", &gfid_heal_msg);
b7d4d7
     if (!ret) {
b7d4d7
         ret = dict_set_str_sizen(local->replies[read_subvol].xdata,
b7d4d7
                                  "gfid-heal-msg", gfid_heal_msg);
b7d4d7
@@ -2768,9 +2768,12 @@ afr_lookup_selfheal_wrap(void *opaque)
b7d4d7
     local = frame->local;
b7d4d7
     this = frame->this;
b7d4d7
     loc_pargfid(&local->loc, pargfid);
b7d4d7
+    if (!local->xattr_rsp)
b7d4d7
+        local->xattr_rsp = dict_new();
b7d4d7
 
b7d4d7
     ret = afr_selfheal_name(frame->this, pargfid, local->loc.name,
b7d4d7
-                            &local->cont.lookup.gfid_req, local->xattr_req);
b7d4d7
+                            &local->cont.lookup.gfid_req, local->xattr_req,
b7d4d7
+                            local->xattr_rsp);
b7d4d7
     if (ret == -EIO)
b7d4d7
         goto unwind;
b7d4d7
 
b7d4d7
@@ -2786,7 +2789,8 @@ afr_lookup_selfheal_wrap(void *opaque)
b7d4d7
     return 0;
b7d4d7
 
b7d4d7
 unwind:
b7d4d7
-    AFR_STACK_UNWIND(lookup, frame, -1, EIO, NULL, NULL, NULL, NULL);
b7d4d7
+    AFR_STACK_UNWIND(lookup, frame, -1, EIO, NULL, NULL, local->xattr_rsp,
b7d4d7
+                     NULL);
b7d4d7
     return 0;
b7d4d7
 }
b7d4d7
 
b7d4d7
diff --git a/xlators/cluster/afr/src/afr-self-heal-common.c b/xlators/cluster/afr/src/afr-self-heal-common.c
b7d4d7
index 0a8a7fd..0954d2c 100644
b7d4d7
--- a/xlators/cluster/afr/src/afr-self-heal-common.c
b7d4d7
+++ b/xlators/cluster/afr/src/afr-self-heal-common.c
b7d4d7
@@ -245,7 +245,8 @@ int
b7d4d7
 afr_gfid_split_brain_source(xlator_t *this, struct afr_reply *replies,
b7d4d7
                             inode_t *inode, uuid_t pargfid, const char *bname,
b7d4d7
                             int src_idx, int child_idx,
b7d4d7
-                            unsigned char *locked_on, int *src, dict_t *xdata)
b7d4d7
+                            unsigned char *locked_on, int *src, dict_t *req,
b7d4d7
+                            dict_t *rsp)
b7d4d7
 {
b7d4d7
     afr_private_t *priv = NULL;
b7d4d7
     char g1[64] = {
b7d4d7
@@ -266,8 +267,8 @@ afr_gfid_split_brain_source(xlator_t *this, struct afr_reply *replies,
b7d4d7
         gf_msg(this->name, GF_LOG_ERROR, 0, AFR_MSG_SPLIT_BRAIN,
b7d4d7
                "All the bricks should be up to resolve the gfid split "
b7d4d7
                "barin");
b7d4d7
-        if (xdata) {
b7d4d7
-            ret = dict_set_sizen_str_sizen(xdata, "gfid-heal-msg",
b7d4d7
+        if (rsp) {
b7d4d7
+            ret = dict_set_sizen_str_sizen(rsp, "gfid-heal-msg",
b7d4d7
                                            SALL_BRICKS_UP_TO_RESOLVE);
b7d4d7
             if (ret)
b7d4d7
                 gf_msg(this->name, GF_LOG_ERROR, 0, AFR_MSG_DICT_SET_FAILED,
b7d4d7
@@ -277,8 +278,8 @@ afr_gfid_split_brain_source(xlator_t *this, struct afr_reply *replies,
b7d4d7
         goto out;
b7d4d7
     }
b7d4d7
 
b7d4d7
-    if (xdata) {
b7d4d7
-        ret = dict_get_int32_sizen(xdata, "heal-op", &heal_op);
b7d4d7
+    if (req) {
b7d4d7
+        ret = dict_get_int32_sizen(req, "heal-op", &heal_op);
b7d4d7
         if (ret)
b7d4d7
             goto fav_child;
b7d4d7
     } else {
b7d4d7
@@ -292,8 +293,8 @@ afr_gfid_split_brain_source(xlator_t *this, struct afr_reply *replies,
b7d4d7
             if (*src == -1) {
b7d4d7
                 gf_msg(this->name, GF_LOG_ERROR, 0, AFR_MSG_SPLIT_BRAIN,
b7d4d7
                        SNO_BIGGER_FILE);
b7d4d7
-                if (xdata) {
b7d4d7
-                    ret = dict_set_sizen_str_sizen(xdata, "gfid-heal-msg",
b7d4d7
+                if (rsp) {
b7d4d7
+                    ret = dict_set_sizen_str_sizen(rsp, "gfid-heal-msg",
b7d4d7
                                                    SNO_BIGGER_FILE);
b7d4d7
                     if (ret)
b7d4d7
                         gf_msg(this->name, GF_LOG_ERROR, 0,
b7d4d7
@@ -310,8 +311,8 @@ afr_gfid_split_brain_source(xlator_t *this, struct afr_reply *replies,
b7d4d7
             if (*src == -1) {
b7d4d7
                 gf_msg(this->name, GF_LOG_ERROR, 0, AFR_MSG_SPLIT_BRAIN,
b7d4d7
                        SNO_DIFF_IN_MTIME);
b7d4d7
-                if (xdata) {
b7d4d7
-                    ret = dict_set_sizen_str_sizen(xdata, "gfid-heal-msg",
b7d4d7
+                if (rsp) {
b7d4d7
+                    ret = dict_set_sizen_str_sizen(rsp, "gfid-heal-msg",
b7d4d7
                                                    SNO_DIFF_IN_MTIME);
b7d4d7
                     if (ret)
b7d4d7
                         gf_msg(this->name, GF_LOG_ERROR, 0,
b7d4d7
@@ -323,7 +324,7 @@ afr_gfid_split_brain_source(xlator_t *this, struct afr_reply *replies,
b7d4d7
             break;
b7d4d7
 
b7d4d7
         case GF_SHD_OP_SBRAIN_HEAL_FROM_BRICK:
b7d4d7
-            ret = dict_get_str_sizen(xdata, "child-name", &src_brick);
b7d4d7
+            ret = dict_get_str_sizen(req, "child-name", &src_brick);
b7d4d7
             if (ret) {
b7d4d7
                 gf_msg(this->name, GF_LOG_ERROR, 0, AFR_MSG_SPLIT_BRAIN,
b7d4d7
                        "Error getting the source "
b7d4d7
@@ -335,8 +336,8 @@ afr_gfid_split_brain_source(xlator_t *this, struct afr_reply *replies,
b7d4d7
             if (*src == -1) {
b7d4d7
                 gf_msg(this->name, GF_LOG_ERROR, 0, AFR_MSG_SPLIT_BRAIN,
b7d4d7
                        SERROR_GETTING_SRC_BRICK);
b7d4d7
-                if (xdata) {
b7d4d7
-                    ret = dict_set_sizen_str_sizen(xdata, "gfid-heal-msg",
b7d4d7
+                if (rsp) {
b7d4d7
+                    ret = dict_set_sizen_str_sizen(rsp, "gfid-heal-msg",
b7d4d7
                                                    SERROR_GETTING_SRC_BRICK);
b7d4d7
                     if (ret)
b7d4d7
                         gf_msg(this->name, GF_LOG_ERROR, 0,
b7d4d7
@@ -400,7 +401,7 @@ out:
b7d4d7
                  uuid_utoa_r(replies[child_idx].poststat.ia_gfid, g1), src_idx,
b7d4d7
                  priv->children[src_idx]->name, src_idx,
b7d4d7
                  uuid_utoa_r(replies[src_idx].poststat.ia_gfid, g2));
b7d4d7
-        return -1;
b7d4d7
+        return -EIO;
b7d4d7
     }
b7d4d7
     return 0;
b7d4d7
 }
b7d4d7
diff --git a/xlators/cluster/afr/src/afr-self-heal-entry.c b/xlators/cluster/afr/src/afr-self-heal-entry.c
b7d4d7
index 20b07dd..a17dd93 100644
b7d4d7
--- a/xlators/cluster/afr/src/afr-self-heal-entry.c
b7d4d7
+++ b/xlators/cluster/afr/src/afr-self-heal-entry.c
b7d4d7
@@ -399,7 +399,7 @@ afr_selfheal_detect_gfid_and_type_mismatch(xlator_t *this,
b7d4d7
             (ia_type == replies[i].poststat.ia_type)) {
b7d4d7
             ret = afr_gfid_split_brain_source(this, replies, inode, pargfid,
b7d4d7
                                               bname, src_idx, i, locked_on, src,
b7d4d7
-                                              NULL);
b7d4d7
+                                              NULL, NULL);
b7d4d7
             if (ret)
b7d4d7
                 gf_msg(this->name, GF_LOG_ERROR, 0, AFR_MSG_SPLIT_BRAIN,
b7d4d7
                        "Skipping conservative merge on the "
b7d4d7
@@ -474,7 +474,7 @@ __afr_selfheal_merge_dirent(call_frame_t *frame, xlator_t *this, fd_t *fd,
b7d4d7
         return ret;
b7d4d7
 
b7d4d7
     /* In case of type mismatch / unable to resolve gfid mismatch on the
b7d4d7
-     * entry, return -1.*/
b7d4d7
+     * entry, return -EIO.*/
b7d4d7
     ret = afr_selfheal_detect_gfid_and_type_mismatch(
b7d4d7
         this, replies, inode, fd->inode->gfid, name, source, locked_on, &src;;
b7d4d7
 
b7d4d7
@@ -905,7 +905,7 @@ afr_selfheal_entry_do_subvol(call_frame_t *frame, xlator_t *this, fd_t *fd,
b7d4d7
                 break;
b7d4d7
             }
b7d4d7
 
b7d4d7
-            if (ret == -1) {
b7d4d7
+            if (ret == -EIO) {
b7d4d7
                 /* gfid or type mismatch. */
b7d4d7
                 mismatch = _gf_true;
b7d4d7
                 ret = 0;
b7d4d7
@@ -1072,7 +1072,7 @@ afr_selfheal_entry_do(call_frame_t *frame, xlator_t *this, fd_t *fd, int source,
b7d4d7
         else
b7d4d7
             ret = afr_selfheal_entry_do_subvol(frame, this, fd, i);
b7d4d7
 
b7d4d7
-        if (ret == -1) {
b7d4d7
+        if (ret == -EIO) {
b7d4d7
             /* gfid or type mismatch. */
b7d4d7
             mismatch = _gf_true;
b7d4d7
             ret = 0;
b7d4d7
diff --git a/xlators/cluster/afr/src/afr-self-heal-name.c b/xlators/cluster/afr/src/afr-self-heal-name.c
b7d4d7
index 51e3d8c..9ec2066 100644
b7d4d7
--- a/xlators/cluster/afr/src/afr-self-heal-name.c
b7d4d7
+++ b/xlators/cluster/afr/src/afr-self-heal-name.c
b7d4d7
@@ -217,7 +217,8 @@ afr_selfheal_name_gfid_mismatch_check(xlator_t *this, struct afr_reply *replies,
b7d4d7
                                       int source, unsigned char *sources,
b7d4d7
                                       int *gfid_idx, uuid_t pargfid,
b7d4d7
                                       const char *bname, inode_t *inode,
b7d4d7
-                                      unsigned char *locked_on, dict_t *xdata)
b7d4d7
+                                      unsigned char *locked_on, dict_t *req,
b7d4d7
+                                      dict_t *rsp)
b7d4d7
 {
b7d4d7
     int i = 0;
b7d4d7
     int gfid_idx_iter = -1;
b7d4d7
@@ -245,11 +246,11 @@ afr_selfheal_name_gfid_mismatch_check(xlator_t *this, struct afr_reply *replies,
b7d4d7
         if (sources[i] || source == -1) {
b7d4d7
             if ((sources[gfid_idx_iter] || source == -1) &&
b7d4d7
                 gf_uuid_compare(gfid, gfid1)) {
b7d4d7
-                ret = afr_gfid_split_brain_source(this, replies, inode, pargfid,
b7d4d7
-                                                  bname, gfid_idx_iter, i,
b7d4d7
-                                                  locked_on, gfid_idx, xdata);
b7d4d7
+                ret = afr_gfid_split_brain_source(
b7d4d7
+                    this, replies, inode, pargfid, bname, gfid_idx_iter, i,
b7d4d7
+                    locked_on, gfid_idx, req, rsp);
b7d4d7
                 if (!ret && *gfid_idx >= 0) {
b7d4d7
-                    ret = dict_set_sizen_str_sizen(xdata, "gfid-heal-msg",
b7d4d7
+                    ret = dict_set_sizen_str_sizen(rsp, "gfid-heal-msg",
b7d4d7
                                                    "GFID split-brain resolved");
b7d4d7
                     if (ret)
b7d4d7
                         gf_msg(this->name, GF_LOG_ERROR, 0,
b7d4d7
@@ -303,7 +304,7 @@ __afr_selfheal_name_do(call_frame_t *frame, xlator_t *this, inode_t *parent,
b7d4d7
                        unsigned char *sources, unsigned char *sinks,
b7d4d7
                        unsigned char *healed_sinks, int source,
b7d4d7
                        unsigned char *locked_on, struct afr_reply *replies,
b7d4d7
-                       void *gfid_req, dict_t *xdata)
b7d4d7
+                       void *gfid_req, dict_t *req, dict_t *rsp)
b7d4d7
 {
b7d4d7
     int gfid_idx = -1;
b7d4d7
     int ret = -1;
b7d4d7
@@ -333,7 +334,7 @@ __afr_selfheal_name_do(call_frame_t *frame, xlator_t *this, inode_t *parent,
b7d4d7
 
b7d4d7
     ret = afr_selfheal_name_gfid_mismatch_check(this, replies, source, sources,
b7d4d7
                                                 &gfid_idx, pargfid, bname,
b7d4d7
-                                                inode, locked_on, xdata);
b7d4d7
+                                                inode, locked_on, req, rsp);
b7d4d7
     if (ret)
b7d4d7
         return ret;
b7d4d7
 
b7d4d7
@@ -450,7 +451,7 @@ out:
b7d4d7
 int
b7d4d7
 afr_selfheal_name_do(call_frame_t *frame, xlator_t *this, inode_t *parent,
b7d4d7
                      uuid_t pargfid, const char *bname, void *gfid_req,
b7d4d7
-                     dict_t *xdata)
b7d4d7
+                     dict_t *req, dict_t *rsp)
b7d4d7
 {
b7d4d7
     afr_private_t *priv = NULL;
b7d4d7
     unsigned char *sources = NULL;
b7d4d7
@@ -505,7 +506,7 @@ afr_selfheal_name_do(call_frame_t *frame, xlator_t *this, inode_t *parent,
b7d4d7
 
b7d4d7
         ret = __afr_selfheal_name_do(frame, this, parent, pargfid, bname, inode,
b7d4d7
                                      sources, sinks, healed_sinks, source,
b7d4d7
-                                     locked_on, replies, gfid_req, xdata);
b7d4d7
+                                     locked_on, replies, gfid_req, req, rsp);
b7d4d7
     }
b7d4d7
 unlock:
b7d4d7
     afr_selfheal_unentrylk(frame, this, parent, this->name, bname, locked_on,
b7d4d7
@@ -578,7 +579,7 @@ afr_selfheal_name_unlocked_inspect(call_frame_t *frame, xlator_t *this,
b7d4d7
 
b7d4d7
 int
b7d4d7
 afr_selfheal_name(xlator_t *this, uuid_t pargfid, const char *bname,
b7d4d7
-                  void *gfid_req, dict_t *xdata)
b7d4d7
+                  void *gfid_req, dict_t *req, dict_t *rsp)
b7d4d7
 {
b7d4d7
     inode_t *parent = NULL;
b7d4d7
     call_frame_t *frame = NULL;
b7d4d7
@@ -600,7 +601,7 @@ afr_selfheal_name(xlator_t *this, uuid_t pargfid, const char *bname,
b7d4d7
 
b7d4d7
     if (need_heal) {
b7d4d7
         ret = afr_selfheal_name_do(frame, this, parent, pargfid, bname,
b7d4d7
-                                   gfid_req, xdata);
b7d4d7
+                                   gfid_req, req, rsp);
b7d4d7
         if (ret)
b7d4d7
             goto out;
b7d4d7
     }
b7d4d7
diff --git a/xlators/cluster/afr/src/afr-self-heal.h b/xlators/cluster/afr/src/afr-self-heal.h
b7d4d7
index c8dc384..6b0bf69 100644
b7d4d7
--- a/xlators/cluster/afr/src/afr-self-heal.h
b7d4d7
+++ b/xlators/cluster/afr/src/afr-self-heal.h
b7d4d7
@@ -127,7 +127,7 @@ afr_throttled_selfheal(call_frame_t *frame, xlator_t *this);
b7d4d7
 
b7d4d7
 int
b7d4d7
 afr_selfheal_name(xlator_t *this, uuid_t gfid, const char *name, void *gfid_req,
b7d4d7
-                  dict_t *xdata);
b7d4d7
+                  dict_t *req, dict_t *rsp);
b7d4d7
 
b7d4d7
 int
b7d4d7
 afr_selfheal_data(call_frame_t *frame, xlator_t *this, fd_t *fd);
b7d4d7
@@ -357,7 +357,8 @@ int
b7d4d7
 afr_gfid_split_brain_source(xlator_t *this, struct afr_reply *replies,
b7d4d7
                             inode_t *inode, uuid_t pargfid, const char *bname,
b7d4d7
                             int src_idx, int child_idx,
b7d4d7
-                            unsigned char *locked_on, int *src, dict_t *xdata);
b7d4d7
+                            unsigned char *locked_on, int *src, dict_t *req,
b7d4d7
+                            dict_t *rsp);
b7d4d7
 int
b7d4d7
 afr_mark_source_sinks_if_file_empty(xlator_t *this, unsigned char *sources,
b7d4d7
                                     unsigned char *sinks,
b7d4d7
diff --git a/xlators/cluster/afr/src/afr-self-heald.c b/xlators/cluster/afr/src/afr-self-heald.c
b7d4d7
index 939a135..18aed93 100644
b7d4d7
--- a/xlators/cluster/afr/src/afr-self-heald.c
b7d4d7
+++ b/xlators/cluster/afr/src/afr-self-heald.c
b7d4d7
@@ -295,7 +295,7 @@ afr_shd_selfheal_name(struct subvol_healer *healer, int child, uuid_t parent,
b7d4d7
 {
b7d4d7
     int ret = -1;
b7d4d7
 
b7d4d7
-    ret = afr_selfheal_name(THIS, parent, bname, NULL, NULL);
b7d4d7
+    ret = afr_selfheal_name(THIS, parent, bname, NULL, NULL, NULL);
b7d4d7
 
b7d4d7
     return ret;
b7d4d7
 }
b7d4d7
-- 
b7d4d7
1.8.3.1
b7d4d7