Pure-Rust filesystem tooling: it builds and reads filesystem images in userspace, over ordinary byte streams, in safe Rust. Two families — ext2/ext3/ext4 and FAT12/FAT16/FAT32 — and a build takes the ones it names.
This Cargo workspace holds two crates:
ferrosys— the library: a formatter and reader per family, each behind a feature of its own, with byte-reproducible on-disk geometry.ferrosys-cli— theferrosysbinary, which puts the library on the command line and carries every family.
Both build on Rust 1.88 or newer.
Status: under active development. The APIs are not yet stable. Following Cargo's
0.xsemantics, a breaking change bumps the minor version, and a0.xrequirement resolves only within that minor — so a breaking release reaches no one unasked.
- Two families, one at a time or both — ext2, ext3, and ext4 across one lineage, from the classic direct/indirect block map to extent trees of any depth; FAT12, FAT16, and FAT32 across another, where the type is derived from the cluster count rather than chosen. Each is a feature, so a consumer wanting one filesystem compiles one.
- Resize-safe ext geometry — descriptor backups and reserved GDT blocks, sized by a grow reservation, let the image grow in place without relocating its descriptor table.
- Byte-reproducible — the identifiers and timestamps an image carries are inputs, so the same inputs write the same image every time and nothing about the machine that wrote one reaches it.
- Full fidelity, and a report where a format cannot hold it — ext records every file type, ownership and mode bits, nanosecond timestamps, extended attributes, POSIX ACLs, metadata checksums, a jbd2 journal, and an orphan file. Where a format holds less than the tree it is given, what it could not keep is named rather than dropped in silence.
- A robust reader per family — bounds-checks every field into typed errors, reads foreign images other tools wrote, and scans a whole image into typed findings rendered as JSON, SARIF, or a table, allocating in proportion to the bytes an image holds rather than to what it claims.
- Built for scale — streaming in both directions: a format writes only the blocks the filesystem uses, so an image stays sparse and may be larger than memory, and a read windows its way through a file rather than holding it, so pulling a multi-gigabyte file out of an image costs a working set. ext's 64-bit block addressing reaches past 16 TiB.
- Sources and sinks, belonging to no family — a programmatic tree, a tar archive, or a directory on this machine feeds whichever family is being written, and an archive or a directory drains whichever one was opened. Each hands a file's bytes over as a handle, so a format's peak memory is the largest single file rather than the sum of them all.
The crate README and the guide carry the complete feature list.
$ cargo install --path crates/ferrosys-cli
$ ferrosys format --size 512M --uuid "$(uuidgen)" --time 1700000000 \
--from-tar rootfs.tar rootfs.img
$ ferrosys inspect rootfs.img
$ ferrosys extract rootfs.img --to-tar - | tar -tv
$ ferrosys format --type fat32 --size auto --from-dir seed/ seed.imgformat writes a filesystem — of the type --type names, from a tar archive, a directory
tree, or empty, at a size you name or one --size auto finds from the contents —
inspect reports on one and says whether it is sound, extract reads the contents back
out as a tar archive, a directory tree, one file's bytes, one path's metadata, or a
listing, detect says which filesystem an image holds, and identity changes what one is
known by. Every command takes any family the binary carries. The identifiers and
timestamps are inputs, so the same inputs write the same image every time. The exit codes
mirror e2fsck's. See the guide's
command-line chapter.
cargo build
cargo test
cargo doc --no-deps # clean under RUSTDOCFLAGS="-D warnings"
ci/lint-features.sh # and clean in every feature configuration on offerThe guide and the API reference are published together to GitHub Pages:
- The guide — a narrative introduction,
built with mdbook from
book/. Build it locally withmdbook serve book(ormdbook build book). - The API reference — rustdoc for the
crate, generated by
cargo doc --no-deps. The guide's code examples compile against the crate withmdbook test book -L target/debug/deps, so they stay in step with the API.
Licensed under either of
- Apache License, Version 2.0 (LICENSE-APACHE)
- MIT license (LICENSE-MIT)
at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.