diff options
author | Raghavendra G <raghavendra@gluster.com> | 2009-10-08 06:21:40 +0000 |
---|---|---|
committer | Anand V. Avati <avati@dev.gluster.com> | 2009-10-09 00:49:34 -0700 |
commit | aa8323817ebacf664b0e4c68996efa5847342bf8 (patch) | |
tree | 43e5fc4f67a4f9b913f9fcdf74095130cb3e3e0a /xlators/performance | |
parent | 5cb21335e3f12815d3e60b93d5edaea8d4ba26da (diff) |
performance/stat-prefetch: lookup oldpath and newpath in rename if they've not already been looked up.
Signed-off-by: Anand V. Avati <avati@dev.gluster.com>
BUG: 221 (stat prefetch implementation)
URL: http://bugs.gluster.com/cgi-bin/bugzilla3/show_bug.cgi?id=221
Diffstat (limited to 'xlators/performance')
-rw-r--r-- | xlators/performance/stat-prefetch/src/stat-prefetch.c | 201 | ||||
-rw-r--r-- | xlators/performance/stat-prefetch/src/stat-prefetch.h | 1 |
2 files changed, 185 insertions, 17 deletions
diff --git a/xlators/performance/stat-prefetch/src/stat-prefetch.c b/xlators/performance/stat-prefetch/src/stat-prefetch.c index c08fa2eec..baa6fa6db 100644 --- a/xlators/performance/stat-prefetch/src/stat-prefetch.c +++ b/xlators/performance/stat-prefetch/src/stat-prefetch.c @@ -2172,25 +2172,124 @@ unwind: int32_t +sp_rename_helper (call_frame_t *frame, xlator_t *this, loc_t *oldloc, + loc_t *newloc) +{ + uint64_t value = 0; + char need_unwind = 0; + char can_wind = 0; + int32_t ret = 0, op_errno = -1; + int32_t old_op_ret = -1, old_op_errno = -1; + int32_t new_op_ret = -1, new_op_errno = -1; + char old_inode_looked_up = 0, new_inode_looked_up = 0; + sp_inode_ctx_t *old_inode_ctx = NULL, *new_inode_ctx = NULL; + + ret = inode_ctx_get (oldloc->inode, this, &value); + if (ret == -1) { + gf_log (this->name, GF_LOG_DEBUG, "context not set in inode " + "(%p)", oldloc->inode); + op_errno = EINVAL; + goto unwind; + } + + old_inode_ctx = (sp_inode_ctx_t *)(long) value; + GF_VALIDATE_OR_GOTO_WITH_ERROR (this->name, old_inode_ctx, unwind, + op_errno, EINVAL); + + LOCK (&old_inode_ctx->lock); + { + old_inode_looked_up = old_inode_ctx->looked_up; + old_op_ret = old_inode_ctx->op_ret; + old_op_errno = old_inode_ctx->op_errno; + need_unwind = old_inode_ctx->need_unwind; + } + UNLOCK (&old_inode_ctx->lock); + + if (need_unwind) { + /* there was an error while queuing up lookup stub for newloc */ + goto unwind; + } + + if (newloc->inode != NULL) { + ret = inode_ctx_get (newloc->inode, this, &value); + if (ret == 0) { + new_inode_ctx = (sp_inode_ctx_t *)(long)value; + if (new_inode_ctx != NULL) { + LOCK (&new_inode_ctx->lock); + { + new_inode_looked_up = new_inode_ctx->looked_up; + new_op_ret = new_inode_ctx->op_ret; + new_op_errno = new_inode_ctx->op_errno; + } + UNLOCK (&new_inode_ctx->lock); + } + } + } + + if (new_inode_ctx == NULL) { + if (old_op_ret == -1) { + op_errno = old_op_errno; + goto unwind; + } else { + can_wind = 1; + } + } else { + if (new_inode_looked_up && old_inode_looked_up) { + if ((old_op_ret == -1) + || ((new_op_ret == -1) + && (new_op_errno != ENOENT))) { + if (old_op_ret == -1) { + op_errno = old_op_errno; + } else { + op_errno = new_op_errno; + } + + goto unwind; + } else { + can_wind = 1; + } + } + } + + if (can_wind) { + STACK_WIND (frame, sp_rename_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->rename, oldloc, newloc); + } + + return 0; + +unwind: + SP_STACK_UNWIND (frame, -1, op_errno, NULL, NULL, NULL, NULL, NULL); + return 0; +} + + +int32_t sp_rename (call_frame_t *frame, xlator_t *this, loc_t *oldloc,loc_t *newloc) { - sp_cache_t *cache = NULL; - int32_t ret = -1, op_errno = EINVAL; + char need_unwind = 1; + uint64_t value = 0; + call_stub_t *stub = NULL; + sp_cache_t *cache = NULL; + sp_inode_ctx_t *inode_ctx = NULL; + int32_t ret = -1, op_errno = -1; + char old_inode_can_wind = 0, new_inode_can_wind = 0; + char old_inode_need_lookup = 0, new_inode_need_lookup = 0; - GF_VALIDATE_OR_GOTO_WITH_ERROR (this->name, oldloc, unwind, op_errno, + GF_VALIDATE_OR_GOTO_WITH_ERROR (this->name, oldloc, out, op_errno, EINVAL); - GF_VALIDATE_OR_GOTO_WITH_ERROR (this->name, oldloc->path, unwind, + GF_VALIDATE_OR_GOTO_WITH_ERROR (this->name, oldloc->path, out, op_errno, EINVAL); - GF_VALIDATE_OR_GOTO_WITH_ERROR (this->name, oldloc->name, unwind, + GF_VALIDATE_OR_GOTO_WITH_ERROR (this->name, oldloc->name, out, op_errno, EINVAL); - GF_VALIDATE_OR_GOTO_WITH_ERROR (this->name, oldloc->parent, unwind, + GF_VALIDATE_OR_GOTO_WITH_ERROR (this->name, oldloc->parent, out, op_errno, EINVAL); - GF_VALIDATE_OR_GOTO_WITH_ERROR (this->name, oldloc->inode, unwind, + GF_VALIDATE_OR_GOTO_WITH_ERROR (this->name, oldloc->inode, out, op_errno, EINVAL); - GF_VALIDATE_OR_GOTO_WITH_ERROR (this->name, newloc, unwind, op_errno, + GF_VALIDATE_OR_GOTO_WITH_ERROR (this->name, newloc, out, op_errno, EINVAL); - GF_VALIDATE_OR_GOTO_WITH_ERROR (this->name, newloc->path, unwind, + GF_VALIDATE_OR_GOTO_WITH_ERROR (this->name, newloc->path, out, op_errno, EINVAL); cache = sp_get_cache_inode (this, oldloc->parent, frame->root->pid); @@ -2206,26 +2305,94 @@ sp_rename (call_frame_t *frame, xlator_t *this, loc_t *oldloc,loc_t *newloc) ret = sp_cache_remove_parent_entry (frame, this, (char *)oldloc->path); if (ret == -1) { gf_log (this->name, GF_LOG_ERROR, "out of memory"); - goto unwind; + goto out; } ret = sp_cache_remove_parent_entry (frame, this, (char *)newloc->path); if (ret == -1) { gf_log (this->name, GF_LOG_ERROR, "out of memory"); - goto unwind; + goto out; } if (S_ISDIR (oldloc->inode->st_mode)) { sp_remove_caches_from_all_fds_opened (this, oldloc->inode); } - STACK_WIND (frame, sp_rename_cbk, FIRST_CHILD(this), - FIRST_CHILD(this)->fops->rename, oldloc, newloc); - return 0; + stub = fop_rename_stub (frame, sp_rename_helper, oldloc, newloc); + if (stub == NULL) { + op_errno = ENOMEM; + gf_log (this->name, GF_LOG_ERROR, "out of memory"); + goto out; + } -unwind: - SP_STACK_UNWIND (frame, -1, op_errno, NULL); - return 0; + ret = sp_process_inode_ctx (frame, this, oldloc, stub, &need_unwind, + &old_inode_need_lookup, &old_inode_can_wind, + &op_errno); + if (ret == -1) { + goto out; + } + + if (newloc->inode != NULL) { + stub = fop_rename_stub (frame, sp_rename_helper, oldloc, + newloc); + if (stub == NULL) { + op_errno = ENOMEM; + gf_log (this->name, GF_LOG_ERROR, "out of memory"); + goto out; + } + + ret = sp_process_inode_ctx (frame, this, newloc, stub, + &need_unwind, + &new_inode_need_lookup, + &new_inode_can_wind, &op_errno); + if (ret == -1) { + ret = inode_ctx_get (oldloc->inode, this, &value); + if (ret == -1) { + goto out; + } + + inode_ctx = (sp_inode_ctx_t *)(long)value; + if (inode_ctx == NULL) { + goto out; + } + + LOCK (&inode_ctx->lock); + { + if (!inode_ctx->looked_up) { + /* unwind in sp_rename_helper */ + need_unwind = 0; + inode_ctx->need_unwind = 1; + } + } + UNLOCK (&inode_ctx->lock); + } + + } else { + new_inode_can_wind = 1; + } + +out: + if (need_unwind) { + SP_STACK_UNWIND (frame, -1, op_errno, NULL, NULL, NULL, NULL, + NULL); + } else if (old_inode_need_lookup || new_inode_need_lookup) { + if (old_inode_need_lookup) { + STACK_WIND (frame, sp_lookup_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->lookup, oldloc, + NULL); + } + + if (new_inode_need_lookup) { + STACK_WIND (frame, sp_lookup_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->lookup, newloc, + NULL); + } + } else if (old_inode_can_wind && new_inode_can_wind) { + STACK_WIND (frame, sp_rename_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->rename, oldloc, newloc); + } + + return 0; } diff --git a/xlators/performance/stat-prefetch/src/stat-prefetch.h b/xlators/performance/stat-prefetch/src/stat-prefetch.h index 81f504a7f..0245703fa 100644 --- a/xlators/performance/stat-prefetch/src/stat-prefetch.h +++ b/xlators/performance/stat-prefetch/src/stat-prefetch.h @@ -69,6 +69,7 @@ typedef struct sp_local sp_local_t; struct sp_inode_ctx { char looked_up; char lookup_in_progress; + char need_unwind; int32_t op_ret; int32_t op_errno; struct stat stbuf; |