21ab4e
From 6fd12d2b182da4696d536f5b01a4b6701654b95f Mon Sep 17 00:00:00 2001
21ab4e
From: N Balachandran <nbalacha@redhat.com>
21ab4e
Date: Mon, 26 Jun 2017 21:12:56 +0530
21ab4e
Subject: [PATCH 559/566] cluster/dht: Check if fd is opened on dst subvol
21ab4e
21ab4e
If an fd is opened on a file, the file is migrated
21ab4e
and the cached subvol is updated in the inode_ctx
21ab4e
before an fd based fop is sent, the fop is sent to
21ab4e
the dst subvol on which the fd is not opened.
21ab4e
This causes the FOP to fail with EBADF.
21ab4e
21ab4e
Now, every fd based fop will check to see that the fd
21ab4e
has been opened on the dst subvol before winding it down.
21ab4e
21ab4e
> BUG: 1465075
21ab4e
> Signed-off-by: N Balachandran <nbalacha@redhat.com>
21ab4e
> Reviewed-on: https://review.gluster.org/17630
21ab4e
> Smoke: Gluster Build System <jenkins@build.gluster.org>
21ab4e
> Reviewed-by: Raghavendra G <rgowdapp@redhat.com>
21ab4e
> Reviewed-by: Susant Palai <spalai@redhat.com>
21ab4e
> CentOS-regression: Gluster Build System <jenkins@build.gluster.org>
21ab4e
Signed-off-by: N Balachandran <nbalacha@redhat.com>
21ab4e
21ab4e
Change-Id: I38ad5a7e0ecf86f74cf695e7e65942013ca2d86d
21ab4e
BUG: 1463907
21ab4e
Reviewed-on: https://code.engineering.redhat.com/gerrit/111154
21ab4e
Tested-by: Nithya Balachandran <nbalacha@redhat.com>
21ab4e
Reviewed-by: Atin Mukherjee <amukherj@redhat.com>
21ab4e
---
21ab4e
 xlators/cluster/dht/src/dht-common.c      |   8 +
21ab4e
 xlators/cluster/dht/src/dht-common.h      |  61 +++++++
21ab4e
 xlators/cluster/dht/src/dht-helper.c      | 280 ++++++++++++++++++++++++++++++
21ab4e
 xlators/cluster/dht/src/dht-inode-read.c  |  83 +++++++--
21ab4e
 xlators/cluster/dht/src/dht-inode-write.c | 130 +++++++++++---
21ab4e
 xlators/cluster/dht/src/dht-layout.c      |   5 +
21ab4e
 6 files changed, 537 insertions(+), 30 deletions(-)
21ab4e
21ab4e
diff --git a/xlators/cluster/dht/src/dht-common.c b/xlators/cluster/dht/src/dht-common.c
21ab4e
index 567990b..aebea2f 100644
21ab4e
--- a/xlators/cluster/dht/src/dht-common.c
21ab4e
+++ b/xlators/cluster/dht/src/dht-common.c
21ab4e
@@ -6774,6 +6774,14 @@ dht_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
21ab4e
                                            postparent, 1);
21ab4e
         }
21ab4e
 
21ab4e
+        ret = dht_fd_ctx_set (this, fd, prev);
21ab4e
+        if (ret != 0) {
21ab4e
+                gf_msg_debug (this->name, 0, "Possible fd leak. "
21ab4e
+                              "Could not set fd ctx for subvol %s",
21ab4e
+                              prev->name);
21ab4e
+        }
21ab4e
+
21ab4e
+
21ab4e
         ret = dht_layout_preset (this, prev, inode);
21ab4e
         if (ret != 0) {
21ab4e
                 gf_msg_debug (this->name, 0,
21ab4e
diff --git a/xlators/cluster/dht/src/dht-common.h b/xlators/cluster/dht/src/dht-common.h
21ab4e
index 28e9bbf..8112b01 100644
21ab4e
--- a/xlators/cluster/dht/src/dht-common.h
21ab4e
+++ b/xlators/cluster/dht/src/dht-common.h
21ab4e
@@ -1274,4 +1274,65 @@ dht_remove_stale_linkto (void *data);
21ab4e
 int
21ab4e
 dht_remove_stale_linkto_cbk (int ret, call_frame_t *sync_frame, void *data);
21ab4e
 
21ab4e
+
21ab4e
+int
21ab4e
+dht_fd_ctx_set (xlator_t *this, fd_t *fd, xlator_t *subvol);
21ab4e
+
21ab4e
+int
21ab4e
+dht_check_and_open_fd_on_subvol (xlator_t *this, call_frame_t *frame);
21ab4e
+
21ab4e
+
21ab4e
+/* FD fop callbacks */
21ab4e
+
21ab4e
+int
21ab4e
+dht_writev_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
21ab4e
+                int op_ret, int op_errno, struct iatt *prebuf,
21ab4e
+                struct iatt *postbuf, dict_t *xdata);
21ab4e
+
21ab4e
+int
21ab4e
+dht_flush_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
21ab4e
+               int op_ret, int op_errno, dict_t *xdata);
21ab4e
+
21ab4e
+int
21ab4e
+dht_file_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
21ab4e
+                      int op_ret, int op_errno, struct iatt *prebuf,
21ab4e
+                      struct iatt *postbuf, dict_t *xdata);
21ab4e
+
21ab4e
+int
21ab4e
+dht_zerofill_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
21ab4e
+                int op_ret, int op_errno, struct iatt *prebuf,
21ab4e
+                struct iatt *postbuf, dict_t *xdata);
21ab4e
+
21ab4e
+int
21ab4e
+dht_discard_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
21ab4e
+                int op_ret, int op_errno, struct iatt *prebuf,
21ab4e
+                struct iatt *postbuf, dict_t *xdata);
21ab4e
+
21ab4e
+int
21ab4e
+dht_fallocate_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
21ab4e
+                  int op_ret, int op_errno, struct iatt *prebuf,
21ab4e
+                  struct iatt *postbuf, dict_t *xdata);
21ab4e
+
21ab4e
+int
21ab4e
+dht_truncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
21ab4e
+                  int op_ret, int op_errno, struct iatt *prebuf,
21ab4e
+                  struct iatt *postbuf, dict_t *xdata);
21ab4e
+
21ab4e
+int
21ab4e
+dht_fsync_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int op_ret,
21ab4e
+               int op_errno, struct iatt *prebuf, struct iatt *postbuf,
21ab4e
+               dict_t *xdata);
21ab4e
+
21ab4e
+
21ab4e
+int
21ab4e
+dht_readv_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
21ab4e
+               int op_ret, int op_errno,
21ab4e
+               struct iovec *vector, int count, struct iatt *stbuf,
21ab4e
+               struct iobref *iobref, dict_t *xdata);
21ab4e
+
21ab4e
+int
21ab4e
+dht_file_attr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
21ab4e
+                   int op_ret, int op_errno, struct iatt *stbuf, dict_t *xdata);
21ab4e
+
21ab4e
+
21ab4e
 #endif/* _DHT_H */
