Blame SPECS/0422-cluster-afr-Prioritize-ENOSPC-over-other-errors.patch

Packit Service 150ff0
From 8b11ac1575ef167af2a47a96f7b7ed0f32bb5897 Mon Sep 17 00:00:00 2001
Packit Service 150ff0
From: karthik-us <ksubrahm@redhat.com>
Packit Service 150ff0
Date: Fri, 5 Jun 2020 17:20:04 +0530
Packit Service 150ff0
Subject: [PATCH 422/449] cluster/afr: Prioritize ENOSPC over other errors
Packit Service 150ff0
Packit Service 150ff0
Backport of: https://review.gluster.org/#/c/glusterfs/+/24477/
Packit Service 150ff0
Packit Service 150ff0
Problem:
Packit Service 150ff0
In a replicate/arbiter volume if file creations or writes fails on
Packit Service 150ff0
quorum number of bricks and on one brick it is due to ENOSPC and
Packit Service 150ff0
on other brick it fails for a different reason, it may fail with
Packit Service 150ff0
errors other than ENOSPC in some cases.
Packit Service 150ff0
Packit Service 150ff0
Fix:
Packit Service 150ff0
Prioritize ENOSPC over other lesser priority errors and do not set
Packit Service 150ff0
op_errno in posix_gfid_set if op_ret is 0 to avoid receiving any
Packit Service 150ff0
error_no which can be misinterpreted by __afr_dir_write_finalize().
Packit Service 150ff0
Packit Service 150ff0
Also removing the function afr_has_arbiter_fop_cbk_quorum() which
Packit Service 150ff0
might consider a successful reply form a single brick as quorum
Packit Service 150ff0
success in some cases, whereas we always need fop to be successful
Packit Service 150ff0
on quorum number of bricks in arbiter configuration.
Packit Service 150ff0
Packit Service 150ff0
Change-Id: I4dd2bff17e6812bc7c8372130976e365e2407d88
Packit Service 150ff0
Signed-off-by: karthik-us <ksubrahm@redhat.com>
Packit Service 150ff0
BUG: 1837467
Packit Service 150ff0
Reviewed-on: https://code.engineering.redhat.com/gerrit/202526
Packit Service 150ff0
Tested-by: RHGS Build Bot <nigelb@redhat.com>
Packit Service 150ff0
Reviewed-by: Sunil Kumar Heggodu Gopala Acharya <sheggodu@redhat.com>
Packit Service 150ff0
---
Packit Service 150ff0
 .../bugs/replicate/issue-1254-prioritize-enospc.t  | 80 ++++++++++++++++++++++
Packit Service 150ff0
 xlators/cluster/afr/src/afr-common.c               |  4 +-
Packit Service 150ff0
 xlators/cluster/afr/src/afr-transaction.c          | 48 +------------
Packit Service 150ff0
 xlators/storage/posix/src/posix-helpers.c          |  2 +-
Packit Service 150ff0
 4 files changed, 86 insertions(+), 48 deletions(-)
Packit Service 150ff0
 create mode 100644 tests/bugs/replicate/issue-1254-prioritize-enospc.t
