summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRavishankar N <ravishankar@redhat.com>2018-01-18 14:21:57 +0530
committerShyamsundar Ranganathan <srangana@redhat.com>2018-02-01 13:57:42 +0000
commite31a697c28dfc36748f7551428b97a863fba3968 (patch)
treeaa4cf0101bfc117d657a5594cc1086b6539f2d0f
parent8c32648d0d4034fb301168e11eadaf0827eb971d (diff)
afr: add quorum checks in post-op
afr relies on pending changelog xattrs to identify source and sinks and the setting of these xattrs happen in post-op. So if post-op fails, we need to unwind the write txn with a failure. Change-Id: I0f019ac03890108324ee7672883d774918b20be1 BUG: 1536346 Signed-off-by: Ravishankar N <ravishankar@redhat.com> (cherry picked from commit a40a87ec3b226ae86a6ed8f4af25b45965a20cad)
-rw-r--r--tests/bugs/replicate/bug-1363721.t2
-rw-r--r--xlators/cluster/afr/src/afr-transaction.c29
2 files changed, 30 insertions, 1 deletions
diff --git a/tests/bugs/replicate/bug-1363721.t b/tests/bugs/replicate/bug-1363721.t
index ec39889b27e..580d8b06502 100644
--- a/tests/bugs/replicate/bug-1363721.t
+++ b/tests/bugs/replicate/bug-1363721.t
@@ -27,7 +27,7 @@ TEST $CLI volume set $V0 cluster.data-self-heal off
TEST $CLI volume set $V0 cluster.metadata-self-heal off
TEST $CLI volume set $V0 cluster.entry-self-heal off
TEST $CLI volume start $V0
-TEST $GFS --volfile-id=$V0 --volfile-server=$H0 $M0 --direct-io-mode=enable
+TEST $GFS --volfile-id=$V0 --volfile-server=$H0 --direct-io-mode=enable $M0
cd $M0
diff --git a/xlators/cluster/afr/src/afr-transaction.c b/xlators/cluster/afr/src/afr-transaction.c
index ba621204fdc..3ee92e5f756 100644
--- a/xlators/cluster/afr/src/afr-transaction.c
+++ b/xlators/cluster/afr/src/afr-transaction.c
@@ -534,6 +534,29 @@ afr_lock_server_count (afr_private_t *priv, afr_transaction_type type)
/* {{{ pending */
+gf_boolean_t
+afr_post_op_has_quorum (afr_local_t *local, xlator_t *this)
+{
+ afr_private_t *priv = NULL;
+ int i = 0;
+ unsigned char *post_op_children = NULL;
+
+ priv = this->private;
+ post_op_children = alloca0 (priv->child_count);
+
+ for (i = 0; i < priv->child_count; i++) {
+ if (!local->transaction.failed_subvols[i]) {
+ post_op_children[i] = 1;
+ }
+ }
+
+ if (afr_has_quorum (post_op_children, this)) {
+ return _gf_true;
+ }
+
+ return _gf_false;
+}
+
int
afr_changelog_post_op_done (call_frame_t *frame, xlator_t *this)
{
@@ -545,6 +568,12 @@ afr_changelog_post_op_done (call_frame_t *frame, xlator_t *this)
priv = this->private;
int_lock = &local->internal_lock;
+ /* Fail the FOP if post-op did not succeed on quorum no. of bricks. */
+ if (!afr_post_op_has_quorum (local, this)) {
+ local->op_ret = -1;
+ local->op_errno = ENOTCONN;
+ }
+
if (local->transaction.resume_stub) {
call_resume (local->transaction.resume_stub);
local->transaction.resume_stub = NULL;