diff options
| -rw-r--r-- | xlators/cluster/ec/src/ec-data.h | 1 | ||||
| -rw-r--r-- | xlators/cluster/ec/src/ec-heal.c | 40 | ||||
| -rw-r--r-- | xlators/cluster/ec/src/ec-helpers.c | 12 | 
3 files changed, 39 insertions, 14 deletions
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; /*<gfid:gfid-str>*/ +                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'",  | 
