# DF-5534 — nfs_mount() swallows nfs_mountroot() failure → NULL mnt_data deref in nfs_root on failed diskless NFS-root mount

## What

`nfs_mount()` discards the return value of `nfs_mountroot()` and unconditionally
returns 0 (success) to the VFS layer:

```c
	sys/vfs/nfs/nfs_vfsops.c:942
	if (path == NULL) {
		nfs_mountroot(mp);
		return (0);              /* error swallowed */
	}
```

When the diskless NFS root mount fails (unreachable server, failed mount RPC),
`vfs_mountroot_try()` therefore takes the SUCCESS branch
(sys/kern/vfs_conf.c:441 `error = VFS_MOUNT(...)` → `if (!error) break;`) and
runs the success path on a mount that was never mounted: `mountlist_insert()`,
`inittodr()`, then `VFS_ROOT(mp)` → `nfs_root()`:

```c
	sys/vfs/nfs/nfs_vfsops.c:~
	nmp = VFSTONFS(mp);              /* mp->mnt_data == NULL (mountnfs never ran) */
	lwkt_gettoken(&nmp->nm_token);   /* &NULL->nm_token == 0x450 → Fatal trap 12 */
```

The error unwind also double-drops `vfc_refcount`
(nfs_mountdiskless haderror nfs_vfsops.c:772 + nfs_mountroot nfs_vfsops.c:660)
for the single reference taken by `vfs_rootmountalloc()` (vfs_mount.c:344).

## Reachability (this file's surface)

`sys/platform/vkernel64/x86_64/autoconf.c` `pxe_setup_nfsdiskless()`
(autoconf.c:388-486) parses operator command-line kenv (`-e boot.netif.ip`,
`boot.netif.netmask`, `boot.netif.name`, `boot.nfsroot.server`) and sets
`nfs_diskless_valid = 1` (autoconf.c:485); `cpu_rootconf()` then sets
`rootdevnames[0] = "nfs:"` (autoconf.c:279). With the NFS server unreachable,
mountroot fails → panic loop instead of the intended "Root mount failed" +
manual-prompt fallback. The same nfs_vfsops.c code is shared by pc64
(loader/PXE-supplied `boot.netif.*` env); the vkernel is the reproducible rig.

## Reproduce (guest, root; vkernel rig)

```
sh build.sh                        # VKERNEL64 kernel + /vkroot.img (see env.txt)
sh run.sh                          # boots vkernel with hostile NFS-root boot args
```

Success criterion (baseline): console shows
`nfs_mountroot: mount 127.0.0.1: on /: 65` immediately followed by
`Fatal trap 12: page fault while in kernel mode` (fault VA 0x450,
IP lwkt_gettoken+0x64), then a db> crash-spin loop (millions of re-faults).
Patched: `Root mount failed: 65` → manual `mountroot>` prompt →
`ufs:vkd0` mounts → boots to userland, zero traps (run.fixed.log).

## Fix validation

`fix.diff` (error propagation + removal of the extra refcount drop):
baseline kernel MD5 a3a76c8c358d3df60cea81a31587ccf6 crashes as above;
patched kernel MD5 3cb21e35f1447c8d69ceb1401226fefee survives and boots.
Bad behavior gone. See VERDICT.md.

## Files

- trigger.sh         exact repro (deepX boot args) + nbuf control boot
- matrix.sh          wider negative-validation matrix (parse-garbage boots)
- build.sh           guest kernel/image build commands
- run.sh             minimal single-run driver
- build.log          baseline + patched kernel build tails
- run.log            baseline decisive console (crash)
- run.fixed.log      patched full console (57 lines, 0 traps, boots to userland)
- panic.txt          Fatal trap 12 excerpt (baseline)
- env.txt            uname, kernel MD5s, rig details
- fix.diff           git-apply-able fix
- manifest.json      machine catalog
