Blob Blame History Raw
From 0c861887464556cef735a8bd5ad42f9bc79963e9 Mon Sep 17 00:00:00 2001
From: karthik-us <ksubrahm@redhat.com>
Date: Fri, 30 Jun 2017 11:26:58 +0530
Subject: [PATCH 535/539] cluster/afr: Returning single and list of node uuids
 from AFR

Backport of : https://review.gluster.org/#/c/17576/

Problem:
The change in afr to return list of node uuids was causing problems
with geo-rep.

Fix:
This patch will allow to get the single node uuid as it was doing
before with the key "GF_XATTR_NODE_UUID_KEY", and will also allow
to get the list of node uuids by using a new key
"GF_XATTR_LIST_NODE_UUIDS_KEY". This will solve the problem with
geo-rep and any other feature which were depending on this.

Change-Id: I2e805c0ac2797918d383345394f5f52a87fb8298
BUG: 1462693
Signed-off-by: karthik-us <ksubrahm@redhat.com>
Reviewed-on: https://code.engineering.redhat.com/gerrit/110564
Reviewed-by: Atin Mukherjee <amukherj@redhat.com>
---
 libglusterfs/src/glusterfs.h             |  1 +
 xlators/cluster/afr/src/afr-inode-read.c | 88 ++++++++++++++++++++++++++++----
 2 files changed, 80 insertions(+), 9 deletions(-)

diff --git a/libglusterfs/src/glusterfs.h b/libglusterfs/src/glusterfs.h
index 86519b0..0f68ecd 100644
--- a/libglusterfs/src/glusterfs.h
+++ b/libglusterfs/src/glusterfs.h
@@ -84,6 +84,7 @@
 #define GF_XATTR_CLRLK_CMD      "glusterfs.clrlk"
 #define GF_XATTR_PATHINFO_KEY   "trusted.glusterfs.pathinfo"
 #define GF_XATTR_NODE_UUID_KEY  "trusted.glusterfs.node-uuid"
+#define GF_XATTR_LIST_NODE_UUIDS_KEY "trusted.glusterfs.list-node-uuids"
 #define GF_REBAL_FIND_LOCAL_SUBVOL "glusterfs.find-local-subvol"
 #define GF_XATTR_VOL_ID_KEY   "trusted.glusterfs.volume-id"
 #define GF_XATTR_LOCKINFO_KEY   "trusted.glusterfs.lockinfo"
diff --git a/xlators/cluster/afr/src/afr-inode-read.c b/xlators/cluster/afr/src/afr-inode-read.c
index 20446d8..ecf94a5 100644
--- a/xlators/cluster/afr/src/afr-inode-read.c
+++ b/xlators/cluster/afr/src/afr-inode-read.c
@@ -713,14 +713,64 @@ unwind:
         return ret;
 }
 
+/**
+ * node-uuid cbk uses next child querying mechanism
+ */
+int32_t
+afr_getxattr_node_uuid_cbk (call_frame_t *frame, void *cookie,
+                            xlator_t *this, int32_t op_ret, int32_t op_errno,
+                            dict_t *dict, dict_t *xdata)
+{
+        afr_private_t  *priv            = NULL;
+        afr_local_t    *local           = NULL;
+        xlator_t      **children        = NULL;
+        int             unwind          = 1;
+        int             curr_call_child = 0;
+
+        priv = this->private;
+        children = priv->children;
+
+        local = frame->local;
+
+        if (op_ret == -1) { /** query the _next_ child */
+
+                /**
+                 * _current_ becomes _next_
+                 * If done with all childs and yet no success; give up !
+                 */
+                curr_call_child = (int) ((long)cookie);
+                if (++curr_call_child == priv->child_count)
+                        goto unwind;
+
+                gf_msg_debug (this->name, op_errno,
+                              "op_ret (-1): Re-querying afr-child (%d/%d)",
+                              curr_call_child, priv->child_count);
+
+                unwind = 0;
+                STACK_WIND_COOKIE (frame, afr_getxattr_node_uuid_cbk,
+                                   (void *) (long) curr_call_child,
+                                   children[curr_call_child],
+                                   children[curr_call_child]->fops->getxattr,
+                                   &local->loc,
+                                   local->cont.getxattr.name,
+                                   local->xdata_req);
+        }
+
+ unwind:
+        if (unwind)
+                AFR_STACK_UNWIND (getxattr, frame, op_ret, op_errno, dict,
+                                  xdata);
+
+        return 0;
+}
 
 /**
- * node-uuid cbk returns the list of node_uuids for the subvolume.
+ * list-node-uuids cbk returns the list of node_uuids for the subvolume.
  */
 int32_t
