SafeFS
`SafeFS` is a user-space filesystem prototype for Windows that stores its data in one large container file and mounts it through Dokan.
It is aimed at unreliable SSD/USB media where you want:
- logical bad-block retirement
- copy-on-write writes with simple wear spreading
- redundant data storage with automatic repair
- metadata snapshots with mirrored copies
- a mounted filesystem view for normal system use
What This Version Does
- Uses the host volume's current sector size for alignment.
- Uses a larger logical storage block size by default (`64 KiB`) so metadata remains tractable on large images.
- Reserves mirrored metadata regions at the front and end of the container file.
- Stores file data in `2 data blocks + 1 parity block` stripes.
- Detects corruption with per-block CRC32.
- Repairs single-block corruption from parity during reads and scrubs.
- Tracks free extents and bad extents with in-memory B+tree indexes rebuilt from the persisted snapshot.
- Chooses new write locations from lower-wear regions first.
- Mounts as either a drive letter or an NTFS mount directory via Dokan.
Important Limitation
This first version works inside a normal host filesystem file. That means it can manage **logical** bad blocks and rewrite around corruption inside the container, but it cannot fully control where the host filesystem places the container on the physical flash.
So:
- it does provide redundancy, scrubbing, and logical retirement
- it does not provide the same guarantees as a direct raw-device implementation
The direct-device version is the right next step if you want true physical placement control and stronger wear-management guarantees.
Layout
- `src/storage.cpp`
- container geometry
- metadata snapshots
- block IO
- parity repair
- wear-aware allocator
- B+tree-backed indexes
- `src/dokan_mount.cpp`
- Dokan callbacks
- mounted filesystem surface
- `src/main.cpp`
- CLI commands
Build
This repo is C++20 + CMake and expects the local Dokan SDK under:
`C:\Program Files\Dokan\DokanLibrary-1.0.5`
Build from a VS Build Tools developer environment:
cmd /c '"C:\Program Files (x86)\Microsoft Visual Studio\18\BuildTools\VC\Auxiliary\Build\vcvars64.bat" && cmake -S . -B build -G "NMake Makefiles" && cmake --build build'
The executable will be:
`build\safefs.exe`
Commands
Initialize a container that uses nearly all free space on the target volume:
.\build\safefs.exe init --image T:\safefs.img --size auto --label SAFEFS
Mount it as a drive letter:
.\build\safefs.exe mount --image T:\safefs.img --mount M:
Unmount it:
.\build\safefs.exe unmount --mount M:
Mount it into an NTFS directory:
mkdir C:\safefs-mount
.\build\safefs.exe mount --image T:\safefs.img --mount C:\safefs-mount
Unmount the directory mount:
.\build\safefs.exe unmount --mount C:\safefs-mount
Check status:
.\build\safefs.exe status --image T:\safefs.img
Fill the remaining free SafeFS space with a deterministic test file, read it back, and seed the bad-block map:
.\build\safefs.exe autofill --image T:\safefs.img --chunk 4MB
Keep some free space reserved and preserve the fill file for later inspection:
.\build\safefs.exe autofill --image T:\safefs.img --reserve 128MB --keep-file
Scrub and repair:
.\build\safefs.exe scrub --image T:\safefs.img --repair
Run the built-in corruption/recovery test:
.\build\safefs.exe selftest --workdir .\test-output
Current Design Notes
- Metadata is snapshot-based, not journal-based.
- File data is extent-based and copy-on-write.
- Recovery today handles single-block stripe damage.
- `autofill` writes a single large file with a deterministic pattern, then verifies it stripe-by-stripe and retires blocks that fail during write, repair, or readback.
- The initial bad-block dictionary is therefore based on blocks SafeFS can actually touch through the container file. It is useful for seeding the map, but it is still limited by the host filesystem's placement decisions.
- The wear-leveling policy is intentionally simple: it prefers lower-write segments instead of rewriting hot locations in place.
- The free-space and bad-space trees are rebuilt on open from the authoritative snapshot, which keeps crash recovery simple.
Future Work
- raw-device backend instead of host-file backend
- stronger ECC / erasure coding profiles
- background scrub daemon
- optional mirrored container on a second local device
- bootable USB layout with FAT32/exFAT wrapper, multiple executable copies, and RAM-loaded repair mode