# DF-3117 — racing create vs cross-parent msdosfs directory rename wedges the system

## What

Two unprivileged processes on any writable msdosfs directory:

- R: cross-parent **directory** renames (`bouncer`: mkdir D<k> in p1,
  rename into a deep parent p2 — every rename runs `doscheckpath()`
  with the target directory unlocked), and
- C: a create/stat/unlink churn loop (`creator`)

race for 30–60 s.  All racer processes exit cleanly, but afterwards:

1. `umount` of the filesystem **hangs forever** (leaked mount/vnode
   references — the earlier console diagnostic printed
   `unmount(/fatrace): ... 2 mount refs still present`), and
2. the guest then goes **catatonic**: sshd stops accepting connections
   ("Connection timed out during banner exchange"), the serial console
   freezes, and `vm.sh status` reports down while the QEMU process is
   still alive.  No panic, no DDB — a hard system wedge.

Reproduced twice (run.9 and the attribution-clean run.10), on a fresh
`vm.sh reset with-src` guest with a fresh image and verified-zero
leftover processes before the umount.

Control: the Window-B configuration (file renames only, no
`doscheckpath`) unmounts instantly after identical churn (run.3.log /
run.5.log stage [6]) — isolating the trigger to the
directory-rename/`doscheckpath` path.

## Where (kernel_refs)

The leak site is not line-pinned (needs VFS refcount instrumentation);
the racing surface spans:

- `sys/vfs/msdosfs/msdosfs_vnops.c:916-1294` — msdosfs_rename state
  machine (vref/vput/vrele protocol across the doscheckpath + relookup
  unlock windows, `kern_rename` EAGAIN retry interplay)
- `sys/vfs/msdosfs/msdosfs_lookup.c:792-872` — doscheckpath's
  deget/vput ancestor walk (brelse/deget error contract verified clean
  sequentially; suspect under interleaving)
- `sys/kern/vfs_syscalls.c:4316-4332` — `kern_rename: retry due to
  race` EAGAIN path (logged live during the race)
- `sys/kern/vfs_default.c:953-1069` — vop_compat_nrename

## PoC

Same harness as DF-3116 (`trigger.c`, `wedge.sh`).  The decisive run
is `run.10.wedge.log`: racers done + "leftover procs: none" + umount
watchdog never completing + ssh channel death.

No fix.diff: a correct fix requires pinpointing the leaking statement
(upstream should reproduce under a VFS_REFCOUNT/debug-refcount kernel
build).  Recommended containment while unfixed: none realistic;
severity is availability of the whole system, triggered by any local
user with write access to one msdosfs directory.
