Blob Blame History Raw
From 5408885124731a65d3a0d571b26f4c6cadcdae1e Mon Sep 17 00:00:00 2001
From: Raghavendra G <rgowdapp@redhat.com>
Date: Wed, 27 May 2015 17:19:30 +0530
Subject: [PATCH 28/57] cluster/dht: pass a destination subvol to fop2 variants to avoid races.

The destination subvol used in the fop2 variants is either stored in
inode-ctx1 or local->cached_subvol. However, it is not guaranteed that
a value stored in these locations before invocation of fop2 is still
present after the invocation as these locations are shared among
different concurrent operations. So, to preserve the atomicity of
"check dst-subvol and invoke fop2 variant if dst-subvol found", we
pass down the dst-subvol to fop2 variant.

This patch also fixes error handling in some fop2 variants.

Change-Id: Icc226228a246d3f223e3463519736c4495b364d2
BUG: 1140506
Signed-off-by: Raghavendra G <rgowdapp@redhat.com>
Reviewed-on: http://review.gluster.org/10966
Tested-by: Gluster Build System <jenkins@build.gluster.com>
Reviewed-on: https://code.engineering.redhat.com/gerrit/50191
Reviewed-by: Nithya Balachandran <nbalacha@redhat.com>
---
 xlators/cluster/dht/src/dht-common.c      |  112 ++++++--------------
 xlators/cluster/dht/src/dht-common.h      |    6 +-
 xlators/cluster/dht/src/dht-helper.c      |   41 ++++++-
 xlators/cluster/dht/src/dht-inode-read.c  |   96 +++++++++--------
 xlators/cluster/dht/src/dht-inode-write.c |  164 +++++++++++++++++------------
 5 files changed, 222 insertions(+), 197 deletions(-)

diff --git a/xlators/cluster/dht/src/dht-common.c b/xlators/cluster/dht/src/dht-common.c
index 48a003c..acad4da 100644
--- a/xlators/cluster/dht/src/dht-common.c
+++ b/xlators/cluster/dht/src/dht-common.c
@@ -29,14 +29,13 @@
 #include <libgen.h>
 #include <signal.h>
 
-int dht_link2 (xlator_t *this, call_frame_t *frame, int op_ret);
+int dht_link2 (xlator_t *this, xlator_t *dst_node, call_frame_t *frame);
 
 int
-dht_removexattr2 (xlator_t *this, call_frame_t *frame, int op_ret);
+dht_removexattr2 (xlator_t *this, xlator_t *subvol, call_frame_t *frame);
 
 int
-dht_setxattr2 (xlator_t *this, call_frame_t *frame, int op_ret);
-
+dht_setxattr2 (xlator_t *this, xlator_t *subvol, call_frame_t *frame);
 
 int
 dht_aggregate_quota_xattr (dict_t *dst, char *key, data_t *value)
