summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2020-11-11 14:12:48 -0500
committerKent Overstreet <kent.overstreet@gmail.com>2022-03-10 11:47:17 -0500
commitf6fa93c115e4e9984f6af293d026715c0e886004 (patch)
treea4a5fd0aa05754da458efb627191396628b19acb
parent2d5a4670334cbab47d674ba23c0c271f17961ef6 (diff)
Add generic/648 for pagecache_add lock deadlock torture test
-rw-r--r--.gitignore1
-rw-r--r--src/Makefile3
-rw-r--r--src/dio_mmap_torture.c104
-rw-r--r--tests/generic/67643
4 files changed, 150 insertions, 1 deletions
diff --git a/.gitignore b/.gitignore
index ba0c572b..26d7667d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -74,6 +74,7 @@ tags
/src/devzero
/src/dio-interleaved
/src/dio-invalidate-cache
+/src/dio_mmap_torture
/src/dirhash_collide
/src/dirperf
/src/dirstress
diff --git a/src/Makefile b/src/Makefile
index 111ce1d9..7f6f2b83 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -18,7 +18,8 @@ TARGETS = dirstress fill fill2 getpagesize holes lstat64 \
t_ext4_dax_journal_corruption t_ext4_dax_inline_corruption \
t_ofd_locks t_mmap_collision mmap-write-concurrent \
t_get_file_time t_create_short_dirs t_create_long_dirs t_enospc \
- t_mmap_writev_overlap checkpoint_journal mmap-rw-fault allocstale
+ t_mmap_writev_overlap checkpoint_journal mmap-rw-fault allocstale \
+ dio_mmap_torture
LINUX_TARGETS = xfsctl bstat t_mtab getdevicesize preallo_rw_pattern_reader \
preallo_rw_pattern_writer ftrunc trunc fs_perms testx looptest \
diff --git a/src/dio_mmap_torture.c b/src/dio_mmap_torture.c
new file mode 100644
index 00000000..22967d49
--- /dev/null
+++ b/src/dio_mmap_torture.c
@@ -0,0 +1,104 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2020 Kent Overstreet
+ */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+static const unsigned nr_procs = 3;
+
+int main(int argc, char *argv[])
+{
+ unsigned long i, nr_iters = 0;
+ char *fname = NULL, *my_file, *next_file;
+ pid_t children[nr_procs];
+ int childnr, my_fd, next_fd, c;
+
+ while ((c = getopt(argc, argv, "n:f:")) >= 0) {
+ switch (c) {
+ case 'n':
+ errno = 0;
+ nr_iters = strtoul(optarg, NULL, 10);
+ if (errno) {
+ fprintf(stderr, "Error parsing -n: %m\n");
+ exit(EXIT_FAILURE);
+ }
+ break;
+ case 'f':
+ fname = optarg;
+ break;
+ default:
+ fprintf(stderr, "Usage: dio_mmap_torture -n iters -f filename\n");
+ exit(EXIT_FAILURE);
+ }
+ }
+
+ for (i = 0; i < nr_procs; i++) {
+ children[i] = fork();
+ if (!children[i])
+ goto do_io;
+
+ }
+
+ for (i = 0; i < nr_procs; i++) {
+ int status;
+ waitpid(children[i], &status, 0);
+ }
+
+ exit(EXIT_SUCCESS);
+do_io:
+ childnr = i;
+
+ asprintf(&my_file, "%s.%lu", fname, i);
+ my_fd = open(my_file, O_RDWR|O_CREAT|O_DIRECT, 0644);
+ if (my_fd < 0) {
+ fprintf(stderr, "Error opening %s: %m\n", my_file);
+ exit(EXIT_FAILURE);
+ }
+
+ i = (i + 1) % nr_procs;
+
+ asprintf(&next_file, "%s.%lu", fname, i);
+ next_fd = open(next_file, O_RDWR|O_CREAT, 0644);
+ if (next_fd < 0) {
+ fprintf(stderr, "Error opening %s: %m\n", next_file);
+ exit(EXIT_FAILURE);
+ }
+
+ if (ftruncate(next_fd, 4096)) {
+ fprintf(stderr, "ftruncate error: %m\n");
+ exit(EXIT_FAILURE);
+ }
+
+ void *p = mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_SHARED, next_fd, 0);
+ if (p == MAP_FAILED) {
+ fprintf(stderr, "mmap error: %m\n");
+ exit(EXIT_FAILURE);
+ }
+
+ mlockall(MCL_CURRENT|MCL_FUTURE);
+
+ for (i = 0; i < nr_iters; i++) {
+ int ret = pwrite(my_fd, p, 4096, 0);
+ //fprintf(stderr, "child %u write ret %i\n", childnr, ret);
+
+ if (ret < 0) {
+ fprintf(stderr, "write error: %m\n");
+ exit(EXIT_FAILURE);
+ }
+
+ if (ret != 4096)
+ fprintf(stderr, "short write: %u/%u\n", ret, 4096);
+ }
+
+ exit(EXIT_SUCCESS);
+}
diff --git a/tests/generic/676 b/tests/generic/676
new file mode 100644
index 00000000..66a660b4
--- /dev/null
+++ b/tests/generic/676
@@ -0,0 +1,43 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (c) 2020 Kent Overstreet. All Rights Reserved.
+#
+# FS QA Test 609
+# Test DIO writes from buffers mmapped from files that are also having dio
+# writes done to them
+
+seq=`basename $0`
+seqres=$RESULT_DIR/$seq
+echo "QA output created by $seq"
+
+here=`pwd`
+tmp=/tmp/$$
+status=1 # failure is the default!
+trap "_cleanup; exit \$status" 0 1 2 3 15
+
+_cleanup()
+{
+ cd /
+ rm -f $tmp.*
+}
+
+# get standard environment, filters and checks
+. ./common/rc
+. ./common/filter
+
+# remove previous $seqres.full before test
+rm -f $seqres.full
+
+_supported_fs generic
+_supported_os Linux
+_require_scratch
+
+_scratch_mkfs >> $seqres.full 2>&1
+_scratch_mount
+
+$here/src/dio_mmap_torture -n 10000 -f $SCRATCH_MNT/$seq
+
+# success, all done
+echo "Silence is golden"
+status=0
+exit