diff options
author | karthik-us <ksubrahm@redhat.com> | 2018-04-26 00:58:12 +0530 |
---|---|---|
committer | karthik-us <ksubrahm@redhat.com> | 2018-04-30 14:27:05 +0530 |
commit | 1bf8a8addb61d30177f0d10cec64a9dfcd0add92 (patch) | |
tree | e027e8bf54d95900323372b0f57790b02611c89a /xlators/cluster/afr | |
parent | ef89e1b5bb77706b1910a45640b11a4341c78d6a (diff) |
cluster/afr: shd changes for thin arbiter
Updates #352
Change-Id: I1bbb3c652ba33cec6aa37f3700370674077fb17d
Signed-off-by: karthik-us <ksubrahm@redhat.com>
Diffstat (limited to 'xlators/cluster/afr')
-rw-r--r-- | xlators/cluster/afr/src/afr-self-heald.c | 184 |
1 files changed, 184 insertions, 0 deletions
diff --git a/xlators/cluster/afr/src/afr-self-heald.c b/xlators/cluster/afr/src/afr-self-heald.c index fcf1559e545..4667be63220 100644 --- a/xlators/cluster/afr/src/afr-self-heald.c +++ b/xlators/cluster/afr/src/afr-self-heald.c @@ -15,6 +15,7 @@ #include "protocol-common.h" #include "syncop-utils.h" #include "afr-messages.h" +#include "byte-order.h" #define SHD_INODE_LRU_LIMIT 2048 #define AFR_EH_SPLIT_BRAIN_LIMIT 1024 @@ -555,6 +556,172 @@ afr_shd_full_sweep (struct subvol_healer *healer, inode_t *inode) afr_shd_full_heal); } +void +afr_shd_ta_set_xattrs (xlator_t *this, loc_t *loc, dict_t **xdata, + int healer) +{ + afr_private_t *priv = NULL; + dict_t *xattr = NULL; + struct gf_flock flock = {0, }; + gf_boolean_t need_xattrop = _gf_false; + void *pending_raw = NULL; + int *raw = NULL; + int pending[AFR_NUM_CHANGE_LOGS] = {0,}; + int i = 0; + int j = 0; + int val = 0; + int ret = 0; + + priv = this->private; + + xattr = dict_new (); + if (!xattr) { + goto out; + } + + for (i = 0; i < priv->child_count; i++) { + raw = GF_CALLOC (AFR_NUM_CHANGE_LOGS, sizeof(int), + gf_afr_mt_int32_t); + if (!raw) { + goto out; + } + + ret = dict_get_ptr (*xdata, priv->pending_key[i], &pending_raw); + if (ret) { + gf_msg (this->name, GF_LOG_ERROR, -ret, + AFR_MSG_DICT_GET_FAILED, "Error getting value " + "of pending key %s", priv->pending_key[i]); + GF_FREE (raw); + goto out; + } + + memcpy (pending, pending_raw, sizeof (pending)); + for (j = 0; j < AFR_NUM_CHANGE_LOGS; j++) { + val = ntoh32 (pending[j]); + if (val) { + if (i == healer) { + gf_msg (this->name, GF_LOG_INFO, 0, + AFR_MSG_THIN_ARB, "I am " + "not the good shd. Skipping. " + "SHD = %d.", healer); + GF_FREE (raw); + goto out; + } + need_xattrop = _gf_true; + raw[j] = hton32 (-val); + } + } + + ret = dict_set_bin (xattr, priv->pending_key[i], raw, + AFR_NUM_CHANGE_LOGS * sizeof (int)); + if (ret) { + GF_FREE (raw); + goto out; + } + + memset (pending, 0, sizeof (pending)); + } + + if (!need_xattrop) { + goto out; + } + + flock.l_type = F_WRLCK; + flock.l_start = 0; + flock.l_len = 0; + + ret = syncop_inodelk (priv->children[THIN_ARBITER_BRICK_INDEX], + THIN_ARBITER_DOM1, loc, F_SETLKW, &flock, + NULL, NULL); + if (ret) + goto out; + + ret = syncop_xattrop (priv->children[THIN_ARBITER_BRICK_INDEX], loc, + GF_XATTROP_ADD_ARRAY, xattr, NULL, NULL, NULL); + if (ret) + gf_msg (this->name, GF_LOG_ERROR, -ret, AFR_MSG_THIN_ARB, + "Xattrop failed."); + + flock.l_type = F_UNLCK; + syncop_inodelk (priv->children[THIN_ARBITER_BRICK_INDEX], + THIN_ARBITER_DOM1, loc, F_SETLKW, &flock, NULL, NULL); + +out: + if (xattr) + dict_unref (xattr); + return; +} + +void +afr_shd_ta_get_xattrs (xlator_t *this, loc_t *loc, dict_t **xdata) +{ + afr_private_t *priv = NULL; + dict_t *xattr = NULL; + struct iatt stbuf = {0,}; + int *raw = NULL; + int ret = 0; + int i = 0; + + priv = this->private; + + loc->parent = inode_ref (this->itable->root); + gf_uuid_copy (loc->pargfid, loc->parent->gfid); + loc->name = priv->pending_key[THIN_ARBITER_BRICK_INDEX]; + loc->inode = inode_new (loc->parent->table); + if (!loc->inode) { + goto out; + } + + ret = syncop_lookup (priv->children[THIN_ARBITER_BRICK_INDEX], loc, + &stbuf, 0, 0, 0); + if (ret) { + gf_msg (this->name, GF_LOG_ERROR, -ret, AFR_MSG_THIN_ARB, + "Failed lookup on file %s.", loc->name); + goto out; + } + + gf_uuid_copy (priv->ta_gfid, stbuf.ia_gfid); + gf_uuid_copy (loc->gfid, priv->ta_gfid); + + xattr = dict_new (); + if (!xattr) { + gf_msg (this->name, GF_LOG_ERROR, 0, AFR_MSG_DICT_GET_FAILED, + "Failed to create dict."); + goto out; + } + + for (i = 0; i < priv->child_count; i++) { + raw = GF_CALLOC (AFR_NUM_CHANGE_LOGS, sizeof(int), + gf_afr_mt_int32_t); + if (!raw) { + goto out; + } + + ret = dict_set_bin (xattr, priv->pending_key[i], raw, + AFR_NUM_CHANGE_LOGS * sizeof (int)); + if (ret) { + GF_FREE (raw); + goto out; + } + } + + ret = syncop_xattrop (priv->children[THIN_ARBITER_BRICK_INDEX], + loc, GF_XATTROP_ADD_ARRAY, xattr, NULL, xdata, + NULL); + if (ret) { + gf_msg (this->name, GF_LOG_ERROR, -ret, AFR_MSG_THIN_ARB, + "Xattrop failed."); + goto out; + } + if (!(*xdata)) + gf_msg (this->name, GF_LOG_ERROR, 0, AFR_MSG_DICT_GET_FAILED, + "Xdata response is empty."); + +out: + if (xattr) + dict_unref (xattr); + return; +} void * afr_shd_index_healer (void *data) @@ -563,6 +730,8 @@ afr_shd_index_healer (void *data) xlator_t *this = NULL; int ret = 0; afr_private_t *priv = NULL; + dict_t *xdata = NULL; + loc_t loc = {0, }; healer = data; THIS = this = healer->this; @@ -574,6 +743,12 @@ afr_shd_index_healer (void *data) ASSERT_LOCAL(this, healer); priv->local[healer->subvol] = healer->local; + if (priv->thin_arbiter_count) { + loc_wipe (&loc); + afr_shd_ta_get_xattrs (this, &loc, &xdata); + } + + do { gf_msg_debug (this->name, 0, "starting index sweep on subvol %s", @@ -602,8 +777,17 @@ afr_shd_index_healer (void *data) */ sleep (1); } while (ret > 0); + + if (xdata && !healer->crawl_event.heal_failed_count) { + afr_shd_ta_set_xattrs (this, &loc, &xdata, + healer->subvol); + dict_unref (xdata); + xdata = NULL; + } } + loc_wipe (&loc); + return NULL; } |