From febae2965d1104531d032b2a767428b3b5d5283f Mon Sep 17 00:00:00 2001 From: Ravishankar N Date: Thu, 8 May 2014 11:57:03 +0000 Subject: cluster/afr: send opendirs to all children for entry self-heal Problem: In entry self-heal, opendir was sent only to one source because of which afr_sh_erase_pending() failed to clear the changelogs of other sources. So heals were happening multiple times. Fix :Send opendir to all sources. Change-Id: Ief4f131848b24a0da782f29b9f1d40e136d3fcff BUG: 1096040 Signed-off-by: Ravishankar N Reviewed-on: http://review.gluster.org/7723 Reviewed-by: Pranith Kumar Karampuri Tested-by: Gluster Build System Reviewed-by: Niels de Vos --- xlators/cluster/afr/src/afr-self-heal-data.c | 1 - xlators/cluster/afr/src/afr-self-heal-entry.c | 34 ++++++++------------------- 2 files changed, 10 insertions(+), 25 deletions(-) (limited to 'xlators') diff --git a/xlators/cluster/afr/src/afr-self-heal-data.c b/xlators/cluster/afr/src/afr-self-heal-data.c index e740ac9a308..6c895dbde5d 100644 --- a/xlators/cluster/afr/src/afr-self-heal-data.c +++ b/xlators/cluster/afr/src/afr-self-heal-data.c @@ -1657,7 +1657,6 @@ afr_sh_data_open (call_frame_t *frame, xlator_t *this) fd = fd_create (local->loc.inode, frame->root->pid); sh->healing_fd = fd; - /* open sinks */ for (i = 0; i < priv->child_count; i++) { if(!local->child_up[i]) continue; diff --git a/xlators/cluster/afr/src/afr-self-heal-entry.c b/xlators/cluster/afr/src/afr-self-heal-entry.c index 97f0d68b9f6..d9ee0bc3972 100644 --- a/xlators/cluster/afr/src/afr-self-heal-entry.c +++ b/xlators/cluster/afr/src/afr-self-heal-entry.c @@ -2164,8 +2164,6 @@ afr_sh_entry_open (call_frame_t *frame, xlator_t *this) { int i = 0; int call_count = 0; - - int source = -1; int *sources = NULL; fd_t *fd = NULL; @@ -2178,43 +2176,31 @@ afr_sh_entry_open (call_frame_t *frame, xlator_t *this) sh = &local->self_heal; priv = this->private; - source = local->self_heal.source; sources = local->self_heal.sources; sh->block_size = priv->sh_readdir_size; sh->offset = 0; - call_count = sh->active_sinks; - if (source != -1) - call_count++; - + call_count = afr_up_children_count (local->child_up, + priv->child_count); local->call_count = call_count; fd = fd_create (local->loc.inode, frame->root->pid); sh->healing_fd = fd; - if (source != -1) { - gf_log (this->name, GF_LOG_TRACE, - "opening directory %s on subvolume %s (source)", - local->loc.path, priv->children[source]->name); - - /* open source */ - STACK_WIND_COOKIE (frame, afr_sh_entry_opendir_cbk, - (void *) (long) source, - priv->children[source], - priv->children[source]->fops->opendir, - &local->loc, fd, NULL); - call_count--; - } + /* We need to opendir all sources in addition to the sinks though heal + * happens only from one source, so that afr_sh_erase_pending() can + * clear the changelogs all sources. Otherwise redundant entry + * self-heals can happen to the sinks from each of the sources.*/ - /* open sinks */ for (i = 0; i < priv->child_count; i++) { - if (sources[i] || !local->child_up[i]) + if (!local->child_up[i]) continue; gf_log (this->name, GF_LOG_TRACE, - "opening directory %s on subvolume %s (sink)", - local->loc.path, priv->children[i]->name); + "opening directory %s on subvolume %s (%s)", + local->loc.path, priv->children[i]->name, + local->self_heal.sources[i]? "source":"sink"); STACK_WIND_COOKIE (frame, afr_sh_entry_opendir_cbk, (void *) (long) i, -- cgit