DF-3107 / stress.sh
#!/bin/sh # DF-3107 — ufs_checkpath zero-ref vnode use: bounded race attempt. # # Bug (sys/vfs/ufs/ufs_lookup.c:1160-1161): # vput(vp); /* intermediate ancestor: # refcount 1 -> 0 */ # error = VFS_VGET(vp->v_mount, ...); /* reads the zero-ref, # reclaimable vnode */ # Renaming a directory into a target >= 3 levels deep performs this on the # intermediate ancestor on EVERY rename (deterministic zero-ref window). # FreeBSD caches the mount pointer before the loop for exactly this reason. # # The renames must run on a UFS mount (vn-backed image); the vnode churn # (alloc/free pressure) is global. set -e LOG=/root/df3107/stress.out : > "$LOG" MNT=/mnt/cp # --- UFS test filesystem --- rm -f /root/df3107/cp.img dd if=/dev/zero of=/root/df3107/cp.img bs=1m count=8 2>/dev/null VN=$(vnconfig -c vn /root/df3107/cp.img | awk '{print $1}') newfs -b 4096 -f 512 /dev/$VN >/dev/null 2>&1 mkdir -p "$MNT" mount -t ufs /dev/$VN "$MNT" mkdir -p "$MNT/a/b/c" "$MNT/S" /tmp/churn echo "hierarchy ready; starting stress $(date +%T)" >> "$LOG" # churn: constant vnode alloc/free pressure ( i=0 while [ $i -lt 60000 ]; do i=$((i+1)) : > /tmp/churn/f$i 2>/dev/null || true rm -f /tmp/churn/f$i 2>/dev/null || true done echo "churn iterations: $i" >> "$LOG" ) & # renames on UFS: each does checkpath -> zero-ref vput/read on 'b' ( n=0; rc=0 while [ $n -lt 20000 ]; do mv "$MNT/S" "$MNT/a/b/c/S_moved" 2>>$LOG || rc=1 mv "$MNT/a/b/c/S_moved" "$MNT/S" 2>>$LOG || rc=1 n=$((n+1)) done echo "renames completed: $n (mv errors: $rc)" >> "$LOG" ) & wait echo "STRESS_DONE $(date +%T); dmesg tail:" >> "$LOG" dmesg | tail -5 >> "$LOG" 2>/dev/null || true echo done |