diff options
Diffstat (limited to 'xlators/cluster/afr/src/afr-common.c')
-rw-r--r-- | xlators/cluster/afr/src/afr-common.c | 86 |
1 files changed, 55 insertions, 31 deletions
diff --git a/xlators/cluster/afr/src/afr-common.c b/xlators/cluster/afr/src/afr-common.c index cba18b2ff8f..a255f9d14ad 100644 --- a/xlators/cluster/afr/src/afr-common.c +++ b/xlators/cluster/afr/src/afr-common.c @@ -45,6 +45,12 @@ #include "afr-messages.h" #include "compound-fop-utils.h" +typedef struct afr_lookup_heal_data { + call_frame_t *fop_frame; + void (*heal_done_cbk)(call_frame_t *, xlator_t *); + gf_boolean_t can_free; +} afr_lookup_heal_data_t; + int32_t afr_quorum_errno (afr_private_t *priv) { @@ -1031,14 +1037,14 @@ afr_replies_interpret (call_frame_t *frame, xlator_t *this, inode_t *inode, return ret; } - - int afr_refresh_selfheal_done (int ret, call_frame_t *heal, void *opaque) { - if (heal) - STACK_DESTROY (heal->root); - return 0; + afr_lookup_heal_data_t *data = opaque; + + if (data && data->can_free) + GF_FREE (data); + return 0; } int @@ -2393,7 +2399,8 @@ afr_attempt_local_discovery (xlator_t *this, int32_t child_index) int afr_lookup_sh_metadata_wrap (void *opaque) { - call_frame_t *frame = opaque; + afr_lookup_heal_data_t *data = opaque; + call_frame_t *frame = data->fop_frame; afr_local_t *local = NULL; xlator_t *this = NULL; inode_t *inode = NULL; @@ -2431,13 +2438,23 @@ afr_lookup_sh_metadata_wrap (void *opaque) "Unable to set link-count in dict "); } - inode = afr_selfheal_unlocked_lookup_on (frame, local->loc.parent, - local->loc.name, local->replies, - local->child_up, dict); + if (!local->loc.parent && gf_uuid_is_null (local->loc.pargfid)) { + ret = afr_selfheal_unlocked_discover_on (frame, local->inode, + local->loc.gfid, + local->replies, + local->child_up); + } else { + inode = afr_selfheal_unlocked_lookup_on (frame, + local->loc.parent, + local->loc.name, + local->replies, + local->child_up, dict); + } if (inode) inode_unref (inode); out: - afr_lookup_done (frame, this); + data->can_free = _gf_true; + data->heal_done_cbk (frame, this); if (dict) dict_unref (dict); @@ -2498,25 +2515,23 @@ afr_can_start_metadata_self_heal(call_frame_t *frame, xlator_t *this) } int -afr_lookup_metadata_heal_check (call_frame_t *frame, xlator_t *this) +afr_lookup_metadata_heal_check (afr_lookup_heal_data_t *data, xlator_t *this) { - call_frame_t *heal = NULL; - int ret = 0; + call_frame_t *frame = data->fop_frame; + int ret = -1; if (!afr_can_start_metadata_self_heal (frame, this)) goto out; - heal = copy_frame (frame); - if (heal) - heal->root->pid = GF_CLIENT_PID_SELF_HEALD; ret = synctask_new (this->ctx->env, afr_lookup_sh_metadata_wrap, - afr_refresh_selfheal_done, heal, frame); + afr_refresh_selfheal_done, NULL, data); if(ret) goto out; return ret; out: - afr_lookup_done (frame, this); + data->can_free = _gf_true; + data->heal_done_cbk (frame, this); return ret; } @@ -2524,7 +2539,8 @@ int afr_lookup_selfheal_wrap (void *opaque) { int ret = 0; - call_frame_t *frame = opaque; + afr_lookup_heal_data_t *data = opaque; + call_frame_t *frame = data->fop_frame; afr_local_t *local = NULL; xlator_t *this = NULL; inode_t *inode = NULL; @@ -2547,10 +2563,11 @@ afr_lookup_selfheal_wrap (void *opaque) if (inode) inode_unref (inode); - afr_lookup_metadata_heal_check(frame, this); + afr_lookup_metadata_heal_check (data, this); return 0; unwind: + data->can_free = _gf_true; AFR_STACK_UNWIND (lookup, frame, -1, EIO, NULL, NULL, NULL, NULL); return 0; } @@ -2560,15 +2577,19 @@ afr_lookup_entry_heal (call_frame_t *frame, xlator_t *this) { afr_local_t *local = NULL; afr_private_t *priv = NULL; - call_frame_t *heal = NULL; int i = 0, first = -1; gf_boolean_t need_heal = _gf_false; struct afr_reply *replies = NULL; + afr_lookup_heal_data_t *data = NULL; int ret = 0; local = frame->local; replies = local->replies; priv = this->private; + data = GF_CALLOC (1, sizeof (afr_lookup_heal_data_t), + gf_afr_mt_afr_lookup_heal_data_t); + data->fop_frame = frame; + data->heal_done_cbk = afr_lookup_done; for (i = 0; i < priv->child_count; i++) { if (!replies[i].valid) @@ -2596,18 +2617,16 @@ afr_lookup_entry_heal (call_frame_t *frame, xlator_t *this) } if (need_heal) { - - heal = copy_frame (frame); - if (heal) - heal->root->pid = GF_CLIENT_PID_SELF_HEALD; ret = synctask_new (this->ctx->env, afr_lookup_selfheal_wrap, - afr_refresh_selfheal_done, heal, frame); + afr_refresh_selfheal_done, NULL, data); if (ret) goto metadata_heal; return ret; } metadata_heal: - ret = afr_lookup_metadata_heal_check (frame, this); + ret = afr_lookup_metadata_heal_check (data, this); + if (ret && data->can_free) + GF_FREE (data); return ret; } @@ -2661,8 +2680,6 @@ afr_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this, return 0; } - - static void afr_discover_done (call_frame_t *frame, xlator_t *this) { @@ -2738,6 +2755,7 @@ afr_discover_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int child_index = -1; GF_UNUSED int ret = 0; int8_t need_heal = 1; + afr_lookup_heal_data_t *data = NULL; child_index = (long) cookie; @@ -2765,8 +2783,14 @@ afr_discover_cbk (call_frame_t *frame, void *cookie, xlator_t *this, call_count = afr_frame_return (frame); if (call_count == 0) { - afr_set_need_heal (this, local); - afr_discover_done (frame, this); + data = GF_CALLOC (1, sizeof (afr_lookup_heal_data_t), + gf_afr_mt_afr_lookup_heal_data_t); + data->fop_frame = frame; + data->heal_done_cbk = afr_discover_done; + afr_set_need_heal (this, local); + ret = afr_lookup_metadata_heal_check (data, this); + if (ret && data->can_free) + GF_FREE (data); } return 0; |