The branch main has been updated by pho:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=c2b513335f688ac5657abc1bc40f6848988958d7

commit c2b513335f688ac5657abc1bc40f6848988958d7
Author:     Peter Holm <[email protected]>
AuthorDate: 2026-01-24 12:30:31 +0000
Commit:     Peter Holm <[email protected]>
CommitDate: 2026-01-24 12:30:31 +0000

    stress2: Added two new test scenarios
---
 tools/test/stress2/misc/swap8.sh     | 141 +++++++++++++++++++++++++++++++++++
 tools/test/stress2/misc/unionfs21.sh |  44 +++++++++++
 2 files changed, 185 insertions(+)

diff --git a/tools/test/stress2/misc/swap8.sh b/tools/test/stress2/misc/swap8.sh
new file mode 100755
index 000000000000..46abcf747346
--- /dev/null
+++ b/tools/test/stress2/misc/swap8.sh
@@ -0,0 +1,141 @@
+#!/bin/sh
+
+#
+# Copyright (c) 2026 Peter Holm <[email protected]>
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+
+# sendfile over tmpfs
+
+# "panic: vm_page_assert_busied: page 0xfffffe000015fb88 not busy @ 
../../../vm/vm_page.c:5845" seen
+# Triggered by: 72ddb6de1028 - main - unix: increase 
net.local.(stream|seqpacket).(recv|send)space to 64 KiB
+# Fixed by: d198ad51ea73 - main - swap_pager_getpages(): some pages from ma[] 
might be bogus
+
+[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
+[ `sysctl -n vm.swap_total` -eq 0 ] && exit 0
+
+. ../default.cfg
+
+prog=$(basename "$0" .sh)
+
+cat > /tmp/$prog.c <<EOF
+#include <sys/types.h>
+#include <sys/fcntl.h>
+#include <sys/mman.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/uio.h>
+#include <sys/wait.h>
+
+#include <err.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+static int use_sendfile = 1;
+
+int
+main(int argc, char *argv[])
+{
+       off_t rsize, wsize, pos;
+       ssize_t n;
+       struct stat st;
+       int from, pair[2], pid, status;
+       const char *from_name;
+       char *buf, *cp;
+
+       if (argc != 2)
+               errx(1, "Usage: %s from", argv[0]);
+       from_name = argv[1];
+
+       if ((from = open(from_name, O_RDONLY)) == -1)
+               err(1, "open read %s", from_name);
+
+       if (fstat(from, &st) == -1)
+               err(1, "stat %s", from_name);
+
+       if (socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == -1)
+               err(1, "socketpair");
+
+       pid = fork();
+       if (pid == -1)
+               err(1, "fork");
+       if (pid == 0) { /* child */
+               setproctitle("reader");
+               close(pair[0]);
+               buf = malloc(st.st_size);
+               if (buf == NULL)
+                       err(1, "malloc %jd", st.st_size);
+               pos = 0;
+               sleep(1);
+               for (;;) {
+                       rsize = 413; /* arbitrary small block size */
+                       if (rsize > st.st_size - pos)
+                               rsize = st.st_size - pos;
+                       n = read(pair[1], buf + pos, rsize);
+                       if (n == -1)
+                               err(1, "read()");
+                       else if (n == 0)
+                               errx(1, "Short read: Read %jd bytes out of 
%jd\n",
+                                       (intmax_t)pos, (intmax_t)st.st_size);
+                       pos += n;
+                       if (pos == st.st_size)
+                               break;
+               }
+               close(pair[1]);
+               _exit(0);
+       }
+       setproctitle("writer");
+       close(pair[1]);
+
+       if (use_sendfile == 1) {
+               pos = 0;
+               for (;;) {
+                       n = sendfile(from, pair[0], pos, st.st_size - pos,
+                           NULL, &wsize, 0);
+                       if (n == -1) {
+                               if (errno != EAGAIN)
+                                       err(1, "sendfile()");
+                       }
+                       if (wsize != st.st_size)
+                               fprintf(stderr, "sendfile() wrote %jd bytes\n", 
(intmax_t)wsize);
+                       pos += wsize;
+                       if (pos == st.st_size)
+                               break;
+               }
+       } else {
+               fprintf(stderr, "Not using sendfile().\n");
+               if ((cp = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, from, 
0)) == MAP_FAILED)
+                       err(1, "mmap");
+
+               if ((n = write(pair[0], cp, st.st_size)) == -1)
+                       err(1, "write()");
+               if (n != st.st_size)
+                       errx(1, "short write: %jd of %jd\n", (intmax_t)n, 
(intmax_t)st.st_size);
+               if (munmap(cp, st.st_size) == -1)
+                       err(1, "munmap()");
+       }
+       if (waitpid(pid, &status, 0) != pid)
+               err(1, "waitpid()");
+       close(pair[0]);
+
+       return (status != 0);
+}
+EOF
+mycc -o /tmp/$prog -Wall -Wextra -O0 /tmp/$prog.c || exit 1
+
+mount | grep -q "on $mntpoint " && umount -f $mntpoint
+mount -t tmpfs dummy $mntpoint || exit 1
+dd if=/dev/zero of=$mntpoint/file bs=1m count=1024 status=none # 1Gb
+
+../testcases/swap/swap -t 5m -i 40 > /dev/null 2>&1 &
+sleep 5
+/tmp/$prog $mntpoint/file
+while pkill swap; do :; done
+wait
+
+umount $mntpoint
+rm -f /tmp/$prog /tmp/$prog.c $diskimage
+exit 0
diff --git a/tools/test/stress2/misc/unionfs21.sh 
b/tools/test/stress2/misc/unionfs21.sh
new file mode 100755
index 000000000000..c182274b52be
--- /dev/null
+++ b/tools/test/stress2/misc/unionfs21.sh
@@ -0,0 +1,44 @@
+#!/bin/sh
+
+# "panic: unionfs_lock_lvp: vnode is locked but should not be" seen
+
+# Test scenario based on:
+# Bug 275871 - [unionfs] [nullfs] [zfs] corrupt filesystem
+# Bug 172334 - unionfs permits recursive union mounts; causes panic quickly
+
+. ../default.cfg
+
+prog=$(basename "$0" .sh)
+here=`pwd`
+log=/tmp/$prog.log
+md1=$mdstart
+md2=$((md1 + 1))
+mp1=/mnt$md1
+mp2=/mnt$md2
+
+set -eu
+mdconfig -l | grep -q md$md1 && mdconfig -d -u $md1
+mdconfig -l | grep -q md$md2 && mdconfig -d -u $md2
+
+mdconfig -s 2g -u $md1
+newfs $newfs_flags /dev/md$md1 > /dev/null
+mdconfig -s 2g -u $md2
+newfs $newfs_flags /dev/md$md2 > /dev/null
+
+mkdir -p $mp1 $mp2
+mount /dev/md$md1 $mp1
+mount /dev/md$md2 $mp2
+set +e
+mount -t unionfs -o noatime $mp1 $mp2
+mount -t unionfs -o noatime $mp2 $mp1
+
+ls -lr $mp1 $mp2 > /dev/null # triggers the panic
+
+umount $mp2 # The unionfs mount
+umount $mp2
+umount $mp1
+
+mdconfig -d -u $md1
+mdconfig -d -u $md2
+rm -f /tmp/$prog
+exit 0

Reply via email to