@@ -3303,14 +3302,13 @@ int
 dht_file_setxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
                      int op_ret, int op_errno, dict_t *xdata)
 {
-        int           ret  = -1;
-        dht_local_t  *local = NULL;
-        call_frame_t *prev = NULL;
-        struct iatt  *stbuf = NULL;
-        inode_t      *inode = NULL;
+        int           ret    = -1;
+        dht_local_t  *local  = NULL;
+        call_frame_t *prev   = NULL;
+        struct iatt  *stbuf  = NULL;
+        inode_t      *inode  = NULL;
         xlator_t     *subvol = NULL;
 
-
         local = frame->local;
         prev = cookie;
 
@@ -3346,11 +3344,13 @@ dht_file_setxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
         /* Phase 1 of migration */
         if (IS_DHT_MIGRATION_PHASE1 (stbuf)) {
                 inode = (local->fd) ? local->fd->inode : local->loc.inode;
-                dht_inode_ctx_get1 (this, inode, &subvol);
+
+                ret = dht_inode_ctx_get1 (this, inode, &subvol);
                 if (subvol) {
-                        dht_setxattr2 (this, frame, 0);
+                        dht_setxattr2 (this, subvol, frame);
                         return 0;
                 }
+
                 ret = dht_rebalance_in_progress_check (this, frame);
                 if (!ret)
                         return 0;
@@ -3515,30 +3515,15 @@ out:
 
 
 int
-dht_setxattr2 (xlator_t *this, call_frame_t *frame, int op_ret)
+dht_setxattr2 (xlator_t *this, xlator_t *subvol, call_frame_t *frame)
 {
-        dht_local_t  *local  = NULL;
-        xlator_t     *subvol = NULL;
+        dht_local_t *local    = NULL;
         int          op_errno = EINVAL;
-        inode_t      *inode = NULL;
-
-        local = frame->local;
-
-        inode = (local->fd) ? local->fd->inode : local->loc.inode;
 
-        dht_inode_ctx_get1 (this, inode, &subvol);
-
-        /* In phase2, dht_migration_complete_check_task will
-         * reset inode_ctx_reset1 and update local->cached_subvol
-         * with the dst subvol.
-         */
-        if (!subvol)
-                subvol = local->cached_subvol;
-
-        if (!subvol) {
-                op_errno = EINVAL;
+        if (!frame || !frame->local || !subvol)
                 goto err;
-        }
+
+        local = frame->local;
 
         local->call_cnt = 2; /* This is the second attempt */
 
@@ -3557,7 +3542,7 @@ dht_setxattr2 (xlator_t *this, call_frame_t *frame, int op_ret)
         return 0;
 
 err:
-        DHT_STACK_UNWIND (setxattr, frame, local->op_ret, op_errno, NULL);
+        DHT_STACK_UNWIND (setxattr, frame, -1, op_errno, NULL);
         return 0;
 }
 
@@ -3829,14 +3814,13 @@ int
 dht_file_removexattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
                      int op_ret, int op_errno, dict_t *xdata)
 {
-        int           ret  = -1;
-        dht_local_t  *local = NULL;
-        call_frame_t *prev = NULL;
-        struct iatt  *stbuf = NULL;
-        inode_t      *inode = NULL;
+        int           ret    = -1;
+        dht_local_t  *local  = NULL;
+        call_frame_t *prev   = NULL;
+        struct iatt  *stbuf  = NULL;
+        inode_t      *inode  = NULL;
         xlator_t     *subvol = NULL;
 
-
         local = frame->local;
         prev = cookie;
 
@@ -3872,11 +3856,12 @@ dht_file_removexattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
         /* Phase 1 of migration */
         if (IS_DHT_MIGRATION_PHASE1 (stbuf)) {
                 inode = (local->fd) ? local->fd->inode : local->loc.inode;
-                dht_inode_ctx_get1 (this, inode, &subvol);
+                ret = dht_inode_ctx_get1 (this, inode, &subvol);
                 if (subvol) {
-                        dht_removexattr2 (this, frame, 0);
+                        dht_removexattr2 (this, subvol, frame);
                         return 0;
                 }
+
                 ret = dht_rebalance_in_progress_check (this, frame);
                 if (!ret)
                         return 0;
@@ -3893,32 +3878,15 @@ out:
 }
 
 int
-dht_removexattr2 (xlator_t *this, call_frame_t *frame, int op_ret)
+dht_removexattr2 (xlator_t *this, xlator_t *subvol, call_frame_t *frame)
 {
-        dht_local_t  *local  = NULL;
-        xlator_t     *subvol = NULL;
+        dht_local_t *local    = NULL;
         int          op_errno = EINVAL;
-        inode_t      *inode = NULL;
-
-        local = frame->local;
 
-        inode = (local->fd) ? local->fd->inode : local->loc.inode;
-
-        dht_inode_ctx_get1 (this, inode, &subvol);
-
-        /* In phase2, dht_migration_complete_check_task will
-         * reset inode_ctx_reset1 and update local->cached_subvol
-         * with the dst subvol.
-         */
-        if (!subvol)
-                subvol = local->cached_subvol;
-
-        if (!subvol) {
-                op_errno = EINVAL;
+        if (!frame || !frame->local || !subvol)
                 goto err;
 
-        }
-
+        local = frame->local;
 
         local->call_cnt = 2; /* This is the second attempt */
 
@@ -3935,11 +3903,10 @@ dht_removexattr2 (xlator_t *this, call_frame_t *frame, int op_ret)
         return 0;
 
 err:
-        DHT_STACK_UNWIND (removexattr, frame, local->op_ret, op_errno, NULL);
+        DHT_STACK_UNWIND (removexattr, frame, -1, op_errno, NULL);
         return 0;
 }
 
-
 int
 dht_removexattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
                      int op_ret, int op_errno, dict_t *xdata)
@@ -5268,7 +5235,7 @@ dht_link_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
                         if (!ret)
                                 return 0;
                 } else {
-                        dht_link2 (this, frame, 0);
+                        dht_link2 (this, subvol, frame);
                         return 0;
                 }
         }
