summaryrefslogtreecommitdiffstats
path: root/xlators/cluster/dht/src/dht-common.c
diff options
context:
space:
mode:
Diffstat (limited to 'xlators/cluster/dht/src/dht-common.c')
-rw-r--r--xlators/cluster/dht/src/dht-common.c76
1 files changed, 69 insertions, 7 deletions
diff --git a/xlators/cluster/dht/src/dht-common.c b/xlators/cluster/dht/src/dht-common.c
index 79ba77bf16c..6af55d5d42e 100644
--- a/xlators/cluster/dht/src/dht-common.c
+++ b/xlators/cluster/dht/src/dht-common.c
@@ -212,17 +212,22 @@ out:
return ret;
}
-
int
dht_discover_complete (xlator_t *this, call_frame_t *discover_frame)
{
- dht_local_t *local = NULL;
- call_frame_t *main_frame = NULL;
- int op_errno = 0;
- int ret = -1;
- dht_layout_t *layout = NULL;
- dht_conf_t *conf = NULL;
+ dht_local_t *local = NULL;
+ dht_local_t *heal_local = NULL;
+ call_frame_t *main_frame = NULL;
+ call_frame_t *heal_frame = NULL;
+ int op_errno = 0;
+ int ret = -1;
+ dht_layout_t *layout = NULL;
+ dht_conf_t *conf = NULL;
uint32_t vol_commit_hash = 0;
+ xlator_t *source = NULL;
+ int heal_path = 0;
+ int i = 0;
+ loc_t loc = {0 };
local = discover_frame->local;
layout = local->layout;
@@ -301,6 +306,63 @@ dht_discover_complete (xlator_t *this, call_frame_t *discover_frame)
}
}
+ if (IA_ISDIR (local->stbuf.ia_type)) {
+ for (i = 0; i < layout->cnt; i++) {
+ if (!source && !layout->list[i].err)
+ source = layout->list[i].xlator;
+ if (layout->list[i].err == ENOENT ||
+ layout->list[i].err == ESTALE) {
+ heal_path = 1;
+ }
+ if (source && heal_path)
+ break;
+ }
+ }
+ if (source && heal_path) {
+ gf_uuid_copy (loc.gfid, local->gfid);
+ if (gf_uuid_is_null (loc.gfid)) {
+ goto done;
+ }
+
+ if (local->inode)
+ loc.inode = inode_ref (local->inode);
+ else
+ goto done;
+
+ heal_frame = create_frame (this, this->ctx->pool);
+ if (heal_frame) {
+ heal_local = dht_local_init (heal_frame, &loc,
+ NULL, 0);
+ if (!heal_local)
+ goto cleanup;
+
+ gf_uuid_copy (heal_local->gfid, local->gfid);
+ heal_frame->cookie = source;
+ heal_local->xattr = dict_ref (local->xattr);
+ heal_local->stbuf = local->stbuf;
+ heal_local->postparent = local->postparent;
+ heal_local->inode = inode_ref (loc.inode);
+ heal_local->main_frame = main_frame;
+ FRAME_SU_DO (heal_frame, dht_local_t);
+ ret = synctask_new (this->ctx->env,
+ dht_heal_full_path,
+ dht_heal_full_path_done,
+ heal_frame, heal_frame);
+ if (!ret) {
+ loc_wipe (&loc);
+ return 0;
+ }
+ /*
+ * Failed to spawn the synctask. Returning
+ * with out doing heal.
+ */
+cleanup:
+ loc_wipe (&loc);
+ DHT_STACK_DESTROY (heal_frame);
+ }
+
+ }
+done:
DHT_STACK_UNWIND (lookup, main_frame, local->op_ret, local->op_errno,
local->inode, &local->stbuf, local->xattr,
&local->postparent);