summaryrefslogtreecommitdiffstats
path: root/xlators/cluster/afr/src/afr-self-heal-metadata.c
diff options
context:
space:
mode:
Diffstat (limited to 'xlators/cluster/afr/src/afr-self-heal-metadata.c')
-rw-r--r--xlators/cluster/afr/src/afr-self-heal-metadata.c30
1 files changed, 24 insertions, 6 deletions
diff --git a/xlators/cluster/afr/src/afr-self-heal-metadata.c b/xlators/cluster/afr/src/afr-self-heal-metadata.c
index dc7825d3d16..e98728ba54f 100644
--- a/xlators/cluster/afr/src/afr-self-heal-metadata.c
+++ b/xlators/cluster/afr/src/afr-self-heal-metadata.c
@@ -82,12 +82,12 @@ __afr_selfheal_metadata_do (call_frame_t *frame, xlator_t *this, inode_t *inode,
/*
- * Look for mismatching uid/gid or mode even if xattrs don't say so, and
- * pick one arbitrarily as winner.
- */
+ * Look for mismatching uid/gid or mode or user xattrs even if
+ * AFR xattrs don't say so, and pick one arbitrarily as winner. */
static int
-__afr_selfheal_metadata_finalize_source (xlator_t *this, unsigned char *sources,
+__afr_selfheal_metadata_finalize_source (call_frame_t *frame, xlator_t *this,
+ unsigned char *sources,
unsigned char *healed_sinks,
unsigned char *locked_on,
struct afr_reply *replies)
@@ -97,6 +97,7 @@ __afr_selfheal_metadata_finalize_source (xlator_t *this, unsigned char *sources,
struct iatt first = {0, };
int source = -1;
int sources_count = 0;
+ int ret = 0;
priv = this->private;
@@ -124,11 +125,12 @@ __afr_selfheal_metadata_finalize_source (xlator_t *this, unsigned char *sources,
if (source == -1) {
source = i;
first = replies[i].poststat;
+ break;
}
}
for (i = 0; i < priv->child_count; i++) {
- if (!sources[i])
+ if (!sources[i] || i == source)
continue;
if (!IA_EQUAL (first, replies[i].poststat, type) ||
!IA_EQUAL (first, replies[i].poststat, uid) ||
@@ -139,6 +141,22 @@ __afr_selfheal_metadata_finalize_source (xlator_t *this, unsigned char *sources,
}
}
+ for (i =0; i < priv->child_count; i++) {
+ if (!sources[i] || i == source)
+ continue;
+ if (replies[source].xdata->count != replies[i].xdata->count) {
+ sources[i] = 0;
+ healed_sinks[i] = 1;
+ continue;
+ }
+ ret = dict_foreach(replies[source].xdata, xattr_is_equal,
+ (void*)replies[i].xdata);
+ if (ret == -1) {
+ sources[i] = 0;
+ healed_sinks[i] = 1;
+ }
+ }
+
return source;
}
@@ -176,7 +194,7 @@ __afr_selfheal_metadata_prepare (call_frame_t *frame, xlator_t *this, inode_t *i
*/
AFR_INTERSECT (healed_sinks, sinks, locked_on, priv->child_count);
- source = __afr_selfheal_metadata_finalize_source (this, sources,
+ source = __afr_selfheal_metadata_finalize_source (frame, this, sources,
healed_sinks,
locked_on, replies);
if (source < 0)