summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--tests/bugs/replicate/bug-1335652.t29
-rw-r--r--xlators/cluster/afr/src/afr-transaction.c8
2 files changed, 35 insertions, 2 deletions
diff --git a/tests/bugs/replicate/bug-1335652.t b/tests/bugs/replicate/bug-1335652.t
new file mode 100644
index 00000000000..653a1b05ce2
--- /dev/null
+++ b/tests/bugs/replicate/bug-1335652.t
@@ -0,0 +1,29 @@
+#!/bin/bash
+. $(dirname $0)/../../include.rc
+. $(dirname $0)/../../volume.rc
+cleanup;
+
+TEST glusterd
+TEST pidof glusterd
+TEST $CLI volume create $V0 replica 3 $H0:$B0/${V0}{0,1,2}
+TEST $CLI volume set $V0 shard on
+TEST $CLI volume set $V0 self-heal-daemon off
+TEST $CLI volume set $V0 data-self-heal off
+TEST $CLI volume set $V0 entry-self-heal off
+TEST $CLI volume set $V0 metadata-self-heal off
+TEST $CLI volume start $V0
+
+TEST glusterfs --volfile-id=$V0 --volfile-server=$H0 $M0;
+
+#Kill the zero'th brick so that 1st and 2nd get marked dirty
+TEST kill_brick $V0 $H0 $B0/${V0}0
+
+TEST dd if=/dev/urandom of=$M0/file bs=10MB count=20
+
+#At any point value of dirty should not be greater than 0 on source bricks
+EXPECT "000000000000000000000000" get_hex_xattr trusted.afr.dirty $B0/${V0}1/.shard
+EXPECT "000000000000000000000000" get_hex_xattr trusted.afr.dirty $B0/${V0}2/.shard
+
+rm -rf $M0/file;
+
+cleanup;
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;
break;
@@ -719,7 +723,7 @@ afr_changelog_post_op_now (call_frame_t *frame, xlator_t *this)
else
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;
}