Packit Service 150ff0
Packit Service 150ff0
diff --git a/tests/bugs/replicate/issue-1254-prioritize-enospc.t b/tests/bugs/replicate/issue-1254-prioritize-enospc.t
Packit Service 150ff0
new file mode 100644
Packit Service 150ff0
index 0000000..fab94b7
Packit Service 150ff0
--- /dev/null
Packit Service 150ff0
+++ b/tests/bugs/replicate/issue-1254-prioritize-enospc.t
Packit Service 150ff0
@@ -0,0 +1,80 @@
Packit Service 150ff0
+#!/bin/bash
Packit Service 150ff0
+
Packit Service 150ff0
+. $(dirname $0)/../../include.rc
Packit Service 150ff0
+. $(dirname $0)/../../volume.rc
Packit Service 150ff0
+
Packit Service 150ff0
+cleanup
Packit Service 150ff0
+
Packit Service 150ff0
+function create_bricks {
Packit Service 150ff0
+    TEST truncate -s 100M $B0/brick0
Packit Service 150ff0
+    TEST truncate -s 100M $B0/brick1
Packit Service 150ff0
+    TEST truncate -s 20M $B0/brick2
Packit Service 150ff0
+    LO1=`SETUP_LOOP $B0/brick0`
Packit Service 150ff0
+    TEST [ $? -eq 0 ]
Packit Service 150ff0
+    TEST MKFS_LOOP $LO1
Packit Service 150ff0
+    LO2=`SETUP_LOOP $B0/brick1`
Packit Service 150ff0
+    TEST [ $? -eq 0 ]
Packit Service 150ff0
+    TEST MKFS_LOOP $LO2
Packit Service 150ff0
+    LO3=`SETUP_LOOP $B0/brick2`
Packit Service 150ff0
+    TEST [ $? -eq 0 ]
Packit Service 150ff0
+    TEST MKFS_LOOP $LO3
Packit Service 150ff0
+    TEST mkdir -p $B0/${V0}0 $B0/${V0}1 $B0/${V0}2
Packit Service 150ff0
+    TEST MOUNT_LOOP $LO1 $B0/${V0}0
Packit Service 150ff0
+    TEST MOUNT_LOOP $LO2 $B0/${V0}1
Packit Service 150ff0
+    TEST MOUNT_LOOP $LO3 $B0/${V0}2
Packit Service 150ff0
+}
Packit Service 150ff0
+
Packit Service 150ff0
+function create_files {
Packit Service 150ff0
+        local i=1
Packit Service 150ff0
+        while (true)
Packit Service 150ff0
+        do
Packit Service 150ff0
+                touch $M0/file$i
Packit Service 150ff0
+                if [ -e $B0/${V0}2/file$i ];
Packit Service 150ff0
+                then
Packit Service 150ff0
+                        ((i++))
Packit Service 150ff0
+                else
Packit Service 150ff0
+                        break
Packit Service 150ff0
+                fi
Packit Service 150ff0
+        done
Packit Service 150ff0
+}
Packit Service 150ff0
+
Packit Service 150ff0
+TESTS_EXPECTED_IN_LOOP=13
Packit Service 150ff0
+
Packit Service 150ff0
+#Arbiter volume: Check for ENOSPC when arbiter brick becomes full#
Packit Service 150ff0
+TEST glusterd
Packit Service 150ff0
+create_bricks
Packit Service 150ff0
+TEST $CLI volume create $V0 replica 3 arbiter 1 $H0:$B0/${V0}{0,1,2}
Packit Service 150ff0
+TEST $CLI volume start $V0
Packit Service 150ff0
+TEST $CLI volume set $V0 performance.write-behind off
Packit Service 150ff0
+TEST $GFS --volfile-server=$H0 --volfile-id=$V0 $M0
Packit Service 150ff0
+
Packit Service 150ff0
+create_files
Packit Service 150ff0
+TEST kill_brick $V0 $H0 $B0/${V0}1
Packit Service 150ff0
+error1=$(touch $M0/file-1 2>&1)
Packit Service 150ff0
+EXPECT "No space left on device" echo $error1
Packit Service 150ff0
+error2=$(mkdir $M0/dir-1 2>&1)
Packit Service 150ff0
+EXPECT "No space left on device" echo $error2
Packit Service 150ff0
+error3=$((echo "Test" > $M0/file-3) 2>&1)
Packit Service 150ff0
+EXPECT "No space left on device" echo $error3
Packit Service 150ff0
+
Packit Service 150ff0
+cleanup
Packit Service 150ff0
+
Packit Service 150ff0
+#Replica-3 volume: Check for ENOSPC when one of the brick becomes full#
Packit Service 150ff0
+#Keeping the third brick of lower size to simulate disk full scenario#
Packit Service 150ff0
+TEST glusterd
Packit Service 150ff0
+create_bricks
Packit Service 150ff0
+TEST $CLI volume create $V0 replica 3 $H0:$B0/${V0}{0,1,2}
Packit Service 150ff0
+TEST $CLI volume start $V0
Packit Service 150ff0
+TEST $CLI volume set $V0 performance.write-behind off
Packit Service 150ff0
+TEST $GFS --volfile-server=$H0 --volfile-id=$V0 $M0
Packit Service 150ff0
+
Packit Service 150ff0
+create_files
Packit Service 150ff0
+TEST kill_brick $V0 $H0 $B0/${V0}1
Packit Service 150ff0
+error1=$(touch $M0/file-1 2>&1)
Packit Service 150ff0
+EXPECT "No space left on device" echo $error1
Packit Service 150ff0
+error2=$(mkdir $M0/dir-1 2>&1)
Packit Service 150ff0
+EXPECT "No space left on device" echo $error2
Packit Service 150ff0
+error3=$((cat /dev/zero > $M0/file1) 2>&1)
Packit Service 150ff0
+EXPECT "No space left on device" echo $error3
Packit Service 150ff0
+
Packit Service 150ff0
+cleanup
Packit Service 150ff0
diff --git a/xlators/cluster/afr/src/afr-common.c b/xlators/cluster/afr/src/afr-common.c
Packit Service 150ff0
index 5806556..59710aa 100644
Packit Service 150ff0
--- a/xlators/cluster/afr/src/afr-common.c
Packit Service 150ff0
+++ b/xlators/cluster/afr/src/afr-common.c
Packit Service 150ff0
@@ -2464,7 +2464,7 @@ error:
Packit Service 150ff0
  * others in that they must be given higher priority while
