OpenZFS mount shadowing — candidate upstream fixes

Speculative work, agreed 2026-09-17 as "note it for later". Arises from the /usr/obj shadowing bug on radagast — full diagnosis at hosts/radagast/source-upgrade. Fits the wider "own our critical software" theme (CVE → review → build), except here the ambition is to fix upstream rather than just build it.

Do this FIRST, before writing any code

Candidate 1 (strongest): zpool export gives up instead of retrying

Observed: with a shadowed dataset, zpool export zroot failed, and so did zpool export -f zrootcannot unmount '/mnt/radagast/zroot/usr/obj': no such pool or dataset. The pool could not be exported at all until every covering mount was unwound by hand, deepest first. That is a real robustness bug: -f ought to mean forced, and the pool was left in a state the tools could not leave.

Proposed fix: export already knows every mount belonging to the pool. Instead of one pass that aborts on first failure, unmount what succeeds and loop while progress is being made — a fixed point. Unmounting a coverer releases whatever it covered, so a second pass succeeds. Self-contained, no new interfaces, easy to test.

Candidate 2 (highest value, but only a lead): the mount ordering itself

After zfs inherit mountpoint zroot/usr/obj made the child's path a genuine child of the parent's path, FreeBSD 11.4 mounted them in the correct order — but Linux OpenZFS 2.2.2 still mounted the child first, visible in /proc/self/mountinfo as a mount whose parent ID was the host root filesystem rather than the pool's root dataset. If that reproduces, it is an ordering bug in the parallel mounter, and it is the one worth fixing, because it is the thing that actually causes the damage. Not yet diagnosed — treat as a lead, not a finding. OpenZFS 2.x mounts in parallel; the question is whether the dependency ordering (parent dataset before child) is genuinely enforced or only implied by sorting mountpoint strings.

Candidate 3: error message is simply wrong

zfs unmount zroot/usr/obj on a mounted-but-shadowed dataset reports no such pool or dataset. The dataset exists and is mounted; only its mountpoint path is unreachable. It should say so — something naming the covering mount and suggesting it be unmounted first. Small, uncontroversial, and would have saved most of the time spent on this.

Candidate 4 (weakest): warn when a child's mountpoint is not under its parent's

ZFS has everything it needs at zfs set mountpoint time to say that the result will be shadowed. It stayed silent for nine years on radagast while builds risked landing on the wrong dataset. Genuinely useful, but upstreams are rightly resistant to new warnings on common paths, so expect bikeshedding about whether it belongs at set time, mount time, or in zpool status.

Explicitly NOT a bug

tags ideas, zfs, openzfs, upstream, freebsd, radagast