7f4c2a
From ec6028d919a974dcbe9d8428a09fc9de85a5fafd Mon Sep 17 00:00:00 2001
7f4c2a
From: Anuradha Talur <atalur@redhat.com>
7f4c2a
Date: Fri, 11 Sep 2015 18:43:36 +0530
7f4c2a
Subject: [PATCH 329/330] afr : get split-brain-status in a synctask
7f4c2a
7f4c2a
On executing `getfattr -n replica.split-brain-status <file>` on mount,
7f4c2a
there is a possibility that the mount hangs. To avoid this hang,
7f4c2a
fetch the split-brain-status of a file in synctask.
7f4c2a
7f4c2a
Upstream master patch : review.gluster.org/12163
7f4c2a
Upstream 3.7 patch    : review.gluster.org/12166
7f4c2a
7f4c2a
Change-Id: I87b781419ffc63248f915325b845e3233143d385
7f4c2a
BUG: 1262291
7f4c2a
Signed-off-by: Anuradha Talur <atalur@redhat.com>
7f4c2a
Reviewed-on: https://code.engineering.redhat.com/gerrit/57674
7f4c2a
Reviewed-by: Pranith Kumar Karampuri <pkarampu@redhat.com>
7f4c2a
Tested-by: Pranith Kumar Karampuri <pkarampu@redhat.com>
7f4c2a
---
7f4c2a
 xlators/cluster/afr/src/afr-common.c      |   32 +++++++++++---
7f4c2a
 xlators/cluster/afr/src/afr-inode-read.c  |   67 +++++++++++++++++++++++-----
7f4c2a
 xlators/cluster/afr/src/afr-inode-write.c |    3 +
7f4c2a
 xlators/cluster/afr/src/afr-mem-types.h   |    1 +
7f4c2a
 xlators/cluster/afr/src/afr-messages.h    |    9 +++-
7f4c2a
 xlators/cluster/afr/src/afr.h             |   13 ++++-
7f4c2a
 6 files changed, 103 insertions(+), 22 deletions(-)
7f4c2a
7f4c2a
diff --git a/xlators/cluster/afr/src/afr-common.c b/xlators/cluster/afr/src/afr-common.c
7f4c2a
index 7255179..9abb96d 100644
7f4c2a
--- a/xlators/cluster/afr/src/afr-common.c
7f4c2a
+++ b/xlators/cluster/afr/src/afr-common.c
7f4c2a
@@ -4741,8 +4741,7 @@ out:
7f4c2a
 }
7f4c2a
 
7f4c2a
 int
7f4c2a
-afr_get_heal_info (call_frame_t *frame, xlator_t *this, loc_t *loc,
7f4c2a
-                   dict_t *xdata)
7f4c2a
+afr_get_heal_info (call_frame_t *frame, xlator_t *this, loc_t *loc)
7f4c2a
 {
7f4c2a
         gf_boolean_t    data_selfheal     = _gf_false;
7f4c2a
         gf_boolean_t    metadata_selfheal = _gf_false;
7f4c2a
@@ -4867,7 +4866,14 @@ out:
7f4c2a
 }
7f4c2a
 
7f4c2a
 int
7f4c2a
-afr_get_split_brain_status (call_frame_t *frame, xlator_t *this, loc_t *loc)
7f4c2a
+afr_get_split_brain_status_cbk (int ret, call_frame_t *frame, void *opaque)
7f4c2a
+{
7f4c2a
+        GF_FREE (opaque);
7f4c2a
+        return 0;
7f4c2a
+}
7f4c2a
+
7f4c2a
+int
7f4c2a
+afr_get_split_brain_status (void *opaque)
7f4c2a
 {
7f4c2a
         gf_boolean_t      d_spb             = _gf_false;
7f4c2a
         gf_boolean_t      m_spb             = _gf_false;
7f4c2a
@@ -4880,7 +4886,15 @@ afr_get_split_brain_status (call_frame_t *frame, xlator_t *this, loc_t *loc)
7f4c2a
         inode_t          *inode             = NULL;
7f4c2a
         afr_private_t    *priv              = NULL;
7f4c2a
         xlator_t         **children         = NULL;
7f4c2a
-
7f4c2a
+        call_frame_t     *frame             = NULL;
7f4c2a
+        xlator_t         *this              = NULL;
7f4c2a
+        loc_t            *loc               = NULL;
7f4c2a
+        afr_spb_status_t *data              = NULL;
7f4c2a
+
7f4c2a
+        data     = opaque;
7f4c2a
+        frame    = data->frame;
7f4c2a
+        this     = frame->this;
7f4c2a
+        loc      = data->loc;
7f4c2a
         priv     = this->private;
7f4c2a
         children = priv->children;
7f4c2a
 
7f4c2a
@@ -4930,14 +4944,20 @@ afr_get_split_brain_status (call_frame_t *frame, xlator_t *this, loc_t *loc)
7f4c2a
                         goto out;
7f4c2a
                 }