Packit Service 150ff0
  * returning to the user.
Packit Service 150ff0
  *
Packit Service 150ff0
- * The hierarchy is ENODATA > ENOENT > ESTALE > others
Packit Service 150ff0
+ * The hierarchy is ENODATA > ENOENT > ESTALE > ENOSPC others
Packit Service 150ff0
  */
Packit Service 150ff0
 
Packit Service 150ff0
 int
Packit Service 150ff0
@@ -2476,6 +2476,8 @@ afr_higher_errno(int32_t old_errno, int32_t new_errno)
Packit Service 150ff0
         return ENOENT;
Packit Service 150ff0
     if (old_errno == ESTALE || new_errno == ESTALE)
Packit Service 150ff0
         return ESTALE;
Packit Service 150ff0
+    if (old_errno == ENOSPC || new_errno == ENOSPC)
Packit Service 150ff0
+        return ENOSPC;
Packit Service 150ff0
 
Packit Service 150ff0
     return new_errno;
Packit Service 150ff0
 }
Packit Service 150ff0
diff --git a/xlators/cluster/afr/src/afr-transaction.c b/xlators/cluster/afr/src/afr-transaction.c
Packit Service 150ff0
index 15f3a7e..8e65ae2 100644
Packit Service 150ff0
--- a/xlators/cluster/afr/src/afr-transaction.c
Packit Service 150ff0
+++ b/xlators/cluster/afr/src/afr-transaction.c
Packit Service 150ff0
@@ -514,42 +514,6 @@ afr_compute_pre_op_sources(call_frame_t *frame, xlator_t *this)
Packit Service 150ff0
                 local->transaction.pre_op_sources[j] = 0;
Packit Service 150ff0
 }
Packit Service 150ff0
 