-afr_getxattr_node_uuid_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
-                            int32_t op_ret, int32_t op_errno, dict_t *dict,
-                            dict_t *xdata)
+afr_getxattr_list_node_uuids_cbk (call_frame_t *frame, void *cookie,
+                                  xlator_t *this, int32_t op_ret,
+                                  int32_t op_errno, dict_t *dict, dict_t *xdata)
 {
         afr_local_t    *local          = NULL;
         afr_private_t  *priv           = NULL;
@@ -794,7 +844,8 @@ unlock:
                         local->op_errno = ENOMEM;
                         goto unwind;
                 }
-                ret = dict_set_dynstr (local->dict, local->cont.getxattr.name,
+                ret = dict_set_dynstr (local->dict,
+                                       GF_XATTR_LIST_NODE_UUIDS_KEY,
                                        xattr_serz);
                 if (ret) {
                         gf_msg (this->name, GF_LOG_ERROR,
@@ -1427,8 +1478,8 @@ afr_is_special_xattr (const char *name, fop_getxattr_cbk_t *cbk,
                 *cbk = afr_common_getxattr_stime_cbk;
         } else if (strcmp (name, QUOTA_SIZE_KEY) == 0) {
                 *cbk = afr_getxattr_quota_size_cbk;
-        } else if (!strcmp (name, GF_XATTR_NODE_UUID_KEY)) {
-                *cbk = afr_getxattr_node_uuid_cbk;
+        } else if (!strcmp (name, GF_XATTR_LIST_NODE_UUIDS_KEY)) {
+                *cbk = afr_getxattr_list_node_uuids_cbk;
         } else {
                 is_spl = _gf_false;
         }
@@ -1453,15 +1504,20 @@ afr_getxattr_all_subvols (xlator_t *this, call_frame_t *frame,
         //local->call_count set in afr_local_init
         call_count = local->call_count;
 
+        if (!strcmp (name, GF_XATTR_LIST_NODE_UUIDS_KEY)) {
+                GF_FREE (local->cont.getxattr.name);
+                local->cont.getxattr.name = gf_strdup (GF_XATTR_NODE_UUID_KEY);
+        }
+
         //If up-children count is 0, afr_local_init would have failed already
         //and the call would have unwound so not handling it here.
-
         for (i = 0; i < priv->child_count; i++) {
                 if (local->child_up[i]) {
                         STACK_WIND_COOKIE (frame, cbk,
                                            (void *) (long) i, priv->children[i],
                                            priv->children[i]->fops->getxattr,
-                                           loc, name, NULL);
+                                           loc, local->cont.getxattr.name,
+                                           NULL);
                         if (!--call_count)
                                 break;
                 }
@@ -1545,6 +1601,8 @@ afr_getxattr (call_frame_t *frame, xlator_t *this,
 {
         afr_private_t           *priv         = NULL;
         afr_local_t             *local        = NULL;
+        xlator_t                **children    = NULL;
+        int                     i             = 0;
         int32_t                 op_errno      = 0;
         int                     ret           = -1;
         fop_getxattr_cbk_t      cbk           = NULL;
@@ -1556,6 +1614,8 @@ afr_getxattr (call_frame_t *frame, xlator_t *this,
 
         priv     = this->private;
 
+        children = priv->children;
+
         loc_copy (&local->loc, loc);
 
 	local->op = GF_FOP_GETXATTR;
@@ -1596,6 +1656,16 @@ afr_getxattr (call_frame_t *frame, xlator_t *this,
                 return 0;
         }
 
+        if (XATTR_IS_NODE_UUID (name)) {
+                i = 0;
+                STACK_WIND_COOKIE (frame, afr_getxattr_node_uuid_cbk,
+                                   (void *) (long) i,
+                                   children[i],
+                                   children[i]->fops->getxattr,
+                                   loc, name, xdata);
+                return 0;
+        }
+
 no_name:
 
 	afr_read_txn (frame, this, local->loc.inode, afr_getxattr_wind,
-- 
1.8.3.1