summaryrefslogtreecommitdiffstats
path: root/xlators/cluster/afr/src/afr-common.c
diff options
context:
space:
mode:
Diffstat (limited to 'xlators/cluster/afr/src/afr-common.c')
-rw-r--r--xlators/cluster/afr/src/afr-common.c86
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;