1# 2# Copyright (c) 2025 Dag-Erling Smørgrav <des@FreeBSD.org> 3# 4# SPDX-License-Identifier: BSD-2-Clause 5# 6 7# Create and mount a UFS filesystem on a small memory disk 8quot_setup() 9{ 10 atf_check -o save:dev mdconfig -t malloc -s 16M 11 local dev=$(cat dev) 12 atf_check -o ignore newfs "$@" /dev/$dev 13 atf_check mkdir mnt 14 local mnt=$(realpath mnt) 15 atf_check mount /dev/$dev "$mnt" 16 echo "/dev/$dev: ($mnt)" >expect 17 printf "%5d\t%5d\t%-8s\n" 8 2 "#0" >>expect 18} 19 20# Create a directory owned by a given UID 21quot_adduid() 22{ 23 local uid=$1 24 atf_check install -d -o $uid -g 0 mnt/$uid 25 printf "%5d\t%5d\t%-8s\n" 4 1 "#$uid" >>expect 26} 27 28# Perform the tests 29quot_test() 30{ 31 local dev=$(cat dev) 32 # Create inodes owned by a large number of users to exercise 33 # hash collisions and rehashing. The code uses an open hash 34 # table that starts out with only 8 entries and doubles every 35 # time it fills up. 36 local uid 37 for uid in $(seq 1 32); do 38 quot_adduid $uid 39 done 40 # Also create inodes owned by users with long UIDs, up to the 41 # highest possible value (2^32 - 2, because chown(2) and 42 # friends interpret 2^32 - 1 as “leave unchanged”). 43 local shift 44 for shift in $(seq 6 32); do 45 quot_adduid $(((1 << shift) - 2)) 46 done 47 # Since quot operates directly on the underlying device, not 48 # on the mounted filesystem, we remount read-only to ensure 49 # that everything gets flushed to the memory disk. 50 atf_check mount -ur /dev/$dev 51 atf_check -o file:expect quot -fkN /dev/$dev 52 atf_check -o file:expect quot -fkN $(realpath mnt) 53} 54 55# Unmount and release the memory disk 56quot_cleanup() 57{ 58 if [ -d mnt ]; then 59 umount mnt || true 60 fi 61 if [ -f dev ]; then 62 mdconfig -d -u $(cat dev) || true 63 fi 64} 65 66atf_test_case ufs1 cleanup 67ufs1_head() 68{ 69 atf_set descr "Test quot on UFS1" 70 atf_set require.user root 71} 72ufs1_body() 73{ 74 quot_setup -O1 75 quot_test 76} 77ufs1_cleanup() 78{ 79 quot_cleanup 80} 81 82atf_test_case ufs2 cleanup 83ufs2_head() 84{ 85 atf_set descr "Test quot on UFS2" 86 atf_set require.user root 87} 88ufs2_body() 89{ 90 quot_setup -O2 91 quot_test 92} 93ufs2_cleanup() 94{ 95 quot_cleanup 96} 97 98atf_init_test_cases() 99{ 100 atf_add_test_case ufs1 101 atf_add_test_case ufs2 102} 103