From b80a2a150b874031df35af8d4f06657906024861 Mon Sep 17 00:00:00 2001 From: Pranith Kumar K Date: Tue, 27 Sep 2011 14:44:01 +0530 Subject: cluster/afr: Handle files without gfid Change-Id: Ie831ae8542c1382c17fb7837cd18b0e4e4d3db75 BUG: 3734 Reviewed-on: http://review.gluster.com/619 Tested-by: Gluster Build System Reviewed-by: Vijay Bellur --- xlators/cluster/afr/src/afr-self-heal-entry.c | 584 ++++++++++---------------- 1 file changed, 217 insertions(+), 367 deletions(-) (limited to 'xlators/cluster/afr/src/afr-self-heal-entry.c') diff --git a/xlators/cluster/afr/src/afr-self-heal-entry.c b/xlators/cluster/afr/src/afr-self-heal-entry.c index 3977ae101f6..e32b507631a 100644 --- a/xlators/cluster/afr/src/afr-self-heal-entry.c +++ b/xlators/cluster/afr/src/afr-self-heal-entry.c @@ -49,6 +49,15 @@ #include "afr-self-heal.h" #include "afr-self-heal-common.h" +#define AFR_INIT_SH_FRAME_VALS(_frame, _local, _sh, _sh_frame, _sh_local, _sh_sh)\ + do {\ + _local = _frame->local;\ + _sh = &_local->self_heal;\ + _sh_frame = _sh->sh_frame;\ + _sh_local = _sh_frame->local;\ + _sh_sh = &_sh_local->self_heal;\ + } while (0); + int afr_sh_entry_done (call_frame_t *frame, xlator_t *this) { @@ -298,51 +307,6 @@ next_active_sink (call_frame_t *frame, xlator_t *this, return next_active_sink; } - -int -build_child_loc (xlator_t *this, loc_t *child, loc_t *parent, char *name) -{ - int ret = -1; - - if (!child) { - goto out; - } - - if (strcmp (parent->path, "/") == 0) - ret = gf_asprintf ((char **)&child->path, "/%s", name); - else - ret = gf_asprintf ((char **)&child->path, "%s/%s", parent->path, - name); - - if (-1 == ret) { - gf_log (this->name, GF_LOG_ERROR, - "asprintf failed while setting child path"); - } - - if (!child->path) { - goto out; - } - - child->name = strrchr (child->path, '/'); - if (child->name) - child->name++; - - child->parent = inode_ref (parent->inode); - child->inode = inode_new (parent->inode->table); - - if (!child->inode) { - goto out; - } - - ret = 0; -out: - if (ret == -1) - loc_wipe (child); - - return ret; -} - - int afr_sh_entry_impunge_all (call_frame_t *frame, xlator_t *this); @@ -759,7 +723,7 @@ afr_sh_entry_expunge_entry (call_frame_t *frame, xlator_t *this, expunge_sh->active_source = active_src; expunge_sh->entrybuf = entry->d_stat; - ret = build_child_loc (this, &expunge_local->loc, &local->loc, name); + ret = afr_build_child_loc (this, &expunge_local->loc, &local->loc, name); if (ret != 0) { op_errno = EINVAL; goto out; @@ -916,15 +880,47 @@ afr_sh_entry_impunge_entry_done (call_frame_t *frame, xlator_t *this, int32_t op_errno) { int call_count = 0; + afr_local_t *local = NULL; + afr_self_heal_t *sh = NULL; + local = frame->local; + sh = &local->self_heal; call_count = afr_frame_return (frame); + if (op_ret == -1) + sh->op_failed = 1; - if (call_count == 0) + if (call_count == 0) { + if (sh->op_failed) { + afr_sh_entry_finish (frame, this); + goto out; + } afr_sh_entry_impunge_subvol (frame, this, active_src); - + } +out: return 0; } +void +afr_sh_entry_call_impunge_done (call_frame_t *impunge_frame, xlator_t *this, + int32_t op_ret, int32_t op_errno) +{ + afr_local_t *impunge_local = NULL; + afr_local_t *local = NULL; + afr_self_heal_t *sh = NULL; + afr_self_heal_t *impunge_sh = NULL; + call_frame_t *frame = NULL; + int32_t impunge_ret_child = 0; + afr_private_t *priv = NULL; + + priv = this->private; + AFR_INIT_SH_FRAME_VALS (impunge_frame, impunge_local, impunge_sh, + frame, local, sh); + + impunge_ret_child = impunge_sh->impunge_ret_child; + AFR_STACK_DESTROY (impunge_frame); + sh->impunge_done (frame, this, impunge_ret_child, op_ret, + op_errno); +} int afr_sh_entry_impunge_setattr_cbk (call_frame_t *impunge_frame, void *cookie, @@ -935,21 +931,12 @@ afr_sh_entry_impunge_setattr_cbk (call_frame_t *impunge_frame, void *cookie, int call_count = 0; afr_private_t *priv = NULL; afr_local_t *impunge_local = NULL; - afr_local_t *local = NULL; - afr_self_heal_t *sh = NULL; afr_self_heal_t *impunge_sh = NULL; - call_frame_t *frame = NULL; - int active_src = 0; int child_index = 0; - int32_t impunge_ret_child = 0; priv = this->private; impunge_local = impunge_frame->local; impunge_sh = &impunge_local->self_heal; - frame = impunge_sh->sh_frame; - local = frame->local; - sh = &local->self_heal; - active_src = impunge_sh->active_source; child_index = (long) cookie; if (op_ret == 0) { @@ -971,12 +958,9 @@ afr_sh_entry_impunge_setattr_cbk (call_frame_t *impunge_frame, void *cookie, } UNLOCK (&impunge_frame->lock); - if (call_count == 0) { - impunge_ret_child = impunge_sh->impunge_ret_child; - AFR_STACK_DESTROY (impunge_frame); - sh->impunge_done (frame, this, impunge_ret_child, op_ret, - op_errno); - } + if (call_count == 0) + afr_sh_entry_call_impunge_done (impunge_frame, this, + op_ret, op_errno); return 0; } @@ -1059,7 +1043,6 @@ afr_sh_entry_impunge_parent_setattr_cbk (call_frame_t *setattr_frame, return 0; } - int afr_sh_entry_impunge_newfile_cbk (call_frame_t *impunge_frame, void *cookie, xlator_t *this, @@ -1072,27 +1055,20 @@ afr_sh_entry_impunge_newfile_cbk (call_frame_t *impunge_frame, void *cookie, afr_private_t *priv = NULL; afr_local_t *impunge_local = NULL; afr_self_heal_t *impunge_sh = NULL; - call_frame_t *frame = NULL; int active_src = 0; int child_index = 0; int32_t *pending_array = NULL; dict_t *xattr = NULL; int ret = 0; int idx = 0; - afr_local_t *local = NULL; - afr_self_heal_t *sh = NULL; call_frame_t *setattr_frame = NULL; int32_t valid = 0; loc_t *parent_loc = NULL; struct iatt parentbuf = {0,}; - int32_t impunge_ret_child = 0; priv = this->private; impunge_local = impunge_frame->local; impunge_sh = &impunge_local->self_heal; - frame = impunge_sh->sh_frame; - local = frame->local; - sh = &local->self_heal; active_src = impunge_sh->active_source; child_index = (long) cookie; @@ -1110,7 +1086,6 @@ afr_sh_entry_impunge_newfile_cbk (call_frame_t *impunge_frame, void *cookie, xattr = dict_new (); if (!xattr) { - sh->op_failed = 1; gf_log (this->name, GF_LOG_ERROR, "Out of memory"); goto out; } @@ -1119,7 +1094,6 @@ afr_sh_entry_impunge_newfile_cbk (call_frame_t *impunge_frame, void *cookie, gf_common_mt_int32_t); if (!pending_array) { - sh->op_failed = 1; gf_log (this->name, GF_LOG_ERROR, "Out of memory"); goto out; } @@ -1147,7 +1121,6 @@ afr_sh_entry_impunge_newfile_cbk (call_frame_t *impunge_frame, void *cookie, parent_loc = GF_CALLOC (1, sizeof (*parent_loc), gf_afr_mt_loc_t); if (!parent_loc) { - sh->op_failed = 1; gf_log (this->name, GF_LOG_ERROR, "Out of memory"); goto out; } @@ -1182,12 +1155,9 @@ out: } UNLOCK (&impunge_frame->lock); - if (call_count == 0) { - impunge_ret_child = impunge_sh->impunge_ret_child; - AFR_STACK_DESTROY (impunge_frame); - sh->impunge_done (frame, this, impunge_ret_child, -1, - op_errno); - } + if (call_count == 0) + afr_sh_entry_call_impunge_done (impunge_frame, this, + -1, op_errno); return 0; } @@ -1214,6 +1184,7 @@ afr_sh_entry_impunge_mknod (call_frame_t *impunge_frame, xlator_t *this, if (!dict) gf_log (this->name, GF_LOG_ERROR, "Out of memory"); + GF_ASSERT (!uuid_is_null (stbuf->ia_gfid)); ret = afr_set_dict_gfid (dict, stbuf->ia_gfid); if (ret) gf_log (this->name, GF_LOG_INFO, "%s: gfid set failed", @@ -1256,6 +1227,7 @@ afr_sh_entry_impunge_mkdir (call_frame_t *impunge_frame, xlator_t *this, return 0; } + GF_ASSERT (!uuid_is_null (stbuf->ia_gfid)); ret = afr_set_dict_gfid (dict, stbuf->ia_gfid); if (ret) gf_log (this->name, GF_LOG_INFO, "%s: gfid set failed", @@ -1290,32 +1262,22 @@ afr_sh_entry_impunge_symlink (call_frame_t *impunge_frame, xlator_t *this, dict_t *dict = NULL; struct iatt *buf = NULL; int ret = 0; - call_frame_t *frame = NULL; - afr_local_t *local = NULL; - afr_self_heal_t *sh = NULL; afr_self_heal_t *impunge_sh = NULL; - int32_t impunge_ret_child = 0; priv = this->private; impunge_local = impunge_frame->local; impunge_sh = &impunge_local->self_heal; - frame = impunge_sh->sh_frame; - local = frame->local; - sh = &local->self_heal; buf = &impunge_local->cont.symlink.buf; dict = dict_new (); if (!dict) { - gf_log (this->name, GF_LOG_ERROR, - "Out of memory"); - impunge_ret_child = impunge_sh->impunge_ret_child; - AFR_STACK_DESTROY (impunge_frame); - sh->impunge_done (impunge_frame, this, impunge_ret_child, -1, - ENOMEM); + afr_sh_entry_call_impunge_done (impunge_frame, this, + -1, ENOMEM); goto out; } + GF_ASSERT (!uuid_is_null (buf->ia_gfid)); ret = afr_set_dict_gfid (dict, buf->ia_gfid); if (ret) gf_log (this->name, GF_LOG_INFO, @@ -1351,20 +1313,11 @@ afr_sh_entry_impunge_symlink_unlink_cbk (call_frame_t *impunge_frame, afr_local_t *impunge_local = NULL; afr_self_heal_t *impunge_sh = NULL; int child_index = -1; - call_frame_t *frame = NULL; int call_count = -1; - int active_src = -1; - afr_local_t *local = NULL; - afr_self_heal_t *sh = NULL; - int32_t impunge_ret_child = 0; priv = this->private; impunge_local = impunge_frame->local; impunge_sh = &impunge_local->self_heal; - frame = impunge_sh->sh_frame; - local = frame->local; - sh = &local->self_heal; - active_src = impunge_sh->active_source; child_index = (long) cookie; @@ -1388,12 +1341,9 @@ out: } UNLOCK (&impunge_frame->lock); - if (call_count == 0) { - impunge_ret_child = impunge_sh->impunge_ret_child; - AFR_STACK_DESTROY (impunge_frame); - sh->impunge_done (frame, this, impunge_ret_child, op_ret, - op_errno); - } + if (call_count == 0) + afr_sh_entry_call_impunge_done (impunge_frame, this, + op_ret, op_errno); return 0; } @@ -1434,19 +1384,12 @@ afr_sh_entry_impunge_readlink_sink_cbk (call_frame_t *impunge_frame, void *cooki afr_local_t *impunge_local = NULL; afr_self_heal_t *impunge_sh = NULL; int child_index = -1; - call_frame_t *frame = NULL; int call_count = -1; int active_src = -1; - afr_local_t *local = NULL; - afr_self_heal_t *sh = NULL; - int32_t impunge_ret_child = 0; priv = this->private; impunge_local = impunge_frame->local; impunge_sh = &impunge_local->self_heal; - frame = impunge_sh->sh_frame; - local = frame->local; - sh = &local->self_heal; active_src = impunge_sh->active_source; child_index = (long) cookie; @@ -1491,12 +1434,9 @@ out: } UNLOCK (&impunge_frame->lock); - if (call_count == 0) { - impunge_ret_child = impunge_sh->impunge_ret_child; - AFR_STACK_DESTROY (impunge_frame); - sh->impunge_done (frame, this, impunge_ret_child, op_ret, - op_errno); - } + if (call_count == 0) + afr_sh_entry_call_impunge_done (impunge_frame, this, + op_ret, op_errno); return 0; } @@ -1536,19 +1476,12 @@ afr_sh_entry_impunge_readlink_cbk (call_frame_t *impunge_frame, void *cookie, afr_local_t *impunge_local = NULL; afr_self_heal_t *impunge_sh = NULL; int child_index = -1; - call_frame_t *frame = NULL; int call_count = -1; int active_src = -1; - afr_local_t *local = NULL; - afr_self_heal_t *sh = NULL; - int32_t impunge_ret_child = 0; priv = this->private; impunge_local = impunge_frame->local; impunge_sh = &impunge_local->self_heal; - frame = impunge_sh->sh_frame; - local = frame->local; - sh = &local->self_heal; active_src = impunge_sh->active_source; child_index = (long) cookie; @@ -1574,12 +1507,9 @@ out: } UNLOCK (&impunge_frame->lock); - if (call_count == 0) { - impunge_ret_child = impunge_sh->impunge_ret_child; - AFR_STACK_DESTROY (impunge_frame); - sh->impunge_done (frame, this, impunge_ret_child, op_ret, - op_errno); - } + if (call_count == 0) + afr_sh_entry_call_impunge_done (impunge_frame, this, + op_ret, op_errno); return 0; } @@ -1659,177 +1589,162 @@ afr_sh_entry_impunge_create (call_frame_t *impunge_frame, xlator_t *this, return ret; } -int -afr_sh_entry_impunge_recreate_lookup_cbk (call_frame_t *impunge_frame, - void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, - inode_t *inode, struct iatt *buf, - dict_t *xattr,struct iatt *postparent) +gf_boolean_t +afr_sh_need_recreate (afr_self_heal_t *impunge_sh, int *sources, + unsigned int child, unsigned int child_count) { - afr_private_t *priv = NULL; - afr_local_t *impunge_local = NULL; - afr_local_t *local = NULL; - afr_self_heal_t *impunge_sh = NULL; - afr_self_heal_t *sh = NULL; - int active_src = 0; - int child_index = 0; - call_frame_t *frame = NULL; - int call_count = 0; - int ret = 0; - int32_t impunge_ret_child = 0; + int32_t *success_children = NULL; + gf_boolean_t recreate = _gf_false; - priv = this->private; - impunge_local = impunge_frame->local; - impunge_sh = &impunge_local->self_heal; - frame = impunge_sh->sh_frame; - local = frame->local; - sh = &local->self_heal; + GF_ASSERT (impunge_sh->impunging_entry_mode); + GF_ASSERT (impunge_sh->child_errno); + GF_ASSERT (sources); - child_index = (long) cookie; - - active_src = impunge_sh->active_source; - - if (op_ret != 0) { - gf_log (this->name, GF_LOG_DEBUG, - "looking up %s on %s (for %s) failed (%s)", - impunge_local->loc.path, - priv->children[active_src]->name, - priv->children[child_index]->name, - strerror (op_errno)); + success_children = impunge_sh->child_success; + if (sources[child] || (child == impunge_sh->active_source)) { + GF_ASSERT (afr_is_child_present (success_children, + child_count, child)); goto out; } - ret = afr_sh_entry_impunge_create (impunge_frame, this, child_index, buf, - postparent); - if (ret) + if (IA_ISLNK (impunge_sh->impunging_entry_mode)) { + recreate = _gf_true; goto out; + } - return 0; - + if (impunge_sh->child_errno[child] == ENOENT) + recreate = _gf_true; out: - LOCK (&impunge_frame->lock); - { - call_count = --impunge_local->call_count; - } - UNLOCK (&impunge_frame->lock); + return recreate; +} - if (call_count == 0) { - impunge_ret_child = impunge_sh->impunge_ret_child; - AFR_STACK_DESTROY (impunge_frame); - sh->impunge_done (frame, this, impunge_ret_child, op_ret, - op_errno); +unsigned int +afr_sh_recreate_count (afr_self_heal_t *impunge_sh, int *sources, + unsigned int child_count) +{ + int count = 0; + int i = 0; + + for (i = 0; i < child_count; i++) { + if (afr_sh_need_recreate (impunge_sh, sources, i, child_count)) + count++; } - return 0; + return count; } - int -afr_sh_entry_impunge_recreate (call_frame_t *impunge_frame, xlator_t *this, - int child_index) +afr_sh_entry_call_impunge_recreate (call_frame_t *impunge_frame, + xlator_t *this) { afr_private_t *priv = NULL; afr_local_t *impunge_local = NULL; afr_self_heal_t *impunge_sh = NULL; + call_frame_t *frame = NULL; + afr_local_t *local = NULL; + afr_self_heal_t *sh = NULL; + struct iatt *buf = NULL; + struct iatt *postparent = NULL; + unsigned int recreate_count = 0; + int i = 0; int active_src = 0; + priv = this->private; + AFR_INIT_SH_FRAME_VALS (impunge_frame, impunge_local, impunge_sh, + frame, local, sh); + active_src = impunge_sh->active_source; + buf = &impunge_sh->buf[active_src]; + postparent = &impunge_sh->parentbufs[active_src]; - priv = this->private; - impunge_local = impunge_frame->local; - impunge_sh = &impunge_local->self_heal; - - active_src = impunge_sh->active_source; - - STACK_WIND_COOKIE (impunge_frame, - afr_sh_entry_impunge_recreate_lookup_cbk, - (void *) (long) child_index, - priv->children[active_src], - priv->children[active_src]->fops->lookup, - &impunge_local->loc, 0); - + recreate_count = afr_sh_recreate_count (impunge_sh, sh->sources, + priv->child_count); + GF_ASSERT (recreate_count); + impunge_local->call_count = recreate_count; + for (i = 0; i < priv->child_count; i++) { + if (afr_sh_need_recreate (impunge_sh, sh->sources, i, + priv->child_count)) { + (void)afr_sh_entry_impunge_create (impunge_frame, this, + i, buf, + postparent); + recreate_count--; + } + } + GF_ASSERT (!recreate_count); return 0; } - -int -afr_sh_entry_impunge_entry_cbk (call_frame_t *impunge_frame, void *cookie, - xlator_t *this, - int32_t op_ret, int32_t op_errno, - inode_t *inode, struct iatt *buf, dict_t *x, - struct iatt *postparent) +void +afr_sh_entry_common_lookup_done (call_frame_t *impunge_frame, xlator_t *this, + int32_t op_ret, int32_t op_errno) { afr_private_t *priv = NULL; afr_local_t *impunge_local = NULL; afr_self_heal_t *impunge_sh = NULL; - int call_count = 0; - int child_index = 0; call_frame_t *frame = NULL; int active_src = 0; afr_local_t *local = NULL; afr_self_heal_t *sh = NULL; - int32_t impunge_ret_child = 0; - - priv = this->private; - impunge_local = impunge_frame->local; - impunge_sh = &impunge_local->self_heal; - frame = impunge_sh->sh_frame; - local = frame->local; - sh = &local->self_heal; - child_index = (long) cookie; - active_src = impunge_sh->active_source; - - if ((op_ret == -1 && op_errno == ENOENT) - || (IA_ISLNK (impunge_sh->impunging_entry_mode))) { + unsigned int recreate_count = 0; + unsigned int gfid_miss_count = 0; + unsigned int children_up_count = 0; + uuid_t gfid = {0}; - /* - * A symlink's target might have changed, so - * always go down the recreate path for them. - */ - - /* decrease call_count in recreate-callback */ - - gf_log (this->name, GF_LOG_TRACE, - "missing entry %s on %s", - impunge_local->loc.path, - priv->children[child_index]->name); - - afr_sh_entry_impunge_recreate (impunge_frame, this, - child_index); - return 0; - } - - if (op_ret == 0) { - gf_log (this->name, GF_LOG_TRACE, - "%s exists under %s", - impunge_local->loc.path, - priv->children[child_index]->name); + priv = this->private; + AFR_INIT_SH_FRAME_VALS (impunge_frame, impunge_local, impunge_sh, + frame, local, sh); + active_src = impunge_sh->active_source; - impunge_sh->parentbuf = *postparent; + if (op_ret < 0) + goto done; + if (impunge_sh->child_errno[active_src]) { + op_ret = -1; + op_errno = impunge_sh->child_errno[active_src]; + goto done; + } + + gfid_miss_count = afr_gfid_missing_count (this->name, + impunge_sh->child_success, + impunge_sh->buf, priv->child_count, + impunge_local->loc.path); + children_up_count = afr_up_children_count (priv->child_count, + impunge_local->child_up); + if ((gfid_miss_count == children_up_count) && + (children_up_count < priv->child_count)) { + op_ret = -1; + op_errno = ENODATA; + gf_log (this->name, GF_LOG_ERROR, "Not all children are up, " + "gfid should not be assigned in this state for %s", + impunge_local->loc.path); + goto done; + } + + if (gfid_miss_count) { + afr_update_gfid_from_iatts (gfid, impunge_sh->buf, + impunge_sh->child_success, + priv->child_count); + if (uuid_is_null (gfid)) + uuid_generate (gfid); + afr_sh_common_lookup (impunge_frame, this, &impunge_local->loc, + afr_sh_entry_common_lookup_done, gfid, + AFR_LOOKUP_FAIL_CONFLICTS | + AFR_LOOKUP_FAIL_MISSING_GFIDS); } else { - gf_log (this->name, GF_LOG_WARNING, - "looking up %s under %s failed (%s)", - impunge_local->loc.path, - priv->children[child_index]->name, - strerror (op_errno)); - } - - LOCK (&impunge_frame->lock); - { - call_count = --impunge_local->call_count; - } - UNLOCK (&impunge_frame->lock); - - if (call_count == 0) { - impunge_ret_child = impunge_sh->impunge_ret_child; - AFR_STACK_DESTROY (impunge_frame); - sh->impunge_done (frame, this, impunge_ret_child, op_ret, - op_errno); + recreate_count = afr_sh_recreate_count (impunge_sh, sh->sources, + priv->child_count); + if (!recreate_count) { + op_ret = 0; + op_errno = 0; + goto done; + } + afr_sh_entry_call_impunge_recreate (impunge_frame, this); } - - return 0; + return; +done: + afr_sh_entry_call_impunge_done (impunge_frame, this, + op_ret, op_errno); + return; } - int afr_sh_entry_impunge_entry (call_frame_t *frame, xlator_t *this, gf_dirent_t *entry) @@ -1840,12 +1755,10 @@ afr_sh_entry_impunge_entry (call_frame_t *frame, xlator_t *this, int ret = -1; call_frame_t *impunge_frame = NULL; afr_local_t *impunge_local = NULL; - afr_self_heal_t *impunge_sh = NULL; int active_src = 0; - int i = 0; - int call_count = 0; int op_errno = 0; int op_ret = -1; + mode_t entry_mode = 0; priv = this->private; local = frame->local; @@ -1870,70 +1783,34 @@ afr_sh_entry_impunge_entry (call_frame_t *frame, xlator_t *this, "inspecting existance of %s under %s", entry->d_name, local->loc.path); - impunge_frame = copy_frame (frame); - if (!impunge_frame) { - gf_log (this->name, GF_LOG_ERROR, - "Out of memory."); - op_errno = ENOMEM; + entry_mode = st_mode_from_ia (entry->d_stat.ia_prot, + entry->d_stat.ia_type); + ret = afr_impunge_frame_create (frame, this, active_src, active_src, + entry_mode, &impunge_frame); + if (ret) { + op_errno = -ret; goto out; } - ALLOC_OR_GOTO (impunge_local, afr_local_t, out); - - impunge_frame->local = impunge_local; - impunge_sh = &impunge_local->self_heal; - impunge_sh->sh_frame = frame; - impunge_sh->active_source = active_src; - impunge_sh->impunge_ret_child = active_src; - - impunge_sh->impunging_entry_mode = - st_mode_from_ia (entry->d_stat.ia_prot, entry->d_stat.ia_type); - - ret = build_child_loc (this, &impunge_local->loc, &local->loc, entry->d_name); + impunge_local = impunge_frame->local; + ret = afr_build_child_loc (this, &impunge_local->loc, &local->loc, + entry->d_name); if (ret != 0) { op_errno = ENOMEM; goto out; } - for (i = 0; i < priv->child_count; i++) { - if (i == active_src) - continue; - if (local->child_up[i] == 0) - continue; - if (sh->sources[i] == 1) - continue; - call_count++; - } + afr_sh_common_lookup (impunge_frame, this, &impunge_local->loc, + afr_sh_entry_common_lookup_done, NULL, + AFR_LOOKUP_FAIL_CONFLICTS); - impunge_local->call_count = call_count; - - for (i = 0; i < priv->child_count; i++) { - if (i == active_src) - continue; - if (local->child_up[i] == 0) - continue; - if (sh->sources[i] == 1) - continue; - - gf_log (this->name, GF_LOG_TRACE, - "looking up %s on %s", impunge_local->loc.path, - priv->children[i]->name); - - STACK_WIND_COOKIE (impunge_frame, - afr_sh_entry_impunge_entry_cbk, - (void *) (long) i, - priv->children[i], - priv->children[i]->fops->lookup, - &impunge_local->loc, 0); - - if (!--call_count) - break; - } - - ret = 0; + op_ret = 0; out: - if (ret == -1) + if (ret) { + if (impunge_frame) + AFR_STACK_DESTROY (impunge_frame); sh->impunge_done (frame, this, active_src, op_ret, op_errno); + } return 0; } @@ -2194,7 +2071,6 @@ afr_sh_entry_sync_prepare (call_frame_t *frame, xlator_t *this) priv = this->private; source = sh->source; - for (i = 0; i < priv->child_count; i++) { if (sh->sources[i] == 0 && local->child_up[i] == 1) { active_sinks++; @@ -2204,6 +2080,7 @@ afr_sh_entry_sync_prepare (call_frame_t *frame, xlator_t *this) if (source != -1) sh->success[source] = 1; + sh->active_sinks = active_sinks; if (active_sinks == 0) { gf_log (this->name, GF_LOG_TRACE, "no active sinks for self-heal on dir %s", @@ -2218,7 +2095,6 @@ afr_sh_entry_sync_prepare (call_frame_t *frame, xlator_t *this) afr_sh_entry_finish (frame, this); return 0; } - sh->active_sinks = active_sinks; if (source != -1) gf_log (this->name, GF_LOG_DEBUG, @@ -2238,8 +2114,9 @@ afr_sh_entry_sync_prepare (call_frame_t *frame, xlator_t *this) } -int -afr_sh_entry_fix (call_frame_t *frame, xlator_t *this) +void +afr_sh_entry_fix (call_frame_t *frame, xlator_t *this, + int32_t op_ret, int32_t op_errno) { afr_local_t *local = NULL; afr_self_heal_t *sh = NULL; @@ -2252,6 +2129,13 @@ afr_sh_entry_fix (call_frame_t *frame, xlator_t *this) sh = &local->self_heal; priv = this->private; + if (op_ret < 0) { + sh->op_failed = 1; + afr_sh_set_error (sh, op_errno); + afr_sh_entry_finish (frame, this); + goto out; + } + if (sh->forced_merge) { sh->source = -1; goto heal; @@ -2273,54 +2157,18 @@ afr_sh_entry_fix (call_frame_t *frame, xlator_t *this) local->loc.path); afr_sh_entry_finish (frame, this); - return 0; + return; } source = afr_sh_select_source (sh->sources, priv->child_count); sh->source = source; + heal: afr_sh_entry_sync_prepare (frame, this); - - return 0; -} - - - -int -afr_sh_entry_lookup_cbk (call_frame_t *frame, void *cookie, - xlator_t *this, int32_t op_ret, int32_t op_errno, - inode_t *inode, struct iatt *buf, dict_t *xattr, - struct iatt *postparent) -{ - afr_local_t *local = NULL; - afr_self_heal_t *sh = NULL; - - int call_count = -1; - int child_index = (long) cookie; - - local = frame->local; - sh = &local->self_heal; - - LOCK (&frame->lock); - { - if (op_ret != -1) { - sh->xattr[child_index] = dict_ref (xattr); - sh->buf[child_index] = *buf; - sh->child_success[sh->success_count] = child_index; - sh->success_count++; - } - } - UNLOCK (&frame->lock); - - call_count = afr_frame_return (frame); - - if (call_count == 0) { - afr_sh_entry_fix (frame, this); - } - - return 0; +out: + return; } int @@ -2344,7 +2192,9 @@ afr_sh_post_nonblocking_entry_cbk (call_frame_t *frame, xlator_t *this) gf_log (this->name, GF_LOG_DEBUG, "Non Blocking entrylks done " "for %s. Proceeding to FOP", local->loc.path); afr_sh_common_lookup (frame, this, &local->loc, - afr_sh_entry_lookup_cbk, _gf_false); + afr_sh_entry_fix, NULL, + AFR_LOOKUP_FAIL_CONFLICTS | + AFR_LOOKUP_FAIL_MISSING_GFIDS); } return 0; -- cgit