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