@@ -5277,7 +5244,7 @@ dht_link_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
         if (IS_DHT_MIGRATION_PHASE1 (stbuf)) {
                 ret = dht_inode_ctx_get1 (this, local->loc.inode, &subvol);
                 if (subvol) {
-                        dht_link2 (this, frame, 0);
+                        dht_link2 (this, subvol, frame);
                         return 0;
                 }
                 ret = dht_rebalance_in_progress_check (this, frame);
@@ -5295,10 +5262,9 @@ out:
 
 
 int
-dht_link2 (xlator_t *this, call_frame_t *frame, int op_ret)
+dht_link2 (xlator_t *this, xlator_t *subvol, call_frame_t *frame)
 {
         dht_local_t *local  = NULL;
-        xlator_t    *subvol = NULL;
         int          op_errno = EINVAL;
 
         local = frame->local;
@@ -5306,16 +5272,8 @@ dht_link2 (xlator_t *this, call_frame_t *frame, int op_ret)
                 goto err;
 
         op_errno = local->op_errno;
-        if (op_ret == -1)
+        if (subvol == NULL) {
                 goto err;
-
-        dht_inode_ctx_get1 (this, local->loc.inode, &subvol);
-        if (!subvol) {
-                subvol = local->cached_subvol;
-                if (!subvol) {
-                        op_errno = EINVAL;
-                        goto err;
-                }
         }
 
         /* Second call to create link file could result in EEXIST as the
diff --git a/xlators/cluster/dht/src/dht-common.h b/xlators/cluster/dht/src/dht-common.h
index 4b6531c..eebc13b 100644
--- a/xlators/cluster/dht/src/dht-common.h
+++ b/xlators/cluster/dht/src/dht-common.h
@@ -39,9 +39,9 @@
 typedef int (*dht_selfheal_dir_cbk_t) (call_frame_t *frame, void *cookie,
                                        xlator_t     *this,
                                        int32_t       op_ret, int32_t op_errno,
-                                       dict_t *xdata);
-typedef int (*dht_defrag_cbk_fn_t) (xlator_t        *this, call_frame_t *frame,
-                                    int              ret);
+                                       dict_t       *xdata);
+typedef int (*dht_defrag_cbk_fn_t) (xlator_t        *this, xlator_t *dst_node,
+                                    call_frame_t    *frame);
 
 
 struct dht_layout {
diff --git a/xlators/cluster/dht/src/dht-helper.c b/xlators/cluster/dht/src/dht-helper.c
index 1b5ad41..ee99b99 100644
--- a/xlators/cluster/dht/src/dht-helper.c
+++ b/xlators/cluster/dht/src/dht-helper.c
@@ -820,11 +820,23 @@ dht_init_subvolumes (xlator_t *this, dht_conf_t *conf)
 static int
 dht_migration_complete_check_done (int op_ret, call_frame_t *frame, void *data)
 {
-        dht_local_t *local = NULL;
+        dht_local_t *local  = NULL;
+        xlator_t    *subvol = NULL;
 
         local = frame->local;
 
-        local->rebalance.target_op_fn (THIS, frame, op_ret);
+        if (op_ret == -1)
+                goto out;
+
+        if (local->cached_subvol == NULL) {
+                local->op_errno = EINVAL;
+                goto out;
+        }
+
+        subvol = local->cached_subvol;
+
+out:
+        local->rebalance.target_op_fn (THIS, subvol, frame);
 
         return 0;
 }
@@ -1003,13 +1015,30 @@ dht_rebalance_complete_check (xlator_t *this, call_frame_t *frame)
 
 /* During 'in-progress' state, both nodes should have the file */
 static int
-dht_inprogress_check_done (int op_ret, call_frame_t *sync_frame, void *data)
+dht_inprogress_check_done (int op_ret, call_frame_t *frame, void *data)
 {
-        dht_local_t *local = NULL;
+        dht_local_t *local  = NULL;
+        xlator_t    *subvol = NULL;
+        inode_t     *inode  = NULL;
 
-        local = sync_frame->local;
+        local = frame->local;
+
+        if (op_ret == -1)
+                goto out;
+
+        inode = local->loc.inode ? local->loc.inode : local->fd->inode;
+
+        dht_inode_ctx_get1 (THIS, inode, &subvol);
+        if (!subvol) {
+                subvol = dht_subvol_get_cached (THIS, inode);
+                if (!subvol) {
+                        local->op_errno = EINVAL;
+                        goto out;
+                }
+        }
 
-        local->rebalance.target_op_fn (THIS, sync_frame, op_ret);
+out:
+        local->rebalance.target_op_fn (THIS, subvol, frame);
 
         return 0;
 }
diff --git a/xlators/cluster/dht/src/dht-inode-read.c b/xlators/cluster/dht/src/dht-inode-read.c
index 78e3ef4..46df5b6 100644
--- a/xlators/cluster/dht/src/dht-inode-read.c
+++ b/xlators/cluster/dht/src/dht-inode-read.c
@@ -15,13 +15,13 @@
 
 #include "dht-common.h"
 
-int dht_access2 (xlator_t *this, call_frame_t *frame, int ret);
-int dht_readv2 (xlator_t *this, call_frame_t *frame, int ret);
-int dht_attr2 (xlator_t *this, call_frame_t *frame, int ret);
-int dht_open2 (xlator_t *this, call_frame_t *frame, int ret);
-int dht_flush2 (xlator_t *this, call_frame_t *frame, int ret);
-int dht_lk2 (xlator_t *this, call_frame_t *frame, int ret);
-int dht_fsync2 (xlator_t *this, call_frame_t *frame, int ret);
+int dht_access2 (xlator_t *this, xlator_t *dst_node, call_frame_t *frame);
+int dht_readv2 (xlator_t *this, xlator_t *dst_node, call_frame_t *frame);
+int dht_attr2 (xlator_t *this, xlator_t *dst_node, call_frame_t *frame);
+int dht_open2 (xlator_t *this, xlator_t *dst_node, call_frame_t *frame);
+int dht_flush2 (xlator_t *this, xlator_t *dst_node, call_frame_t *frame);
+int dht_lk2 (xlator_t *this, xlator_t *dst_node, call_frame_t *frame);
+int dht_fsync2 (xlator_t *this, xlator_t *dst_node, call_frame_t *frame);
 
 int
 dht_open_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
@@ -58,22 +58,21 @@ out:
 }
 
 int
-dht_open2 (xlator_t *this, call_frame_t *frame, int op_ret)
+dht_open2 (xlator_t *this, xlator_t *subvol, call_frame_t *frame)
 {
-        dht_local_t *local  = NULL;
-        xlator_t    *subvol = NULL;
+        dht_local_t *local    = NULL;
         int          op_errno = EINVAL;
 
-        local = frame->local;
-        if (!local)
+        if (!frame || !frame->local)
                 goto out;
 
+        local = frame->local;
         op_errno = ENOENT;
-        if (op_ret)
+
+        if (subvol == NULL)
                 goto out;
 
         local->call_cnt = 2;
-        subvol = local->cached_subvol;
 
         STACK_WIND (frame, dht_open_cbk, subvol, subvol->fops->open,
                     &local->loc, local->rebalance.flags, local->fd,
@@ -169,7 +168,7 @@ dht_file_attr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
                 } else {
                         /* value is already set in fd_ctx, that means no need
                            to check for whether its complete or not. */
-                        dht_attr2 (this, frame, 0);
+                        dht_attr2 (this, subvol, frame);
                         return 0;
                 }
         }
@@ -182,10 +181,9 @@ err:
 }
 
 int
-dht_attr2 (xlator_t *this, call_frame_t *frame, int op_ret)
+dht_attr2 (xlator_t *this, xlator_t *subvol, call_frame_t *frame)
 {
-        dht_local_t *local  = NULL;
-        xlator_t    *subvol = NULL;
+        dht_local_t *local    = NULL;
         int          op_errno = EINVAL;
 
         local = frame->local;
@@ -193,10 +191,9 @@ dht_attr2 (xlator_t *this, call_frame_t *frame, int op_ret)
                 goto out;
 
         op_errno = local->op_errno;
-        if (op_ret == -1)
+        if (subvol == NULL)
                 goto out;
 
-        subvol = local->cached_subvol;
         local->call_cnt = 2;
 
         if (local->fop == GF_FOP_FSTAT) {
@@ -206,6 +203,7 @@ dht_attr2 (xlator_t *this, call_frame_t *frame, int op_ret)
                 STACK_WIND (frame, dht_file_attr_cbk, subvol,
                             subvol->fops->stat, &local->loc, NULL);
         }
+
         return 0;
 
 out:
@@ -413,7 +411,7 @@ dht_readv_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
                 } else {
                         /* value is already set in fd_ctx, that means no need
                            to check for whether its complete or not. */
-                        dht_readv2 (this, frame, 0);
+                        dht_readv2 (this, subvol, frame);
                         return 0;
                 }
         }
