diff options
Diffstat (limited to 'xlators/cluster/ec/src/ec-helpers.c')
-rw-r--r-- | xlators/cluster/ec/src/ec-helpers.c | 271 |
1 files changed, 148 insertions, 123 deletions
diff --git a/xlators/cluster/ec/src/ec-helpers.c b/xlators/cluster/ec/src/ec-helpers.c index 6dae0232a01..3c3e2302e53 100644 --- a/xlators/cluster/ec/src/ec-helpers.c +++ b/xlators/cluster/ec/src/ec-helpers.c @@ -324,218 +324,242 @@ int32_t ec_loc_gfid_check(xlator_t * xl, uuid_t dst, uuid_t src) return 1; } -int32_t ec_loc_parent(xlator_t *xl, loc_t *loc, loc_t *parent) +int32_t ec_loc_setup_inode(xlator_t *xl, loc_t *loc) { - char * str = NULL; - int32_t error = 0; - - memset(parent, 0, sizeof(loc_t)); + int32_t ret = -1; - if (loc->inode == NULL) - { - gf_log(xl->name, GF_LOG_ERROR, "Invalid loc"); - - error = EINVAL; - - goto out; + if (loc->inode != NULL) { + if (!ec_loc_gfid_check(xl, loc->gfid, loc->inode->gfid)) { + goto out; + } + } 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) { + loc->inode = inode_resolve(loc->parent->table, (char *)loc->path); + } } - if (__is_root_gfid(loc->inode->gfid) || __is_root_gfid(loc->gfid) || - ((loc->path != NULL) && (strcmp(loc->path, "/") == 0))) - { - parent->path = gf_strdup("/"); - if (parent->path == NULL) { - gf_log(xl->name, GF_LOG_ERROR, "Unable to duplicate path '/'"); + ret = 0; - error = ENOMEM; +out: + return ret; +} +int32_t ec_loc_setup_parent(xlator_t *xl, loc_t *loc) +{ + char *path, *parent; + int32_t ret = -1; + + if (loc->parent != NULL) { + if (!ec_loc_gfid_check(xl, loc->pargfid, loc->parent->gfid)) { goto out; } - - parent->gfid[15] = 1; - parent->inode = inode_find(loc->inode->table, parent->gfid); - - return 0; + } 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) { + path = gf_strdup(loc->path); + if (path == NULL) { + gf_log(xl->name, GF_LOG_ERROR, "Unable to duplicate path '%s'", + loc->path); + + goto out; + } + parent = dirname(path); + loc->parent = inode_resolve(loc->inode->table, parent); + GF_FREE(path); + } } - if (loc->path != NULL) { - str = gf_strdup(loc->path); - if (str == NULL) - { - gf_log(xl->name, GF_LOG_ERROR, "Unable to duplicate path " - "'%s'", loc->path); + ret = 0; - error = ENOMEM; +out: + return ret; +} - goto out; - } - parent->path = gf_strdup(dirname(str)); - if (parent->path == NULL) - { - gf_log(xl->name, GF_LOG_ERROR, "Unable to get dirname of " - "'%s'", loc->path); +int32_t ec_loc_setup_path(xlator_t *xl, loc_t *loc) +{ + uuid_t root = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}; + char *name; + int32_t ret = -1; - error = ENOMEM; + 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; } - parent->name = strrchr(parent->path, '/'); - if (parent->name == NULL) - { - gf_log(xl->name, GF_LOG_ERROR, "Invalid path name (%s)", - parent->path); + if (name == loc->path) { + if (name[1] == 0) { + if (!ec_loc_gfid_check(xl, loc->gfid, root)) { + goto out; + } + } else { + if (!ec_loc_gfid_check(xl, loc->pargfid, root)) { + goto out; + } + } + } + name++; - error = EINVAL; + if (loc->name != NULL) { + if (strcmp(loc->name, name) != 0) { + gf_log(xl->name, GF_LOG_ERROR, "Invalid name '%s' in loc", + loc->name); - goto out; + goto out; + } + } else { + loc->name = name; } - parent->name++; } + + ret = 0; + +out: + return ret; +} + +int32_t ec_loc_parent(xlator_t *xl, loc_t *loc, loc_t *parent) +{ + char *str = NULL; + int32_t ret = -1; + + memset(parent, 0, sizeof(loc_t)); + if (loc->parent != NULL) { parent->inode = inode_ref(loc->parent); - uuid_copy(parent->gfid, loc->parent->gfid); } - if (!uuid_is_null(loc->pargfid) && uuid_is_null(parent->gfid)) { + if (!uuid_is_null(loc->pargfid)) { uuid_copy(parent->gfid, loc->pargfid); } - - if ((parent->inode == NULL) && (parent->path != NULL)) - { - if (strcmp(parent->path, "/") == 0) { - parent->inode = inode_ref(loc->inode->table->root); + if (loc->path != NULL) { + str = gf_strdup(loc->path); + if (str == NULL) { + gf_log(xl->name, GF_LOG_ERROR, "Unable to duplicate path '%s'", + loc->path); goto out; } - parent->inode = inode_resolve(loc->inode->table, (char *)parent->path); - if (parent->inode != NULL) { - goto out; - } - - gf_log(xl->name, GF_LOG_WARNING, "Unable to resolve parent inode"); - } - - if ((parent->inode == NULL) && !uuid_is_null(parent->gfid)) { - if (__is_root_gfid(parent->gfid)) { - parent->inode = inode_ref(loc->inode->table->root); + parent->path = gf_strdup(dirname(str)); + if (parent->path == NULL) { + gf_log(xl->name, GF_LOG_ERROR, "Unable to duplicate path '%s'", + dirname(str)); goto out; } - parent->inode = inode_find(loc->inode->table, parent->gfid); - if (parent->inode != NULL) { - goto out; - } + } - gf_log(xl->name, GF_LOG_WARNING, "Unable to find parent inode"); + if ((ec_loc_setup_path(xl, parent) != 0) || + (ec_loc_setup_inode(xl, parent) != 0) || + (ec_loc_setup_parent(xl, parent) != 0)) { + goto out; } if ((parent->inode == NULL) && (parent->path == NULL) && uuid_is_null(parent->gfid)) { gf_log(xl->name, GF_LOG_ERROR, "Parent inode missing for loc_t"); - error = EINVAL; - goto out; } + ret = 0; + out: GF_FREE(str); - if (error != 0) + if (ret != 0) { loc_wipe(parent); } - return error; + return ret; } -int32_t ec_loc_prepare(xlator_t * xl, loc_t * loc, inode_t * inode, - struct iatt * iatt) +int32_t ec_loc_update(xlator_t *xl, loc_t *loc, inode_t *inode, + struct iatt *iatt) { - if ((inode != NULL) && (loc->inode != inode)) - { - if (loc->inode != NULL) - { + int32_t ret = -1; + + if ((inode != NULL) && (loc->inode != inode)) { + if (loc->inode != NULL) { inode_unref(loc->inode); } loc->inode = inode_ref(inode); - uuid_copy(loc->gfid, inode->gfid); } - else if (loc->inode != NULL) - { - if (!ec_loc_gfid_check(xl, loc->gfid, loc->inode->gfid)) - { - return 0; - } - } - if (iatt != NULL) - { - if (!ec_loc_gfid_check(xl, loc->gfid, iatt->ia_gfid)) - { - return 0; + if (iatt != NULL) { + if (!ec_loc_gfid_check(xl, loc->gfid, iatt->ia_gfid)) { + goto out; } } - if (loc->parent != NULL) - { - if (!ec_loc_gfid_check(xl, loc->pargfid, loc->parent->gfid)) - { - return 0; - } - + if ((ec_loc_setup_path(xl, loc) != 0) || + (ec_loc_setup_inode(xl, loc) != 0) || + (ec_loc_setup_parent(xl, loc) != 0)) { + goto out; } - if (uuid_is_null(loc->gfid)) - { - gf_log(xl->name, GF_LOG_WARNING, "GFID not available for inode"); - } + ret = 0; - return 1; +out: + return ret; } int32_t ec_loc_from_fd(xlator_t * xl, loc_t * loc, fd_t * fd) { ec_fd_t * ctx; + int32_t ret = -1; memset(loc, 0, sizeof(*loc)); ctx = ec_fd_get(fd, xl); - if (ctx != NULL) - { - if (loc_copy(loc, &ctx->loc) != 0) - { - return 0; + if (ctx != NULL) { + if (loc_copy(loc, &ctx->loc) != 0) { + goto out; } } - if (ec_loc_prepare(xl, loc, fd->inode, NULL)) - { - return 1; + if (ec_loc_update(xl, loc, fd->inode, NULL) != 0) { + goto out; } - loc_wipe(loc); + ret = 0; - return 0; +out: + if (ret != 0) { + loc_wipe(loc); + } + + return ret; } int32_t ec_loc_from_loc(xlator_t * xl, loc_t * dst, loc_t * src) { + int32_t ret = -1; + memset(dst, 0, sizeof(*dst)); - if (loc_copy(dst, src) != 0) - { - return 0; + if (loc_copy(dst, src) != 0) { + goto out; } - if (ec_loc_prepare(xl, dst, NULL, NULL)) - { - return 1; + if (ec_loc_update(xl, dst, NULL, NULL) != 0) { + goto out; } - loc_wipe(dst); + ret = 0; - return 0; +out: + if (ret != 0) { + loc_wipe(dst); + } + + return ret; } void ec_owner_set(call_frame_t * frame, void * owner) @@ -560,6 +584,7 @@ ec_inode_t * __ec_inode_get(inode_t * inode, xlator_t * xl) if (ctx != NULL) { memset(ctx, 0, sizeof(*ctx)); + INIT_LIST_HEAD(&ctx->heal); value = (uint64_t)(uintptr_t)ctx; if (__inode_ctx_set(inode, xl, &value) != 0) |