21ab4e
diff --git a/xlators/cluster/dht/src/dht-helper.c b/xlators/cluster/dht/src/dht-helper.c
21ab4e
index f6cbe2c..50cdb83 100644
21ab4e
--- a/xlators/cluster/dht/src/dht-helper.c
21ab4e
+++ b/xlators/cluster/dht/src/dht-helper.c
21ab4e
@@ -267,6 +267,286 @@ dht_mig_info_is_invalid (xlator_t *current, xlator_t *src_subvol,
21ab4e
         return _gf_false;
21ab4e
 }
21ab4e
 
21ab4e
+
21ab4e
+
21ab4e
+/* Used to check if fd fops have the fd opened on the cached subvol
21ab4e
+ * This is required when:
21ab4e
+ * 1. an fd is opened on FILE1 on subvol1
21ab4e
+ * 2. the file is migrated to subvol2
21ab4e
+ * 3. a lookup updates the cached subvol in the inode_ctx to subvol2
21ab4e
+ * 4. a write comes on the fd
21ab4e
+ * The write is sent to subvol2 on an fd which has been opened only on fd1
21ab4e
+ * Since the migration phase checks don't kick in, the fop fails with EBADF
21ab4e
+ *
21ab4e
+ */
21ab4e
+
21ab4e
+
21ab4e
+int
21ab4e
+dht_check_and_open_fd_on_subvol_complete (int ret, call_frame_t *frame,
21ab4e
+                                          void *data)
21ab4e
+{
21ab4e
+        glusterfs_fop_t     fop     = 0;
21ab4e
+        dht_local_t        *local   = NULL;
21ab4e
+        xlator_t           *subvol  = NULL;
21ab4e
+        fd_t               *fd      = NULL;
21ab4e
+        int                 op_errno = -1;
21ab4e
+
21ab4e
+        local = frame->local;
21ab4e
+        fop = local->fop;
21ab4e
+        subvol = local->cached_subvol;
21ab4e
+        fd = local->fd;
21ab4e
+
21ab4e
+        if (ret) {
21ab4e
+                op_errno = local->op_errno;
21ab4e
+                goto handle_err;
21ab4e
+        }
21ab4e
+
21ab4e
+        switch (fop) {
21ab4e
+
21ab4e
+        case GF_FOP_WRITE:
21ab4e
+
21ab4e
+                STACK_WIND_COOKIE (frame, dht_writev_cbk, subvol, subvol,
21ab4e
+                                   subvol->fops->writev, fd,
21ab4e
+                                   local->rebalance.vector,
21ab4e
+                                   local->rebalance.count,
21ab4e
+                                   local->rebalance.offset,
21ab4e
+                                   local->rebalance.flags,
21ab4e
+                                   local->rebalance.iobref, local->xattr_req);
21ab4e
+                break;
21ab4e
+
21ab4e
+        case GF_FOP_FLUSH:
21ab4e
+
21ab4e
+                STACK_WIND (frame, dht_flush_cbk, subvol,
21ab4e
+                            subvol->fops->flush, fd, local->xattr_req);
21ab4e
+                break;
21ab4e
+
21ab4e
+        case GF_FOP_FSETATTR:
21ab4e
+
21ab4e
+                STACK_WIND_COOKIE (frame, dht_file_setattr_cbk, subvol,
21ab4e
+                                   subvol, subvol->fops->fsetattr, fd,
21ab4e
+                                   &local->rebalance.stbuf,
21ab4e
+                                   local->rebalance.flags,
21ab4e
+                                   local->xattr_req);
21ab4e
+                break;
21ab4e
+
21ab4e
+        case GF_FOP_ZEROFILL:
21ab4e
+                STACK_WIND_COOKIE (frame, dht_zerofill_cbk, subvol, subvol,
21ab4e
+                                   subvol->fops->zerofill, fd,
21ab4e
+                                   local->rebalance.offset,
21ab4e
+                                   local->rebalance.size, local->xattr_req);
21ab4e
+
21ab4e
+                break;
21ab4e
+
21ab4e
+        case GF_FOP_DISCARD:
21ab4e
+                STACK_WIND_COOKIE (frame, dht_discard_cbk, subvol, subvol,
21ab4e
+                                   subvol->fops->discard, local->fd,
21ab4e
+                                   local->rebalance.offset,
21ab4e
+                                   local->rebalance.size,
21ab4e
+                                   local->xattr_req);
21ab4e
+                break;
21ab4e
+
21ab4e
+        case GF_FOP_FALLOCATE:
21ab4e
+                STACK_WIND_COOKIE (frame, dht_fallocate_cbk, subvol, subvol,
21ab4e
+                                   subvol->fops->fallocate, fd,
21ab4e
+                                   local->rebalance.flags,
21ab4e
+                                   local->rebalance.offset,
21ab4e
+                                   local->rebalance.size,
21ab4e
+                                   local->xattr_req);
21ab4e
+                break;
21ab4e
+
21ab4e
+        case GF_FOP_FTRUNCATE:
21ab4e
+                STACK_WIND_COOKIE (frame, dht_truncate_cbk, subvol, subvol,
21ab4e
+                                   subvol->fops->ftruncate, fd,
21ab4e
+                                   local->rebalance.offset, local->xattr_req);
21ab4e
+                break;
21ab4e
+
21ab4e
+        case GF_FOP_FSYNC:
21ab4e
+                STACK_WIND_COOKIE (frame, dht_fsync_cbk, subvol, subvol,
21ab4e
+                                   subvol->fops->fsync, local->fd,
21ab4e
+                                   local->rebalance.flags, local->xattr_req);
21ab4e
+                break;
21ab4e
+
21ab4e
+        case GF_FOP_READ:
21ab4e
+                STACK_WIND (frame, dht_readv_cbk, subvol, subvol->fops->readv,
21ab4e
+                            local->fd, local->rebalance.size,
21ab4e
+                            local->rebalance.offset,
21ab4e
+                            local->rebalance.flags, local->xattr_req);
21ab4e
+                break;
21ab4e
+
21ab4e
+        case GF_FOP_FSTAT:
21ab4e
+                STACK_WIND_COOKIE (frame, dht_file_attr_cbk, subvol,
21ab4e
+                                   subvol, subvol->fops->fstat, fd,
21ab4e
+                                   local->xattr_req);
21ab4e
+                break;
21ab4e
+
21ab4e
+        default:
21ab4e
+                break;
21ab4e
+
21ab4e
+        }
21ab4e
+
21ab4e
+        goto out;
21ab4e
+
21ab4e
+        /* Could not open the fd on the dst. Unwind */
21ab4e
+
21ab4e
+handle_err:
21ab4e
+
21ab4e
+        switch (fop) {
21ab4e
+
21ab4e
+        case GF_FOP_WRITE:
21ab4e
+                DHT_STACK_UNWIND (writev, frame, -1,
21ab4e
+                                  op_errno, NULL, NULL, NULL);
21ab4e
+                break;
21ab4e
+
21ab4e
+        case GF_FOP_FLUSH:
21ab4e
+                DHT_STACK_UNWIND (flush, frame, -1, op_errno, NULL);
21ab4e
+                break;
21ab4e
+
21ab4e
+        case GF_FOP_FSETATTR:
21ab4e
+                DHT_STACK_UNWIND (fsetattr, frame, -1, op_errno,
21ab4e
+                                  NULL, NULL, NULL);
21ab4e
+                break;
21ab4e
+
21ab4e
+        case GF_FOP_ZEROFILL:
21ab4e
+                DHT_STACK_UNWIND (zerofill, frame, -1, op_errno,
21ab4e
+                                  NULL, NULL, NULL);
21ab4e
+                break;
21ab4e
+
21ab4e
+        case GF_FOP_DISCARD:
21ab4e
+                DHT_STACK_UNWIND (discard, frame, -1, op_errno,
21ab4e
+                                  NULL, NULL, NULL);
21ab4e
+                break;
21ab4e
+
21ab4e
+        case GF_FOP_FALLOCATE:
21ab4e
+                DHT_STACK_UNWIND (fallocate, frame, -1, op_errno,
21ab4e
+                                  NULL, NULL, NULL);
21ab4e
+                break;
21ab4e
+
21ab4e
+        case GF_FOP_FTRUNCATE:
21ab4e
+                DHT_STACK_UNWIND (ftruncate, frame, -1, op_errno,
21ab4e
+                                  NULL, NULL, NULL);
21ab4e
+                break;
21ab4e
+
21ab4e
+        case GF_FOP_FSYNC:
21ab4e
+                DHT_STACK_UNWIND (fsync, frame, -1, op_errno, NULL, NULL, NULL);
21ab4e
+                break;
21ab4e
+
21ab4e
+        case GF_FOP_READ:
21ab4e
+                DHT_STACK_UNWIND (readv, frame, -1, op_errno, NULL,
21ab4e
+                                  0, NULL, NULL, NULL);
21ab4e
+                break;
21ab4e
+
21ab4e
+        case GF_FOP_FSTAT:
21ab4e
+                DHT_STACK_UNWIND (fstat, frame, -1, op_errno, NULL, NULL);
21ab4e
+                break;
21ab4e
+
21ab4e
+        default:
21ab4e
+                break;
21ab4e
+        }
21ab4e
+
21ab4e
+out:
21ab4e
+
21ab4e
+        return 0;
21ab4e
+
21ab4e
+}
21ab4e
+
21ab4e
+
21ab4e
+/* Check once again if the fd has been opened on the cached subvol.
21ab4e
+ * If not, open and update the fd_ctx.
21ab4e
+ */
21ab4e
+
21ab4e
+int
21ab4e
+dht_check_and_open_fd_on_subvol_task (void *data)
21ab4e
+{
21ab4e
+        loc_t          loc        = {0,};
21ab4e
+        int            ret        = -1;
21ab4e
+        call_frame_t  *frame      = NULL;
21ab4e
+        dht_local_t   *local      = NULL;
21ab4e
+        fd_t          *fd         = NULL;
21ab4e
+        xlator_t      *this       = NULL;
21ab4e
+        xlator_t      *subvol     = NULL;
21ab4e
+
21ab4e
+
21ab4e
+        frame = data;
21ab4e
+        local = frame->local;
21ab4e
+        this = THIS;
21ab4e
+        fd = local->fd;
21ab4e
+        subvol = local->cached_subvol;
21ab4e
+
21ab4e
+
21ab4e
+        if (fd_is_anonymous (fd) || dht_fd_open_on_dst (this, fd, subvol)) {
21ab4e
+                ret = 0;
21ab4e
+                goto out;
21ab4e
+        }
21ab4e
+
21ab4e
+        gf_msg_debug (this->name, 0,
21ab4e
+                      "Opening fd (%p, flags=0%o) on file %s @ %s",
21ab4e
+                      fd, fd->flags, uuid_utoa (fd->inode->gfid),
21ab4e
+                      subvol->name);
21ab4e
+
21ab4e
+
21ab4e
+        loc.inode = inode_ref (fd->inode);
21ab4e
+        gf_uuid_copy (loc.gfid, fd->inode->gfid);
21ab4e
+
21ab4e
+        /* Open this on the dst subvol */
21ab4e
+
21ab4e
+        SYNCTASK_SETID(0, 0);
21ab4e
+
21ab4e
+        ret = syncop_open (subvol, &loc,
21ab4e
+                           (fd->flags & ~(O_CREAT | O_EXCL | O_TRUNC)),
21ab4e
+                           fd, NULL, NULL);
21ab4e
+
21ab4e
+        if (ret < 0) {
21ab4e
+
21ab4e
+                gf_msg (this->name, GF_LOG_ERROR, -ret,
21ab4e
+                        DHT_MSG_OPEN_FD_ON_DST_FAILED,
21ab4e
+                        "Failed to open the fd"
21ab4e
+                        " (%p, flags=0%o) on file %s @ %s",
21ab4e
+                        fd, fd->flags, uuid_utoa (fd->inode->gfid),
21ab4e
+                        subvol->name);
21ab4e
+
21ab4e
+                local->op_errno = -ret;
21ab4e
+                ret = -1;
21ab4e
+
21ab4e
+        } else {
21ab4e
+                dht_fd_ctx_set (this, fd, subvol);
21ab4e
+        }
21ab4e
+
21ab4e
+        SYNCTASK_SETID (frame->root->uid, frame->root->gid);
21ab4e
+out:
21ab4e
+        loc_wipe (&loc;;
21ab4e
+
21ab4e
+        return ret;
21ab4e
+}
21ab4e
+
21ab4e
+
21ab4e
+int
21ab4e
+dht_check_and_open_fd_on_subvol (xlator_t *this, call_frame_t *frame)
21ab4e
+{
21ab4e
+        int ret            = -1;
21ab4e
+        dht_local_t *local = NULL;
21ab4e
+
21ab4e
+/*
21ab4e
+        if (dht_fd_open_on_dst (this, fd, subvol))
21ab4e
+                goto out;
21ab4e
+*/
21ab4e
+        local = frame->local;
21ab4e
+
21ab4e
+        ret = synctask_new (this->ctx->env,
21ab4e
+                            dht_check_and_open_fd_on_subvol_task,
21ab4e
+                            dht_check_and_open_fd_on_subvol_complete,
21ab4e
+                            frame, frame);
21ab4e
+
21ab4e
+        if (ret) {
21ab4e
+                gf_msg (this->name, GF_LOG_ERROR, 0, 0,
21ab4e
+                        "Failed to create synctask"
21ab4e
+                        " to check and open fd=%p", local->fd);
21ab4e
+        }
21ab4e
+
21ab4e
+        return ret;
21ab4e
+}
21ab4e
+
21ab4e
+
21ab4e
+
21ab4e
 int
21ab4e
 dht_frame_return (call_frame_t *frame)
21ab4e
 {
21ab4e
diff --git a/xlators/cluster/dht/src/dht-inode-read.c b/xlators/cluster/dht/src/dht-inode-read.c
21ab4e
index c53662d..58a0430 100644
21ab4e
--- a/xlators/cluster/dht/src/dht-inode-read.c
21ab4e
+++ b/xlators/cluster/dht/src/dht-inode-read.c
21ab4e
@@ -46,6 +46,12 @@ dht_open_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
21ab4e
                 goto out;
21ab4e
         }
21ab4e
 
21ab4e
+        /* Update ctx if the fd has been opened on the target*/
21ab4e
+        if (!op_ret && (local->call_cnt == 1)) {
21ab4e
+                dht_fd_ctx_set (this, fd, prev);
21ab4e
+                goto out;
21ab4e
+        }
21ab4e
+
21ab4e
         if (!op_ret || (local->call_cnt != 1))
21ab4e
                 goto out;
21ab4e
 
21ab4e
@@ -371,6 +377,7 @@ dht_fstat (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
21ab4e
         dht_layout_t *layout = NULL;
21ab4e
         int           i = 0;
21ab4e
         int           call_cnt = 0;
21ab4e
+        int           ret      = -1;
21ab4e
 
21ab4e
 
21ab4e
         VALIDATE_OR_GOTO (frame, err);
21ab4e
@@ -397,9 +404,18 @@ dht_fstat (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
21ab4e
                 local->call_cnt = 1;
21ab4e
 
21ab4e
                 subvol = local->cached_subvol;
21ab4e
+                if (dht_fd_open_on_dst (this, fd, subvol)) {
21ab4e
 
21ab4e
-                STACK_WIND_COOKIE (frame, dht_file_attr_cbk, subvol, subvol,
21ab4e
-                                   subvol->fops->fstat, fd, xdata);
21ab4e
+                        STACK_WIND_COOKIE (frame, dht_file_attr_cbk, subvol,
21ab4e
+                                           subvol, subvol->fops->fstat, fd,
21ab4e
+                                           xdata);
21ab4e
+
21ab4e
+                } else {
21ab4e
+                        ret = dht_check_and_open_fd_on_subvol (this, frame);
21ab4e
+
21ab4e
+                        if (ret)
21ab4e
+                                goto err;
21ab4e
+                }
21ab4e
 
21ab4e
                 return 0;
21ab4e
         }
21ab4e
@@ -529,6 +545,7 @@ dht_readv (call_frame_t *frame, xlator_t *this,
21ab4e
         xlator_t     *subvol = NULL;
21ab4e
         int           op_errno = -1;
21ab4e
         dht_local_t  *local = NULL;
21ab4e
+        int           ret      = -1;
21ab4e
 
21ab4e
         VALIDATE_OR_GOTO (frame, err);
21ab4e
         VALIDATE_OR_GOTO (this, err);
21ab4e
@@ -547,6 +564,7 @@ dht_readv (call_frame_t *frame, xlator_t *this,
21ab4e
                 op_errno = EINVAL;
21ab4e
                 goto err;
21ab4e
         }
21ab4e
+
21ab4e
         if (xdata)
21ab4e
                 local->xattr_req = dict_ref (xdata);
21ab4e
 
21ab4e
@@ -555,9 +573,19 @@ dht_readv (call_frame_t *frame, xlator_t *this,
21ab4e
         local->rebalance.flags  = flags;
21ab4e
         local->call_cnt = 1;
21ab4e
 
21ab4e
-        STACK_WIND (frame, dht_readv_cbk,
21ab4e
-                    subvol, subvol->fops->readv,
21ab4e
-                    fd, size, off, flags, xdata);
21ab4e
+        if (dht_fd_open_on_dst (this, fd, subvol)) {
21ab4e
+
21ab4e
+                STACK_WIND (frame, dht_readv_cbk, subvol, subvol->fops->readv,
21ab4e
+                            local->fd, local->rebalance.size,
21ab4e
+                            local->rebalance.offset,
21ab4e
+                            local->rebalance.flags, local->xattr_req);
21ab4e
+
21ab4e
+        } else {
21ab4e
+                ret = dht_check_and_open_fd_on_subvol (this, frame);
21ab4e
+                if (ret)
21ab4e
+                        goto err;
21ab4e
+        }
21ab4e
+
21ab4e
 
21ab4e
         return 0;
21ab4e
 
21ab4e
@@ -776,6 +804,7 @@ dht_flush (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
21ab4e
         xlator_t     *subvol = NULL;
21ab4e
         int           op_errno = -1;
21ab4e
         dht_local_t  *local = NULL;
21ab4e
+        int           ret      = -1;
21ab4e
 
21ab4e
         VALIDATE_OR_GOTO (frame, err);
21ab4e
         VALIDATE_OR_GOTO (this, err);
21ab4e
@@ -794,14 +823,24 @@ dht_flush (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
21ab4e
                 op_errno = EINVAL;
21ab4e
                 goto err;
21ab4e
         }
21ab4e
+
21ab4e
         if (xdata)
21ab4e
                 local->xattr_req = dict_ref (xdata);
21ab4e
 
21ab4e
         local->call_cnt = 1;
21ab4e
 
21ab4e
-        STACK_WIND (frame, dht_flush_cbk,
21ab4e
-                    subvol, subvol->fops->flush, fd, xdata);
21ab4e
+        if (dht_fd_open_on_dst (this, fd, subvol)) {
21ab4e
+
21ab4e
+                STACK_WIND (frame, dht_flush_cbk,
21ab4e
+                            subvol, subvol->fops->flush, fd, local->xattr_req);
21ab4e
+                return 0;
21ab4e
 
21ab4e
+        } else {
21ab4e
+
21ab4e
+                ret = dht_check_and_open_fd_on_subvol (this, frame);
21ab4e
+                if (ret)
21ab4e
+                        goto err;
21ab4e
+        }
21ab4e
         return 0;
21ab4e
 
21ab4e
 err:
21ab4e
@@ -935,6 +974,7 @@ dht_fsync (call_frame_t *frame, xlator_t *this, fd_t *fd, int datasync,
21ab4e
         xlator_t     *subvol = NULL;
21ab4e
         int           op_errno = -1;
21ab4e
         dht_local_t  *local = NULL;
21ab4e
+        int           ret      = -1;
21ab4e
 
21ab4e
         VALIDATE_OR_GOTO (frame, err);
21ab4e
         VALIDATE_OR_GOTO (this, err);
21ab4e
@@ -954,8 +994,19 @@ dht_fsync (call_frame_t *frame, xlator_t *this, fd_t *fd, int datasync,
21ab4e
 
21ab4e
         subvol = local->cached_subvol;
21ab4e
 
21ab4e
-        STACK_WIND_COOKIE (frame, dht_fsync_cbk, subvol, subvol,
21ab4e
-                           subvol->fops->fsync, fd, datasync, xdata);
21ab4e
+
21ab4e
+        if (dht_fd_open_on_dst (this, fd, subvol)) {
21ab4e
+
21ab4e
+                STACK_WIND_COOKIE (frame, dht_fsync_cbk, subvol, subvol,
21ab4e
+                                   subvol->fops->fsync, local->fd,
21ab4e
+                                   local->rebalance.flags, local->xattr_req);
21ab4e
+
21ab4e
+        } else {
21ab4e
+                ret = dht_check_and_open_fd_on_subvol (this, frame);
21ab4e
+                if (ret)
21ab4e
+                        goto err;
21ab4e
+        }
21ab4e
+
21ab4e
 
21ab4e
         return 0;
21ab4e
 
21ab4e
@@ -1073,6 +1124,13 @@ dht_lk (call_frame_t *frame, xlator_t *this,
21ab4e
                 op_errno = EINVAL;
21ab4e
                 goto err;
21ab4e
         }
21ab4e
+
21ab4e
+/*
21ab4e
+        local->cached_subvol = lock_subvol;
21ab4e
+        ret = dht_check_and_open_fd_on_subvol (this, frame);
21ab4e
+        if (ret)
21ab4e
+                goto err;
21ab4e
+*/
21ab4e
         if (xdata)
21ab4e
                 local->xattr_req = dict_ref (xdata);
21ab4e
 
21ab4e
@@ -1399,7 +1457,12 @@ dht_finodelk (call_frame_t *frame, xlator_t *this, const char *volume,
21ab4e
                 goto err;
21ab4e
         }
21ab4e
 
21ab4e
-
21ab4e
+/*
21ab4e
+        local->cached_subvol = lock_subvol;
21ab4e
+        ret = dht_check_and_open_fd_on_subvol (this, frame);
21ab4e
+        if (ret)
21ab4e
+                goto err;
21ab4e
+*/
21ab4e
         STACK_WIND (frame, dht_finodelk_cbk, lock_subvol,
21ab4e
                     lock_subvol->fops->finodelk,
21ab4e
                     volume, fd, cmd, lock, xdata);
21ab4e
diff --git a/xlators/cluster/dht/src/dht-inode-write.c b/xlators/cluster/dht/src/dht-inode-write.c
21ab4e
index 825822a..f925d4b 100644
21ab4e
--- a/xlators/cluster/dht/src/dht-inode-write.c
21ab4e
+++ b/xlators/cluster/dht/src/dht-inode-write.c
21ab4e
@@ -159,9 +159,10 @@ dht_writev (call_frame_t *frame, xlator_t *this, fd_t *fd,
21ab4e
             struct iovec *vector, int count, off_t off, uint32_t flags,
21ab4e
             struct iobref *iobref, dict_t *xdata)
21ab4e
 {
21ab4e
-        xlator_t     *subvol = NULL;
21ab4e
+        xlator_t     *subvol   = NULL;
21ab4e
         int           op_errno = -1;
21ab4e
-        dht_local_t  *local = NULL;
21ab4e
+        dht_local_t  *local    = NULL;
21ab4e
+        int           ret      = -1;
21ab4e
 
21ab4e
         VALIDATE_OR_GOTO (frame, err);
21ab4e
         VALIDATE_OR_GOTO (this, err);
21ab4e
@@ -181,6 +182,8 @@ dht_writev (call_frame_t *frame, xlator_t *this, fd_t *fd,
21ab4e
                 op_errno = EINVAL;
21ab4e
                 goto err;
21ab4e
         }
21ab4e
+
21ab4e
+
21ab4e
         if (xdata)
21ab4e
                 local->xattr_req = dict_ref (xdata);
21ab4e
 
21ab4e
@@ -191,9 +194,22 @@ dht_writev (call_frame_t *frame, xlator_t *this, fd_t *fd,
21ab4e
         local->rebalance.iobref = iobref_ref (iobref);
21ab4e
         local->call_cnt = 1;
21ab4e
 
21ab4e
-        STACK_WIND_COOKIE (frame, dht_writev_cbk, subvol, subvol,
21ab4e
-                           subvol->fops->writev, fd, vector, count, off, flags,
21ab4e
-                           iobref, xdata);
21ab4e
+        if (dht_fd_open_on_dst (this, fd, subvol)) {
21ab4e
+
21ab4e
+                STACK_WIND_COOKIE (frame, dht_writev_cbk, subvol, subvol,
21ab4e
+                                   subvol->fops->writev, fd,
21ab4e
+                                   local->rebalance.vector,
21ab4e
+                                   local->rebalance.count,
21ab4e
+                                   local->rebalance.offset,
21ab4e
+                                   local->rebalance.flags,
21ab4e
+                                   local->rebalance.iobref, local->xattr_req);
21ab4e
+                return 0;
21ab4e
+
21ab4e
+        } else {
21ab4e
+                ret = dht_check_and_open_fd_on_subvol (this, frame);
21ab4e
+                if (ret)
21ab4e
+                        goto err;
21ab4e
+        }
21ab4e
 
21ab4e
         return 0;
21ab4e
 
21ab4e
@@ -218,6 +234,7 @@ dht_truncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
21ab4e
         xlator_t     *dst_subvol = NULL;
21ab4e
         inode_t      *inode      = NULL;
21ab4e
 
21ab4e
+
21ab4e
         GF_VALIDATE_OR_GOTO ("dht", frame, err);
21ab4e
         GF_VALIDATE_OR_GOTO ("dht", this, out);
21ab4e
         GF_VALIDATE_OR_GOTO ("dht", frame->local, out);
21ab4e
@@ -368,6 +385,7 @@ dht_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset,
21ab4e
                 op_errno = EINVAL;
21ab4e
                 goto err;
21ab4e
         }
21ab4e
+
21ab4e
         if (xdata)
21ab4e
                 local->xattr_req = dict_ref (xdata);
21ab4e
 
21ab4e
@@ -390,6 +408,8 @@ dht_ftruncate (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
21ab4e
         xlator_t     *subvol = NULL;
21ab4e
         int           op_errno = -1;
21ab4e
         dht_local_t  *local = NULL;
21ab4e
+        int           ret   = -1;
21ab4e
+
21ab4e
 
21ab4e
         VALIDATE_OR_GOTO (frame, err);
21ab4e
         VALIDATE_OR_GOTO (this, err);
21ab4e
@@ -410,11 +430,23 @@ dht_ftruncate (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
21ab4e
                 op_errno = EINVAL;
21ab4e
                 goto err;
21ab4e
         }
21ab4e
+
21ab4e
         if (xdata)
21ab4e
                 local->xattr_req = dict_ref (xdata);
21ab4e
 
21ab4e
-        STACK_WIND_COOKIE (frame, dht_truncate_cbk, subvol, subvol,
21ab4e
-                           subvol->fops->ftruncate, fd, offset, xdata);
21ab4e
+        if (dht_fd_open_on_dst (this, fd, subvol)) {
21ab4e
+
21ab4e
+                STACK_WIND_COOKIE (frame, dht_truncate_cbk, subvol, subvol,
21ab4e
+                                   subvol->fops->ftruncate, fd,
21ab4e
+                                   local->rebalance.offset, local->xattr_req);
21ab4e
+                return 0;
21ab4e
+
21ab4e
+        } else {
21ab4e
+
21ab4e
+                ret = dht_check_and_open_fd_on_subvol (this, frame);
21ab4e
+                if (ret)
21ab4e
+                        goto err;
21ab4e
+        }
21ab4e
 
21ab4e
         return 0;
21ab4e
 
21ab4e
@@ -548,12 +580,13 @@ out:
21ab4e
 }
21ab4e
 
21ab4e
 int
21ab4e
-dht_fallocate(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t mode,
21ab4e
+dht_fallocate (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t mode,
21ab4e
 	      off_t offset, size_t len, dict_t *xdata)
21ab4e
 {
21ab4e
         xlator_t     *subvol = NULL;
21ab4e
         int           op_errno = -1;
21ab4e
         dht_local_t  *local = NULL;
21ab4e
+        int           ret      = -1;
21ab4e
 
21ab4e
         VALIDATE_OR_GOTO (frame, err);
21ab4e
         VALIDATE_OR_GOTO (this, err);
21ab4e
@@ -577,12 +610,26 @@ dht_fallocate(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t mode,
21ab4e
                 op_errno = EINVAL;
21ab4e
                 goto err;
21ab4e
         }
21ab4e
+
21ab4e
         if (xdata)
21ab4e
                 local->xattr_req = dict_ref (xdata);
21ab4e
 
21ab4e
-        STACK_WIND_COOKIE (frame, dht_fallocate_cbk, subvol, subvol,
21ab4e
-                           subvol->fops->fallocate, fd, mode, offset, len,
21ab4e
-                           xdata);
21ab4e
+        if (dht_fd_open_on_dst (this, fd, subvol)) {
21ab4e
+
21ab4e
+                STACK_WIND_COOKIE (frame, dht_fallocate_cbk, subvol, subvol,
21ab4e
+                                   subvol->fops->fallocate, fd,
21ab4e
+                                   local->rebalance.flags,
21ab4e
+                                   local->rebalance.offset,
21ab4e
+                                   local->rebalance.size,
21ab4e
+                                   local->xattr_req);
21ab4e
+                return 0;
21ab4e
+
21ab4e
+        } else {
21ab4e
+
21ab4e
+                ret = dht_check_and_open_fd_on_subvol (this, frame);
21ab4e
+                if (ret)
21ab4e
+                        goto err;
21ab4e
+        }
21ab4e
 
21ab4e
         return 0;
21ab4e
 
21ab4e
@@ -716,12 +763,13 @@ out:
21ab4e
 }
21ab4e
 
21ab4e
 int
21ab4e
-dht_discard(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
21ab4e
+dht_discard (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
21ab4e
 	    size_t len, dict_t *xdata)
21ab4e
 {
21ab4e
         xlator_t     *subvol = NULL;
21ab4e
         int           op_errno = -1;
21ab4e
         dht_local_t  *local = NULL;
21ab4e
+        int           ret      = -1;
21ab4e
 
21ab4e
         VALIDATE_OR_GOTO (frame, err);
21ab4e
         VALIDATE_OR_GOTO (this, err);
21ab4e
@@ -744,11 +792,26 @@ dht_discard(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
21ab4e
                 op_errno = EINVAL;
21ab4e
                 goto err;
21ab4e
         }
21ab4e
+
21ab4e
         if (xdata)
21ab4e
                 local->xattr_req = dict_ref (xdata);
21ab4e
 
21ab4e
-        STACK_WIND_COOKIE (frame, dht_discard_cbk, subvol, subvol,
21ab4e
-                           subvol->fops->discard, fd, offset, len, xdata);
21ab4e
+        if (dht_fd_open_on_dst (this, fd, subvol)) {
21ab4e
+
21ab4e
+                STACK_WIND_COOKIE (frame, dht_discard_cbk, subvol, subvol,
21ab4e
+                                   subvol->fops->discard, fd,
21ab4e
+                                   local->rebalance.offset,
21ab4e
+                                   local->rebalance.size,
21ab4e
+                                   local->xattr_req);
21ab4e
+                return 0;
21ab4e
+
21ab4e
+        } else {
21ab4e
+
21ab4e
+                ret = dht_check_and_open_fd_on_subvol (this, frame);
21ab4e
+                if (ret)
21ab4e
+                        goto err;
21ab4e
+
21ab4e
+        }
21ab4e
 
21ab4e
         return 0;
21ab4e
 
21ab4e
@@ -883,12 +946,13 @@ out:
21ab4e
 }
21ab4e
 
21ab4e
 int
21ab4e
-dht_zerofill(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
21ab4e
+dht_zerofill (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
21ab4e
             off_t len, dict_t *xdata)
21ab4e
 {
21ab4e
         xlator_t     *subvol       = NULL;
21ab4e
         int           op_errno     = -1;
21ab4e
         dht_local_t  *local        = NULL;
21ab4e
+        int           ret          = -1;
21ab4e
 
21ab4e
         VALIDATE_OR_GOTO (frame, err);
21ab4e
         VALIDATE_OR_GOTO (this, err);
21ab4e
@@ -911,11 +975,25 @@ dht_zerofill(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
21ab4e
                 op_errno = EINVAL;
21ab4e
                 goto err;
21ab4e
         }
21ab4e
+
21ab4e
         if (xdata)
21ab4e
                 local->xattr_req = dict_ref (xdata);
21ab4e
 
21ab4e
-        STACK_WIND_COOKIE (frame, dht_zerofill_cbk, subvol, subvol,
21ab4e
-                           subvol->fops->zerofill, fd, offset, len, xdata);
21ab4e
+        if (dht_fd_open_on_dst (this, fd, subvol)) {
21ab4e
+
21ab4e
+                STACK_WIND_COOKIE (frame, dht_zerofill_cbk, subvol, subvol,
21ab4e
+                                   subvol->fops->zerofill, fd,
21ab4e
+                                   local->rebalance.offset,
21ab4e
+                                   local->rebalance.size, local->xattr_req);
21ab4e
+                return 0;
21ab4e
+
21ab4e
+        } else {
21ab4e
+
21ab4e
+                ret = dht_check_and_open_fd_on_subvol (this, frame);
21ab4e
+                if (ret)
21ab4e
+                        goto err;
21ab4e
+        }
21ab4e
+
21ab4e
 
21ab4e
         return 0;
21ab4e
 
21ab4e
@@ -1163,6 +1241,7 @@ dht_fsetattr (call_frame_t *frame, xlator_t *this, fd_t *fd, struct iatt *stbuf,
21ab4e
         int           op_errno = -1;
21ab4e
         int           i = -1;
21ab4e
         int           call_cnt = 0;
21ab4e
+        int           ret      = -1;
21ab4e
 
21ab4e
 
21ab4e
         VALIDATE_OR_GOTO (frame, err);
21ab4e
@@ -1200,10 +1279,21 @@ dht_fsetattr (call_frame_t *frame, xlator_t *this, fd_t *fd, struct iatt *stbuf,
21ab4e
                 local->call_cnt = 1;
21ab4e
                 subvol = local->cached_subvol;
21ab4e
 
21ab4e
-                STACK_WIND_COOKIE (frame, dht_file_setattr_cbk, subvol,
21ab4e
-                                   subvol, subvol->fops->fsetattr, fd, stbuf,
21ab4e
-                                   valid, xdata);
21ab4e
+                if (dht_fd_open_on_dst (this, fd, subvol)) {
21ab4e
+
21ab4e
+                        STACK_WIND_COOKIE (frame, dht_file_setattr_cbk, subvol,
21ab4e
+                                           subvol, subvol->fops->fsetattr, fd,
21ab4e
+                                           &local->rebalance.stbuf,
21ab4e
+                                           local->rebalance.flags,
21ab4e
+                                           local->xattr_req);
21ab4e
+                        return 0;
21ab4e
+
21ab4e
+                } else {
21ab4e
+                        ret = dht_check_and_open_fd_on_subvol (this, frame);
21ab4e
+                        if (ret)
21ab4e
+                                goto err;
21ab4e
 
21ab4e
+                }
21ab4e
                 return 0;
21ab4e
         }
21ab4e
 
21ab4e
diff --git a/xlators/cluster/dht/src/dht-layout.c b/xlators/cluster/dht/src/dht-layout.c
21ab4e
index 4352ffe..3414dc9 100644
21ab4e
--- a/xlators/cluster/dht/src/dht-layout.c
21ab4e
+++ b/xlators/cluster/dht/src/dht-layout.c
21ab4e
@@ -855,6 +855,7 @@ dht_layout_preset (xlator_t *this, xlator_t *subvol, inode_t *inode)
21ab4e
         if (!conf)
21ab4e
                 goto out;
21ab4e
 
21ab4e
+
21ab4e
         layout = dht_layout_for_subvol (this, subvol);
21ab4e
         if (!layout) {
21ab4e
                 gf_msg (this->name, GF_LOG_INFO, 0,
21ab4e
@@ -865,10 +866,14 @@ dht_layout_preset (xlator_t *this, xlator_t *subvol, inode_t *inode)
21ab4e
                 goto out;
21ab4e
         }
21ab4e
 
21ab4e
+        gf_msg_debug (this->name, 0, "file = %s, subvol = %s",
21ab4e
+                      uuid_utoa (inode->gfid), subvol ? subvol->name : "<nil>");
21ab4e
+
21ab4e
         LOCK (&conf->layout_lock);
21ab4e
         {
21ab4e
                 dht_inode_ctx_layout_set (inode, this, layout);
21ab4e
         }
21ab4e
+
21ab4e
         UNLOCK (&conf->layout_lock);
21ab4e
 
21ab4e
         ret = 0;
21ab4e
-- 
21ab4e
1.8.3.1
21ab4e