diff options
author | Kent Overstreet <kent.overstreet@gmail.com> | 2020-11-11 14:12:48 -0500 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@gmail.com> | 2022-03-10 11:47:17 -0500 |
commit | f6fa93c115e4e9984f6af293d026715c0e886004 (patch) | |
tree | a4a5fd0aa05754da458efb627191396628b19acb | |
parent | 2d5a4670334cbab47d674ba23c0c271f17961ef6 (diff) |
Add generic/648 for pagecache_add lock deadlock torture test
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | src/Makefile | 3 | ||||
-rw-r--r-- | src/dio_mmap_torture.c | 104 | ||||
-rw-r--r-- | tests/generic/676 | 43 |
4 files changed, 150 insertions, 1 deletions
@@ -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 |