NFSv4.1: racing open/unlink/recreate of the same filename can leave processes unkillable

I've been building an SMB client and hoping to ship it as an FSKit module, but because of some blocking issues I decided to serve it over NFS instead. Unfortunately, I've run into another blocker, which I'll share in case others are seeing the same behavior.

While testing against an NFSv4.1 server (stock Linux nfsd), I ran into a situation where processes on the Mac end up permanently blocked inside the NFS client, and I wanted to share it in case others hit the same thing. Filed as FB24538163.

The trigger is several processes concurrently opening, unlinking and recreating the same filenames in one directory. Something like ten shell loops each doing cat, rm, and echo > over the same five names will do it. When it happens:

  • The stuck processes ignore SIGKILL and sit in state U indefinitely (I have had them survive more than eight hours).
  • umount -f on the mount blocks the same way, so the mount cannot be cleared either.
  • Only a reboot recovers. The rest of the system stays responsive.

Two details that may help narrow it down:

  • It really is the name collision, not the load. The same loops using distinct filenames per process, at the same traffic volume and latency, ran clean for twenty minutes, while the same-name version wedged every time. Adding 8 ms of reply latency made it roughly ten times more frequent.
  • It happens on a soft mount (timeo=100,retrycnt=3), where I would have expected EIO after the retry budget instead of an indefinite wait.

Spindumps show the blocked threads inside nfs_vnop_open / nfs4_vnop_create, down through nfs4_open_rpc_internal into nfs_node_set_busy_helper, with one thread typically waiting on a write RPC reply (nfs_wait_reply) inside that same open path. A self-contained repro script is attached to the Feedback. The script only needs any NFSv4.1 server to point at, and its header has a one-line Docker command that produces one.

This looks related to what the FUSE-T project has reported (macos-fuse-t/fuse-t issues 112 and 45), since FUSE-T rides the same client.

If anyone knows a mount option or usage pattern that avoids the wait, or can confirm seeing this elsewhere, I would love to hear it.

NFSv4.1: racing open/unlink/recreate of the same filename can leave processes unkillable
 
 
Q