diff options
author | Ravishankar N <ravishankar@redhat.com> | 2014-04-11 05:45:56 +0000 |
---|---|---|
committer | Vijay Bellur <vbellur@redhat.com> | 2014-04-28 09:56:03 -0700 |
commit | 0d2dbd569f5ee187fc7b864c30cc668fee465bb1 (patch) | |
tree | afe712e558fc1eeca8c91cfeb450f241af25ac21 | |
parent | 82c244a390679e03ea25830abbb90b0dcc7a69cc (diff) |
cluster/afr: perform list-xattr during lookup
Detect and heal mismatching user extended attributes during lookup.
Depends on: http://review.gluster.org/#/c/7434/
Change-Id: I49410aafd319ac159fdf9e6f9201871bbf2f67bd
BUG: 1078061
Signed-off-by: Ravishankar N <ravishankar@redhat.com>
Reviewed-on: http://review.gluster.org/7444
Reviewed-by: Pranith Kumar Karampuri <pkarampu@redhat.com>
Tested-by: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: Vijay Bellur <vbellur@redhat.com>
-rw-r--r-- | xlators/cluster/afr/src/afr-common.c | 83 | ||||
-rw-r--r-- | xlators/cluster/afr/src/afr-self-heal-metadata.c | 6 | ||||
-rw-r--r-- | xlators/cluster/afr/src/afr.h | 3 |
3 files changed, 92 insertions, 0 deletions
diff --git a/xlators/cluster/afr/src/afr-common.c b/xlators/cluster/afr/src/afr-common.c index 6a453060c9e..2a54a79ed4a 100644 --- a/xlators/cluster/afr/src/afr-common.c +++ b/xlators/cluster/afr/src/afr-common.c @@ -87,6 +87,13 @@ afr_xattr_req_prepare (xlator_t *this, dict_t *xattr_req, const char *path) gf_log (this->name, GF_LOG_DEBUG, "%s: failed to set gfidless " "lookup", path); } + ret = dict_set_int32 (xattr_req, "list-xattr", 1); + if (ret) { + gf_log (this->name, GF_LOG_DEBUG, + "%s: Unable to set dict value for list-xattr", + path); + } + } int @@ -1743,6 +1750,77 @@ afr_data_self_heal_enabled (char *data_self_heal) return enabled; } +static char *afr_ignore_xattrs[] = { + GLUSTERFS_OPEN_FD_COUNT, + GLUSTERFS_PARENT_ENTRYLK, + GLUSTERFS_ENTRYLK_COUNT, + GLUSTERFS_INODELK_COUNT, + GF_SELINUX_XATTR_KEY, + NULL +}; + + +static gf_boolean_t +afr_lookup_xattr_ignorable (char *key) +{ + int i = 0; + + if (!strncmp (key, AFR_XATTR_PREFIX, strlen(AFR_XATTR_PREFIX))) + return _gf_true; + for (i = 0; afr_ignore_xattrs[i]; i++) { + if (!strcmp (key, afr_ignore_xattrs[i])) + return _gf_true; + } + return _gf_false; +} + +static int +xattr_is_equal (dict_t *this, char *key1, data_t *value1, void *data) +{ + dict_t *xattr2 = (dict_t *)data; + data_t *value2 = NULL; + + if (afr_lookup_xattr_ignorable (key1)) + return 0; + + value2 = dict_get (xattr2, key1); + if (!value2) + return -1; + + if (value1->len != value2->len) + return -1; + if(memcmp(value1->data, value2->data, value1->len)) + return -1; + else + return 0; + +} + +gf_boolean_t +afr_lookup_xattrs_are_equal (dict_t **xattr, int32_t *success_children, int success_count) +{ + int i = 0; + int child1 = -1; + int child2 = -1; + int ret = 0; + + if (success_count < 2) + return _gf_true; + + child1 = success_children[0]; + for (i = 1; i < success_count; i++) { + child2 = success_children[i]; + if (xattr[child1]->count != xattr[child2]->count) + return _gf_false; + ret = dict_foreach (xattr[child1], xattr_is_equal, + (void*) xattr[child2]); + if (ret == -1) + return _gf_false; + } + + return _gf_true; +} + static void afr_lookup_set_self_heal_params (afr_local_t *local, xlator_t *this) { @@ -1784,6 +1862,11 @@ afr_lookup_set_self_heal_params (afr_local_t *local, xlator_t *this) afr_lookup_set_self_heal_params_by_xattr (local, this, xattr[child1]); } + + if(!afr_lookup_xattrs_are_equal (xattr, + local->cont.lookup.success_children, + local->success_count)) + local->self_heal.do_metadata_self_heal = _gf_true; if (afr_open_only_data_self_heal (priv->data_self_heal)) sh->do_data_self_heal = _gf_false; if (sh->do_metadata_self_heal) diff --git a/xlators/cluster/afr/src/afr-self-heal-metadata.c b/xlators/cluster/afr/src/afr-self-heal-metadata.c index 7abd852de6c..6cefc8d0fb0 100644 --- a/xlators/cluster/afr/src/afr-self-heal-metadata.c +++ b/xlators/cluster/afr/src/afr-self-heal-metadata.c @@ -591,6 +591,7 @@ afr_sh_metadata_fix (call_frame_t *frame, xlator_t *this, int nsources = 0; int source = 0; int i = 0; + gf_boolean_t xattrs_match = _gf_false; local = frame->local; sh = &local->self_heal; @@ -652,6 +653,9 @@ afr_sh_metadata_fix (call_frame_t *frame, xlator_t *this, sh->source = source; /* detect changes not visible through pending flags -- JIC */ + xattrs_match = afr_lookup_xattrs_are_equal (sh->xattr, + sh->success_children, + sh->success_count); for (i = 0; i < priv->child_count; i++) { if (i == source || sh->child_errno[i]) continue; @@ -661,6 +665,8 @@ afr_sh_metadata_fix (call_frame_t *frame, xlator_t *this, if (OWNERSHIP_DIFFERS (&sh->buf[i], &sh->buf[source])) sh->sources[i] = 0; + if(!xattrs_match) + sh->sources[i] = 0; } if ((!IA_ISREG (sh->buf[source].ia_type)) && diff --git a/xlators/cluster/afr/src/afr.h b/xlators/cluster/afr/src/afr.h index 49ca64c75c1..cad5de3986a 100644 --- a/xlators/cluster/afr/src/afr.h +++ b/xlators/cluster/afr/src/afr.h @@ -1215,6 +1215,9 @@ afr_inodelk_init (afr_inodelk_t *lk, char *dom, size_t child_count); void afr_handle_open_fd_count (call_frame_t *frame, xlator_t *this); +gf_boolean_t +afr_lookup_xattrs_are_equal (dict_t **xattr, int32_t *success_children, + int success_count); afr_inode_ctx_t* afr_inode_ctx_get (inode_t *inode, xlator_t *this); |