21ab4e
From 4a152008a4f17ff9373978535288f32963c6f87b Mon Sep 17 00:00:00 2001
21ab4e
From: Ravishankar N <ravishankar@redhat.com>
21ab4e
Date: Mon, 5 Jun 2017 09:40:51 +0530
21ab4e
Subject: [PATCH 485/486] afr: add errno to afr_inode_refresh_done()
21ab4e
21ab4e
Backport of https://review.gluster.org/17413 and
21ab4e
https://review.gluster.org/17436
21ab4e
21ab4e
Problem:
21ab4e
When parellel `rm -rf`s were being done from cifs clients, opendir might
21ab4e
fail on some replicas with ENOENT. DHT ignores partial opendir failures
21ab4e
in dht_fd_cbk() and winds readdirs on those replicas. Afr inode refresh
21ab4e
(as a part of readdirp read_txn) sees in its fd context that the state
21ab4e
of the fds is *not* AFR_FD_OPENED and bails out to
21ab4e
afr_inode_refresh_done() without doing a refresh. When this happens, the
21ab4e
errno is set as EIO due to lack of readable subvols, logging split-brain
21ab4e
messages in the logs.
21ab4e
21ab4e
Fix:
21ab4e
Introduce an errno argument to afr_inode_refresh_do() to bail out with
21ab4e
the right error value when inode refresh is not performed.
21ab4e
21ab4e
Change-Id: I015b38d80653961feadb0d07b038e08c19911c33
21ab4e
BUG: 1454689
21ab4e
Signed-off-by: Ravishankar N <ravishankar@redhat.com>
21ab4e
Reviewed-on: https://code.engineering.redhat.com/gerrit/108106
21ab4e
Reviewed-by: Karthik Subrahmanya <ksubrahm@redhat.com>
21ab4e
---
21ab4e
 xlators/cluster/afr/src/afr-common.c | 23 ++++++++++++++++-------
21ab4e
 1 file changed, 16 insertions(+), 7 deletions(-)
21ab4e
21ab4e
diff --git a/xlators/cluster/afr/src/afr-common.c b/xlators/cluster/afr/src/afr-common.c
21ab4e
index 316cc40..4b8334d 100644
21ab4e
--- a/xlators/cluster/afr/src/afr-common.c
21ab4e
+++ b/xlators/cluster/afr/src/afr-common.c
21ab4e
@@ -1142,7 +1142,7 @@ refresh_done:
21ab4e
 }
21ab4e
 
21ab4e
 int
21ab4e
-afr_inode_refresh_done (call_frame_t *frame, xlator_t *this)
21ab4e
+afr_inode_refresh_done (call_frame_t *frame, xlator_t *this, int error)
21ab4e
 {
21ab4e
 	call_frame_t *heal_frame = NULL;
21ab4e
 	afr_local_t *local = NULL;
21ab4e
@@ -1152,6 +1152,11 @@ afr_inode_refresh_done (call_frame_t *frame, xlator_t *this)
21ab4e
 	int ret = 0;
21ab4e
 	int err = 0;
21ab4e
 
21ab4e
+	if (error != 0) {
21ab4e
+		err = error;
21ab4e
+		goto refresh_done;
21ab4e
+	}
21ab4e
+
21ab4e
 	local = frame->local;
21ab4e
 
21ab4e
 	ret = afr_replies_interpret (frame, this, local->refreshinode,
21ab4e
@@ -1215,7 +1220,7 @@ afr_inode_refresh_subvol_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
21ab4e
         call_count = afr_frame_return (frame);
21ab4e
         if (call_count == 0) {
21ab4e
                 afr_set_need_heal (this, local);
21ab4e
-		afr_inode_refresh_done (frame, this);
21ab4e
+		afr_inode_refresh_done (frame, this, 0);
21ab4e
         }
21ab4e
 
21ab4e
 }
21ab4e
@@ -1306,20 +1311,21 @@ afr_inode_refresh_do (call_frame_t *frame, xlator_t *this)
21ab4e
         if (local->fd) {
21ab4e
                 fd_ctx = afr_fd_ctx_get (local->fd, this);
21ab4e
                 if (!fd_ctx) {
21ab4e
-                        afr_inode_refresh_done (frame, this);
21ab4e
+                        afr_inode_refresh_done (frame, this, EINVAL);
21ab4e
                         return 0;
21ab4e
                 }
21ab4e
         }
21ab4e
 
21ab4e
 	xdata = dict_new ();
21ab4e
 	if (!xdata) {
21ab4e
-		afr_inode_refresh_done (frame, this);
21ab4e
+		afr_inode_refresh_done (frame, this, ENOMEM);
21ab4e
 		return 0;
21ab4e
 	}
21ab4e
 
21ab4e
-	if (afr_xattr_req_prepare (this, xdata) != 0) {
21ab4e
+	ret = afr_xattr_req_prepare (this, xdata);
21ab4e
+	if (ret != 0) {
21ab4e
 		dict_unref (xdata);
21ab4e
-		afr_inode_refresh_done (frame, this);
21ab4e
+		afr_inode_refresh_done (frame, this, -ret);
21ab4e
 		return 0;
21ab4e
 	}
21ab4e
 
21ab4e
@@ -1352,7 +1358,10 @@ afr_inode_refresh_do (call_frame_t *frame, xlator_t *this)
21ab4e
 	call_count = local->call_count;
21ab4e
         if (!call_count) {
21ab4e
                 dict_unref (xdata);
21ab4e
-                afr_inode_refresh_done (frame, this);
21ab4e
+		if (local->fd && AFR_COUNT(local->child_up, priv->child_count))
21ab4e
+	                afr_inode_refresh_done (frame, this, EBADFD);
21ab4e
+		else
21ab4e
+	                afr_inode_refresh_done (frame, this, ENOTCONN);
21ab4e
                 return 0;
21ab4e
         }
21ab4e
 	for (i = 0; i < priv->child_count; i++) {
21ab4e
-- 
21ab4e
1.8.3.1
21ab4e