xref: /freebsd/tools/test/stress2/misc/truncate8.sh (revision d4eeb02986980bf33dd56c41ceb9fc5f180c0d47)
1#!/bin/sh
2
3#
4# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
5#
6# Copyright (c) 2019 Dell EMC Isilon
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# Bug 236977 - [msdosfs] returns cached truncated data
31# Fixed by r345847
32
33. ../default.cfg
34[ `id -u` -ne 0 ] && echo "Must be root!" && exit 1
35
36dir=/tmp
37odir=`pwd`
38cd $dir
39sed '1,/^EOF/d' < $odir/$0 > $dir/truncate8.c
40mycc -o truncate8 -Wall -Wextra -O0 -g truncate8.c || exit 1
41rm -f truncate8.c
42cd $odir
43
44echo ufs:
45mount | grep -q "$mntpoint " && umount $mntpoint
46mdconfig -l | grep -q $mdstart && mdconfig -d -u $mdstart
47mdconfig -a -t swap -s 1g -u $mdstart
48gpart create -s bsd md$mdstart > /dev/null
49gpart add -t freebsd-ufs md$mdstart > /dev/null
50part=a
51newfs $newfs_flags md${mdstart}$part > /dev/null
52mount /dev/md${mdstart}$part $mntpoint
53
54(cd $mntpoint; /tmp/truncate8)
55s=$?
56[ $s -ne 0 ] && { echo "UFS exit status is $s"; status=1; }
57while mount | grep -q "$mntpoint "; do
58	umount $mntpoint || sleep 1
59done
60mdconfig -d -u $mdstart
61
62echo nfs:
63if ping -c 2 `echo $nfs_export | sed 's/:.*//'` > /dev/null 2>&1; then
64	mount -t nfs -o tcp -o retrycnt=3 -o intr,soft -o rw $nfs_export \
65	    $mntpoint
66	sleep .2
67	(cd $mntpoint; /tmp/truncate8)
68	s=$?
69	[ $s -ne 0 ] && { echo "NFS exit status is $s"; status=1; }
70
71	umount $mntpoint || umount $mntpoint
72fi
73
74echo msdos:
75if [ -x /sbin/mount_msdosfs ]; then
76	mdconfig -a -t swap -s 1g -u $mdstart
77	gpart create -s bsd md$mdstart > /dev/null
78	gpart add -t freebsd-ufs md$mdstart > /dev/null
79	part=a
80	newfs_msdos -F 16 -b 8192 /dev/md${mdstart}$part > /dev/null 2>&1
81	mount_msdosfs -m 777 /dev/md${mdstart}$part $mntpoint
82
83	(cd /mnt; /tmp/truncate8)
84	s=$?
85	[ $s -ne 0 ] && { echo "MSDOS exit status is $s"; status=1; }
86	while mount | grep -q "$mntpoint "; do
87		umount $mntpoint || sleep 1
88	done
89	mdconfig -d -u $mdstart
90fi
91
92echo tmpfs:
93mount -t tmpfs null $mntpoint
94chmod 777 $mntpoint
95
96(cd $mntpoint; /tmp/truncate8)
97s=$?
98[ $s -ne 0 ] && { echo "TMPFS exit status is $s"; status=1; }
99while mount | grep -q "$mntpoint "; do
100	umount $mntpoint || sleep 1
101done
102
103rm -rf /tmp/truncate8
104exit $status
105
106EOF
107#include <sys/param.h>
108#include <sys/mman.h>
109#include <sys/stat.h>
110#include <sys/wait.h>
111
112#include <machine/atomic.h>
113
114#include <err.h>
115#include <errno.h>
116#include <fcntl.h>
117#include <stdio.h>
118#include <stdlib.h>
119#include <time.h>
120#include <unistd.h>
121
122static volatile u_int *share;
123
124#define BSIZE 5120
125#define FSIZE (128 * 1024 * 1024)
126#define PARALLEL 2
127#define RUNTIME (1 * 60)
128#define SYNC 0
129
130static void
131test(void)
132{
133	time_t start;
134	off_t pos;
135	int fd, i, n, r;
136	char *buf, name[128];
137
138	atomic_add_int(&share[SYNC], 1);
139	while (share[SYNC] != PARALLEL)
140		;
141
142	srand48(getpid());
143	buf = malloc(BSIZE);
144	for (i = 0; i < (int)sizeof(buf); i++)
145		buf[i] = 123;
146
147	sprintf(name, "f%05d", getpid());
148	if ((fd = open(name, O_RDWR | O_CREAT, 0640)) == -1)
149		err(1, "%s", name);
150	for (i = 0; i < FSIZE / BSIZE; i++)
151		if (write(fd, buf, BSIZE) != BSIZE)
152			err(1, "write");
153
154	start = time(NULL);
155	while (time(NULL) - start < RUNTIME) {
156		pos = lrand48() % (FSIZE - BSIZE);
157//		fprintf(stderr, "truncate(%jd)\n", (intmax_t)pos);
158		if (ftruncate(fd, pos) == -1)
159			err(1, "ftruncate");
160
161		if (ftruncate(fd, FSIZE) == -1)
162			err(1, "ftruncate");
163		if (lseek(fd, pos, SEEK_SET) == -1)
164			err(1, "lseek");
165		n = 0;
166		while ((r = read(fd, buf, BSIZE)) == BSIZE) {
167			n++;
168			for (i = 0; i < BSIZE; i++) {
169				if (buf[i] != 0)
170					errx(1, "Bad read value @ %jd = %d",
171					    (intmax_t)(pos + i), buf[i]);
172			}
173		}
174		if (r == -1)
175			err(1, "read");
176		if (n != (FSIZE - pos) / BSIZE)
177			fprintf(stderr, "n = %d, target = %d\n", n, (int)(FSIZE - pos) / BSIZE);
178	}
179	unlink(name);
180
181	_exit(0);
182}
183
184int
185main(void)
186{
187	pid_t pids[PARALLEL];
188	size_t len;
189	int e, i, status;
190
191	e = 0;
192	len = PAGE_SIZE;
193	if ((share = mmap(NULL, len, PROT_READ | PROT_WRITE,
194	    MAP_ANON | MAP_SHARED, -1, 0)) == MAP_FAILED)
195		err(1, "mmap");
196
197	for (i = 0; i < PARALLEL; i++) {
198		if ((pids[i] = fork()) == 0)
199			test();
200		if (pids[i] == -1)
201			err(1, "fork()");
202	}
203	for (i = 0; i < PARALLEL; i++) {
204		if (waitpid(pids[i], &status, 0) == -1)
205			err(1, "waitpid(%d)", pids[i]);
206		if (status != 0) {
207			if (WIFSIGNALED(status))
208				fprintf(stderr,
209				    "pid %d exit signal %d\n",
210				    pids[i], WTERMSIG(status));
211		}
212		e += status == 0 ? 0 : 1;
213	}
214
215	return (e);
216}
217