@@ -427,10 +425,9 @@ out:
 }
 
 int
-dht_readv2 (xlator_t *this, call_frame_t *frame, int op_ret)
+dht_readv2 (xlator_t *this, xlator_t *subvol, call_frame_t *frame)
 {
         dht_local_t *local  = NULL;
-        xlator_t    *subvol = NULL;
         int          op_errno = EINVAL;
 
         local = frame->local;
@@ -438,11 +435,10 @@ dht_readv2 (xlator_t *this, call_frame_t *frame, int op_ret)
                 goto out;
 
         op_errno = local->op_errno;
-        if (op_ret == -1)
+        if (subvol == NULL)
                 goto out;
 
         local->call_cnt = 2;
-        subvol = local->cached_subvol;
 
         STACK_WIND (frame, dht_readv_cbk, subvol, subvol->fops->readv,
                     local->fd, local->rebalance.size, local->rebalance.offset,
@@ -547,10 +543,9 @@ out:
 }
 
 int
-dht_access2 (xlator_t *this, call_frame_t *frame, int op_ret)
+dht_access2 (xlator_t *this, xlator_t *subvol, call_frame_t *frame)
 {
-        dht_local_t *local  = NULL;
-        xlator_t    *subvol = NULL;
+        dht_local_t *local    = NULL;
         int          op_errno = EINVAL;
 
         local = frame->local;
@@ -558,11 +553,10 @@ dht_access2 (xlator_t *this, call_frame_t *frame, int op_ret)
                 goto out;
 
         op_errno = local->op_errno;
-        if (op_ret == -1)
+        if (subvol == NULL)
                 goto out;
 
         local->call_cnt = 2;
-        subvol = local->cached_subvol;
 
         STACK_WIND (frame, dht_access_cbk, subvol, subvol->fops->access,
                     &local->loc, local->rebalance.flags, NULL);
@@ -636,7 +630,7 @@ dht_flush_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
         /* If context is set, then send flush() it to the destination */
         dht_inode_ctx_get1 (this, inode, &subvol);
         if (subvol) {
-                dht_flush2 (this, frame, 0);
+                dht_flush2 (this, subvol, frame);
                 return 0;
         }
 
@@ -647,17 +641,20 @@ out:
 }
 
 int
-dht_flush2 (xlator_t *this, call_frame_t *frame, int op_ret)
+dht_flush2 (xlator_t *this, xlator_t *subvol, call_frame_t *frame)
 {
-        dht_local_t  *local  = NULL;
-        xlator_t     *subvol = NULL;
+        dht_local_t *local    = NULL;
+        int32_t      op_errno = EINVAL;
+
+        if ((frame == NULL) || (frame->local == NULL))
+                goto out;
 
         local = frame->local;
 
-        dht_inode_ctx_get1 (this, local->fd->inode, &subvol);
+        op_errno = local->op_errno;
 
-        if (!subvol)
-                subvol = local->cached_subvol;
+        if (subvol == NULL)
+                goto out;
 
         local->call_cnt = 2; /* This is the second attempt */
 
@@ -665,6 +662,10 @@ dht_flush2 (xlator_t *this, call_frame_t *frame, int op_ret)
                     subvol, subvol->fops->flush, local->fd, NULL);
 
         return 0;
+
+out:
+        DHT_STACK_UNWIND (flush, frame, -1, op_errno, NULL);
+        return 0;
 }
 
 
