21ab4e
From 7afb6d637cf5a27c7c62cd0deefc235a06d1d790 Mon Sep 17 00:00:00 2001
21ab4e
From: N Balachandran <nbalacha@redhat.com>
21ab4e
Date: Mon, 10 Jul 2017 09:38:54 +0530
21ab4e
Subject: [PATCH 560/566] cluster/dht: Fix fd check race
21ab4e
21ab4e
There is a another race between the cached subvol
21ab4e
being updated in the inode_ctx and the fd being opened on
21ab4e
the target.
21ab4e
21ab4e
1. fop1 -> fd1 -> subvol0
21ab4e
2. file migrated from subvol0 to subvol1 and cached_subvol
21ab4e
   changed to subvol1 in inode_ctx
21ab4e
3. fop2 -> fd1 -> subvol1 [takes new cached subvol]
21ab4e
4. fop2 -> checks fd ctx (fd not open on subvol1) -> opens fd1 on subvol1
21ab4e
5. fop1 -> checks fd ctx (fd not open on subvol0)
21ab4e
   -> tries to open fd1 on subvol0 -> fails with "No such file on directory".
21ab4e
21ab4e
Fix:
21ab4e
If dht_fd_open_on_dst fails with ENOENT or ESTALE, wind to old subvol
21ab4e
and let the phase1/phase2 checks handle it.
21ab4e
21ab4e
> BUG: 1465075
21ab4e
> Signed-off-by: N Balachandran <nbalacha@redhat.com>
21ab4e
> Reviewed-on: https://review.gluster.org/17731
21ab4e
> Smoke: Gluster Build System <jenkins@build.gluster.org>
21ab4e
> CentOS-regression: Gluster Build System <jenkins@build.gluster.org>
21ab4e
> Reviewed-by: Raghavendra G <rgowdapp@redhat.com>
21ab4e
> Reviewed-by: Amar Tumballi <amarts@redhat.com>
21ab4e
21ab4e
Change-Id: I34f8011574a8b72e3bcfe03b0cc4f024b352f225
21ab4e
BUG: 1463907
21ab4e
Signed-off-by: N Balachandran <nbalacha@redhat.com>
21ab4e
Reviewed-on: https://code.engineering.redhat.com/gerrit/111949
21ab4e
Reviewed-by: Atin Mukherjee <amukherj@redhat.com>
21ab4e
---
21ab4e
 xlators/cluster/dht/src/dht-helper.c   | 26 +++++++++++++++++
21ab4e
 xlators/cluster/dht/src/dht-messages.h | 51 +++++++++++++++++++++++++++++++++-
21ab4e
 2 files changed, 76 insertions(+), 1 deletion(-)
21ab4e
21ab4e
diff --git a/xlators/cluster/dht/src/dht-helper.c b/xlators/cluster/dht/src/dht-helper.c
21ab4e
index 50cdb83..6bad5db 100644
21ab4e
--- a/xlators/cluster/dht/src/dht-helper.c
21ab4e
+++ b/xlators/cluster/dht/src/dht-helper.c
21ab4e
@@ -288,10 +288,12 @@ dht_check_and_open_fd_on_subvol_complete (int ret, call_frame_t *frame,
21ab4e
         glusterfs_fop_t     fop     = 0;
21ab4e
         dht_local_t        *local   = NULL;
21ab4e
         xlator_t           *subvol  = NULL;
21ab4e
+        xlator_t           *this  = NULL;
21ab4e
         fd_t               *fd      = NULL;
21ab4e
         int                 op_errno = -1;
21ab4e
 
21ab4e
         local = frame->local;
21ab4e
+        this = frame->this;
21ab4e
         fop = local->fop;
21ab4e
         subvol = local->cached_subvol;
21ab4e
         fd = local->fd;
21ab4e
@@ -380,6 +382,11 @@ dht_check_and_open_fd_on_subvol_complete (int ret, call_frame_t *frame,
21ab4e
                 break;
21ab4e
 
21ab4e
         default:
21ab4e
+                gf_msg (this->name, GF_LOG_ERROR, 0,
21ab4e
+                        DHT_MSG_UNKNOWN_FOP,
21ab4e
+                        "Unknown FOP on fd (%p) on file %s @ %s",
21ab4e
+                        fd, uuid_utoa (fd->inode->gfid),
21ab4e
+                        subvol->name);
21ab4e
                 break;
21ab4e
 
21ab4e
         }
21ab4e
@@ -440,6 +447,11 @@ handle_err:
21ab4e
                 break;
21ab4e
 
21ab4e
         default:
21ab4e
+                gf_msg (this->name, GF_LOG_ERROR, 0,
21ab4e
+                        DHT_MSG_UNKNOWN_FOP,
21ab4e
+                        "Unknown FOP on fd (%p) on file %s @ %s",
21ab4e
+                        fd, uuid_utoa (fd->inode->gfid),
21ab4e
+                        subvol->name);
21ab4e
                 break;
21ab4e
         }
