Expand description
btrfs-core — a pure-Rust, from-scratch btrfs filesystem reader.
Phase 0 parses the superblock (at physical offset 65536) — geometry,
tree-root logical addresses, the checksum descriptor, and the
sys_chunk_array bootstrap chunk map that seeds logical→physical translation
— over any byte source. btrfs is little-endian on disk throughout.
Phase 1 adds B-tree node parsing and the chunk tree: a Node decodes
any nodesize-byte block (btrfs_header + leaf items or interior
key-pointers, with non-fatal crc32c status), ChunkMap walks the chunk
tree into a full logical→physical map, and read_node reads any node by
its logical address.
Phase 2 adds root-tree navigation and FS-tree semantics: fs_tree_root
locates the FS_TREE’s ROOT_ITEM in the root tree, and read_inode,
list_dir, and read_by_path decode btrfs_inode_item metadata (size,
mode, the four timestamps), directory entries (DIR_ITEM/DIR_INDEX), and
resolve a slash-separated path from the FS_TREE root directory.
Phase 3 adds EXTENT_DATA → file content: read_file /
read_by_path_content assemble a file’s bytes from its
btrfs_file_extent_items (inline, regular, prealloc, hole zero-fill),
truncated to the inode’s size, decompressing zlib / LZO / zstd extents via
decompress_extent (batteries-included — the decoders are always compiled
in, never feature-gated).
Import path is btrfs_core (the bare btrfs crate on crates.io is an
unrelated live-FS ioctl wrapper we do not shadow): use btrfs_core::Superblock;.
§Safety and robustness
This crate parses untrusted, attacker-controllable disk images. It is
#![forbid(unsafe_code)] and every integer is read through bounds-checked
little-endian helpers that yield 0/None out of range rather than panic
(the Paranoid Gatekeeper standard).
Re-exports§
pub use crc::superblock_crc_status;pub use crc::verify_superblock_crc32c;pub use crc::CsumType;pub use crc::BTRFS_CSUM_SIZE;
Modules§
- bytes
- Bounds-checked little-endian readers (the Paranoid Gatekeeper standard).
- crc
- btrfs superblock CRC32c verification.
Structs§
- Chunk
- A parsed
btrfs_chunkitem: chunk geometry + its physical stripes. - Chunk
Map - The chunk-tree logical→physical map: the union of every CHUNK_ITEM’s span and its physical placement. Covers single-device profiles (SINGLE/DUP); for DUP the first stripe (first mirror) is returned.
- DirEntry
- One directory entry: a child’s name, its inode objectid, and its declared type.
- DiskKey
- A
btrfs_disk_key— the(objectid, type, offset)tuple every btrfs item is keyed by. Fields are LE on disk; compared as host integers on the tuple (that ordering is P2’s concern; P0 just carries the decoded values). - FsTree
Root - The FS_TREE root as located in the root tree: where the FS tree’s own root node lives and how deep it is.
- Header
- A parsed
btrfs_header— the fixed 101-byte prefix of every node/leaf. - Inode
- A decoded
btrfs_inode_item: file/dir metadata + the four timestamps. - KeyPtr
- A
btrfs_key_ptrfrom an interior node: the child’s smallest key, its logical block address, and the generation it was written in. - Node
- A parsed btrfs B-tree node (leaf or interior), plus its non-fatal checksum status. The raw block bytes are retained so leaf item data can be sliced on demand (bounds-checked).
- Stripe
- One stripe of a chunk: a physical placement on a device. For single-device
single/DUP the physical byte address of a logical address
lwithin the chunk isstripe.offset + (l - chunk_key.offset). - Superblock
- A parsed btrfs superblock — the filesystem geometry, tree-root logical
addresses, checksum descriptor, and the decoded
sys_chunk_arraybootstrap map (the P1 seed for logical→physical translation). - SysChunk
- A decoded chunk map entry from the
sys_chunk_array: the chunk’s logical key, its geometry, and its stripes. This is the bootstrap logical→physical record for a SYSTEM block group. - Timestamp
- A
btrfs_timespec: seconds since the Unix epoch + nanoseconds.
Enums§
- Btrfs
Error - Errors surfaced while parsing btrfs on-disk structures.
- Compression
- The compression algorithm of an extent (
btrfs_file_extent_item.compression). Unknown values carry their raw byte so an unsupported codec is identifiable (fail-loud: the offending value is shown, never dropped). - DirItem
Type - The
btrfs_dir_itemtypebyte — the kind of the child a directory entry points at. Only the members the oracle exercises are named; any other value is preserved inDirItemType::Otherwith its raw byte (fail-loud: the unknown value is shown, never dropped).
Constants§
- BLOCK_
GROUP_ DATA BTRFS_BLOCK_GROUP_DATA(1 << 0).- BLOCK_
GROUP_ DUP BTRFS_BLOCK_GROUP_DUP(1 << 5).- BLOCK_
GROUP_ METADATA BTRFS_BLOCK_GROUP_METADATA(1 << 2).- BLOCK_
GROUP_ SYSTEM BTRFS_BLOCK_GROUP_SYSTEM(1 << 1).- BTRFS_
FSID_ SIZE BTRFS_FSID_SIZE— the filesystem UUID width.- BTRFS_
HEADER_ SIZE sizeof(btrfs_header)on disk:csum[32] + fsid[16] + bytenr(u64) + flags(u64) + chunk_tree_uuid[16] + generation(u64) + owner(u64) + nritems(u32) + level(u8)= 101 bytes.- BTRFS_
ITEM_ SIZE sizeof(btrfs_item):disk_key[17] + offset(u32) + size(u32)= 25 bytes.offsetis the item’s data start relative to the end of the header;sizeis the item data length.- BTRFS_
KEY_ PTR_ SIZE sizeof(btrfs_key_ptr):disk_key[17] + blockptr(u64) + generation(u64)= 33 bytes.- BTRFS_
LABEL_ SIZE BTRFS_LABEL_SIZE— the filesystem label field width.- BTRFS_
MAGIC - The btrfs magic, ASCII
"_BHRfS_M", at superblock offset 0x40 (little-endianu64=0x4D5F_5366_5248_425F). - BTRFS_
SUPER_ INFO_ OFFSET BTRFS_SUPER_INFO_OFFSET— the primary superblock’s physical byte offset.- BTRFS_
SUPER_ INFO_ SIZE BTRFS_SUPER_INFO_SIZE— the superblock block size (4096 bytes).- CHUNK_
HEADER_ SIZE - The
btrfs_chunkfixed header (up to the variable stripe array):length,owner,stripe_len,type(4×u64) +io_align,io_width,sector_size(3×u32) +num_stripes,sub_stripes(2×u16) = 48 bytes. - CHUNK_
ITEM_ KEY BTRFS_CHUNK_ITEM_KEY— the disk-key type byte of a chunk item (228).- CHUNK_
TREE_ OBJECTID BTRFS_CHUNK_TREE_OBJECTID— the owner tree id of a chunk-tree node (3).- DIR_
INDEX_ KEY BTRFS_DIR_INDEX_KEY— abtrfs_dir_itemkeyed by sequential index.- DIR_
ITEM_ KEY BTRFS_DIR_ITEM_KEY— abtrfs_dir_itemkeyed by name hash.- DISK_
KEY_ SIZE btrfs_disk_keyon-disk size:objectid(u64) + type(u8) + offset(u64).- EXTENT_
DATA_ KEY BTRFS_EXTENT_DATA_KEY— abtrfs_file_extent_item(file data).- FS_
TREE_ OBJECTID BTRFS_FS_TREE_OBJECTID— the default subvolume / FS tree objectid (5).- FS_
TREE_ ROOT_ DIR_ OBJECTID BTRFS_FIRST_FREE_OBJECTID— the FS_TREE’s root directory inode (256); the first normal (non-reserved) objectid, where path resolution begins.- INODE_
ITEM_ KEY BTRFS_INODE_ITEM_KEY— abtrfs_inode_item(inode metadata).- INODE_
ITEM_ SIZE sizeof(btrfs_inode_item)on disk = 160 bytes: the scalar block (up toreserved[4]= 112 bytes) + four 12-byteTimestamps.- INODE_
REF_ KEY BTRFS_INODE_REF_KEY— abtrfs_inode_ref(name + parent-dir link).- ROOT_
ITEM_ KEY BTRFS_ROOT_ITEM_KEY— abtrfs_root_itemin the root tree (132).- STRIPE_
SIZE btrfs_stripeon-disk size:devid(u64) + offset(u64) + dev_uuid[16].- SYS_
CHUNK_ ARRAY_ OFFSET - Offset of the
sys_chunk_arraywithin the superblock block. - TIMESTAMP_
SIZE sizeof(btrfs_timespec)on disk:sec(u64) + nsec(u32)= 12 bytes.
Functions§
- decompress_
extent - Decompress one extent’s
srcbytes to at mostram_bytesoutput usingalgo.sectorsizeis needed only for LZO’s per-sector framing. - fs_
tree_ root - Locate the FS_TREE (
FS_TREE_OBJECTID)ROOT_ITEMby walking the root tree from the superblock’srootlogical address, returning where the FS tree’s own root node lives. - list_
dir - List a directory’s entries from an FS_TREE
leaf: everyDIR_ITEM/DIR_INDEXkeyed bydir_objectid, deduplicated by name (both aDIR_ITEMand aDIR_INDEXname each child; the listing surfaces each name once). - read_
by_ path - Resolve a slash-separated
pathto(objectid, Inode)within an FS_TREEleaf, starting from the FS_TREE root directory (FS_TREE_ROOT_DIR_OBJECTID). - read_
by_ path_ content - Resolve
pathfrom the FS_TREE root directory and read the resolved inode’s content over the wholeimage. - read_
file - Assemble the file content for objectid
inoover the wholeimage: locate the FS_TREE root from the root tree, read its leaf, and delegate toread_file_from_leaf. - read_
file_ from_ leaf - Assemble the file content for objectid
inofrom an already-parsed FS_TREEleaf, reading regular extents fromimageviamap. - read_
inode - Read the
INODE_ITEMforobjectidfrom an FS_TREEleaf, orNoneif the leaf holds no inode item for it. - read_
node - Read the btrfs node at logical address
logical: translate it to a physical offset viachunk_map(falling back to the superblocksys_chunk_arraybootstrap for addresses inside the chunk_root’s own range), slicenodesizebytes, and parse the header + items/pointers.