summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRaghavendra G <raghavendra@gluster.com>2009-12-04 11:32:53 +0000
committerAnand V. Avati <avati@dev.gluster.com>2009-12-06 09:28:31 -0800
commit58768ac88263ad73d593a319f50c2089719f76bd (patch)
tree94b750a2ee7bc0df3cb94455f6a0ef9593232002
parent496ff502e2b00b37051c1319885ff495475196fc (diff)
performance/stat-prefetch: dont check for inode context in fops like create, mkdir.
- context will not be set as a fresh inode is passed in each of these calls. instead create a new context. Signed-off-by: Raghavendra G <raghavendra@gluster.com> Signed-off-by: Anand V. Avati <avati@dev.gluster.com> BUG: 257 (Backport stat-prefetch to 2.0) URL: http://bugs.gluster.com/cgi-bin/bugzilla3/show_bug.cgi?id=257
-rw-r--r--xlators/performance/stat-prefetch/src/stat-prefetch.c610
1 files changed, 293 insertions, 317 deletions
diff --git a/xlators/performance/stat-prefetch/src/stat-prefetch.c b/xlators/performance/stat-prefetch/src/stat-prefetch.c
index 6ac77dd..78e4cd5 100644
--- a/xlators/performance/stat-prefetch/src/stat-prefetch.c
+++ b/xlators/performance/stat-prefetch/src/stat-prefetch.c
@@ -22,6 +22,169 @@
#define GF_SP_CACHE_BUCKETS 1
#define GF_SP_CACHE_ENTRIES_EXPECTED 1048576
+
+typedef enum {
+ SP_EXPECT,
+ SP_DONT_EXPECT,
+ SP_DONT_CARE
+}sp_expect_t;
+
+
+void
+sp_inode_ctx_free (xlator_t *this, sp_inode_ctx_t *ctx)
+{
+ call_stub_t *stub = NULL, *tmp = NULL;
+
+ if (ctx == NULL) {
+ goto out;
+ }
+
+ LOCK (&ctx->lock);
+ {
+ if (!list_empty (&ctx->waiting_ops)) {
+ gf_log (this->name, GF_LOG_CRITICAL, "inode ctx is "
+ "being freed even when there are file "
+ "operations waiting for lookup-behind to "
+ "complete. The operations in the waiting list "
+ "are:");
+ list_for_each_entry_safe (stub, tmp, &ctx->waiting_ops,
+ list) {
+ gf_log (this->name, GF_LOG_CRITICAL,
+ "OP (%d)", stub->fop);
+
+ list_del_init (&stub->list);
+ call_stub_destroy (stub);
+ }
+ }
+ }
+ UNLOCK (&ctx->lock);
+
+ LOCK_DESTROY (&ctx->lock);
+ FREE (ctx);
+
+out:
+ return;
+}
+
+
+sp_inode_ctx_t *
+sp_inode_ctx_init ()
+{
+ sp_inode_ctx_t *inode_ctx = NULL;
+
+ inode_ctx = CALLOC (1, sizeof (*inode_ctx));
+ if (inode_ctx == NULL) {
+ goto out;
+ }
+
+ LOCK_INIT (&inode_ctx->lock);
+ INIT_LIST_HEAD (&inode_ctx->waiting_ops);
+
+out:
+ return inode_ctx;
+}
+
+
+sp_inode_ctx_t *
+sp_check_and_create_inode_ctx (xlator_t *this, inode_t *inode,
+ sp_expect_t expect, glusterfs_fop_t caller)
+{
+ uint64_t value = 0;
+ sp_inode_ctx_t *inode_ctx = NULL;
+ int32_t ret = 0;
+
+ if ((this == NULL) || (inode == NULL)) {
+ goto out;
+ }
+
+ LOCK (&inode->lock);
+ {
+ ret = __inode_ctx_get (inode, this, &value);
+ if (ret == 0) {
+ if (expect == SP_DONT_EXPECT) {
+ gf_log (this->name, GF_LOG_DEBUG, "inode_ctx "
+ "is not NULL (caller %d)", caller);
+ }
+
+ inode_ctx = (sp_inode_ctx_t *)(long)value;
+ } else {
+ if (expect == SP_EXPECT) {
+ gf_log (this->name, GF_LOG_DEBUG, "inode_ctx is"
+ " NULL (caller %d)", caller);
+ }
+
+ inode_ctx = sp_inode_ctx_init ();
+ if (inode_ctx != NULL) {
+ ret = __inode_ctx_put (inode, this,
+ (long)inode_ctx);
+ if (ret == -1) {
+ sp_inode_ctx_free (this, inode_ctx);
+ inode_ctx = NULL;
+ }
+ }
+ }
+ }
+ UNLOCK (&inode->lock);
+
+out:
+ return inode_ctx;
+}
+
+
+int
+sp_update_inode_ctx (xlator_t *this, inode_t *inode, int32_t *op_ret,
+ int32_t *op_errno, char *lookup_in_progress,
+ char *looked_up, struct list_head *waiting_ops,
+ int32_t *error)
+{
+ int32_t ret = 0;
+ sp_inode_ctx_t *inode_ctx = NULL;
+ uint64_t value = 0;
+
+ ret = inode_ctx_get (inode, this, &value);
+ if (ret == 0) {
+ inode_ctx = (sp_inode_ctx_t *)(long)value;
+ }
+
+ if (inode_ctx == NULL) {
+ ret = -1;
+ if (error != NULL) {
+ *error = EINVAL;
+ }
+
+ goto out;
+ }
+
+ LOCK (&inode_ctx->lock);
+ {
+ if (op_ret != NULL) {
+ inode_ctx->op_ret = *op_ret;
+ }
+
+ if (op_errno != NULL) {
+ inode_ctx->op_errno = *op_errno;
+ }
+
+ if (looked_up != NULL) {
+ inode_ctx->looked_up = *looked_up;
+ }
+
+ if (lookup_in_progress != NULL) {
+ inode_ctx->lookup_in_progress = *lookup_in_progress;
+ }
+
+ if (waiting_ops != NULL) {
+ list_splice_init (&inode_ctx->waiting_ops,
+ waiting_ops);
+ }
+ }
+ UNLOCK (&inode_ctx->lock);
+
+out:
+ return ret;
+}
+
+
sp_cache_t *
sp_cache_ref (sp_cache_t *cache)
{
@@ -749,61 +912,6 @@ out:
}
-void
-sp_inode_ctx_free (xlator_t *this, sp_inode_ctx_t *ctx)
-{
- call_stub_t *stub = NULL, *tmp = NULL;
-
- if (ctx == NULL) {
- goto out;
- }
-
- LOCK (&ctx->lock);
- {
- if (!list_empty (&ctx->waiting_ops)) {
- gf_log (this->name, GF_LOG_CRITICAL, "inode ctx is "
- "being freed even when there are file "
- "operations waiting for lookup-behind to "
- "complete. The operations in the waiting list "
- "are:");
- list_for_each_entry_safe (stub, tmp, &ctx->waiting_ops,
- list) {
- gf_log (this->name, GF_LOG_CRITICAL,
- "OP (%d)", stub->fop);
-
- list_del_init (&stub->list);
- call_stub_destroy (stub);
- }
- }
- }
- UNLOCK (&ctx->lock);
-
- LOCK_DESTROY (&ctx->lock);
- FREE (ctx);
-
-out:
- return;
-}
-
-
-sp_inode_ctx_t *
-sp_inode_ctx_init ()
-{
- sp_inode_ctx_t *inode_ctx = NULL;
-
- inode_ctx = CALLOC (1, sizeof (*inode_ctx));
- if (inode_ctx == NULL) {
- goto out;
- }
-
- LOCK_INIT (&inode_ctx->lock);
- INIT_LIST_HEAD (&inode_ctx->waiting_ops);
-
-out:
- return inode_ctx;
-}
-
-
int32_t
sp_lookup_helper (call_frame_t *frame,xlator_t *this, loc_t *loc,
dict_t *xattr_req)
@@ -1381,8 +1489,9 @@ sp_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, fd_t *fd, inode_t *inode,
struct stat *buf)
{
- sp_local_t *local = NULL;
- sp_fd_ctx_t *fd_ctx = NULL;
+ sp_local_t *local = NULL;
+ sp_fd_ctx_t *fd_ctx = NULL;
+ char lookup_in_progress = 0, looked_up = 0;
if (op_ret == -1) {
goto out;
@@ -1392,6 +1501,14 @@ sp_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
GF_VALIDATE_OR_GOTO_WITH_ERROR (this->name, local, out, op_errno,
EINVAL);
+ looked_up = 1;
+ op_ret = sp_update_inode_ctx (this, local->loc.inode, &op_ret,
+ &op_errno, &lookup_in_progress,
+ &looked_up, NULL, &op_errno);
+ if (op_ret == -1) {
+ goto out;
+ }
+
fd_ctx = sp_fd_ctx_new (this, local->loc.parent, fd,
(char *)local->loc.name, NULL);
if (fd_ctx == NULL) {
@@ -1406,55 +1523,13 @@ out:
int32_t
-sp_create_helper (call_frame_t *frame, xlator_t *this, loc_t *loc,
- int32_t flags, mode_t mode, fd_t *fd)
-{
- uint64_t value = 0;
- sp_inode_ctx_t *inode_ctx = NULL;
- int32_t ret = 0, op_ret = -1, op_errno = -1;
-
- ret = inode_ctx_get (loc->inode, this, &value);
- if (ret == -1) {
- gf_log (this->name, GF_LOG_DEBUG, "context not set in inode "
- "(%p)", loc->inode);
- op_errno = EINVAL;
- goto unwind;
- }
-
- inode_ctx = (sp_inode_ctx_t *)(long) value;
- GF_VALIDATE_OR_GOTO_WITH_ERROR (this->name, inode_ctx, unwind, op_errno,
- EINVAL);
-
- LOCK (&inode_ctx->lock);
- {
- op_ret = inode_ctx->op_ret;
- op_errno = inode_ctx->op_errno;
- }
- UNLOCK (&inode_ctx->lock);
-
- if ((op_ret == -1) && (op_errno != ENOENT)) {
- goto unwind;
- }
-
- STACK_WIND (frame, sp_create_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->create, loc, flags, mode, fd);
-
- return 0;
-
-unwind:
- SP_STACK_UNWIND (frame, -1, op_errno, NULL);
- return 0;
-}
-
-
-int32_t
sp_create (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,
mode_t mode, fd_t *fd)
{
- sp_local_t *local = NULL;
- int32_t op_errno = -1, ret = -1;
- call_stub_t *stub = NULL;
- char can_wind = 0, need_lookup = 0, need_unwind = 1;
+ sp_local_t *local = NULL;
+ int32_t op_errno = -1, ret = -1;
+ char need_unwind = 1;
+ sp_inode_ctx_t *inode_ctx = NULL;
GF_VALIDATE_OR_GOTO_WITH_ERROR (this->name, loc, out, op_errno,
EINVAL);
@@ -1475,42 +1550,30 @@ sp_create (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,
goto out;
}
- stub = fop_create_stub (frame, sp_create_helper, loc, flags, mode, fd);
- if (stub == NULL) {
+ local = CALLOC (1, sizeof (*local));
+ GF_VALIDATE_OR_GOTO_WITH_ERROR (this->name, local, out, op_errno,
+ ENOMEM);
+ frame->local = local;
+ ret = loc_copy (&local->loc, loc);
+ if (ret == -1) {
+ op_errno = errno;
+ gf_log (this->name, GF_LOG_ERROR, "%s", strerror (op_errno));
+ goto out;
+ }
+
+ inode_ctx = sp_check_and_create_inode_ctx (this, loc->inode,
+ SP_DONT_CARE, GF_FOP_LOOKUP);
+ if (inode_ctx == NULL) {
op_errno = ENOMEM;
gf_log (this->name, GF_LOG_ERROR, "out of memory");
goto out;
}
- sp_process_inode_ctx (frame, this, loc, stub, &need_unwind,
- &need_lookup, &can_wind, &op_errno);
-
+ need_unwind = 0;
out:
if (need_unwind) {
SP_STACK_UNWIND (frame, -1, op_errno, NULL);
- } else if (need_lookup) {
- STACK_WIND (frame, sp_lookup_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->lookup, loc, NULL);
- } else if (can_wind) {
- if (frame->local == NULL) {
- need_unwind = 1;
-
- local = CALLOC (1, sizeof (*local));
- GF_VALIDATE_OR_GOTO_WITH_ERROR (this->name, local,
- out, op_errno,
- ENOMEM);
-
- frame->local = local;
-
- ret = loc_copy (&local->loc, loc);
- if (ret == -1) {
- op_errno = errno;
- gf_log (this->name, GF_LOG_ERROR, "%s",
- strerror (op_errno));
- goto out;
- }
- }
-
+ } else {
STACK_WIND (frame, sp_create_cbk, FIRST_CHILD(this),
FIRST_CHILD(this)->fops->create, loc, flags,
mode, fd);
@@ -1617,64 +1680,37 @@ sp_new_entry_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, inode_t *inode,
struct stat *buf)
{
- STACK_UNWIND (frame, op_ret, op_errno, inode, buf);
- return 0;
-}
+ sp_local_t *local = NULL;
+ char lookup_in_progress = 0, looked_up = 0;
-
-int32_t
-sp_mkdir_helper (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode)
-{
- uint64_t value = 0;
- sp_inode_ctx_t *inode_ctx = NULL;
- int32_t ret = 0, op_ret = -1, op_errno = -1;
-
- ret = inode_ctx_get (loc->inode, this, &value);
- if (ret == -1) {
- gf_log (this->name, GF_LOG_DEBUG, "context not set in inode "
- "(%p)", loc->inode);
- op_errno = EINVAL;
- goto unwind;
- }
-
- inode_ctx = (sp_inode_ctx_t *)(long) value;
- GF_VALIDATE_OR_GOTO_WITH_ERROR (this->name, inode_ctx, unwind, op_errno,
- EINVAL);
-
- LOCK (&inode_ctx->lock);
- {
- op_ret = inode_ctx->op_ret;
- op_errno = inode_ctx->op_errno;
+ if (op_ret == -1) {
+ goto out;
}
- UNLOCK (&inode_ctx->lock);
- if (((op_ret == -1) && (op_errno != ENOENT))
- || (op_ret == 0)) {
- if (op_ret == 0) {
- op_ret = -1;
- op_errno = EEXIST;
- }
-
- goto unwind;
+ local = frame->local;
+ if (local == NULL) {
+ op_errno = EINVAL;
+ goto out;
}
- STACK_WIND (frame, sp_new_entry_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->mkdir, loc, mode);
+ looked_up = 1;
+ op_ret = sp_update_inode_ctx (this, local->loc.inode, &op_ret,
+ &op_errno, &lookup_in_progress,
+ &looked_up, NULL, &op_errno);
- return 0;
-
-unwind:
- SP_STACK_UNWIND (frame, -1, op_errno, NULL, NULL);
- return 0;
+out:
+ STACK_UNWIND (frame, op_ret, op_errno, inode, buf);
+ return 0;
}
int32_t
sp_mkdir (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode)
{
- int32_t ret = -1, op_errno = -1;
- call_stub_t *stub = NULL;
- char can_wind = 0, need_lookup = 0, need_unwind = 1;
+ char need_unwind = 1;
+ sp_inode_ctx_t *inode_ctx = NULL;
+ sp_local_t *local = NULL;
+ int32_t op_errno = 0, ret = 0;
GF_VALIDATE_OR_GOTO_WITH_ERROR (this->name, loc, out, op_errno,
EINVAL);
@@ -1687,6 +1723,19 @@ sp_mkdir (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode)
GF_VALIDATE_OR_GOTO_WITH_ERROR (this->name, loc->inode, out,
op_errno, EINVAL);
+ local = CALLOC (1, sizeof (*local));
+ GF_VALIDATE_OR_GOTO_WITH_ERROR (this->name, local, out, op_errno,
+ ENOMEM);
+
+ frame->local = local;
+
+ ret = loc_copy (&local->loc, loc);
+ if (ret == -1) {
+ op_errno = errno;
+ gf_log (this->name, GF_LOG_ERROR, "%s", strerror (op_errno));
+ goto out;
+ }
+
ret = sp_cache_remove_parent_entry (frame, this, loc->parent->table,
(char *)loc->path);
if (ret == -1) {
@@ -1695,23 +1744,20 @@ sp_mkdir (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode)
goto out;
}
- stub = fop_mkdir_stub (frame, sp_mkdir_helper, loc, mode);
- if (stub == NULL) {
+ inode_ctx = sp_check_and_create_inode_ctx (this, loc->inode,
+ SP_DONT_EXPECT,
+ GF_FOP_MKDIR);
+ if (inode_ctx == NULL) {
op_errno = ENOMEM;
gf_log (this->name, GF_LOG_ERROR, "out of memory");
goto out;
}
- sp_process_inode_ctx (frame, this, loc, stub, &need_unwind,
- &need_lookup, &can_wind, &op_errno);
-
+ need_unwind = 0;
out:
if (need_unwind) {
SP_STACK_UNWIND (frame, -1, op_errno, NULL, NULL);
- } else if (need_lookup) {
- STACK_WIND (frame, sp_lookup_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->lookup, loc, NULL);
- } else if (can_wind) {
+ } else {
STACK_WIND (frame, sp_new_entry_cbk, FIRST_CHILD(this),
FIRST_CHILD(this)->fops->mkdir, loc, mode);
}
@@ -1721,59 +1767,13 @@ out:
int32_t
-sp_mknod_helper (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
- dev_t rdev)
-{
- uint64_t value = 0;
- sp_inode_ctx_t *inode_ctx = NULL;
- int32_t ret = 0, op_ret = -1, op_errno = -1;
-
- ret = inode_ctx_get (loc->inode, this, &value);
- if (ret == -1) {
- gf_log (this->name, GF_LOG_DEBUG, "context not set in inode "
- "(%p)", loc->inode);
- op_errno = EINVAL;
- goto unwind;
- }
-
- inode_ctx = (sp_inode_ctx_t *)(long) value;
- GF_VALIDATE_OR_GOTO_WITH_ERROR (this->name, inode_ctx, unwind, op_errno,
- EINVAL);
-
- LOCK (&inode_ctx->lock);
- {
- op_ret = inode_ctx->op_ret;
- op_errno = inode_ctx->op_errno;
- }
- UNLOCK (&inode_ctx->lock);
-
- if (((op_ret == -1) && (op_errno != ENOENT))
- || (op_ret == 0)) {
- if (op_ret == 0) {
- op_ret = -1;
- op_errno = EEXIST;
- }
- goto unwind;
- }
-
- STACK_WIND (frame, sp_new_entry_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->mknod, loc, mode, rdev);
-
- return 0;
-
-unwind:
- SP_STACK_UNWIND (frame, -1, op_errno, NULL);
- return 0;
-}
-
-
-int32_t
sp_mknod (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
dev_t rdev)
{
- int32_t op_errno = -1, ret = -1;
- call_stub_t *stub = NULL;
- char can_wind = 0, need_lookup = 0, need_unwind = 1;
+ char need_unwind = 1;
+ sp_inode_ctx_t *inode_ctx = NULL;
+ sp_local_t *local = NULL;
+ int32_t op_errno = 0, ret = 0;
GF_VALIDATE_OR_GOTO_WITH_ERROR (this->name, loc, out, op_errno,
EINVAL);
@@ -1794,23 +1794,33 @@ sp_mknod (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
goto out;
}
- stub = fop_mknod_stub (frame, sp_mknod_helper, loc, mode, rdev);
- if (stub == NULL) {
+ local = CALLOC (1, sizeof (*local));
+ GF_VALIDATE_OR_GOTO_WITH_ERROR (this->name, local, out, op_errno,
+ ENOMEM);
+
+ frame->local = local;
+
+ ret = loc_copy (&local->loc, loc);
+ if (ret == -1) {
+ op_errno = errno;
+ gf_log (this->name, GF_LOG_ERROR, "%s", strerror (op_errno));
+ goto out;
+ }
+
+ inode_ctx = sp_check_and_create_inode_ctx (this, loc->inode,
+ SP_DONT_EXPECT,
+ GF_FOP_MKNOD);
+ if (inode_ctx == NULL) {
op_errno = ENOMEM;
gf_log (this->name, GF_LOG_ERROR, "out of memory");
goto out;
}
- sp_process_inode_ctx (frame, this, loc, stub, &need_unwind,
- &need_lookup, &can_wind, &op_errno);
-
+ need_unwind = 0;
out:
if (need_unwind) {
SP_STACK_UNWIND (frame, -1, op_errno, NULL, NULL);
- } else if (need_lookup) {
- STACK_WIND (frame, sp_lookup_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->lookup, loc, NULL);
- } else if (can_wind) {
+ } else {
STACK_WIND (frame, sp_new_entry_cbk, FIRST_CHILD(this),
FIRST_CHILD(this)->fops->mknod, loc, mode, rdev);
}
@@ -1820,58 +1830,13 @@ out:
int32_t
-sp_symlink_helper (call_frame_t *frame, xlator_t *this, const char *linkpath,
- loc_t *loc)
-{
- uint64_t value = 0;
- sp_inode_ctx_t *inode_ctx = NULL;
- int32_t ret = 0, op_ret = -1, op_errno = -1;
-
- ret = inode_ctx_get (loc->inode, this, &value);
- if (ret == -1) {
- gf_log (this->name, GF_LOG_DEBUG, "context not set in inode "
- "(%p)", loc->inode);
- op_errno = EINVAL;
- goto unwind;
- }
-
- inode_ctx = (sp_inode_ctx_t *)(long) value;
- GF_VALIDATE_OR_GOTO_WITH_ERROR (this->name, inode_ctx, unwind, op_errno,
- EINVAL);
-
- LOCK (&inode_ctx->lock);
- {
- op_ret = inode_ctx->op_ret;
- op_errno = inode_ctx->op_errno;
- }
- UNLOCK (&inode_ctx->lock);
-
- if (((op_ret == -1) && (op_errno != ENOENT)) || (op_ret == 0)) {
- if (op_ret == 0) {
- op_ret = -1;
- op_errno = EEXIST;
- }
- goto unwind;
- }
-
- STACK_WIND (frame, sp_new_entry_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->symlink, linkpath, loc);
-
- return 0;
-
-unwind:
- SP_STACK_UNWIND (frame, -1, op_errno);
- return 0;
-}
-
-
-int32_t
sp_symlink (call_frame_t *frame, xlator_t *this, const char *linkpath,
loc_t *loc)
{
- int32_t ret = -1, op_errno = -1;
- call_stub_t *stub = NULL;
- char can_wind = 0, need_lookup = 0, need_unwind = 1;
+ char need_unwind = 1;
+ sp_inode_ctx_t *inode_ctx = NULL;
+ sp_local_t *local = NULL;
+ int32_t op_errno = 0, ret = 0;
GF_VALIDATE_OR_GOTO_WITH_ERROR (this->name, loc, out, op_errno,
EINVAL);
@@ -1892,23 +1857,33 @@ sp_symlink (call_frame_t *frame, xlator_t *this, const char *linkpath,
goto out;
}
- stub = fop_symlink_stub (frame, sp_symlink_helper, linkpath, loc);
- if (stub == NULL) {
+ local = CALLOC (1, sizeof (*local));
+ GF_VALIDATE_OR_GOTO_WITH_ERROR (this->name, local, out, op_errno,
+ ENOMEM);
+
+ frame->local = local;
+
+ ret = loc_copy (&local->loc, loc);
+ if (ret == -1) {
+ op_errno = errno;
+ gf_log (this->name, GF_LOG_ERROR, "%s", strerror (op_errno));
+ goto out;
+ }
+
+ inode_ctx = sp_check_and_create_inode_ctx (this, loc->inode,
+ SP_DONT_EXPECT,
+ GF_FOP_SYMLINK);
+ if (inode_ctx == NULL) {
op_errno = ENOMEM;
gf_log (this->name, GF_LOG_ERROR, "out of memory");
goto out;
}
- sp_process_inode_ctx (frame, this, loc, stub, &need_unwind,
- &need_lookup, &can_wind, &op_errno);
-
+ need_unwind = 0;
out:
if (need_unwind) {
SP_STACK_UNWIND (frame, -1, op_errno);
- } else if (need_lookup) {
- STACK_WIND (frame, sp_lookup_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->lookup, loc, NULL);
- } else if (can_wind) {
+ } else {
STACK_WIND (frame, sp_new_entry_cbk, FIRST_CHILD(this),
FIRST_CHILD(this)->fops->symlink, linkpath, loc);
}
@@ -1918,6 +1893,15 @@ out:
int32_t
+sp_link_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret,
+ int32_t op_errno, inode_t *inode, struct stat *buf)
+{
+ SP_STACK_UNWIND (frame, op_ret, op_errno, inode, buf);
+ return 0;
+}
+
+
+int32_t
sp_link_helper (call_frame_t *frame, xlator_t *this, loc_t *oldloc,
loc_t *newloc)
{
@@ -1948,7 +1932,7 @@ sp_link_helper (call_frame_t *frame, xlator_t *this, loc_t *oldloc,
goto unwind;
}
- STACK_WIND (frame, sp_new_entry_cbk, FIRST_CHILD(this),
+ STACK_WIND (frame, sp_link_cbk, FIRST_CHILD(this),
FIRST_CHILD(this)->fops->link, oldloc, newloc);
return 0;
@@ -1962,10 +1946,10 @@ unwind:
int32_t
sp_link (call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc)
{
- call_stub_t *stub = NULL;
- sp_cache_t *cache = NULL;
- int32_t ret = 0, op_errno = -1;
- char can_wind = 0, need_lookup = 0, need_unwind = 1;
+ call_stub_t *stub = NULL;
+ sp_cache_t *cache = NULL;
+ int32_t ret = 0, op_errno = -1;
+ char can_wind = 0, need_lookup = 0, need_unwind = 1;
GF_VALIDATE_OR_GOTO_WITH_ERROR (this->name, oldloc, out, op_errno,
EINVAL);
@@ -2010,14 +1994,6 @@ sp_link (call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc)
sp_process_inode_ctx (frame, this, oldloc, stub, &need_unwind,
&need_lookup, &can_wind, &op_errno);
- /*
- * no need to process context in newloc->inode for following reasons:
- * 1. if dentry corresponding to newloc->path was cached, sp_lookup
- * would've unwound indicating success and link fop itself would've
- * not been called.
- * 2. if dentry corresponding to newloc->path was not cached, lookup
- * would've anyways be sent to underlying translators in sp_lookup.
- */
out:
if (need_unwind) {
SP_STACK_UNWIND (frame, -1, op_errno, NULL, NULL);
@@ -2025,7 +2001,7 @@ out:
STACK_WIND (frame, sp_lookup_cbk, FIRST_CHILD(this),
FIRST_CHILD(this)->fops->lookup, oldloc, NULL);
} else if (can_wind) {
- STACK_WIND (frame, sp_new_entry_cbk, FIRST_CHILD(this),
+ STACK_WIND (frame, sp_link_cbk, FIRST_CHILD(this),
FIRST_CHILD(this)->fops->link, oldloc, newloc);
}