21ab4e
From 5ad413d493042d938a021ef944e3c88184b96e68 Mon Sep 17 00:00:00 2001
21ab4e
From: N Balachandran <nbalacha@redhat.com>
21ab4e
Date: Fri, 4 Aug 2017 14:46:38 +0530
21ab4e
Subject: [PATCH 594/601] cluster/dht: Check for open fd only on EBADF
21ab4e
21ab4e
DHT fd based fops used to check if the fd was open
21ab4e
on the cached subvol before winding the call. However,
21ab4e
this introduced a performance regression of about
21ab4e
30% for reads.
21ab4e
21ab4e
This check was introduced to handle cases where files
21ab4e
were migrated while IOs were happening. As this is not
21ab4e
the common case, dht will now check if the fd is
21ab4e
open on the cached subvol only if the call fails
21ab4e
with EBADF.
21ab4e
21ab4e
This will prevent a performance hit where a rebalance
21ab4e
is not running.
21ab4e
21ab4e
> BUG: 1476665
21ab4e
> Signed-off-by: N Balachandran <nbalacha@redhat.com>
21ab4e
> Reviewed-on: https://review.gluster.org/17976
21ab4e
> Smoke: Gluster Build System <jenkins@build.gluster.org>
21ab4e
> CentOS-regression: Gluster Build System <jenkins@build.gluster.org>
21ab4e
> Reviewed-by: Amar Tumballi <amarts@redhat.com>
21ab4e
> Reviewed-by: Susant Palai <spalai@redhat.com>
21ab4e
> Reviewed-by: Raghavendra G <rgowdapp@redhat.com>
21ab4e
21ab4e
> (cherry picked from commit cdca1cb26a0aba390c6d8485c0d6d95e22ffc8bd)
21ab4e
> BUG: 1479303
21ab4e
> Signed-off-by: N Balachandran <nbalacha@redhat.com>
21ab4e
21ab4e
Change-Id: I2035a858d63c3fcd22bb634055bbb0ad01686808
21ab4e
BUG: 1475136
21ab4e
Signed-off-by: N Balachandran <nbalacha@redhat.com>
21ab4e
Reviewed-on: https://code.engineering.redhat.com/gerrit/114677
21ab4e
Reviewed-by: Atin Mukherjee <amukherj@redhat.com>
21ab4e
---
21ab4e
 xlators/cluster/dht/src/dht-common.h      |   3 +
21ab4e
 xlators/cluster/dht/src/dht-helper.c      |   1 +
21ab4e
 xlators/cluster/dht/src/dht-inode-read.c  | 106 +++++++--------
21ab4e
 xlators/cluster/dht/src/dht-inode-write.c | 210 ++++++++++++++++--------------
21ab4e
 xlators/storage/posix/src/posix.c         |   3 +-
21ab4e
 5 files changed, 162 insertions(+), 161 deletions(-)
21ab4e
21ab4e
diff --git a/xlators/cluster/dht/src/dht-common.h b/xlators/cluster/dht/src/dht-common.h
21ab4e
index 6db4c06..5f125ee 100644
21ab4e
--- a/xlators/cluster/dht/src/dht-common.h
21ab4e
+++ b/xlators/cluster/dht/src/dht-common.h
21ab4e
@@ -292,6 +292,9 @@ struct dht_local {
21ab4e
 
21ab4e
         call_stub_t *stub;
21ab4e
         int32_t      parent_disk_layout[4];
21ab4e
+
21ab4e
+        /* fd open check */
21ab4e
+        gf_boolean_t fd_checked;
21ab4e
 };
21ab4e
 typedef struct dht_local dht_local_t;
21ab4e
 
21ab4e
diff --git a/xlators/cluster/dht/src/dht-helper.c b/xlators/cluster/dht/src/dht-helper.c
21ab4e
index 6bad5db..ca9184f 100644
21ab4e
--- a/xlators/cluster/dht/src/dht-helper.c
21ab4e
+++ b/xlators/cluster/dht/src/dht-helper.c
21ab4e
@@ -484,6 +484,7 @@ dht_check_and_open_fd_on_subvol_task (void *data)
21ab4e
         fd = local->fd;
21ab4e
         subvol = local->cached_subvol;
21ab4e
 
21ab4e
+        local->fd_checked = _gf_true;
21ab4e
 
