summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRavishankar N <ravishankar@redhat.com>2017-06-05 09:40:51 +0530
committerjiffin tony Thottan <jthottan@redhat.com>2017-06-19 04:54:40 +0000
commit5d13784dc6aa406f69061f2608a19ef0c8a80581 (patch)
tree2ce796379466db474488fe8c61bf2d1a755d24c0
parent5a48cf93a0383d79b6525268cee93158dbee8132 (diff)
afr: add errno to afr_inode_refresh_done()
Backport of https://review.gluster.org/17413 and https://review.gluster.org/17436 Problem: When parellel `rm -rf`s were being done from cifs clients, opendir might fail on some replicas with ENOENT. DHT ignores partial opendir failures in dht_fd_cbk() and winds readdirs on those replicas. Afr inode refresh (as a part of readdirp read_txn) sees in its fd context that the state of the fds is *not* AFR_FD_OPENED and bails out to afr_inode_refresh_done() without doing a refresh. When this happens, the errno is set as EIO due to lack of readable subvols, logging split-brain messages in the logs. Fix: Introduce an errno argument to afr_inode_refresh_do() to bail out with the right error value when inode refresh is not performed. Change-Id: I8eed4d6e6c85332c1f5813c74cb54ae73693a369 BUG: 1460661 Signed-off-by: Ravishankar N <ravishankar@redhat.com> Reviewed-on: https://review.gluster.org/17518 Smoke: Gluster Build System <jenkins@build.gluster.org> NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org> CentOS-regression: Gluster Build System <jenkins@build.gluster.org> Reviewed-by: Pranith Kumar Karampuri <pkarampu@redhat.com>
-rw-r--r--xlators/cluster/afr/src/afr-common.c23
1 files changed, 16 insertions, 7 deletions
diff --git a/xlators/cluster/afr/src/afr-common.c b/xlators/cluster/afr/src/afr-common.c
index 5ebe86bb368..7532b014ff7 100644
--- a/xlators/cluster/afr/src/afr-common.c
+++ b/xlators/cluster/afr/src/afr-common.c
@@ -1076,7 +1076,7 @@ refresh_done:
}
int
-afr_inode_refresh_done (call_frame_t *frame, xlator_t *this)
+afr_inode_refresh_done (call_frame_t *frame, xlator_t *this, int error)
{
call_frame_t *heal_frame = NULL;
afr_local_t *local = NULL;
@@ -1086,6 +1086,11 @@ afr_inode_refresh_done (call_frame_t *frame, xlator_t *this)
int ret = 0;
int err = 0;
+ if (error != 0) {
+ err = error;
+ goto refresh_done;
+ }
+
local = frame->local;
ret = afr_replies_interpret (frame, this, local->refreshinode,
@@ -1149,7 +1154,7 @@ afr_inode_refresh_subvol_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
call_count = afr_frame_return (frame);
if (call_count == 0) {
afr_set_need_heal (this, local);
- afr_inode_refresh_done (frame, this);
+ afr_inode_refresh_done (frame, this, 0);
}
}
@@ -1240,20 +1245,21 @@ afr_inode_refresh_do (call_frame_t *frame, xlator_t *this)
if (local->fd) {
fd_ctx = afr_fd_ctx_get (local->fd, this);
if (!fd_ctx) {
- afr_inode_refresh_done (frame, this);
+ afr_inode_refresh_done (frame, this, EINVAL);
return 0;
}
}
xdata = dict_new ();
if (!xdata) {
- afr_inode_refresh_done (frame, this);
+ afr_inode_refresh_done (frame, this, ENOMEM);
return 0;
}
- if (afr_xattr_req_prepare (this, xdata) != 0) {
+ ret = afr_xattr_req_prepare (this, xdata);
+ if (ret != 0) {
dict_unref (xdata);
- afr_inode_refresh_done (frame, this);
+ afr_inode_refresh_done (frame, this, -ret);
return 0;
}
@@ -1286,7 +1292,10 @@ afr_inode_refresh_do (call_frame_t *frame, xlator_t *this)
call_count = local->call_count;
if (!call_count) {
dict_unref (xdata);
- afr_inode_refresh_done (frame, this);
+ if (local->fd && AFR_COUNT(local->child_up, priv->child_count))
+ afr_inode_refresh_done (frame, this, EBADFD);
+ else
+ afr_inode_refresh_done (frame, this, ENOTCONN);
return 0;
}
for (i = 0; i < priv->child_count; i++) {