@@ -758,7 +759,7 @@ dht_fsync_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int op_ret,
                 if (!ret)
                         return 0;
         } else {
-                dht_fsync2 (this, frame, 0);
+                dht_fsync2 (this, subvol, frame);
                 return 0;
         }
 
@@ -772,16 +773,19 @@ out:
 }
 
 int
-dht_fsync2 (xlator_t *this, call_frame_t *frame, int op_ret)
+dht_fsync2 (xlator_t *this, xlator_t *subvol, call_frame_t *frame)
 {
-        dht_local_t  *local  = NULL;
-        xlator_t     *subvol = NULL;
+        dht_local_t *local    = NULL;
+        int32_t      op_errno = EINVAL;
+
+        if ((frame == NULL) || (frame->local == NULL))
+                goto out;
 
         local = frame->local;
+        op_errno = local->op_errno;
 
-        dht_inode_ctx_get1 (this, local->fd->inode, &subvol);
-        if (!subvol)
-                subvol = local->cached_subvol;
+        if (subvol == NULL)
+                goto out;
 
         local->call_cnt = 2; /* This is the second attempt */
 
@@ -789,6 +793,10 @@ dht_fsync2 (xlator_t *this, call_frame_t *frame, int op_ret)
                     local->fd, local->rebalance.flags, NULL);
 
         return 0;