Packit Service 150ff0
-gf_boolean_t
Packit Service 150ff0
-afr_has_arbiter_fop_cbk_quorum(call_frame_t *frame)
Packit Service 150ff0
-{
Packit Service 150ff0
-    afr_local_t *local = NULL;
Packit Service 150ff0
-    afr_private_t *priv = NULL;
Packit Service 150ff0
-    xlator_t *this = NULL;
Packit Service 150ff0
-    gf_boolean_t fop_failed = _gf_false;
Packit Service 150ff0
-    unsigned char *pre_op_sources = NULL;
Packit Service 150ff0
-    int i = 0;
Packit Service 150ff0
-
Packit Service 150ff0
-    local = frame->local;
Packit Service 150ff0
-    this = frame->this;
Packit Service 150ff0
-    priv = this->private;
Packit Service 150ff0
-    pre_op_sources = local->transaction.pre_op_sources;
Packit Service 150ff0
-
Packit Service 150ff0
-    /* If the fop failed on the brick, it is not a source. */
Packit Service 150ff0
-    for (i = 0; i < priv->child_count; i++)
Packit Service 150ff0
-        if (local->transaction.failed_subvols[i])
Packit Service 150ff0
-            pre_op_sources[i] = 0;
Packit Service 150ff0
-
Packit Service 150ff0
-    switch (AFR_COUNT(pre_op_sources, priv->child_count)) {
Packit Service 150ff0
-        case 1:
Packit Service 150ff0
-            if (pre_op_sources[ARBITER_BRICK_INDEX])
Packit Service 150ff0
-                fop_failed = _gf_true;
Packit Service 150ff0
-            break;
Packit Service 150ff0
-        case 0:
Packit Service 150ff0
-            fop_failed = _gf_true;
Packit Service 150ff0
-            break;
Packit Service 150ff0
-    }
Packit Service 150ff0
-
Packit Service 150ff0
-    if (fop_failed)
Packit Service 150ff0
-        return _gf_false;
Packit Service 150ff0
-
Packit Service 150ff0
-    return _gf_true;
Packit Service 150ff0
-}
Packit Service 150ff0
-
Packit Service 150ff0
 void
Packit Service 150ff0
 afr_txn_arbitrate_fop(call_frame_t *frame, xlator_t *this)
Packit Service 150ff0
 {
Packit Service 150ff0
@@ -968,12 +932,8 @@ afr_need_dirty_marking(call_frame_t *frame, xlator_t *this)
Packit Service 150ff0
         priv->child_count)
Packit Service 150ff0
         return _gf_false;
Packit Service 150ff0
 
Packit Service 150ff0
-    if (priv->arbiter_count) {
Packit Service 150ff0
-        if (!afr_has_arbiter_fop_cbk_quorum(frame))
Packit Service 150ff0
-            need_dirty = _gf_true;
Packit Service 150ff0
-    } else if (!afr_has_fop_cbk_quorum(frame)) {
Packit Service 150ff0
+    if (!afr_has_fop_cbk_quorum(frame))
Packit Service 150ff0
         need_dirty = _gf_true;
Packit Service 150ff0
-    }
Packit Service 150ff0
 
Packit Service 150ff0
     return need_dirty;
Packit Service 150ff0
 }
Packit Service 150ff0
@@ -1023,12 +983,8 @@ afr_handle_quorum(call_frame_t *frame, xlator_t *this)
Packit Service 150ff0
      * no split-brain with the fix. The problem is eliminated completely.
Packit Service 150ff0
      */
Packit Service 150ff0
 
Packit Service 150ff0
-    if (priv->arbiter_count) {
Packit Service 150ff0
-        if (afr_has_arbiter_fop_cbk_quorum(frame))
Packit Service 150ff0
-            return;
Packit Service 150ff0
-    } else if (afr_has_fop_cbk_quorum(frame)) {
Packit Service 150ff0
+    if (afr_has_fop_cbk_quorum(frame))
Packit Service 150ff0
         return;
Packit Service 150ff0
-    }
Packit Service 150ff0
 
Packit Service 150ff0
     if (afr_need_dirty_marking(frame, this))
Packit Service 150ff0
         goto set_response;
Packit Service 150ff0
diff --git a/xlators/storage/posix/src/posix-helpers.c b/xlators/storage/posix/src/posix-helpers.c
Packit Service 150ff0
index 2c27d22..949c799 100644
Packit Service 150ff0
--- a/xlators/storage/posix/src/posix-helpers.c
Packit Service 150ff0
+++ b/xlators/storage/posix/src/posix-helpers.c
Packit Service 150ff0
@@ -1059,7 +1059,7 @@ verify_handle:
Packit Service 150ff0
         ret = posix_handle_soft(this, path, loc, uuid_curr, &stat;;
Packit Service 150ff0
 
Packit Service 150ff0
 out:
Packit Service 150ff0
-    if (!(*op_errno))
Packit Service 150ff0
+    if (ret && !(*op_errno))
Packit Service 150ff0
         *op_errno = errno;
Packit Service 150ff0
     return ret;
Packit Service 150ff0
 }
Packit Service 150ff0
-- 
Packit Service 150ff0
1.8.3.1
Packit Service 150ff0