summaryrefslogtreecommitdiffstats
path: root/xlators/cluster/ec/src/ec-heal.c
diff options
context:
space:
mode:
Diffstat (limited to 'xlators/cluster/ec/src/ec-heal.c')
-rw-r--r--xlators/cluster/ec/src/ec-heal.c40
1 files changed, 33 insertions, 7 deletions
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)