+
+out:
+        DHT_STACK_UNWIND (fsync, frame, -1, op_errno, NULL, NULL, NULL);
+        return 0;
 }
 
 int
diff --git a/xlators/cluster/dht/src/dht-inode-write.c b/xlators/cluster/dht/src/dht-inode-write.c
index 7d04376..57ce89c 100644
--- a/xlators/cluster/dht/src/dht-inode-write.c
+++ b/xlators/cluster/dht/src/dht-inode-write.c
@@ -16,12 +16,12 @@
 
 #include "dht-common.h"
 
-int dht_writev2 (xlator_t *this, call_frame_t *frame, int ret);
-int dht_truncate2 (xlator_t *this, call_frame_t *frame, int ret);
-int dht_setattr2 (xlator_t *this, call_frame_t *frame, int ret);
-int dht_fallocate2(xlator_t *this, call_frame_t *frame, int op_ret);
-int dht_discard2(xlator_t *this, call_frame_t *frame, int op_ret);
-int dht_zerofill2(xlator_t *this, call_frame_t *frame, int op_ret);
+int dht_writev2 (xlator_t *this, xlator_t *subvol, call_frame_t *frame);
+int dht_truncate2 (xlator_t *this, xlator_t *subvol, call_frame_t *frame);
+int dht_setattr2 (xlator_t *this, xlator_t *subvol, call_frame_t *frame);
+int dht_fallocate2 (xlator_t *this, xlator_t *subvol, call_frame_t *frame);
+int dht_discard2 (xlator_t *this, xlator_t *subvol, call_frame_t *frame);
+int dht_zerofill2 (xlator_t *this, xlator_t *subvol, call_frame_t *frame);
 
 int
 dht_writev_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
@@ -69,7 +69,7 @@ dht_writev_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
 
                 ret = dht_inode_ctx_get1 (this, local->fd->inode, &subvol);
                 if (subvol) {
-                        dht_writev2 (this, frame, 0);
+                        dht_writev2 (this, subvol, frame);
                         return 0;
                 }
                 ret = dht_rebalance_in_progress_check (this, frame);
@@ -88,17 +88,19 @@ out:
 }
 
 int
-dht_writev2 (xlator_t *this, call_frame_t *frame, int op_ret)
+dht_writev2 (xlator_t *this, xlator_t *subvol, call_frame_t *frame)
 {
-        dht_local_t  *local  = NULL;
-        xlator_t     *subvol = NULL;
+        dht_local_t *local    = NULL;
+        int32_t      op_errno = EINVAL;
 
-        local = frame->local;
+        if ((frame == NULL) || (frame->local == NULL))
+                goto out;
 
-        dht_inode_ctx_get1 (this, local->fd->inode, &subvol);
+        local = frame->local;
+        op_errno = local->op_errno;
 
-        if (!subvol)
-                subvol = local->cached_subvol;
+        if (subvol == NULL)
+                goto out;
 
         local->call_cnt = 2; /* This is the second attempt */
 
@@ -109,6 +111,11 @@ dht_writev2 (xlator_t *this, call_frame_t *frame, int op_ret)
                     local->rebalance.iobref, NULL);
 
         return 0;
+
+out:
+        DHT_STACK_UNWIND (writev, frame, -1, op_errno, NULL, NULL, NULL);
+
+        return 0;
 }
 
 int
@@ -216,7 +223,7 @@ dht_truncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
                 inode = (local->fd) ? local->fd->inode : local->loc.inode;
                 dht_inode_ctx_get1 (this, inode, &subvol);
                 if (subvol) {
-                        dht_truncate2 (this, frame, 0);
+                        dht_truncate2 (this, subvol, frame);
                         return 0;
                 }
                 ret = dht_rebalance_in_progress_check (this, frame);
