d1681e
From a7e4ed507c3332f896fb4822cfc3f98731c11785 Mon Sep 17 00:00:00 2001
d1681e
From: Ravishankar N <ravishankar@redhat.com>
d1681e
Date: Mon, 16 Apr 2018 15:38:34 +0530
d1681e
Subject: [PATCH 228/236] afr: fixes to afr-eager locking
d1681e
d1681e
Upstream patch: https://review.gluster.org/#/c/19879/
d1681e
d1681e
1. If pre-op fails on all bricks,set lock->release to true in
d1681e
afr_handle_lock_acquire_failure so that the GF_ASSERT in afr_unlock() does not
d1681e
crash.
d1681e
d1681e
2. Added a missing 'return' after handling pre-op failure in
d1681e
afr_transaction_perform_fop(), fixing a use-after-free issue.
d1681e
d1681e
Change-Id: If0627a9124cb5d6405037cab3f17f8325eed2d83
d1681e
BUG: 1554291
d1681e
Signed-off-by: Ravishankar N <ravishankar@redhat.com>
d1681e
Reviewed-on: https://code.engineering.redhat.com/gerrit/136228
d1681e
Reviewed-by: Pranith Kumar Karampuri <pkarampu@redhat.com>
d1681e
Tested-by: RHGS Build Bot <nigelb@redhat.com>
d1681e
---
d1681e
 tests/bugs/replicate/bug-1561129-enospc.t | 24 ++++++++++++++++++++++++
d1681e
 xlators/cluster/afr/src/afr-transaction.c |  2 ++
d1681e
 2 files changed, 26 insertions(+)
d1681e
 create mode 100644 tests/bugs/replicate/bug-1561129-enospc.t
d1681e
d1681e
diff --git a/tests/bugs/replicate/bug-1561129-enospc.t b/tests/bugs/replicate/bug-1561129-enospc.t
d1681e
new file mode 100644
d1681e
index 0000000..1b402fc
d1681e
--- /dev/null
d1681e
+++ b/tests/bugs/replicate/bug-1561129-enospc.t
d1681e
@@ -0,0 +1,24 @@
d1681e
+#!/bin/bash
d1681e
+#Tests that sequential write workload doesn't lead to FSYNCs
d1681e
+
d1681e
+. $(dirname $0)/../../include.rc
d1681e
+. $(dirname $0)/../../volume.rc
d1681e
+
d1681e
+cleanup;
d1681e
+
d1681e
+TEST truncate -s 128M $B0/xfs_image
d1681e
+TEST mkfs.xfs -f $B0/xfs_image
d1681e
+TEST mkdir $B0/bricks
d1681e
+TEST mount -t xfs -o loop $B0/xfs_image $B0/bricks
d1681e
+
d1681e
+TEST glusterd
d1681e
+TEST pidof glusterd
d1681e
+TEST $CLI volume create $V0 replica 3 $H0:$B0/bricks/brick{0,1,3}
d1681e
+TEST $CLI volume start $V0
d1681e
+TEST $GFS --volfile-id=$V0 --volfile-server=$H0 $M0;
d1681e
+
d1681e
+# Write 50MB of data, which will try to consume 50x3=150MB on $B0/bricks.
d1681e
+# Before that, we hit ENOSPC in pre-op cbk, which should not crash the mount.
d1681e
+TEST ! dd if=/dev/zero of=$M0/a bs=1M count=50
d1681e
+TEST stat $M0/a
d1681e
+cleanup;
d1681e
diff --git a/xlators/cluster/afr/src/afr-transaction.c b/xlators/cluster/afr/src/afr-transaction.c
d1681e
index 88dc821..0506a78 100644
d1681e
--- a/xlators/cluster/afr/src/afr-transaction.c
d1681e
+++ b/xlators/cluster/afr/src/afr-transaction.c
d1681e
@@ -285,6 +285,7 @@ afr_handle_lock_acquire_failure (afr_local_t *local, gf_boolean_t locked)
d1681e
         INIT_LIST_HEAD (&shared);
d1681e
         LOCK (&local->inode->lock);
d1681e
         {
d1681e
+                lock->release = _gf_true;
d1681e
                 list_splice_init (&lock->waiting, &shared);
d1681e
         }
d1681e
         UNLOCK (&local->inode->lock);
d1681e
@@ -510,6 +511,7 @@ afr_transaction_perform_fop (call_frame_t *frame, xlator_t *this)
d1681e
                                    priv->child_count);
d1681e
         if (failure_count == priv->child_count) {
d1681e
                 afr_handle_lock_acquire_failure (local, _gf_true);
d1681e
+                return 0;
d1681e
         } else {
d1681e
                 lock = &local->inode_ctx->lock[local->transaction.type];
d1681e
                 LOCK (&local->inode->lock);
d1681e
-- 
d1681e
1.8.3.1
d1681e