littlefs-rust-core
Pure Rust LittleFS implementation, translated function-by-function from the reference C source. On-disk format compatible with upstream LittleFS v2.
#![no_std] by default. No C dependencies, no bindgen, no cross-compilation toolchain required.
Most users should use littlefs-rust instead, which provides a safe Rust API
on top of this core. Use this crate directly only if you need the low-level C-style API for FFI
interop, custom wrappers, or testing.
API
The public API mirrors the C littlefs function signatures: raw pointers, i32 return codes,
unsafe extern "C" callbacks. This is intentional — it keeps the translation verifiable against
upstream and makes porting bug fixes straightforward.
Filesystem lifecycle
lfs_format
File operations
lfs_file_open // bytes read or negative error
lfs_file_write // bytes written or negative error
lfs_file_seek
Directory operations
lfs_mkdir
Path operations
lfs_remove
Filesystem-level
lfs_fs_stat
Block device configuration
LfsConfig carries block device callbacks and geometry parameters:
LfsConfig
Error handling
Functions return 0 on success, negative i32 on error, or positive values for byte counts. Error
codes match the C littlefs constants (LFS_ERR_IO, LFS_ERR_CORRUPT, LFS_ERR_NOENT, etc.).
Module structure
| Module | Responsibility |
|---|---|
bd |
Block device read/prog/erase/sync with read and program caching |
block_alloc |
Block allocator using a lookahead bitmap |
crc |
CRC-32 (polynomial 0x04c11db7, 16-entry lookup table matching lfs_util.c) |
dir |
Metadata pair operations: commit, fetch, find, open, traverse |
file |
File I/O and the CTZ skip-list data structure |
fs |
High-level filesystem: format, mount, mkdir, remove, rename, stat, attrs, grow, traverse |
tag |
Tag encoding/decoding for the metadata log |
lfs_config |
Block device configuration struct and callback types |
lfs_gstate |
Global state tracking (orphans, in-progress moves) |
lfs_info |
LfsInfo, LfsAttr, LfsFileConfig, LfsFsinfo |
lfs_superblock |
Superblock read/write |
lfs_type |
Tag type constants |
types |
Primitive type aliases (lfs_block_t, lfs_size_t, etc.) |
Feature flags
| Feature | Default | Description |
|---|---|---|
alloc |
yes | Heap allocation; enables lfs_file_open |
loop_limits |
yes | Iteration caps to detect infinite loops in mount, traverse, fetch, commit |
std |
no | Standard library support |
log |
no | Logging via the log crate (RUST_LOG=littlefs_rust_core=trace) |
readonly |
no | Omit all write operations |
no_malloc |
no | Disable lfs_file_open; only lfs_file_opencfg (caller-provided buffers) |
multiversion |
no | On-disk version selection via disk_version in config |
shrink |
no | Filesystem shrink support in lfs_fs_grow |
slow_tests |
no | Power-loss and long-running tests (for CI nightly) |
Without alloc, the crate is fully no_std + no_alloc. Use lfs_file_opencfg with
caller-provided buffers in this mode.
Tests
Integration tests cover: allocation, attributes, bad blocks, directories, file operations, entries, path handling, seek, truncation, moves, orphans, relocations, superblocks, storage exhaustion, interspersed operations, evil/corruption scenarios, and power loss.
Test infrastructure (tests/common/):
RamStorage— in-memory block deviceBadBlockRamStorage— configurable bad-block simulationWearLevelingBd— per-block erase cycle trackingPowerLossCtx— write-count based power-loss injection (NoopandOoobehaviors)- Deterministic PRNG matching the C test suite for reproducible data generation
Translation approach
The codebase is a function-by-function translation of the reference lfs.c, preserving the original
control flow, data structures, and assertions. Original C line references are included as comments.
unsafe is used where the C code uses pointer arithmetic and raw buffer access. See docs/rules.md
for the full translation rules.