@@ -235,19 +242,19 @@ err:
 
 
 int
-dht_truncate2 (xlator_t *this, call_frame_t *frame, int op_ret)
+dht_truncate2 (xlator_t *this, xlator_t *subvol, call_frame_t *frame)
 {
-        dht_local_t  *local  = NULL;
-        xlator_t     *subvol = NULL;
-        inode_t      *inode = NULL;
+        dht_local_t *local    = NULL;
+        int32_t      op_errno = EINVAL;
 
-        local = frame->local;
+        if (!frame || !frame->local)
+                goto out;
 
-        inode = local->fd ? local->fd->inode : local->loc.inode;
+        local = frame->local;
+        op_errno = local->op_errno;
 
-        dht_inode_ctx_get1 (this, inode, &subvol);
-        if (!subvol)
-                subvol = local->cached_subvol;
+        if (subvol == NULL)
+                goto out;
 
         local->call_cnt = 2; /* This is the second attempt */
 
@@ -262,6 +269,10 @@ dht_truncate2 (xlator_t *this, call_frame_t *frame, int op_ret)
         }
 
         return 0;
+
+out:
+        DHT_STACK_UNWIND (truncate, frame, -1, op_errno, NULL, NULL, NULL);
+        return 0;
 }
 
 int
@@ -399,7 +410,7 @@ dht_fallocate_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
                 dht_iatt_merge (this, &local->prebuf, prebuf, NULL);
                 dht_inode_ctx_get1 (this, local->fd->inode, &subvol);
                 if (subvol) {
-                        dht_fallocate2 (this, frame, 0);
+                        dht_fallocate2 (this, subvol, frame);
                         return 0;
                 }
                 ret = dht_rebalance_in_progress_check (this, frame);
@@ -417,17 +428,19 @@ err:
 }
 
 int
-dht_fallocate2(xlator_t *this, call_frame_t *frame, int op_ret)
+dht_fallocate2 (xlator_t *this, xlator_t *subvol, call_frame_t *frame)
 {
-        dht_local_t  *local  = NULL;
-        xlator_t     *subvol = NULL;
+        dht_local_t *local    = NULL;
+        int32_t      op_errno = EINVAL;
 
-        local = frame->local;
+        if (!frame || !frame->local)
+                goto out;
 
-        dht_inode_ctx_get1 (this, local->fd->inode, &subvol);
+        local = frame->local;
+        op_errno = local->op_errno;
 
-        if (!subvol)
-                subvol = local->cached_subvol;
+        if (subvol == NULL)
+                goto out;
 
         local->call_cnt = 2; /* This is the second attempt */
 
@@ -436,6 +449,10 @@ dht_fallocate2(xlator_t *this, call_frame_t *frame, int op_ret)
 		   local->rebalance.size, NULL);
 
         return 0;
+
+out:
+        DHT_STACK_UNWIND (fallocate, frame, -1, op_errno, NULL, NULL, NULL);
+        return 0;
 }
 
 int
@@ -533,7 +550,7 @@ dht_discard_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
                 dht_iatt_merge (this, &local->prebuf, prebuf, NULL);
                 dht_inode_ctx_get1 (this, local->fd->inode, &subvol);
                 if (subvol) {
-                        dht_discard2 (this, frame, 0);
+                        dht_discard2 (this, subvol, frame);
                         return 0;
                 }
                 ret = dht_rebalance_in_progress_check (this, frame);
@@ -551,17 +568,19 @@ err:
 }
 
 int
-dht_discard2(xlator_t *this, call_frame_t *frame, int op_ret)
+dht_discard2 (xlator_t *this, xlator_t *subvol, call_frame_t *frame)
 {
-        dht_local_t  *local  = NULL;
-        xlator_t     *subvol = NULL;
+        dht_local_t *local    = NULL;
+        int32_t      op_errno = EINVAL;
 
-        local = frame->local;
+        if (!frame || !frame->local)
+                goto out;
 
-        dht_inode_ctx_get1 (this, local->fd->inode, &subvol);
+        local = frame->local;
+        op_errno = local->op_errno;
 
-        if (!subvol)
-                subvol = local->cached_subvol;
+        if (subvol == NULL)
+                goto out;
 
         local->call_cnt = 2; /* This is the second attempt */
 
@@ -570,6 +589,10 @@ dht_discard2(xlator_t *this, call_frame_t *frame, int op_ret)
 		   NULL);
 
         return 0;
