#!/bin/sh
# DF-3093 run v6: run4's overlap-heavy shape (16 MiB writes) on a volume
# whose free runs STRADDLE bitmap words (132-cluster runs: 132 % 32 != 0),
# so concurrent chainalloc commits RMW shared pm_inusemap words.
set -u
MNT=/mnt/df3093
VND=vn0
IMG=/root/df3093.img
CYCLES=${1:-1}
PROCS=${2:-6}
ROUNDS=${3:-2}
CHUNK=${4:-16777216}
DIR="$(dirname "$0")"
cleanup() { umount $MNT 2>/dev/null || true; vnconfig -u $VND 2>/dev/null || true; }
trap cleanup EXIT
cd "$DIR" || exit 1
c=1
while [ $c -le $CYCLES ]; do
	echo "=== cycle $c: 132-cluster straddling runs, ${PROCS}p x ${ROUNDS}r x ${CHUNK}B ==="
	cleanup
	rm -f $IMG
	newfs_msdos -C 512m -c 8 $IMG >/dev/null 2>&1
	vnconfig -c $VND $IMG
	mkdir -p $MNT
	mount_msdos -m 644 /dev/$VND $MNT
	sysctl -n debug.df3093_overlaps debug.df3093_double > /tmp/dfdbg.before
	# 150 files x 132 clusters (528 KiB) = 19800 clusters, then a tail file
	# eats the rest; delete every 3rd file -> 50 free runs of 132
	i=0
	while [ $i -lt 150 ]; do
		dd if=/dev/zero of=$MNT/G$(printf %03d $i) bs=528k count=1 >/dev/null 2>&1
		i=$((i + 1))
	done
	# fill the tail COMPLETELY (dd stops at ENOSPC, that is intended)
	dd if=/dev/zero of=$MNT/TAILFILE bs=1m count=9999 >/dev/null 2>&1 || true
	rm -f $MNT/TAILFILE.zero 2>/dev/null
	i=0
	while [ $i -lt 150 ]; do
		rm -f $MNT/G$(printf %03d $i)
		i=$((i + 3))
	done
	echo "fragmented: $(df $MNT | tail -1 | awk '{print $4}') 512B-secs free"
	./race2 $MNT $PROCS $ROUNDS $CHUNK 1
	sync
	umount $MNT
	vnconfig -u $VND
	echo "DFDBG before: $(cat /tmp/dfdbg.before | tr '\n' ' ')"
	echo "DFDBG after:  $(sysctl -n debug.df3093_overlaps debug.df3093_double | tr '\n' ' ')"
	if ./fat_scan $IMG; then :; else
		echo "=== CYCLE $c: FAT SCAN FOUND CROSS-LINKS ==="
		cp $IMG /root/df3093-hit-$c.img
		exit 42
	fi
	c=$((c + 1))
done
echo "run6 complete"
