xref: /freebsd/tools/test/stress2/misc/fsync4.sh (revision 9768746b)
1#!/bin/sh
2
3#
4# SPDX-License-Identifier: BSD-2-Clause
5#
6# Copyright (c) 2023 Peter Holm <pho@FreeBSD.org>
7#
8# Redistribution and use in source and binary forms, with or without
9# modification, are permitted provided that the following conditions
10# are met:
11# 1. Redistributions of source code must retain the above copyright
12#    notice, this list of conditions and the following disclaimer.
13# 2. Redistributions in binary form must reproduce the above copyright
14#    notice, this list of conditions and the following disclaimer in the
15#    documentation and/or other materials provided with the distribution.
16#
17# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27# SUCH DAMAGE.
28#
29
30# Regression test for D38114: Handle ERELOOKUP from VOP_FSYNC()
31
32# "fsync4: msync(0x82d3cc000), file d1/d2/d3/d4/d5/../file.92660:
33# Input/output error" seen
34
35# Fixed by: 6189672e6008 - main - Handle ERELOOKUP from VOP_FSYNC() in
36# several other places
37
38. ../default.cfg
39[ `id -u` -ne 0 ] && echo "Must be root!" && exit 1
40
41dir=/tmp
42odir=`pwd`
43pids=""
44prog=$(basename "$0" .sh)
45s=0
46cd $dir
47sed '1,/^EOF/d' < $odir/$0 > $dir/$prog.c
48mycc -o $prog -Wall -Wextra -O0 -g $prog.c || exit 1
49rm -f $prog.c
50cd $odir
51
52set -eu
53mount | grep "on $mntpoint " | grep -q /dev/md && umount -f $mntpoint
54[ -c /dev/md$mdstart ] &&  mdconfig -d -u $mdstart
55mdconfig -a -t swap -s 1g -u $mdstart
56newfs -U md$mdstart > /dev/null
57mount /dev/md$mdstart $mntpoint
58set +e
59
60cd $odir
61../testcases/swap/swap -t 1m -i 20 -l 100 > /dev/null &
62sleep .5
63cd $mntpoint
64mkdir -p d1/d2/d3/d4/d5
65for i in `jot 8`; do
66	$dir/$prog $i &
67	pids="$pids $!"
68done
69cd $odir
70for pid in $pids; do
71	wait $pid
72	[ $? -ne 0 ] && s=1
73done
74
75for i in `jot 6`; do
76	mount | grep -q "on $mntpoint " || break
77	umount $mntpoint && break || sleep 10
78	[ $i -eq 6 ] &&
79	    { echo FATAL; fstat -mf $mntpoint; exit 1; }
80done
81mdconfig -d -u $mdstart
82rm -rf $dir/$prog
83exit $s
84EOF
85#include <sys/types.h>
86#include <sys/mman.h>
87#include <sys/param.h>
88#include <sys/stat.h>
89
90
91#include <err.h>
92#include <fcntl.h>
93#include <stdio.h>
94#include <stdlib.h>
95#include <string.h>
96#include <unistd.h>
97
98#define RUNTIME 60
99#define SIZ (1024 * 1024)
100
101static time_t start;
102
103int
104main(void)
105{
106	size_t len;
107	int fd, i, ps;
108	char *cp;
109	char *path = "d1/d2/d3/d4/d5";
110	char d1[1024], d2[1024], file[1024];
111
112	snprintf(d1, sizeof(d1), "%s/dir.%d", path, getpid());
113	snprintf(d2, sizeof(d2), "%s/new.%d", path, getpid());
114	snprintf(file, sizeof(file), "%s/../file.%d", path, getpid());
115
116	start = time(NULL);
117	while (time(NULL) - start < RUNTIME) {
118		if (mkdir(d1, 0740) == -1)
119			err(1, "mkdir(%s)", d1);
120		if (rename(d1, d2) == -1)
121			err(1, "rename(%s, %s)", d1, d2);
122		if ((fd = open(file, O_RDWR | O_CREAT | O_TRUNC, 0600)) == -1)
123			err(1, "open%s()", file);
124		len = SIZ;
125		if (ftruncate(fd, len) == -1)
126			err(1, "ftruncate");
127		cp = mmap(NULL, len, PROT_READ | PROT_WRITE,
128		    MAP_SHARED, fd, 0);
129		    if (cp == MAP_FAILED)
130		    	err(1, "mmap()");
131		ps = getpagesize();
132		for (i = 0; i < SIZ; i += ps)
133			cp[i] = 1;
134		if (msync(cp, 0, MS_SYNC) == -1)
135			err(1, "msync(%p), file %s", cp, file);
136		if (munmap(cp, len) == -1)
137			err(1, "unmap()");
138		close(fd);
139		if (rename(d2, d1) == -1)
140			err(1, "rename(%s, %s)", d2, d1);
141		if (rmdir(d1) == -1)
142			err(1, "rmdir(%s)", d1);
143	}
144
145	return (0);
146}
147