17b94a
From 27f799563c1c2c1986662ed4a3a83d834c04fd98 Mon Sep 17 00:00:00 2001
17b94a
From: Mohit Agrawal <moagrawal@redhat.com>
17b94a
Date: Mon, 14 Oct 2019 15:42:31 +0530
17b94a
Subject: [PATCH 308/308] dht: Rebalance causing IO Error - File descriptor in
17b94a
 bad state
17b94a
17b94a
Problem : When a file is migrated, dht attempts to re-open all open
17b94a
          fds on the new cached subvol. Earlier, if dht had not opened the fd,
17b94a
          the client xlator would be unable to find the remote fd and would
17b94a
          fall back to using an anon fd for the fop. That behavior changed with
17b94a
          https://review.gluster.org/#/c/glusterfs/+/15804, causing fops to fail
17b94a
          with EBADFD if the fd was not available on the cached subvol.
17b94a
          The client xlator returns EBADFD if the remote fd is not found but
17b94a
          dht only checks for EBADF before re-opening fds on the new cached subvol.
17b94a
17b94a
Solution: Handle EBADFD at dht code path to avoid the issue
17b94a
17b94a
> Change-Id: I43c51995cdd48d05b12e4b2889c8dbe2bb2a72d8
17b94a
> Fixes: bz#1758579
17b94a
> Signed-off-by: Mohit Agrawal <moagrawa@redhat.com>
17b94a
> (Cherry pick from commit 9314a9fbf487614c736cf6c4c1b93078d37bb9df)
17b94a
> (Reviewed on upstream link https://review.gluster.org/#/c/glusterfs/+/23518/)
17b94a
17b94a
Change-Id: I43c51995cdd48d05b12e4b2889c8dbe2bb2a72d8
17b94a
BUG: 1758432
17b94a
Signed-off-by: Mohit Agrawal <moagrawa@redhat.com>
17b94a
Reviewed-on: https://code.engineering.redhat.com/gerrit/183370
17b94a
Tested-by: RHGS Build Bot <nigelb@redhat.com>
17b94a
Reviewed-by: Sunil Kumar Heggodu Gopala Acharya <sheggodu@redhat.com>
17b94a
---
17b94a
 xlators/cluster/dht/src/dht-common.c      | 27 +++++++++++++++++---
17b94a
 xlators/cluster/dht/src/dht-common.h      | 19 ++++++++++++++
17b94a
 xlators/cluster/dht/src/dht-helper.c      | 29 +++++++++++++++++++++
17b94a
 xlators/cluster/dht/src/dht-inode-read.c  | 42 +++++++++++++++++++++++++++----
17b94a
 xlators/cluster/dht/src/dht-inode-write.c | 16 ++++++------
17b94a
 5 files changed, 116 insertions(+), 17 deletions(-)
17b94a
17b94a
diff --git a/xlators/cluster/dht/src/dht-common.c b/xlators/cluster/dht/src/dht-common.c
17b94a
index 99cccd6..37952ba 100644
17b94a
--- a/xlators/cluster/dht/src/dht-common.c
17b94a
+++ b/xlators/cluster/dht/src/dht-common.c
17b94a
@@ -53,6 +53,17 @@ dht_set_dir_xattr_req(xlator_t *this, loc_t *loc, dict_t *xattr_req);
17b94a
 int
17b94a
 dht_do_fresh_lookup(call_frame_t *frame, xlator_t *this, loc_t *loc);
17b94a
 
17b94a
+/* Check the xdata to make sure EBADF has been set by client xlator */
17b94a
+int32_t
17b94a
+dht_check_remote_fd_failed_error(dht_local_t *local, int op_ret, int op_errno)
17b94a
+{
17b94a
+    if (op_ret == -1 && (op_errno == EBADF || op_errno == EBADFD) &&
17b94a
+        !(local->fd_checked)) {
17b94a
+        return 1;
17b94a
+    }
17b94a
+    return 0;
17b94a
+}
17b94a
+
17b94a
 /* Sets the blocks and size values to fixed values. This is to be called
17b94a
  * only for dirs. The caller is responsible for checking the type
17b94a
  */
17b94a
@@ -4529,6 +4540,7 @@ dht_getxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret,
17b94a
     int this_call_cnt = 0;
17b94a
     dht_local_t *local = NULL;
17b94a
     dht_conf_t *conf = NULL;
17b94a
+    int ret = 0;
17b94a
 
17b94a
     VALIDATE_OR_GOTO(frame, err);
17b94a
     VALIDATE_OR_GOTO(frame->local, err);
17b94a
@@ -4537,6 +4549,13 @@ dht_getxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret,
17b94a
     conf = this->private;
17b94a
     local = frame->local;
17b94a
 
17b94a
+    if (dht_check_remote_fd_failed_error(local, op_ret, op_errno)) {
17b94a
+        ret = dht_check_and_open_fd_on_subvol(this, frame);
17b94a
+        if (ret)
17b94a
+            goto err;
17b94a
+        return 0;
17b94a
+    }
17b94a
+
17b94a
     LOCK(&frame->lock);
17b94a
     {
17b94a
         if (!xattr || (op_ret == -1)) {
17b94a
@@ -5204,8 +5223,8 @@ dht_file_setxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
17b94a
 
17b94a
     local->op_errno = op_errno;
17b94a
 
17b94a
-    if ((local->fop == GF_FOP_FSETXATTR) && op_ret == -1 &&
17b94a
-        (op_errno == EBADF) && !(local->fd_checked)) {
17b94a
+    if ((local->fop == GF_FOP_FSETXATTR) &&
17b94a
+        dht_check_remote_fd_failed_error(local, op_ret, op_errno)) {
17b94a
         ret = dht_check_and_open_fd_on_subvol(this, frame);
17b94a
         if (ret)
17b94a
             goto out;
17b94a
@@ -5929,8 +5948,8 @@ dht_file_removexattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
17b94a
 
17b94a
     local->op_errno = op_errno;
17b94a
 
17b94a
-    if ((local->fop == GF_FOP_FREMOVEXATTR) && (op_ret == -1) &&
17b94a
-        (op_errno == EBADF) && !(local->fd_checked)) {
17b94a
+    if ((local->fop == GF_FOP_FREMOVEXATTR) &&
17b94a
+        dht_check_remote_fd_failed_error(local, op_ret, op_errno)) {
17b94a
         ret = dht_check_and_open_fd_on_subvol(this, frame);
17b94a
         if (ret)
17b94a
             goto out;
17b94a
diff --git a/xlators/cluster/dht/src/dht-common.h b/xlators/cluster/dht/src/dht-common.h
17b94a
index c516271..ce11f02 100644
17b94a
--- a/xlators/cluster/dht/src/dht-common.h
17b94a
+++ b/xlators/cluster/dht/src/dht-common.h
17b94a
@@ -1230,6 +1230,22 @@ dht_newfile_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret,
17b94a
                 struct iatt *preparent, struct iatt *postparent, dict_t *xdata);
17b94a
 
17b94a
 int
17b94a
+dht_finodelk_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
17b94a
+                 int32_t op_ret, int32_t op_errno, dict_t *xdata);
17b94a
+
17b94a
+int
17b94a
+dht_getxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret,
17b94a
+                 int op_errno, dict_t *xattr, dict_t *xdata);
17b94a
+
17b94a
+int
17b94a
+dht_common_xattrop_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
17b94a
+                       int32_t op_ret, int32_t op_errno, dict_t *dict,
17b94a
+                       dict_t *xdata);
17b94a
+int
17b94a
+dht_fxattrop_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
17b94a
+                 int32_t op_ret, int32_t op_errno, dict_t *dict, dict_t *xdata);
17b94a
+
17b94a
+int
17b94a
 gf_defrag_status_get(dht_conf_t *conf, dict_t *dict);
17b94a
 
17b94a
 void
17b94a
@@ -1525,4 +1541,7 @@ int
17b94a
 dht_pt_rename(call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc,
17b94a
               dict_t *xdata);
17b94a
 
17b94a
+int32_t
17b94a
+dht_check_remote_fd_failed_error(dht_local_t *local, int op_ret, int op_errno);
17b94a
+
17b94a
 #endif /* _DHT_H */
17b94a
diff --git a/xlators/cluster/dht/src/dht-helper.c b/xlators/cluster/dht/src/dht-helper.c
17b94a
index 1e9fee0..4f7370d 100644
17b94a
--- a/xlators/cluster/dht/src/dht-helper.c
17b94a
+++ b/xlators/cluster/dht/src/dht-helper.c
17b94a
@@ -366,6 +366,23 @@ dht_check_and_open_fd_on_subvol_complete(int ret, call_frame_t *frame,
17b94a
 
17b94a
             break;
17b94a
 
17b94a
+        case GF_FOP_FXATTROP:
17b94a
+            STACK_WIND(frame, dht_common_xattrop_cbk, subvol,
17b94a
+                       subvol->fops->fxattrop, local->fd,
17b94a
+                       local->rebalance.flags, local->rebalance.xattr,
17b94a
+                       local->xattr_req);
17b94a
+            break;
17b94a
+
17b94a
+        case GF_FOP_FGETXATTR:
17b94a
+            STACK_WIND(frame, dht_getxattr_cbk, subvol, subvol->fops->fgetxattr,
17b94a
+                       local->fd, local->key, NULL);
17b94a
+            break;
17b94a
+
17b94a
+        case GF_FOP_FINODELK:
17b94a
+            STACK_WIND(frame, dht_finodelk_cbk, subvol, subvol->fops->finodelk,
17b94a
+                       local->key, local->fd, local->rebalance.lock_cmd,
17b94a
+                       &local->rebalance.flock, local->xattr_req);
17b94a
+            break;
17b94a
         default:
17b94a
             gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_UNKNOWN_FOP,
17b94a
                    "Unknown FOP on fd (%p) on file %s @ %s", fd,
17b94a
@@ -429,6 +446,18 @@ handle_err:
17b94a
             DHT_STACK_UNWIND(fremovexattr, frame, -1, op_errno, NULL);
17b94a
             break;
17b94a
 
17b94a
+        case GF_FOP_FXATTROP:
17b94a
+            DHT_STACK_UNWIND(fxattrop, frame, -1, op_errno, NULL, NULL);
17b94a
+            break;
17b94a
+
17b94a
+        case GF_FOP_FGETXATTR:
17b94a
+            DHT_STACK_UNWIND(fgetxattr, frame, -1, op_errno, NULL, NULL);
17b94a
+            break;
17b94a
+
17b94a
+        case GF_FOP_FINODELK:
17b94a
+            DHT_STACK_UNWIND(finodelk, frame, -1, op_errno, NULL);
17b94a
+            break;
17b94a
+
17b94a
         default:
17b94a
             gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_UNKNOWN_FOP,
17b94a
                    "Unknown FOP on fd (%p) on file %s @ %s", fd,
17b94a
diff --git a/xlators/cluster/dht/src/dht-inode-read.c b/xlators/cluster/dht/src/dht-inode-read.c
17b94a
index cacfe35..0c209a5 100644
17b94a
--- a/xlators/cluster/dht/src/dht-inode-read.c
17b94a
+++ b/xlators/cluster/dht/src/dht-inode-read.c
17b94a
@@ -162,8 +162,8 @@ dht_file_attr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret,
17b94a
     local = frame->local;
17b94a
     prev = cookie;
17b94a
 
17b94a
-    if ((local->fop == GF_FOP_FSTAT) && (op_ret == -1) && (op_errno == EBADF) &&
17b94a
-        !(local->fd_checked)) {
17b94a
+    if ((local->fop == GF_FOP_FSTAT) &&
17b94a
+        dht_check_remote_fd_failed_error(local, op_ret, op_errno)) {
17b94a
         ret = dht_check_and_open_fd_on_subvol(this, frame);
17b94a
         if (ret)
17b94a
             goto out;
17b94a
@@ -431,7 +431,7 @@ dht_readv_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret,
17b94a
     if (local->call_cnt != 1)
17b94a
         goto out;
17b94a
 
17b94a
-    if (op_ret == -1 && (op_errno == EBADF) && !(local->fd_checked)) {
17b94a
+    if (dht_check_remote_fd_failed_error(local, op_ret, op_errno)) {
17b94a
         ret = dht_check_and_open_fd_on_subvol(this, frame);
17b94a
         if (ret)
17b94a
             goto out;
17b94a
@@ -703,7 +703,7 @@ dht_flush_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret,
17b94a
     if (local->call_cnt != 1)
17b94a
         goto out;
17b94a
 
17b94a
-    if (op_ret == -1 && (op_errno == EBADF) && !(local->fd_checked)) {
17b94a
+    if (dht_check_remote_fd_failed_error(local, op_ret, op_errno)) {
17b94a
         ret = dht_check_and_open_fd_on_subvol(this, frame);
17b94a
         if (ret)
17b94a
             goto out;
17b94a
@@ -820,7 +820,7 @@ dht_fsync_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret,
17b94a
 
17b94a
     local->op_errno = op_errno;
17b94a
 
17b94a
-    if (op_ret == -1 && (op_errno == EBADF) && !(local->fd_checked)) {
17b94a
+    if (dht_check_remote_fd_failed_error(local, op_ret, op_errno)) {
17b94a
         ret = dht_check_and_open_fd_on_subvol(this, frame);
17b94a
         if (ret)
17b94a
             goto out;
17b94a
@@ -1223,6 +1223,13 @@ dht_common_xattrop_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
17b94a
     if (local->call_cnt != 1)
17b94a
         goto out;
17b94a
 
17b94a
+    if (dht_check_remote_fd_failed_error(local, op_ret, op_errno)) {
17b94a
+        ret = dht_check_and_open_fd_on_subvol(this, frame);
17b94a
+        if (ret)
17b94a
+            goto out;
17b94a
+        return 0;
17b94a
+    }
17b94a
+
17b94a
     ret = dht_read_iatt_from_xdata(this, xdata, &stbuf);
17b94a
 
17b94a
     if ((!op_ret) && (ret)) {
17b94a
@@ -1535,8 +1542,26 @@ dht_finodelk_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
17b94a
                  int32_t op_ret, int32_t op_errno, dict_t *xdata)
17b94a
 
17b94a
 {
17b94a
+    dht_local_t *local = NULL;
17b94a
+    int ret = 0;
17b94a
+
17b94a
+    GF_VALIDATE_OR_GOTO("dht", frame, out);
17b94a
+    GF_VALIDATE_OR_GOTO("dht", this, out);
17b94a
+    GF_VALIDATE_OR_GOTO("dht", frame->local, out);
17b94a
+
17b94a
+    local = frame->local;
17b94a
+
17b94a
+    if (dht_check_remote_fd_failed_error(local, op_ret, op_errno)) {
17b94a
+        ret = dht_check_and_open_fd_on_subvol(this, frame);
17b94a
+        if (ret)
17b94a
+            goto out;
17b94a
+        return 0;
17b94a
+    }
17b94a
+
17b94a
+out:
17b94a
     dht_lk_inode_unref(frame, op_ret);
17b94a
     DHT_STACK_UNWIND(finodelk, frame, op_ret, op_errno, xdata);
17b94a
+
17b94a
     return 0;
17b94a
 }
17b94a
 
17b94a
@@ -1574,6 +1599,13 @@ dht_finodelk(call_frame_t *frame, xlator_t *this, const char *volume, fd_t *fd,
17b94a
             if (ret)
17b94a
                     goto err;
17b94a
     */
17b94a
+    local->rebalance.flock = *lock;
17b94a
+    local->rebalance.lock_cmd = cmd;
17b94a
+    local->key = gf_strdup(volume);
17b94a
+
17b94a
+    if (xdata)
17b94a
+        local->xattr_req = dict_ref(xdata);
17b94a
+
17b94a
     STACK_WIND(frame, dht_finodelk_cbk, lock_subvol,
17b94a
                lock_subvol->fops->finodelk, volume, fd, cmd, lock, xdata);
17b94a
 
17b94a
diff --git a/xlators/cluster/dht/src/dht-inode-write.c b/xlators/cluster/dht/src/dht-inode-write.c
17b94a
index b26b705..b6b349d 100644
17b94a
--- a/xlators/cluster/dht/src/dht-inode-write.c
17b94a
+++ b/xlators/cluster/dht/src/dht-inode-write.c
17b94a
@@ -49,7 +49,7 @@ dht_writev_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret,
17b94a
      * We only check once as this could be a valid bad fd error.
17b94a
      */
17b94a
 
17b94a
-    if (op_ret == -1 && (op_errno == EBADF) && !(local->fd_checked)) {
17b94a
+    if (dht_check_remote_fd_failed_error(local, op_ret, op_errno)) {
17b94a
         ret = dht_check_and_open_fd_on_subvol(this, frame);
17b94a
         if (ret)
17b94a
             goto out;
17b94a
@@ -262,8 +262,8 @@ dht_truncate_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret,
17b94a
      * We only check once as this could actually be a valid error.
17b94a
      */
17b94a
 
17b94a
-    if ((local->fop == GF_FOP_FTRUNCATE) && (op_ret == -1) &&
17b94a
-        ((op_errno == EBADF) || (op_errno == EINVAL)) && !(local->fd_checked)) {
17b94a
+    if ((local->fop == GF_FOP_FTRUNCATE) &&
17b94a
+        dht_check_remote_fd_failed_error(local, op_ret, op_errno)) {
17b94a
         ret = dht_check_and_open_fd_on_subvol(this, frame);
17b94a
         if (ret)
17b94a
             goto out;
17b94a
@@ -489,7 +489,7 @@ dht_fallocate_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret,
17b94a
      * We only check once as this could actually be a valid error.
17b94a
      */
17b94a
 
17b94a
-    if ((op_ret == -1) && (op_errno == EBADF) && !(local->fd_checked)) {
17b94a
+    if (dht_check_remote_fd_failed_error(local, op_ret, op_errno)) {
17b94a
         ret = dht_check_and_open_fd_on_subvol(this, frame);
17b94a
         if (ret)
17b94a
             goto out;
17b94a
@@ -666,7 +666,7 @@ dht_discard_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret,
17b94a
      * and a lookup updated the cached subvol in the inode ctx.
17b94a
      * We only check once as this could actually be a valid error.
17b94a
      */
17b94a
-    if ((op_ret == -1) && (op_errno == EBADF) && !(local->fd_checked)) {
17b94a
+    if (dht_check_remote_fd_failed_error(local, op_ret, op_errno)) {
17b94a
         ret = dht_check_and_open_fd_on_subvol(this, frame);
17b94a
         if (ret)
17b94a
             goto out;
17b94a
@@ -838,7 +838,7 @@ dht_zerofill_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret,
17b94a
      * and a lookup updated the cached subvol in the inode ctx.
17b94a
      * We only check once as this could actually be a valid error.
17b94a
      */
17b94a
-    if ((op_ret == -1) && (op_errno == EBADF) && !(local->fd_checked)) {
17b94a
+    if (dht_check_remote_fd_failed_error(local, op_ret, op_errno)) {
17b94a
         ret = dht_check_and_open_fd_on_subvol(this, frame);
17b94a
         if (ret)
17b94a
             goto out;
17b94a
@@ -1005,8 +1005,8 @@ dht_file_setattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
17b94a
 
17b94a
     local->op_errno = op_errno;
17b94a
 
17b94a
-    if ((local->fop == GF_FOP_FSETATTR) && (op_ret == -1) &&
17b94a
-        (op_errno == EBADF) && !(local->fd_checked)) {
17b94a
+    if ((local->fop == GF_FOP_FSETATTR) &&
17b94a
+        dht_check_remote_fd_failed_error(local, op_ret, op_errno)) {
17b94a
         ret = dht_check_and_open_fd_on_subvol(this, frame);
17b94a
         if (ret)
17b94a
             goto out;
17b94a
-- 
17b94a
1.8.3.1
17b94a