summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--tests/bugs/shard/parallel-truncate-read.t48
-rw-r--r--xlators/features/shard/src/shard.c13
2 files changed, 61 insertions, 0 deletions
diff --git a/tests/bugs/shard/parallel-truncate-read.t b/tests/bugs/shard/parallel-truncate-read.t
new file mode 100644
index 00000000000..4de876f58f6
--- /dev/null
+++ b/tests/bugs/shard/parallel-truncate-read.t
@@ -0,0 +1,48 @@
+#!/bin/bash
+
+#This test will crash if shard's LRU contains a shard's inode even after the
+#inode is forgotten. Minimum time for crash to happen I saw was 180 seconds
+
+. $(dirname $0)/../../include.rc
+
+function keep_writing {
+ cd $M0;
+ while [ -f /tmp/parallel-truncate-read ]
+ do
+ dd if=/dev/zero of=file1 bs=1M count=16
+ done
+ cd
+}
+
+function keep_reading {
+ cd $M0;
+ while [ -f /tmp/parallel-truncate-read ]
+ do
+ cat file1 > /dev/null
+ done
+ cd
+}
+
+cleanup;
+
+TEST touch /tmp/parallel-truncate-read
+TEST glusterd
+TEST pidof glusterd
+TEST $CLI volume create $V0 replica 3 $H0:$B0/${V0}{0,1,2}
+TEST $CLI volume set $V0 features.shard on
+TEST $CLI volume set $V0 performance.quick-read off
+TEST $CLI volume set $V0 performance.io-cache off
+TEST $CLI volume set $V0 performance.stat-prefetch off
+TEST $CLI volume set $V0 performance.read-ahead off
+TEST $CLI volume start $V0
+
+TEST $GFS --volfile-id=$V0 --volfile-server=$H0 $M0
+keep_writing &
+keep_reading &
+sleep 180
+TEST rm -f /tmp/parallel-truncate-read
+wait
+#test that the mount is operational
+TEST stat $M0
+
+cleanup;
diff --git a/xlators/features/shard/src/shard.c b/xlators/features/shard/src/shard.c
index d7526339591..f892fb69efa 100644
--- a/xlators/features/shard/src/shard.c
+++ b/xlators/features/shard/src/shard.c
@@ -5011,13 +5011,26 @@ shard_forget (xlator_t *this, inode_t *inode)
{
uint64_t ctx_uint = 0;
shard_inode_ctx_t *ctx = NULL;
+ shard_priv_t *priv = NULL;
+ priv = this->private;
inode_ctx_del (inode, this, &ctx_uint);
if (!ctx_uint)
return 0;
ctx = (shard_inode_ctx_t *)ctx_uint;
+ /* When LRU limit reaches inode will be forcefully removed from the
+ * table, inode needs to be removed from LRU of shard as well.
+ */
+ if (!list_empty (&ctx->ilist)) {
+ LOCK(&priv->lock);
+ {
+ list_del_init (&ctx->ilist);
+ priv->inode_count--;
+ }
+ UNLOCK(&priv->lock);
+ }
GF_FREE (ctx);
return 0;