21ab4e
 
21ab4e
@@ -503,6 +515,20 @@ dht_check_and_open_fd_on_subvol_task (void *data)
21ab4e
                         " (%p, flags=0%o) on file %s @ %s",
21ab4e
                         fd, fd->flags, uuid_utoa (fd->inode->gfid),
21ab4e
                         subvol->name);
21ab4e
+                /* This can happen if the cached subvol was updated in the
21ab4e
+                 * inode_ctx and the fd was opened on the new cached suvol
21ab4e
+                 * after this fop was wound on the old cached subvol.
21ab4e
+                 * As we do not close the fd on the old subvol (a leak)
21ab4e
+                 * don't treat ENOENT as an error and allow the phase1/phase2
21ab4e
+                 * checks to handle it.
21ab4e
+                 */
21ab4e
+
21ab4e
+                if ((-ret != ENOENT) && (-ret != ESTALE)) {
21ab4e
+                        local->op_errno = -ret;
21ab4e
+                        ret = -1;
21ab4e
+                } else {
21ab4e
+                        ret = 0;
21ab4e
+                }
21ab4e
 
21ab4e
                 local->op_errno = -ret;
21ab4e
                 ret = -1;
21ab4e
diff --git a/xlators/cluster/dht/src/dht-messages.h b/xlators/cluster/dht/src/dht-messages.h
21ab4e
index 30b64eb..b6184eb 100644
21ab4e
--- a/xlators/cluster/dht/src/dht-messages.h
21ab4e
+++ b/xlators/cluster/dht/src/dht-messages.h
21ab4e
@@ -40,7 +40,7 @@
21ab4e
  */
21ab4e
 
21ab4e
 #define GLFS_DHT_BASE                   GLFS_MSGID_COMP_DHT
21ab4e
-#define GLFS_DHT_NUM_MESSAGES           118
21ab4e
+#define GLFS_DHT_NUM_MESSAGES           125
21ab4e
 #define GLFS_MSGID_END          (GLFS_DHT_BASE + GLFS_DHT_NUM_MESSAGES + 1)
21ab4e
 
21ab4e
 /* Messages with message IDs */
21ab4e
@@ -1085,5 +1085,54 @@
21ab4e
  */
21ab4e
 #define DHT_MSG_DIR_LOOKUP_FAILED          (GLFS_DHT_BASE + 118)
21ab4e
 
21ab4e
+/*
21ab4e
+ * @messageid 109119
21ab4e
+ * @diagnosis
21ab4e
+ * @recommendedaction None
21ab4e
+ */
21ab4e
+#define DHT_MSG_INODELK_FAILED          (GLFS_DHT_BASE + 119)
21ab4e
+
21ab4e
+/*
21ab4e
+ * @messageid 109120
21ab4e
+ * @diagnosis
21ab4e
+ * @recommendedaction None
21ab4e
+ */
21ab4e
+#define DHT_MSG_LOCK_FRAME_FAILED          (GLFS_DHT_BASE + 120)
21ab4e
+
21ab4e
+/*
21ab4e
+ * @messageid 109121
21ab4e
+ * @diagnosis
21ab4e
+ * @recommendedaction None
21ab4e
+ */
21ab4e
+#define DHT_MSG_LOCAL_LOCK_INIT_FAILED          (GLFS_DHT_BASE + 121)
21ab4e
+
21ab4e
+/*
21ab4e
+ * @messageid 109122
21ab4e
+ * @diagnosis
21ab4e
+ * @recommendedaction None
21ab4e
+ */
21ab4e
+#define DHT_MSG_ENTRYLK_ERROR          (GLFS_DHT_BASE + 122)
21ab4e
+
21ab4e
+/*
21ab4e
+ * @messageid 109123
21ab4e
+ * @diagnosis
21ab4e
+ * @recommendedaction None
21ab4e
+ */
21ab4e
+#define DHT_MSG_INODELK_ERROR          (GLFS_DHT_BASE + 123)
21ab4e
+
21ab4e
+/*
21ab4e
+ * @messageid 109124
21ab4e
+ * @diagnosis
21ab4e
+ * @recommendedaction None
21ab4e
+ */
21ab4e
+#define DHT_MSG_LOC_FAILED             (GLFS_DHT_BASE + 124)
21ab4e
+
21ab4e
+/*
21ab4e
+ * @messageid 109125
21ab4e
+ * @diagnosis
21ab4e
+ * @recommendedaction None
21ab4e
+ */
21ab4e
+#define DHT_MSG_UNKNOWN_FOP            (GLFS_DHT_BASE + 125)
21ab4e
+
21ab4e
 #define glfs_msg_end_x GLFS_MSGID_END, "Invalid: End of messages"
21ab4e
 #endif /* _DHT_MESSAGES_H_ */
21ab4e
-- 
21ab4e
1.8.3.1
21ab4e