7f4c2a
                 ret = dict_set_dynstr (dict, GF_AFR_SBRAIN_STATUS, status);
7f4c2a
-                if (ret)
7f4c2a
+                if (ret) {
7f4c2a
+                        op_errno = -ret;
7f4c2a
+                        ret = -1;
7f4c2a
                         goto out;
7f4c2a
+                }
7f4c2a
         } else {
7f4c2a
                 ret = dict_set_str (dict, GF_AFR_SBRAIN_STATUS,
7f4c2a
                                     "The file is not under data or"
7f4c2a
                                     " metadata split-brain");
7f4c2a
-                if (ret)
7f4c2a
+                if (ret) {
7f4c2a
+                        op_errno = -ret;
7f4c2a
+                        ret = -1;
7f4c2a
                         goto out;
7f4c2a
+                }
7f4c2a
         }
7f4c2a
 
7f4c2a
         ret = 0;
7f4c2a
diff --git a/xlators/cluster/afr/src/afr-inode-read.c b/xlators/cluster/afr/src/afr-inode-read.c
7f4c2a
index 1ebe5e5..6afd51d 100644
7f4c2a
--- a/xlators/cluster/afr/src/afr-inode-read.c
7f4c2a
+++ b/xlators/cluster/afr/src/afr-inode-read.c
7f4c2a
@@ -1429,6 +1429,59 @@ afr_marker_populate_args (call_frame_t *frame, int type, int *gauge,
7f4c2a
         return priv->child_count;
7f4c2a
 }
7f4c2a
 
7f4c2a
+static int
7f4c2a
+afr_handle_heal_xattrs (call_frame_t *frame, xlator_t *this, loc_t *loc,
7f4c2a
+                        const char *heal_op)
7f4c2a
+{
7f4c2a
+        int                     ret     = -1;
7f4c2a
+        afr_spb_status_t       *data    = NULL;
7f4c2a
+
7f4c2a
+        if (!strcmp (heal_op, GF_HEAL_INFO)) {
7f4c2a
+                afr_get_heal_info (frame, this, loc);
7f4c2a
+                ret = 0;
7f4c2a
+                goto out;
7f4c2a
+        }
7f4c2a
+
7f4c2a
+        if (!strcmp (heal_op, GF_AFR_HEAL_SBRAIN)) {
7f4c2a
+                afr_heal_splitbrain_file (frame, this, loc);
7f4c2a
+                ret = 0;
7f4c2a
+                goto out;
7f4c2a
+        }
7f4c2a
+
7f4c2a
+        if (!strcmp (heal_op, GF_AFR_SBRAIN_STATUS)) {
7f4c2a
+                data = GF_CALLOC (1, sizeof (*data), gf_afr_mt_spb_status_t);
7f4c2a
+                if (!data) {
7f4c2a
+                        ret = 1;
7f4c2a
+                        goto out;
7f4c2a
+                }
7f4c2a
+                data->frame = frame;
7f4c2a
+                data->loc = loc;
7f4c2a
+                ret = synctask_new (this->ctx->env,
7f4c2a
+                                    afr_get_split_brain_status,
7f4c2a
+                                    afr_get_split_brain_status_cbk,
7f4c2a
+                                    NULL, data);
7f4c2a
+                if (ret) {
7f4c2a
+                        gf_msg (this->name, GF_LOG_ERROR, 0,
7f4c2a
+                                AFR_MSG_SPLIT_BRAIN_STATUS,
7f4c2a
+                                "Failed to create"
7f4c2a
+                                " synctask. Unable to fetch split-brain status"
7f4c2a
+                                " for %s.", loc->name);
7f4c2a
+                        ret = 1;
7f4c2a
+                        goto out;
7f4c2a
+                }
7f4c2a
+                goto out;
7f4c2a
+        }
7f4c2a
+
7f4c2a
+out:
7f4c2a
+        if (ret == 1) {
7f4c2a
+                AFR_STACK_UNWIND (getxattr, frame, -1, ENOMEM, NULL, NULL);
7f4c2a
+                if (data)
7f4c2a
+                        GF_FREE (data);
7f4c2a
+                ret = 0;
7f4c2a
+        }
7f4c2a
+        return ret;
7f4c2a
+}
7f4c2a
+
7f4c2a
 int32_t
