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 36UFS_LINK_MAX=`grep UFS_LINK_MAX /usr/include/ufs/ufs/dinode.h 2>/dev/null` 37[ -z "$UFS_LINK_MAX" ] && exit 0 38UFS_LINK_MAX=`echo $UFS_LINK_MAX | awk '{print $3}'` 39cat > /tmp/nlink5.c <<EOF 40#include <sys/stat.h> 41#include <ufs/ufs/dinode.h> 42#include <err.h> 43#include <errno.h> 44#include <stdio.h> 45#include <unistd.h> 46 47int 48main (void) { 49 int i, mx; 50 char dir[100]; 51 52 mx = UFS_LINK_MAX - 2; 53 for (i = 0; i < mx; i++) { 54 snprintf(dir, sizeof(dir), "%d", i); 55 if (mkdir(dir, 0700) == -1) 56 err(1, "mkdir(%s)", dir); 57 } 58 59 /* The following mkdir(2) must fail */ 60 i = mx; 61 snprintf(dir, sizeof(dir), "%d", i); 62 if (mkdir(dir, 0700) != -1) /* this must fail */ 63 err(1, "mkdir(%s)", dir); 64 if (errno != EMLINK) 65 err(1, "Must fail: mkdir(%s)", dir); 66 67 /* Must succeed */ 68 i = 0; 69 snprintf(dir, sizeof(dir), "%d", i); 70 if (rmdir(dir) == -1) 71 err(1, "rmdir(%s)", dir); 72 snprintf(dir, sizeof(dir), "%s", "x"); 73 if (mkdir(dir, 0700) == -1) 74 err(1, "mkdir(%s)", dir); 75 76 /* Make room for two top level directories */ 77 if (rmdir("1") == -1) 78 err(1, "rmdir(1)"); 79 if (rmdir("2") == -1) 80 err(1, "rmdir(2)"); 81 82 /* mkdir a c */ 83 snprintf(dir, sizeof(dir), "%s", "a"); 84 if (mkdir(dir, 0700) == -1) 85 err(1, "mkdir(%s)", dir); 86 snprintf(dir, sizeof(dir), "%s", "c"); 87 if (mkdir(dir, 0700) == -1) 88 err(1, "mkdir(%s)", dir); 89 90 /* mkdir a/b */ 91 snprintf(dir, sizeof(dir), "%s/%s", "a", "b"); 92 if (mkdir(dir, 0700) == -1) 93 err(1, "mkdir(%s)", dir); 94 95 /* mv a/b c/d */ 96 if (rename("a/b", "c/d") == -1) 97 err(1, "rename(a/b, c/d)"); 98 99 return (0); 100} 101EOF 102mycc -o /tmp/nlink5 -Wall -Wextra -O2 /tmp/nlink5.c || exit 1 103rm /tmp/nlink5.c 104 105set -e 106here=`pwd` 107mount | grep -q "on $mntpoint " && umount -f $mntpoint 108mdconfig -l | grep "md$mdstart " && mdconfig -d -u $mdstart 109mdconfig -a -t swap -s 1g -u $mdstart 110newfs -Un /dev/md$mdstart > /dev/null 111mount /dev/md$mdstart $mntpoint 112set +e 113 114cd $mntpoint 115/tmp/nlink5; s=$? 116n=`find . -type d -maxdepth 1 | wc -l` 117[ $n -ne $((UFS_LINK_MAX - 1)) ] && s=2 118cd $here 119 120umount $mntpoint 121mdconfig -d -u $mdstart 122rm /tmp/nlink5 123exit $s 124