summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRavishankar N <ravishankar@redhat.com>2014-04-11 05:45:56 +0000
committerVijay Bellur <vbellur@redhat.com>2014-04-28 09:56:03 -0700
commit0d2dbd569f5ee187fc7b864c30cc668fee465bb1 (patch)
treeafe712e558fc1eeca8c91cfeb450f241af25ac21
parent82c244a390679e03ea25830abbb90b0dcc7a69cc (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.c83
-rw-r--r--xlators/cluster/afr/src/afr-self-heal-metadata.c6
-rw-r--r--xlators/cluster/afr/src/afr.h3
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);