littlefs-rust
littlefs-rust is a pure Rust implementation of the littlefs v2 on-disk
format, published on crates.io as littlefs2-rust because the shorter package
name is already occupied. It can format, mount, read, and mutate littlefs
images through a synchronous block-device trait, while keeping core library
code compatible with no_std + alloc.
Inspired by littlefs. The implementation is independent Rust code, and interoperability with upstream littlefs remains a design constraint.
The project is built around real interoperability instead of format sketches:
the default test suite writes real images, remounts them, and compares visible
filesystem behavior with the bundled upstream C littlefs implementation in
littlefs_c/ wherever a C oracle exists.
Status
The crate currently supports the common mounted filesystem surface needed by embedded-style applications:
| Area | Supported surface |
|---|---|
| Device model | BlockDevice, MemoryBlockDevice, and default-std FileBlockDevice |
| Lifecycle | format_device, read-only mount_device, owned mutable mount_device_mut |
| Read APIs | stat, read_dir, open_dir, walk, read_file, read_file_into, read_file_at, attrs |
| Write APIs | create, overwrite, append, remove, mkdir, rmdir, rename, user attrs |
| File handles | open flags, read/write/append/truncate, seek, flush, sync, close |
| Large files | CTZ file reads and writes, streaming create and append paths |
| Directories | nested directories, hardtail split chains, split-aware lookup/update/delete/rename/attrs |
| Durability | data-before-metadata write ordering, selected power-loss and fault-injection tests |
| Resource shape | mounted block-device paths avoid resident whole-image ownership |
This is not a byte-for-byte rewrite of every internal C state machine. Some low-level policy details, especially allocator checkpointing, complete wear-leveling fidelity, and rare relocation or split-compaction interleavings, remain documented compatibility work. The public filesystem behavior is already covered by broad Rust/C black-box tests.
Installation
[]
= { = "littlefs2-rust", = "0.1" }
For a no_std build, disable default features. The crate still requires
alloc from the target environment.
[]
= { = "littlefs2-rust", = "0.1", = false }
Quick Start
use ;
Configuration
Config describes physical geometry:
use Config;
let cfg = Config ;
FilesystemOptions mirrors the main non-callback fields of C
struct lfs_config and is accepted by the *_with_options format and mount
APIs. It covers read, program, and cache sizes, lookahead size validation,
block_cycles, name/file/attr limits, metadata_max, and inline-file policy.
use ;
let options = FilesystemOptions ;
See docs/configuration.md for validation rules, feature flags, and block-device expectations.
Block Device Contract
The block-device trait uses littlefs vocabulary:
read(block, off, out)reads bytes inside one logical block.prog(block, off, data)programs bytes inside one block. NOR-style backends should only change bits from1to0until erase.erase(block)resets a whole block to the erased value.sync()flushes durable backend state when the backend needs it.
The bundled MemoryBlockDevice and FileBlockDevice are real block devices
used by integration tests. They are not filesystem behavior mocks.
Documentation
- docs/configuration.md: public configuration and device contract.
- docs/api_surface.md: API audit and release surface.
- docs/architecture.md: implementation architecture.
- docs/sync_semantics.md: mounted sync and file sync semantics.
- docs/atomic_rename.md: rename/orphan design notes.
- tests/README.md: test layout and C oracle discipline.
- tools/blackbox_eval: manual resource/performance evaluation harness.
Testing
Run the default compatibility suite:
The suite includes black-box integration tests that exercise real image bytes
and compare with upstream C littlefs. Performance and memory evaluation is kept
out of default cargo test; see
tools/blackbox_eval/README.md.
Known Gaps
The implementation is intended to be useful today, but the remaining gaps are tracked openly:
- allocator policy still uses an in-memory visible-block bitmap plus a lookahead scan window rather than a fully C-like persistent checkpoint traversal;
- bad-block and relocation retry behavior covers the important public paths, but not every rare split/relocation/orphan interleaving from C littlefs;
- split-chain support preserves public lookup and mutation behavior, while not
reproducing every adjacent-pair balancing choice in
lfs_dir_splittingcompact; read/writehandles with arbitrary-position extension may still choose a simpler buffered path to preserve read-your-writes semantics;- the resource profile is now in the tens of KiB for common mounted workloads, but the C implementation remains smaller on very tight targets.
Release Notes
See CHANGELOG.md.
License
This crate is distributed under the MIT License. The upstream littlefs C reference is used as a Git submodule for compatibility tests and keeps its own upstream license.