7f4c2a
 afr_getxattr (call_frame_t *frame, xlator_t *this,
7f4c2a
               loc_t *loc, const char *name, dict_t *xdata)
7f4c2a
@@ -1478,20 +1531,10 @@ afr_getxattr (call_frame_t *frame, xlator_t *this,
7f4c2a
                                             afr_marker_populate_args) == 0)
7f4c2a
                 return 0;
7f4c2a
 
7f4c2a
-        if (!strcmp (name, GF_HEAL_INFO)) {
7f4c2a
-                afr_get_heal_info (frame, this, loc, xdata);
7f4c2a
+        ret = afr_handle_heal_xattrs (frame, this, &local->loc, name);
7f4c2a
+        if (ret == 0)
7f4c2a
                 return 0;
7f4c2a
-        }
7f4c2a
 
7f4c2a
-        if (!strcmp (name, GF_AFR_HEAL_SBRAIN)) {
7f4c2a
-                afr_heal_splitbrain_file (frame, this, loc);
7f4c2a
-                return 0;
7f4c2a
-        }
7f4c2a
-
7f4c2a
-        if (!strcmp (name, GF_AFR_SBRAIN_STATUS)) {
7f4c2a
-                afr_get_split_brain_status (frame, this, loc);
7f4c2a
-                return 0;
7f4c2a
-        }
7f4c2a
         /*
7f4c2a
          * Special xattrs which need responses from all subvols
7f4c2a
          */
7f4c2a
diff --git a/xlators/cluster/afr/src/afr-inode-write.c b/xlators/cluster/afr/src/afr-inode-write.c
7f4c2a
index be83781..01390f0 100644
7f4c2a
--- a/xlators/cluster/afr/src/afr-inode-write.c
7f4c2a
+++ b/xlators/cluster/afr/src/afr-inode-write.c
7f4c2a
@@ -1302,6 +1302,7 @@ afr_handle_split_brain_commands (xlator_t *this, call_frame_t *frame,
7f4c2a
                                 " synctask. Aborting split-brain choice set"
7f4c2a
                                 " for %s", loc->name);
7f4c2a
                         ret = 1;
7f4c2a
+                        op_errno = ENOMEM;
7f4c2a
                         goto out;
7f4c2a
                 }
7f4c2a
                 ret = 0;
7f4c2a
@@ -1325,6 +1326,8 @@ out:
7f4c2a
         /* key was correct but value was invalid when ret == 1 */
7f4c2a
         if (ret == 1) {
7f4c2a
                 AFR_STACK_UNWIND (setxattr, frame, -1, op_errno, NULL);
7f4c2a
+                if (data)
7f4c2a
+                        GF_FREE (data);
7f4c2a
                 ret = 0;
7f4c2a
         }
7f4c2a
         return ret;
7f4c2a
diff --git a/xlators/cluster/afr/src/afr-mem-types.h b/xlators/cluster/afr/src/afr-mem-types.h
7f4c2a
index a11063c..fd484e4 100644
7f4c2a
--- a/xlators/cluster/afr/src/afr-mem-types.h
7f4c2a
+++ b/xlators/cluster/afr/src/afr-mem-types.h
7f4c2a
@@ -44,6 +44,7 @@ enum gf_afr_mem_types_ {
7f4c2a
 	gf_afr_mt_reply_t,
7f4c2a
 	gf_afr_mt_subvol_healer_t,
7f4c2a
 	gf_afr_mt_spbc_timeout_t,
7f4c2a
+        gf_afr_mt_spb_status_t,
7f4c2a
         gf_afr_mt_end
7f4c2a
 };
