lambutter
no_std read-only btrfs reader for UEFI bootloaders and embedded contexts.
Lambutter is the btrfs counterpart to ext4-view:
a pure-Rust, allocation-aware, read-only btrfs filesystem reader designed for
contexts that cannot link std — UEFI applications, microcontrollers,
bare-metal kernels, and recovery tooling.
Status
v0.3.0 — feature-complete + live-validated (see
docs/SPEC-LAMBUTTER.md §2 for scope, and
CHANGELOG.md for the version arc through v0.1.0 →
v0.3.0). Open and read regular files, symlinks, and directory listings
on SINGLE / DUP / RAID1 / RAID1C3 / RAID1C4 btrfs volumes; decode zstd,
zlib, and LZO extents; surface unsupported profiles (RAID0/10/5/6,
ZONED, RAID_STRIPE_TREE) as typed errors. The public API may add but
not break within the v0.3.x line. Data-block CSUM verification and
snapshot enumeration are tracked for v0.4.0+.
Validation posture:
- 36 host unit tests, all modules
- 9 fixture-based oracle tests (uncompressed, zstd, zlib, LZO, DUP-metadata, NO_HOLES sparse, symlinks, read-at chunked, smoke)
- 5 cargo-fuzz harnesses, 1-hour smoke run completed with zero crashes
- Live host validation:
examples/inspect.rsagainst live openSUSE Tumbleweed btrfs partition with Snapper-managed default-subvol redirect — 6 path reads (regular file 38 MB full-extent walk + inline 11 B + 1.2 KB normal, symlinks in both/bootand/etc) all sha256-byte-identical to kernel oracle - Live embedded validation: linked into LamBoot (Lamco's UEFI bootloader) as the native btrfs backend, booting openSUSE Tumbleweed end-to-end under live UEFI firmware with full trust-chain attribution.
Use
use ;
let mut fs = open?;
// Resolve and read a file in one shot (loads the whole file into memory).
let kernel = fs.read_file?;
// Or stream it in fixed-size chunks (bounded memory).
let inode = fs.resolve?;
let mut buf = ;
let mut off = 0u64;
loop
For integrating from another no_std Rust project — including the
BlockRead impl patterns for UEFI EFI_BLOCK_IO_PROTOCOL, file-backed
host testing, and the standard symlink-follow pattern — see the
Consumer Guide.
A worked end-to-end example lives at examples/inspect.rs: a host-side
CLI that opens any block device or image file, reports the resolved
default-subvol objectid, and reads a named file printing size + sha256
- first 16 bytes. Built with
cargo build --release --example inspect; run as root against a real device for live validation.
Goals
- Read-only by design. The crate cannot mutate a btrfs volume.
no_std+alloc. Nostd, notokio, no async machinery.- Sufficient subset for
/bootreading on stock Linux distributions (openSUSE Tumbleweed/Leap, Fedora Workstation, CachyOS, Garuda) under Secure Boot. - Fuzz-tested against malformed inputs.
- Independent of any other btrfs crate. Implemented from the on-disk format specification, not derived from existing parsers.
Non-goals
- Write support of any kind.
bcachefs/zfs/xfs. Each is its own filesystem; this crate is btrfs-only.- Replacing the kernel's btrfs driver. Lambutter is for code paths where the kernel is not yet running.
Features (Cargo)
| Feature | Default | What it enables |
|---|---|---|
zstd |
yes | zstd-compressed extent decoding via ruzstd (Tumbleweed / Fedora F34+ default) |
zlib |
no | zlib-compressed extent decoding via miniz_oxide (legacy default) |
lzo |
no | LZO-compressed extent decoding via lzokay (rare in modern installs) |
std |
no | enables std::error::Error impl on Error (host-only) |
For UEFI bootloaders that may encounter any compression on /boot,
enable all three: features = ["zstd", "zlib", "lzo"].
Documentation
docs/SPEC-LAMBUTTER.md— design spec, on-disk format scopedocs/FEATURES.md— exhaustive feature inventory + non-featuresdocs/SUPPORTED-SCENARIOS.md— distro × btrfs-config coverage matrixdocs/CONSUMER-GUIDE.md— integrating lambutter into a downstreamno_stdRust projectdocs/TROUBLESHOOTING.md— error catalogue (symptom → cause → fix)docs/TESTING-AND-FUZZING-PLAN.md— test/fuzz strategy + validation resultsdocs/PRE-PUBLISH-AND-TESTING-PLAN.md— pre-publish hygiene checklistCHANGELOG.md— version history
License
Dual-licensed under MIT or Apache-2.0, at your option. See
LICENSE-MIT and LICENSE-APACHE.
Contributing
Contributions welcome — particularly:
- Additional fixture scenarios (
tests/fixtures/) - Per-distro real-world validation across the wider ecosystem
- v0.2.x scope items: data-block CSUM_TREE verification, snapshot enumeration, full subvolume traversal
See docs/SPEC-LAMBUTTER.md for design constraints before opening a PR.