diff options
author | karthik-us <ksubrahm@redhat.com> | 2017-04-19 18:04:46 +0530 |
---|---|---|
committer | Pranith Kumar Karampuri <pkarampu@redhat.com> | 2017-05-17 18:45:51 +0000 |
commit | 0a50167c0a8f950f5a1c76442b6c9abea466200d (patch) | |
tree | e03d01221b4e8ff776dcda1485add58882bbdaab /xlators/cluster | |
parent | bcc34ce05c1be76dae42838d55c15d3af5f80e48 (diff) |
cluster/afr: Return the list of node_uuids for the subvolume
Problem:
AFR was returning the node uuid of the first node for every file if
the replica set was healthy, which was resulting in only one node
migrating all the files.
Fix:
With this patch AFR returns the list of node_uuids to the upper layer,
so that they can decide on which node to migrate which files, resulting
in improved performance. Ordering of node uuids will be maintained based
on the ordering of the bricks. If a brick is down, then the node uuid
for that will be set to all zeros.
Change-Id: I73ee0f9898ae473584fdf487a2980d7a6db22f31
BUG: 1366817
Signed-off-by: karthik-us <ksubrahm@redhat.com>
Reviewed-on: https://review.gluster.org/17084
Reviewed-by: Pranith Kumar Karampuri <pkarampu@redhat.com>
Tested-by: Pranith Kumar Karampuri <pkarampu@redhat.com>
Smoke: Gluster Build System <jenkins@build.gluster.org>
NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org>
CentOS-regression: Gluster Build System <jenkins@build.gluster.org>
Diffstat (limited to 'xlators/cluster')
-rw-r--r-- | xlators/cluster/afr/src/afr-common.c | 49 | ||||
-rw-r--r-- | xlators/cluster/afr/src/afr-inode-read.c | 141 | ||||
-rw-r--r-- | xlators/cluster/afr/src/afr.h | 5 |
3 files changed, 145 insertions, 50 deletions
diff --git a/xlators/cluster/afr/src/afr-common.c b/xlators/cluster/afr/src/afr-common.c index 34d9e56911e..2377419f01c 100644 --- a/xlators/cluster/afr/src/afr-common.c +++ b/xlators/cluster/afr/src/afr-common.c @@ -6291,3 +6291,52 @@ mdata_unlock: return ret; } + +/* + * Concatenates the xattrs in local->replies separated by a delimiter. + */ +int +afr_serialize_xattrs_with_delimiter (call_frame_t *frame, xlator_t *this, + char *buf, const char *default_str, + int32_t *serz_len, char delimiter) +{ + afr_private_t *priv = NULL; + afr_local_t *local = NULL; + char *xattr = NULL; + int i = 0; + int len = 0; + int ret = -1; + + priv = this->private; + local = frame->local; + + for (i = 0; i < priv->child_count; i++) { + if (!local->replies[i].valid || local->replies[i].op_ret) { + buf = strncat (buf, default_str, strlen (default_str)); + len += strlen (default_str); + buf[len++] = delimiter; + buf[len] = '\0'; + } else { + ret = dict_get_str (local->replies[i].xattr, + local->cont.getxattr.name, &xattr); + if (ret) { + gf_msg ("TEST", GF_LOG_ERROR, -ret, + AFR_MSG_DICT_GET_FAILED, + "Failed to get the node_uuid of brick " + "%d", i); + goto out; + } + buf = strncat (buf, xattr, strlen (xattr)); + len += strlen (xattr); + buf[len++] = delimiter; + buf[len] = '\0'; + } + } + buf[--len] = '\0'; /*remove the last delimiter*/ + if (serz_len) + *serz_len = ++len; + ret = 0; + +out: + return ret; +} diff --git a/xlators/cluster/afr/src/afr-inode-read.c b/xlators/cluster/afr/src/afr-inode-read.c index 2b369ca3c68..20446d88c99 100644 --- a/xlators/cluster/afr/src/afr-inode-read.c +++ b/xlators/cluster/afr/src/afr-inode-read.c @@ -713,57 +713,110 @@ unwind: return ret; } + /** - * node-uuid cbk uses next child querying mechanism + * node-uuid 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_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; + afr_local_t *local = NULL; + afr_private_t *priv = NULL; + int32_t callcnt = 0; + int ret = 0; + char *xattr_serz = NULL; + long cky = 0; + int32_t tlen = 0; + local = frame->local; priv = this->private; - children = priv->children; + cky = (long) cookie; - local = frame->local; + LOCK (&frame->lock); + { + callcnt = --local->call_count; + local->replies[cky].valid = 1; + local->replies[cky].op_ret = op_ret; + local->replies[cky].op_errno = op_errno; - if (op_ret == -1) { /** query the _next_ child */ + if (op_ret < 0) + goto unlock; - /** - * _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; + local->op_ret = 0; - 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, - NULL); + if (!local->xdata_rsp && xdata) + local->xdata_rsp = dict_ref (xdata); + local->replies[cky].xattr = dict_ref (dict); } - unwind: - if (unwind) - AFR_STACK_UNWIND (getxattr, frame, op_ret, op_errno, dict, - NULL); +unlock: + UNLOCK (&frame->lock); - return 0; + if (!callcnt) { + + if (local->op_ret != 0) { + /* All bricks gave an error. */ + local->op_errno = afr_final_errno (local, priv); + goto unwind; + } + + /*Since we store the UUID0_STR as node uuid for down bricks and + *for non zero op_ret, assigning length to priv->child_count + *number of uuids*/ + local->cont.getxattr.xattr_len = (strlen (UUID0_STR) + 2) * + priv->child_count; + + if (!local->dict) + local->dict = dict_new (); + if (!local->dict) { + local->op_ret = -1; + local->op_errno = ENOMEM; + goto unwind; + } + + xattr_serz = GF_CALLOC (local->cont.getxattr.xattr_len, + sizeof (char), gf_common_mt_char); + + if (!xattr_serz) { + local->op_ret = -1; + local->op_errno = ENOMEM; + goto unwind; + } + + ret = afr_serialize_xattrs_with_delimiter (frame, this, + xattr_serz, + UUID0_STR, &tlen, + ' '); + if (ret) { + local->op_ret = -1; + local->op_errno = ENOMEM; + goto unwind; + } + ret = dict_set_dynstr (local->dict, local->cont.getxattr.name, + xattr_serz); + if (ret) { + gf_msg (this->name, GF_LOG_ERROR, + -ret, AFR_MSG_DICT_SET_FAILED, + "Cannot set node_uuid key in dict"); + local->op_ret = -1; + local->op_errno = ENOMEM; + } else { + local->op_ret = local->cont.getxattr.xattr_len - 1; + local->op_errno = 0; + } + +unwind: + AFR_STACK_UNWIND (getxattr, frame, local->op_ret, + local->op_errno, local->dict, + local->xdata_rsp); + } + + return ret; } + int32_t afr_getxattr_quota_size_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, @@ -1374,6 +1427,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 { is_spl = _gf_false; } @@ -1489,9 +1544,7 @@ afr_getxattr (call_frame_t *frame, xlator_t *this, loc_t *loc, const char *name, dict_t *xdata) { afr_private_t *priv = NULL; - xlator_t **children = NULL; afr_local_t *local = NULL; - int i = 0; int32_t op_errno = 0; int ret = -1; fop_getxattr_cbk_t cbk = NULL; @@ -1503,8 +1556,6 @@ 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; @@ -1545,16 +1596,6 @@ 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, diff --git a/xlators/cluster/afr/src/afr.h b/xlators/cluster/afr/src/afr.h index 3be15175dc7..3a47ba47241 100644 --- a/xlators/cluster/afr/src/afr.h +++ b/xlators/cluster/afr/src/afr.h @@ -1259,4 +1259,9 @@ __afr_fd_ctx_get (fd_t *fd, xlator_t *this); gf_boolean_t afr_is_inode_refresh_reqd (inode_t *inode, xlator_t *this, int event_gen1, int event_gen2); + +int +afr_serialize_xattrs_with_delimiter (call_frame_t *frame, xlator_t *this, + char *buf, const char *default_str, + int32_t *serz_len, char delimiter); #endif /* __AFR_H__ */ |