From 8fa36bc7a11968086e31ac32b9a24de07dd50d15 Mon Sep 17 00:00:00 2001 From: Pranith Kumar K Date: Mon, 2 Mar 2015 08:09:41 +0530 Subject: cluster/ec: Allow heal on name less loc loc->parent may not always be populated. Even in those cases, self-heal should happen if it can be completed using nameless loc. Change-Id: I8871fc811bec8b881ae7fb09dcd202c6693b9877 BUG: 1177601 Signed-off-by: Pranith Kumar K Reviewed-on: http://review.gluster.org/9717 Reviewed-by: Xavier Hernandez Tested-by: Gluster Build System --- xlators/cluster/ec/src/ec-data.h | 1 + xlators/cluster/ec/src/ec-heal.c | 40 ++++++++++++++++++++++++++++++------- xlators/cluster/ec/src/ec-helpers.c | 12 +++++------ 3 files changed, 39 insertions(+), 14 deletions(-) (limited to 'xlators') diff --git a/xlators/cluster/ec/src/ec-data.h b/xlators/cluster/ec/src/ec-data.h index b17f197837b..ac59a6b2e14 100644 --- a/xlators/cluster/ec/src/ec-data.h +++ b/xlators/cluster/ec/src/ec-data.h @@ -271,6 +271,7 @@ struct _ec_heal fd_t *fd; int32_t partial; int32_t done; + gf_boolean_t nameheal; uintptr_t available; uintptr_t good; uintptr_t bad; diff --git a/xlators/cluster/ec/src/ec-heal.c b/xlators/cluster/ec/src/ec-heal.c index a121bb43e5c..6b513df8fe7 100644 --- a/xlators/cluster/ec/src/ec-heal.c +++ b/xlators/cluster/ec/src/ec-heal.c @@ -489,7 +489,8 @@ int32_t ec_heal_unlink_cbk(call_frame_t * frame, void * cookie, return 0; } -int32_t ec_heal_init(ec_fop_data_t * fop) +int32_t +ec_heal_init (ec_fop_data_t * fop) { ec_t * ec = fop->xl->private; struct iobuf_pool * pool; @@ -518,7 +519,6 @@ int32_t ec_heal_init(ec_fop_data_t * fop) if (ec_loc_from_loc(fop->xl, &heal->loc, &fop->loc[0]) != 0) { error = ENOMEM; - goto out; } @@ -993,13 +993,25 @@ void ec_heal_attr(ec_heal_t * heal) } } -void ec_heal_open(ec_heal_t * heal) +void +ec_heal_open (ec_heal_t * heal) { heal->bad = ec_heal_needs_data_rebuild(heal); if (heal->bad == 0) { return; } + if (!heal->fd) { + /* name-less loc heal */ + heal->fd = fd_create (heal->loc.inode, + heal->fop->frame->root->pid); + } + + if (!heal->fd) { + ec_fop_set_error(heal->fop, ENOMEM); + return; + } + if (ec_heal_open_others(heal)) { ec_open(heal->fop->frame, heal->xl, heal->good, EC_MINIMUM_MIN, @@ -1261,7 +1273,8 @@ void ec_wind_heal(ec_t * ec, ec_fop_data_t * fop, int32_t idx) ec_complete(fop); } -int32_t ec_manager_heal(ec_fop_data_t * fop, int32_t state) +int32_t +ec_manager_heal (ec_fop_data_t * fop, int32_t state) { ec_cbk_data_t * cbk; ec_heal_t *heal = fop->heal; @@ -1277,7 +1290,16 @@ int32_t ec_manager_heal(ec_fop_data_t * fop, int32_t state) return EC_STATE_REPORT; } - return EC_STATE_DISPATCH; + heal = fop->heal; + /* root loc doesn't have pargfid/parent */ + if (loc_is_root (&heal->loc) || + !uuid_is_null(heal->loc.pargfid) || heal->loc.parent) { + heal->nameheal = _gf_true; + return EC_STATE_DISPATCH; + } else { + /* No need to perform 'name' heal.*/ + return EC_STATE_HEAL_PRE_INODELK_LOCK; + } case EC_STATE_DISPATCH: if (heal->done) { @@ -1306,7 +1328,10 @@ int32_t ec_manager_heal(ec_fop_data_t * fop, int32_t state) return EC_STATE_HEAL_PRE_INODELK_LOCK; case EC_STATE_HEAL_PRE_INODELK_LOCK: - // Only heal data/metadata if enough information is supplied. + if (heal->done) + return EC_STATE_HEAL_DISPATCH; + + /* Only heal data/metadata if enough information is supplied. */ if (uuid_is_null(heal->loc.gfid)) { ec_heal_entrylk(heal, ENTRYLK_UNLOCK); @@ -1364,7 +1389,8 @@ int32_t ec_manager_heal(ec_fop_data_t * fop, int32_t state) case -EC_STATE_HEAL_PRE_INODE_LOOKUP: case -EC_STATE_HEAL_UNLOCK_ENTRY: case EC_STATE_HEAL_UNLOCK_ENTRY: - ec_heal_entrylk(heal, ENTRYLK_UNLOCK); + if (heal->nameheal) + ec_heal_entrylk(heal, ENTRYLK_UNLOCK); heal->bad = ec_heal_needs_data_rebuild(heal); if (heal->bad != 0) diff --git a/xlators/cluster/ec/src/ec-helpers.c b/xlators/cluster/ec/src/ec-helpers.c index c580166ef00..783e3d475ce 100644 --- a/xlators/cluster/ec/src/ec-helpers.c +++ b/xlators/cluster/ec/src/ec-helpers.c @@ -335,7 +335,7 @@ int32_t ec_loc_setup_inode(xlator_t *xl, loc_t *loc) } else if (loc->parent != NULL) { if (!uuid_is_null(loc->gfid)) { loc->inode = inode_find(loc->parent->table, loc->gfid); - } else if (loc->path != NULL) { + } else if (loc->path && strchr (loc->path, '/')) { loc->inode = inode_resolve(loc->parent->table, (char *)loc->path); } } @@ -358,7 +358,7 @@ int32_t ec_loc_setup_parent(xlator_t *xl, loc_t *loc) } else if (loc->inode != NULL) { if (!uuid_is_null(loc->pargfid)) { loc->parent = inode_find(loc->inode->table, loc->pargfid); - } else if (loc->path != NULL) { + } else if (loc->path && strchr (loc->path, '/')) { path = gf_strdup(loc->path); if (path == NULL) { gf_log(xl->name, GF_LOG_ERROR, "Unable to duplicate path '%s'", @@ -387,10 +387,8 @@ int32_t ec_loc_setup_path(xlator_t *xl, loc_t *loc) if (loc->path != NULL) { name = strrchr(loc->path, '/'); if (name == NULL) { - gf_log(xl->name, GF_LOG_ERROR, "Invalid path '%s' in loc", - loc->path); - - goto out; + ret = 0; /**/ + goto out; } if (name == loc->path) { if (name[1] == 0) { @@ -436,7 +434,7 @@ int32_t ec_loc_parent(xlator_t *xl, loc_t *loc, loc_t *parent) if (!uuid_is_null(loc->pargfid)) { uuid_copy(parent->gfid, loc->pargfid); } - if (loc->path != NULL) { + if (loc->path && strchr (loc->path, '/')) { str = gf_strdup(loc->path); if (str == NULL) { gf_log(xl->name, GF_LOG_ERROR, "Unable to duplicate path '%s'", -- cgit