mirror of
https://github.com/RhapsodiOS/RhapsodiOS.git
synced 2026-11-03 22:01:40 -07:00
[GH-ISSUE #55] msdosfs: mmap'd files lose their size on truncate and rewrite; no SIGBUS past EOF #46
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#46
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/55
Symptom
On the same FAT16 volume (kernel and setup as in #54),
stress-mmapfailsevery time. The same tests pass on UFS, HFS+ and ext2 (ext2 has its own
truncpanic):private, iteration 2:open(O_TRUNC)on a file that was mappedMAP_PRIVATEin iteration 1,write()of 64 KiB,read()from offset 0. Theread hits EOF at 8 KiB, and the file stays 8192 bytes on disk (
ls -l), so56 KiB of written data is lost.
trunc: on a 64 KiBMAP_SHAREDfile,ftruncateto 20 KiB, then touchingthe mapping at 28 KiB does not fault. The test stops there, and the files
it leaves are 40960 bytes instead of 20480, so the truncated size did not
stick either.
fsck_msdos -nstays clean after these runs. The damage is to file sizes anddata, not the FAT.
Reproduce
Log:
vm/work/fsrepro/res-m6.log,res-m5-final.log,res-m4-final.log.Where to look
bsd/msdosfs/msdosfs_denode.cdetrunc()andmsdosfs_vnops.c. Unlikeffs_truncate(mapfs_trunc) andext2fs_truncate(ext2fs_vm_flush(...,1,length)),msdosfs never runs the MACH_NBC mapped-file truncate. It calls
vnode_pager_setsizedirectly, even on mapped vnodes, so mapped pages pastthe new EOF stay valid. Also
msdosfs_pageoutis a plainVOP_WRITEpass-through. A late pageout of stale pages can therefore writethrough the normal write path after a truncate and change
de_FileSize(compare
ufs_pageout). Port the ufs/ext2 MACH_NBC truncate and pageouthandling to msdosfs.
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 pageout and size handling is inmsdosfs_vnops.candmsdosfs_denode.c.Verified on the repair kernel:
stress-mmap -n 1 -i 2 -s 1 privateand-n 1 -i 1 -s 1 truncnow pass on FAT16, and so does the extendedshared mixed private trunc -n 3 -i 20 -s 2.vm/msdosfs_pageout_test.pycovers stale pageouts past EOF, partial final pages, errors, and cached extension before the on-disk size catches up. It failed before the fix and passes with it.Not covered by this fix, and seen on the unmodified kernel too: mapping a file directly, shrinking it, then growing it again returns old data past the truncated EOF on FAT16, and loses retained dirty data on UFS. Those direct-mmap coherency cases are separate from this issue. The same test using
writeinstead of mmap passes.Test notes and focused regressions:
vm/filesystem-issues-52-55.mdin that commit. Repair kernel cksum 3500498149 (i386, QEMU snapshot); PowerPC not tested.