path: root/xlators
diff options
authorAnuradha Talur <>2016-05-13 15:34:06 +0530
committerPranith Kumar Karampuri <>2016-05-23 22:21:35 -0700
commit324329deee862ba28873172b3124031b5783471e (patch)
tree997a9bd9db485884276f7e07a78cd0e68de5f1b4 /xlators
parentb632ff7e3f614c46d9209f87847a9c0c0892e51e (diff)
cluster/afr : Do post-op in case of symmetric errors
Backport of: In afr_changelog_post_op_now(), if there was any error, meaning op_ret < 0, post-op was not being done even when the errors were symmetric and there were no "failed subvols". Fix: When the errors are symmetric, perform post-op. How was the bug found : In a 1 X 3 volume with shard and write behind on when writes were done into a file with one brick down, the trusted.afr.dirty xattr's value for .shard directory would keep increasing as post op was not done but pre-op was. This incorrectly showed .shard to be in split-brain. RCA: When WB is on, due to multiple writes being sent on offset lying in the same shard, chances are that same shard file will be created more than once with the second one failing with op_ret < 0 and op_errno = EEXIST. As op_ret was negative, afr wouldn't do post-op, leading to no decrement of trusted.afr.dirty xattr. Thus showing .shard directory to be in split-brain. >Change-Id: I711bdeaa1397244e6a7790e96f0c84501798fc59 >BUG: 1335652 >Signed-off-by: Anuradha Talur <> Change-Id: I711bdeaa1397244e6a7790e96f0c84501798fc59 BUG: 1335836 Signed-off-by: Anuradha Talur <> Reviewed-on: Smoke: Gluster Build System <> NetBSD-regression: NetBSD Build System <> CentOS-regression: Gluster Build System <> Reviewed-by: Ravishankar N <> Reviewed-by: Pranith Kumar Karampuri <>
Diffstat (limited to 'xlators')
1 files changed, 6 insertions, 2 deletions
diff --git a/xlators/cluster/afr/src/afr-transaction.c b/xlators/cluster/afr/src/afr-transaction.c
index 908c6bea0b7..2bb4e827c76 100644
--- a/xlators/cluster/afr/src/afr-transaction.c
+++ b/xlators/cluster/afr/src/afr-transaction.c
@@ -537,10 +537,14 @@ afr_handle_symmetric_errors (call_frame_t *frame, xlator_t *this)
i_errno = local->replies[i].op_errno;
- if (i_errno == ENOTCONN) {
+ if (i_errno == ENOTCONN || i_errno == EDQUOT ||
+ i_errno == ENOSPC) {
/* ENOTCONN is not a symmetric error. We do not
know if the operation was performed on the
backend or not.
+ * Before reaching EDQUOT and ENOSPC, each brick would
+ * have written some amount of data, hence this is not
+ * symmetric error.
matching_errors = _gf_false;
@@ -719,7 +723,7 @@ afr_changelog_post_op_now (call_frame_t *frame, xlator_t *this)
need_undirty = _gf_true;
- if (local->op_ret < 0) {
+ if (local->op_ret < 0 && !nothing_failed) {
afr_changelog_post_op_done (frame, this);
goto out;