21ab4e
         if (fd_is_anonymous (fd) || dht_fd_open_on_dst (this, fd, subvol)) {
21ab4e
                 ret = 0;
21ab4e
diff --git a/xlators/cluster/dht/src/dht-inode-read.c b/xlators/cluster/dht/src/dht-inode-read.c
21ab4e
index 58a0430..a9e4766 100644
21ab4e
--- a/xlators/cluster/dht/src/dht-inode-read.c
21ab4e
+++ b/xlators/cluster/dht/src/dht-inode-read.c
21ab4e
@@ -165,6 +165,15 @@ dht_file_attr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
21ab4e
         local = frame->local;
21ab4e
         prev = cookie;
21ab4e
 
21ab4e
+        if ((local->fop == GF_FOP_FSTAT) && (op_ret == -1)
21ab4e
+             && (op_errno == EBADF) && !(local->fd_checked)) {
21ab4e
+
21ab4e
+                ret = dht_check_and_open_fd_on_subvol (this, frame);
21ab4e
+                if (ret)
21ab4e
+                        goto out;
21ab4e
+                return 0;
21ab4e
+        }
21ab4e
+
21ab4e
         if ((op_ret == -1) && !dht_inode_missing(op_errno)) {
21ab4e
                 local->op_errno = op_errno;
21ab4e
                 gf_msg_debug (this->name, op_errno,
21ab4e
@@ -377,8 +386,6 @@ 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
         VALIDATE_OR_GOTO (this, err);
21ab4e
@@ -404,19 +411,10 @@ 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,
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
+                STACK_WIND_COOKIE (frame, dht_file_attr_cbk, subvol,
21ab4e
+                                   subvol, subvol->fops->fstat, fd,
21ab4e
+                                   xdata);
21ab4e
                 return 0;
21ab4e
         }
21ab4e
 
21ab4e
@@ -459,9 +457,17 @@ dht_readv_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
21ab4e
         if (local->call_cnt != 1)
21ab4e
                 goto out;
21ab4e
 
21ab4e
+        if (op_ret == -1 && (op_errno == EBADF) && !(local->fd_checked)) {
21ab4e
+                ret = dht_check_and_open_fd_on_subvol (this, frame);
21ab4e
+                if (ret)
21ab4e
+                        goto out;
21ab4e
+                return 0;
21ab4e
+        }
21ab4e
+
21ab4e
         if ((op_ret == -1) && !dht_inode_missing(op_errno))
21ab4e
                 goto out;
21ab4e
 
21ab4e
+
21ab4e
         local->op_errno = op_errno;
21ab4e
         if ((op_ret == -1) || IS_DHT_MIGRATION_PHASE2 (stbuf)) {
21ab4e
 
21ab4e
@@ -545,7 +551,6 @@ 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
@@ -573,19 +578,10 @@ dht_readv (call_frame_t *frame, xlator_t *this,
21ab4e
         local->rebalance.flags  = flags;
21ab4e
         local->call_cnt = 1;
21ab4e
 
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
+        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
         return 0;
21ab4e
 
21ab4e
@@ -743,6 +739,13 @@ dht_flush_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
21ab4e
         if (local->call_cnt != 1)
21ab4e
                 goto out;
21ab4e
 
21ab4e
+        if (op_ret == -1 && (op_errno == EBADF) && !(local->fd_checked)) {
21ab4e
+                ret = dht_check_and_open_fd_on_subvol (this, frame);
21ab4e
+                if (ret)
21ab4e
+                        goto out;
21ab4e
+                return 0;
21ab4e
+        }
21ab4e
+
21ab4e
         local->rebalance.target_op_fn = dht_flush2;
21ab4e
 
21ab4e
         local->op_ret = op_ret;
21ab4e
@@ -804,7 +807,6 @@ 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
@@ -829,18 +831,8 @@ dht_flush (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
21ab4e
 
21ab4e
         local->call_cnt = 1;
21ab4e
 
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
+        STACK_WIND (frame, dht_flush_cbk,
21ab4e
+                    subvol, subvol->fops->flush, fd, local->xattr_req);
21ab4e
         return 0;
21ab4e
 
21ab4e
 err:
21ab4e
@@ -867,6 +859,14 @@ dht_fsync_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int op_ret,
21ab4e
         prev = cookie;
21ab4e
 
21ab4e
         local->op_errno = op_errno;
21ab4e
+
21ab4e
+        if (op_ret == -1 && (op_errno == EBADF) && !(local->fd_checked)) {
21ab4e
+                ret = dht_check_and_open_fd_on_subvol (this, frame);
21ab4e
+                if (ret)
21ab4e
+                        goto out;
21ab4e
+                return 0;
21ab4e
+        }
21ab4e
+
21ab4e
         if (op_ret == -1 && !dht_inode_missing(op_errno)) {
21ab4e
                 gf_msg_debug (this->name, op_errno,
21ab4e
                               "subvolume %s returned -1",
21ab4e
@@ -974,7 +974,6 @@ 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
@@ -994,20 +993,9 @@ dht_fsync (call_frame_t *frame, xlator_t *this, fd_t *fd, int datasync,
21ab4e
 
21ab4e
         subvol = local->cached_subvol;
21ab4e
 
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
+        STACK_WIND_COOKIE (frame, dht_fsync_cbk, subvol, subvol,
21ab4e
+                           subvol->fops->fsync, local->fd,
21ab4e
+                           local->rebalance.flags, local->xattr_req);
21ab4e
         return 0;
21ab4e
 
21ab4e
 err:
21ab4e
@@ -1301,8 +1289,7 @@ dht_xattrop (call_frame_t *frame, xlator_t *this, loc_t *loc,
21ab4e
 
21ab4e
         local->call_cnt = 1;
21ab4e
 
21ab4e
-        STACK_WIND (frame,
21ab4e
-                    dht_xattrop_cbk,
21ab4e
+        STACK_WIND (frame, dht_xattrop_cbk,
21ab4e
                     subvol, subvol->fops->xattrop,
21ab4e
                     loc, flags, dict, xdata);
21ab4e
 
21ab4e
@@ -1401,8 +1388,7 @@ dht_inodelk (call_frame_t *frame, xlator_t *this, const char *volume,
21ab4e
 
21ab4e
         local->call_cnt = 1;
21ab4e
 
21ab4e
-        STACK_WIND (frame,
21ab4e
-                    dht_inodelk_cbk,
21ab4e
+        STACK_WIND (frame, dht_inodelk_cbk,
21ab4e
                     lock_subvol, lock_subvol->fops->inodelk,
21ab4e
                     volume, loc, cmd, lock, xdata);
21ab4e
 
21ab4e
diff --git a/xlators/cluster/dht/src/dht-inode-write.c b/xlators/cluster/dht/src/dht-inode-write.c
21ab4e
index f925d4b..5392ee4 100644
21ab4e
--- a/xlators/cluster/dht/src/dht-inode-write.c
21ab4e
+++ b/xlators/cluster/dht/src/dht-inode-write.c
21ab4e
@@ -44,6 +44,19 @@ dht_writev_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
21ab4e
                 goto out;
21ab4e
         }
21ab4e
 
21ab4e
+        /* writev fails with EBADF if dht has not yet opened the fd
21ab4e
+         * on the cached subvol. This could happen if the file was migrated
21ab4e
+         * and a lookup updated the cached subvol in the inode ctx.
21ab4e
+         * We only check once as this could be a valid bad fd error.
21ab4e
+         */
21ab4e
+
21ab4e
+        if (op_ret == -1 && (op_errno == EBADF) && !(local->fd_checked)) {
21ab4e
+                ret = dht_check_and_open_fd_on_subvol (this, frame);
21ab4e
+                if (ret)
21ab4e
+                        goto out;
21ab4e
+                return 0;
21ab4e
+        }
21ab4e
+
21ab4e
         if (op_ret == -1 && !dht_inode_missing(op_errno)) {
21ab4e
                 local->op_errno = op_errno;
21ab4e
                 local->op_ret = -1;
21ab4e
@@ -162,7 +175,6 @@ dht_writev (call_frame_t *frame, xlator_t *this, fd_t *fd,
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
@@ -183,7 +195,6 @@ dht_writev (call_frame_t *frame, xlator_t *this, fd_t *fd,
21ab4e
                 goto err;
21ab4e
         }
21ab4e
 
21ab4e
-
21ab4e
         if (xdata)
21ab4e
                 local->xattr_req = dict_ref (xdata);
21ab4e
 
21ab4e
@@ -194,22 +205,13 @@ 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
-        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
+        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
 
21ab4e
         return 0;
21ab4e
 
21ab4e
@@ -243,6 +245,22 @@ dht_truncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
21ab4e
         local = frame->local;
21ab4e
         prev = cookie;
21ab4e
 
21ab4e
+        /* Needs to be checked only for ftruncate.
21ab4e
+         * ftruncate fails with EBADF/EINVAL if dht has not yet opened the fd
21ab4e
+         * on the cached subvol. This could happen if the file was migrated
21ab4e
+         * and a lookup updated the cached subvol in the inode ctx.
21ab4e
+         * We only check once as this could actually be a valid error.
21ab4e
+         */
21ab4e
+
21ab4e
+        if ((local->fop == GF_FOP_FTRUNCATE) && (op_ret == -1)
21ab4e
+             && ((op_errno == EBADF) || (op_errno == EINVAL))
21ab4e
+             && !(local->fd_checked)) {
21ab4e
+                ret = dht_check_and_open_fd_on_subvol (this, frame);
21ab4e
+                if (ret)
21ab4e
+                        goto out;
21ab4e
+                return 0;
21ab4e
+        }
21ab4e
+
21ab4e
         if ((op_ret == -1) && !dht_inode_missing(op_errno)) {
21ab4e
                 local->op_errno = op_errno;
21ab4e
                 local->op_ret = -1;
21ab4e
@@ -253,6 +271,7 @@ dht_truncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
21ab4e
                 goto out;
21ab4e
         }
21ab4e
 
21ab4e
+
21ab4e
         if (local->call_cnt != 1) {
21ab4e
                 if (local->stbuf.ia_blocks) {
21ab4e
                         dht_iatt_merge (this, postbuf, &local->stbuf, NULL);
21ab4e
@@ -408,7 +427,6 @@ 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
@@ -434,20 +452,9 @@ dht_ftruncate (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
21ab4e
         if (xdata)
21ab4e
                 local->xattr_req = dict_ref (xdata);
21ab4e
 
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
+        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
 err:
21ab4e
@@ -477,6 +484,20 @@ dht_fallocate_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
21ab4e
         local = frame->local;
21ab4e
         prev = cookie;
21ab4e
 
21ab4e
+        /* fallocate fails with EBADF if dht has not yet opened the fd
21ab4e
+         * on the cached subvol. This could happen if the file was migrated
21ab4e
+         * and a lookup updated the cached subvol in the inode ctx.
21ab4e
+         * We only check once as this could actually be a valid error.
21ab4e
+         */
21ab4e
+
21ab4e
+        if ((op_ret == -1) && (op_errno == EBADF)
21ab4e
+             && !(local->fd_checked)) {
21ab4e
+                ret = dht_check_and_open_fd_on_subvol (this, frame);
21ab4e
+                if (ret)
21ab4e
+                        goto out;
21ab4e
+                return 0;
21ab4e
+        }
21ab4e
+
21ab4e
         if ((op_ret == -1) && !dht_inode_missing(op_errno)) {
21ab4e
                 local->op_errno = op_errno;
21ab4e
                 local->op_ret = -1;
21ab4e
@@ -586,7 +607,6 @@ dht_fallocate (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t mode,
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
@@ -614,22 +634,12 @@ dht_fallocate (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t mode,
21ab4e
         if (xdata)
21ab4e
                 local->xattr_req = dict_ref (xdata);
21ab4e
 
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
+        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
 
21ab4e
         return 0;
21ab4e
 
21ab4e
@@ -660,6 +670,20 @@ dht_discard_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
21ab4e
         local = frame->local;
21ab4e
         prev = cookie;
21ab4e
 
21ab4e
+
21ab4e
+        /* discard fails with EBADF if dht has not yet opened the fd
21ab4e
+         * on the cached subvol. This could happen if the file was migrated
21ab4e
+         * and a lookup updated the cached subvol in the inode ctx.
21ab4e
+         * We only check once as this could actually be a valid error.
21ab4e
+         */
21ab4e
+        if ((op_ret == -1) && (op_errno == EBADF)
21ab4e
+             && !(local->fd_checked)) {
21ab4e
+                ret = dht_check_and_open_fd_on_subvol (this, frame);
21ab4e
+                if (ret)
21ab4e
+                        goto out;
21ab4e
+                return 0;
21ab4e
+        }
21ab4e
+
21ab4e
         if ((op_ret == -1) && !dht_inode_missing(op_errno)) {
21ab4e
                 local->op_errno = op_errno;
21ab4e
                 local->op_ret = -1;
21ab4e
@@ -769,7 +793,6 @@ dht_discard (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
         VALIDATE_OR_GOTO (frame, err);
21ab4e
         VALIDATE_OR_GOTO (this, err);
21ab4e
@@ -796,22 +819,11 @@ dht_discard (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
21ab4e
         if (xdata)
21ab4e
                 local->xattr_req = dict_ref (xdata);
21ab4e
 
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
+        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
 
21ab4e
         return 0;
21ab4e
 
21ab4e
@@ -840,6 +852,19 @@ dht_zerofill_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
21ab4e
         local = frame->local;
21ab4e
         prev = cookie;
21ab4e
 
21ab4e
+        /* zerofill fails with EBADF if dht has not yet opened the fd
21ab4e
+         * on the cached subvol. This could happen if the file was migrated
21ab4e
+         * and a lookup updated the cached subvol in the inode ctx.
21ab4e
+         * We only check once as this could actually be a valid error.
21ab4e
+         */
21ab4e
+        if ((op_ret == -1) && (op_errno == EBADF)
21ab4e
+             && !(local->fd_checked)) {
21ab4e
+                ret = dht_check_and_open_fd_on_subvol (this, frame);
21ab4e
+                if (ret)
21ab4e
+                        goto out;
21ab4e
+                return 0;
21ab4e
+        }
21ab4e
+
21ab4e
         if ((op_ret == -1) && !dht_inode_missing(op_errno)) {
21ab4e
                 local->op_errno = op_errno;
21ab4e
                 local->op_ret = -1;
21ab4e
@@ -952,7 +977,6 @@ dht_zerofill (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
         VALIDATE_OR_GOTO (frame, err);
21ab4e
         VALIDATE_OR_GOTO (this, err);
21ab4e
@@ -979,21 +1003,10 @@ dht_zerofill (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
21ab4e
         if (xdata)
21ab4e
                 local->xattr_req = dict_ref (xdata);
21ab4e
 
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
+        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
         return 0;
21ab4e
 
21ab4e
@@ -1020,6 +1033,15 @@ dht_file_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
21ab4e
         prev = cookie;
21ab4e
 
21ab4e
         local->op_errno = op_errno;
21ab4e
+
21ab4e
+        if ((op_ret == -1) && (op_errno == EBADF)
21ab4e
+             && !(local->fd_checked)) {
21ab4e
+                ret = dht_check_and_open_fd_on_subvol (this, frame);
21ab4e
+                if (ret)
21ab4e
+                        goto out;
21ab4e
+                return 0;
21ab4e
+        }
21ab4e
+
21ab4e
         if ((op_ret == -1) && !dht_inode_missing(op_errno)) {
21ab4e
                 gf_msg_debug (this->name, op_errno,
21ab4e
                               "subvolume %s returned -1",
21ab4e
@@ -1241,8 +1263,6 @@ 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
         VALIDATE_OR_GOTO (this, err);
21ab4e
@@ -1279,21 +1299,11 @@ 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
-                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
+                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
 
21ab4e
diff --git a/xlators/storage/posix/src/posix.c b/xlators/storage/posix/src/posix.c
21ab4e
index 26038fc..1486d40 100644
21ab4e
--- a/xlators/storage/posix/src/posix.c
21ab4e
+++ b/xlators/storage/posix/src/posix.c
21ab4e
@@ -996,8 +996,9 @@ posix_zerofill(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
21ab4e
 
21ab4e
         ret = posix_do_zerofill (frame, this, fd, offset, len,
21ab4e
                                  &statpre, &statpost, xdata);
21ab4e
-        if (ret < 0)
21ab4e
+        if (ret < 0) {
21ab4e
                 goto err;
21ab4e
+        }
21ab4e
 
21ab4e
         STACK_UNWIND_STRICT(zerofill, frame, 0, 0, &statpre, &statpost, NULL);
21ab4e
         return 0;
21ab4e
-- 
21ab4e
1.8.3.1
21ab4e