+
+out:
+        DHT_STACK_UNWIND (discard, frame, -1, op_errno, NULL, NULL, NULL);
+        return 0;
 }
 
 int
@@ -619,9 +642,10 @@ dht_zerofill_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
                 int op_ret, int op_errno, struct iatt *prebuf,
                 struct iatt *postbuf, dict_t *xdata)
 {
-        dht_local_t  *local = NULL;
-        call_frame_t *prev  = NULL;
-        int           ret   = -1;
+        dht_local_t  *local  = NULL;
+        call_frame_t *prev   = NULL;
+        int           ret    = -1;
+        xlator_t     *subvol = NULL;
 
         GF_VALIDATE_OR_GOTO ("dht", frame, err);
         GF_VALIDATE_OR_GOTO ("dht", this, out);
@@ -659,11 +683,12 @@ dht_zerofill_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
         if (IS_DHT_MIGRATION_PHASE1 (postbuf)) {
                 dht_iatt_merge (this, &local->stbuf, postbuf, NULL);
                 dht_iatt_merge (this, &local->prebuf, prebuf, NULL);
-                ret = fd_ctx_get (local->fd, this, NULL);
-                if (!ret) {
-                        dht_zerofill2 (this, frame, 0);
+                dht_inode_ctx_get1 (this, local->fd->inode, &subvol);
+                if (subvol) {
+                        dht_zerofill2 (this, subvol, frame);
                         return 0;
                 }
+
                 ret = dht_rebalance_in_progress_check (this, frame);
                 if (!ret)
                         return 0;
@@ -679,22 +704,20 @@ err:
 }
 
 int
-dht_zerofill2(xlator_t *this, call_frame_t *frame, int op_ret)
+dht_zerofill2 (xlator_t *this, xlator_t *subvol, call_frame_t *frame)
 {
-        dht_local_t  *local          = NULL;
-        xlator_t     *subvol         = NULL;
-        uint64_t      tmp_subvol     = 0;
-        int           ret            = -1;
+        dht_local_t *local    = NULL;
+        int32_t      op_errno = EINVAL;
+
+        if (!frame || !frame->local)
+                goto out;
 
         local = frame->local;
 
-        if (local->fd)
-                ret = fd_ctx_get (local->fd, this, &tmp_subvol);
-        if (!ret)
-                subvol = (xlator_t *)(long)tmp_subvol;
+        op_errno = local->op_errno;
 
-        if (!subvol)
-                subvol = local->cached_subvol;
+        if (subvol == NULL)
+                goto out;
 
         local->call_cnt = 2; /* This is the second attempt */
 
@@ -703,6 +726,10 @@ dht_zerofill2(xlator_t *this, call_frame_t *frame, int op_ret)
                    NULL);
 
         return 0;
+
+out:
+        DHT_STACK_UNWIND (zerofill, frame, -1, op_errno, NULL, NULL, NULL);
+        return 0;
 }
 
 int
@@ -796,20 +823,19 @@ out:
 }
 
 int
-dht_setattr2 (xlator_t *this, call_frame_t *frame, int op_ret)
+dht_setattr2 (xlator_t *this, xlator_t *subvol, call_frame_t *frame)
 {
-        dht_local_t  *local  = NULL;
-        xlator_t     *subvol = NULL;
-        inode_t      *inode = NULL;
-
-        local = frame->local;
+        dht_local_t *local    = NULL;
+        int32_t      op_errno = EINVAL;
 
-        inode = (local->fd) ? local->fd->inode : local->loc.inode;
+        if (!frame || !frame->local)
+                goto out;
 
-        dht_inode_ctx_get1 (this, inode, &subvol);
+        local = frame->local;
+        op_errno = local->op_errno;
 
-        if (!subvol)
-                subvol = local->cached_subvol;
+        if (subvol == NULL)
+                goto out;
 
         local->call_cnt = 2; /* This is the second attempt */
 
@@ -826,6 +852,10 @@ dht_setattr2 (xlator_t *this, call_frame_t *frame, int op_ret)
         }
 
         return 0;
+
+out:
+        DHT_STACK_UNWIND (setattr, frame, -1, op_errno, NULL, NULL, NULL);
+        return 0;
 }
 
 
-- 
1.7.1