7f4c2a
 #endif
7f4c2a
diff --git a/xlators/cluster/afr/src/afr-messages.h b/xlators/cluster/afr/src/afr-messages.h
7f4c2a
index e4bf85b..4793413 100644
7f4c2a
--- a/xlators/cluster/afr/src/afr-messages.h
7f4c2a
+++ b/xlators/cluster/afr/src/afr-messages.h
7f4c2a
@@ -45,7 +45,7 @@
7f4c2a
  */
7f4c2a
 
7f4c2a
 #define GLFS_COMP_BASE_AFR      GLFS_MSGID_COMP_AFR
7f4c2a
-#define GLFS_NUM_MESSAGES       37
7f4c2a
+#define GLFS_NUM_MESSAGES       38
7f4c2a
 #define GLFS_MSGID_END          (GLFS_COMP_BASE_AFR + GLFS_NUM_MESSAGES + 1)
7f4c2a
 
7f4c2a
 #define glfs_msg_start_x GLFS_COMP_BASE_AFR, "Invalid: Start of messages"
7f4c2a
@@ -333,6 +333,13 @@
7f4c2a
 #define AFR_MSG_SELF_HEAL_FAILED                (GLFS_COMP_BASE_AFR + 37)
7f4c2a
 
7f4c2a
 
7f4c2a
+/*!
7f4c2a
+ * @messageid 108038
7f4c2a
+ * @diagnosis
7f4c2a
+ * @recommendedaction
7f4c2a
+*/
7f4c2a
+#define AFR_MSG_SPLIT_BRAIN_STATUS      (GLFS_COMP_BASE_AFR + 38)
7f4c2a
+
7f4c2a
 
7f4c2a
 #define glfs_msg_end_x GLFS_MSGID_END, "Invalid: End of messages"
7f4c2a
 #endif /* !_AFR_MESSAGES_H_ */
7f4c2a
diff --git a/xlators/cluster/afr/src/afr.h b/xlators/cluster/afr/src/afr.h
7f4c2a
index 729ae82..316eeea 100644
7f4c2a
--- a/xlators/cluster/afr/src/afr.h
7f4c2a
+++ b/xlators/cluster/afr/src/afr.h
7f4c2a
@@ -755,6 +755,11 @@ typedef struct afr_spbc_timeout {
7f4c2a
         int          spb_child_index;
7f4c2a
 } afr_spbc_timeout_t;
7f4c2a
 
7f4c2a
+typedef struct afr_spb_status {
7f4c2a
+        call_frame_t *frame;
7f4c2a
+        loc_t        *loc;
7f4c2a
+} afr_spb_status_t;
7f4c2a
+
7f4c2a
 typedef struct afr_read_subvol_args {
7f4c2a
         ia_type_t ia_type;
7f4c2a
         uuid_t gfid;
7f4c2a
@@ -1050,14 +1055,16 @@ gf_boolean_t
7f4c2a
 afr_is_xattr_ignorable (char *key);
7f4c2a
 
7f4c2a
 int
7f4c2a
-afr_get_heal_info (call_frame_t *frame, xlator_t *this, loc_t *loc,
7f4c2a
-                   dict_t *xdata);
7f4c2a
+afr_get_heal_info (call_frame_t *frame, xlator_t *this, loc_t *loc);
7f4c2a
 
7f4c2a
 int
7f4c2a
 afr_heal_splitbrain_file(call_frame_t *frame, xlator_t *this, loc_t *loc);
7f4c2a
 
7f4c2a
 int
7f4c2a
-afr_get_split_brain_status (call_frame_t *frame, xlator_t *this, loc_t *loc);
7f4c2a
+afr_get_split_brain_status (void *opaque);
7f4c2a
+
7f4c2a
+int
7f4c2a
+afr_get_split_brain_status_cbk (int ret, call_frame_t *frame, void *opaque);
7f4c2a
 
7f4c2a
 int
7f4c2a
 afr_inode_split_brain_choice_set (inode_t *inode, xlator_t *this,
7f4c2a
-- 
7f4c2a
1.7.1
7f4c2a