xref: /freebsd/tools/test/stress2/misc/nlink5.sh (revision ba3c1f5972d7b90feb6e6da47905ff2757e0fe57)
1#!/bin/sh
2#
3# SPDX-License-Identifier: BSD-2-Clause
4#
5# Copyright (c) 2022 Peter Holm <pho@FreeBSD.org>
6#
7# Redistribution and use in source and binary forms, with or without
8# modification, are permitted provided that the following conditions
9# are met:
10# 1. Redistributions of source code must retain the above copyright
11#    notice, this list of conditions and the following disclaimer.
12# 2. Redistributions in binary form must reproduce the above copyright
13#    notice, this list of conditions and the following disclaimer in the
14#    documentation and/or other materials provided with the distribution.
15#
16# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26# SUCH DAMAGE.
27#
28
29# https://reviews.freebsd.org/D35514
30# Rename dir a/b to c/d
31
32# Test scenario suggestion by kib
33
34. ../default.cfg
35
36cat > /tmp/nlink5.c <<EOF
37#include <sys/stat.h>
38#include <ufs/ufs/dinode.h>
39#include <err.h>
40#include <errno.h>
41#include <stdio.h>
42#include <unistd.h>
43
44int
45main (void) {
46	int i, mx;
47	char dir[100];
48
49	mx = UFS_LINK_MAX - 2; /* UFS_LINK_MAX = 32767 */
50	for (i = 0; i < mx; i++) {
51		snprintf(dir, sizeof(dir), "%d", i);
52		if (mkdir(dir, 0700) == -1)
53			err(1, "mkdir(%s)", dir);
54	}
55
56	/* The following mkdir(2) must fail */
57	i = mx;
58	snprintf(dir, sizeof(dir), "%d", i);
59	if (mkdir(dir, 0700) != -1)	/* this must fail */
60		err(1, "mkdir(%s)", dir);
61	if (errno != EMLINK)
62		err(1, "Must fail: mkdir(%s)", dir);
63
64	/* Must succeed */
65	i = 0;
66	snprintf(dir, sizeof(dir), "%d", i);
67	if (rmdir(dir) == -1)
68		err(1, "rmdir(%s)", dir);
69	snprintf(dir, sizeof(dir), "%s", "x");
70	if (mkdir(dir, 0700) == -1)
71		err(1, "mkdir(%s)", dir);
72
73	/* Make room for two top level directories */
74	if (rmdir("1") == -1)
75		err(1, "rmdir(1)");
76	if (rmdir("2") == -1)
77		err(1, "rmdir(2)");
78
79	/* mkdir a c */
80	snprintf(dir, sizeof(dir), "%s", "a");
81	if (mkdir(dir, 0700) == -1)
82		err(1, "mkdir(%s)", dir);
83	snprintf(dir, sizeof(dir), "%s", "c");
84	if (mkdir(dir, 0700) == -1)
85		err(1, "mkdir(%s)", dir);
86
87	/* mkdir a/b */
88	snprintf(dir, sizeof(dir), "%s/%s", "a", "b");
89	if (mkdir(dir, 0700) == -1)
90		err(1, "mkdir(%s)", dir);
91
92	/* mv a/b c/d */
93	if (rename("a/b", "c/d") == -1)
94		err(1, "rename(a/b, c/d)");
95
96	return (0);
97}
98EOF
99mycc -o /tmp/nlink5 -Wall -Wextra -O2 /tmp/nlink5.c || exit 1
100rm /tmp/nlink5.c
101
102set -e
103here=`pwd`
104mount | grep -q "on $mntpoint " && umount -f $mntpoint
105mdconfig -l | grep "md$mdstart " && mdconfig -d -u $mdstart
106mdconfig -a -t swap -s 1g -u $mdstart
107newfs -Un /dev/md$mdstart > /dev/null
108mount /dev/md$mdstart $mntpoint
109set +e
110
111cd $mntpoint
112/tmp/nlink5; s=$?
113n=`find . -type d -maxdepth 1 | wc -l`
114[ $n -ne 32766 ] && s=2
115cd $here
116
117umount $mntpoint
118mdconfig -d -u $mdstart
119rm /tmp/nlink5
120exit $s
121