mirror of
https://github.com/RhapsodiOS/RhapsodiOS.git
synced 2026-11-03 22:01:40 -07:00
[GH-ISSUE #53] hfs: concurrent rename/mkdir/rmdir deadlocks two processes on hfsnode vnode locks, then hangs the system #48
Labels
No labels
bug
documentation
enhancement
enhancement
good first issue
help wanted
help wanted
pull-request
question
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
github-starred/RhapsodiOS#48
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Originally created by @raynorpat on GitHub (Oct 15, 2026).
Original GitHub issue: https://github.com/RhapsodiOS/RhapsodiOS/issues/53
Symptom
stress-fson an HFS+ volume hangs: every worker sits in stateUwith 0 CPUand never finishes. The volume is unusable (
ls -la /mnt/hnever returns), andsoon after new ssh logins hang too, while sshd still sends its banner. The
console shows no panic. The test's own 600 s watchdog cannot kill the workers.
Seen twice in 2 hours with kernel
mach_kernel.issue43(cksum 1562297808,built Oct 15):
stress-fs -n 4 -s 1 -d /mnt/h rw append tree fsync rename link: hung inrename(default 500 iters), after rw/append/tree/fsync had finished.stress-fs -n 4 -s 10 -d /mnt/h treeon a fresh volume: hung. The 19 othertreeseeds finished, each with an EBUSY FAIL (see below).
QEMU gdbstub dump of the four hung
treeworkers (pids 1166-1169). All four sleep intsleep("hfsnode")<-lockmgr<-vn_lock<-vget<-hfs_lookup(directly or through
hfs_vhashget) <-lookup<-namei<- the syscall.That is
renamefor 1167, 1168 and 1169, andopenfor 1166. The lockmgrlocks they wait on:
1166 and 1168 are in a lock-order cycle. Each holds an hfsnode lock the other
needs, and the other two workers queue behind them.
The volume itself is consistent afterwards:
vm/hfs_guest.py checkreportsonly "volume was not cleanly unmounted".
Reproduce
i386 QEMU guest, HFS+ volume built on the host with
tools/hfsimgbuilder.BUILDERS["hfsplus"](scenario.base_manifest(), 256 MiB)behind the 512-byte NeXT label (
hfs_guest.wrap_label), written to partition a ofthe 4th IDE disk and mounted with
mount_hfs /dev/hd3a /mnt/h.mount_hfswas built on theguest from
src/hfs-1/hfs_mountwith/build/src/kernel-7HFS headers. Then:treehas 4 processes doing random mkdir/rmdir/create/unlink/rename/directoryrename in one shared 3-level tree, so lookups of a parent and its child, and
..lookups, race with directory renames.Artifacts in
vm/work/fsrepro/:hfs-10-hang-threads.txtandhfs-10-hang-locks.txt(thread and lock dump),hfs-10-hang.{ppm,png,log},hfs-1-hang.{ppm,png,log}, the walkergdbwalk.py/gdblocks.py(QEMU-gdb tcp:127.0.0.1:1583), and the volume imageshfs-after-hang*.img.Where to look
bsd/hfs/hfs_lookup.chfs_lookup(): thevget/hfs_vhashgetcalls athfs_lookup+0x2bf,+0x9f9and+0xd75in this kernel. Look at how itlocks the child while holding the parent (the
../ ISDOTDOT case mustunlock the parent first), and at
hfs_rename's locking of the source andtarget directories. UFS (
ufs_lookup/ufs_rename) runs the sametreeand
renameloads cleanly on this kernel, so compare against it.Related, probably expected behaviour rather than a bug: on HFS every
treerunFAILs early with
rmdir: EBUSYorrename: EBUSY(hfs_rmdir:v_usecount > 2;hfs_remove: "HFS does not have unlinking"), and every FAIL reportsleak=kalloc.256:+100..+380. Worth checking whether that kalloc.256 growthcomes back once the vnodes are recycled.
Found by the stress suite (
src/Commands/stress, branchstress-phase3) during the phase 3 filesystem run. Related: #45 (rename races, fixed on fs-races).@raynorpat commented on GitHub (Oct 16, 2026):
Fixed in
260033acbb(kernel: Merge filesystem repairs for issues 52-55), on ffs-perf; the HFS part is inhfs_vnodeops.c.Verified on the repair kernel:
vm/hfs_rename_test.cpasses. Its lock test completed 4,000 moves against 10,000 concurrent descendant lookups with no deadlock, and its cache checks (stale case alias, cached.., busy-replacement cleanup) pass.stress-fs treeandrename(4 workers, seeds 1, 3 and 10) now end withEBUSYinstead of hanging. HFS's refusal to remove in-use objects is a remaining filesystem limitation, not this deadlock.Test notes and focused regressions:
vm/filesystem-issues-52-55.mdin that commit. Repair kernel cksum 3500498149 (i386, QEMU snapshot); PowerPC not tested.