summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRavishankar N <ravishankar@redhat.com>2017-05-29 21:56:12 +0530
committerPranith Kumar Karampuri <pkarampu@redhat.com>2017-05-31 01:50:35 +0000
commitfeaea7fa541b81a4988b8f394037bfedb5017f4c (patch)
tree1dfbe4e481121b9b6d496f15708cc4fdd0cb4c39
parentd9978c3b2be3eefc4cd19b61cf99fa20dab77a0d (diff)
afr: add errno to afr_inode_refresh_done()
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: I075707fbb73fd93a923b77b923a96aac79e847f9 BUG: 1456582 Signed-off-by: Ravishankar N <ravishankar@redhat.com> Reviewed-on: https://review.gluster.org/17413 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 2377419f01c..cef7e52a724 100644
--- a/xlators/cluster/afr/src/afr-common.c
+++ b/xlators/cluster/afr/src/afr-common.c
@@ -1156,7 +1156,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;
@@ -1166,6 +1166,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,
@@ -1229,7 +1234,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);
}
}
@@ -1320,20 +1325,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;
}
@@ -1366,7 +1372,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_inode_refresh_done (frame, this, EBADFD);
+ else
+ afr_inode_refresh_done (frame, this, ENOTCONN);
return 0;
}
for (i = 0; i < priv->child_count; i++) {