Skip to main content

Crate btrfs_core

Crate btrfs_core 

Source
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_chunk item: chunk geometry + its physical stripes.
ChunkMap
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).
FsTreeRoot
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_ptr from 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 l within the chunk is stripe.offset + (l - chunk_key.offset).
Superblock
A parsed btrfs superblock — the filesystem geometry, tree-root logical addresses, checksum descriptor, and the decoded sys_chunk_array bootstrap 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§

BtrfsError
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).
DirItemType
The btrfs_dir_item type byte — the kind of the child a directory entry points at. Only the members the oracle exercises are named; any other value is preserved in DirItemType::Other with 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. offset is the item’s data start relative to the end of the header; size is 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-endian u64 = 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_chunk fixed 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 — a btrfs_dir_item keyed by sequential index.
DIR_ITEM_KEY
BTRFS_DIR_ITEM_KEY — a btrfs_dir_item keyed by name hash.
DISK_KEY_SIZE
btrfs_disk_key on-disk size: objectid(u64) + type(u8) + offset(u64).
EXTENT_DATA_KEY
BTRFS_EXTENT_DATA_KEY — a btrfs_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 — a btrfs_inode_item (inode metadata).
INODE_ITEM_SIZE
sizeof(btrfs_inode_item) on disk = 160 bytes: the scalar block (up to reserved[4] = 112 bytes) + four 12-byte Timestamps.
INODE_REF_KEY
BTRFS_INODE_REF_KEY — a btrfs_inode_ref (name + parent-dir link).
ROOT_ITEM_KEY
BTRFS_ROOT_ITEM_KEY — a btrfs_root_item in the root tree (132).
STRIPE_SIZE
btrfs_stripe on-disk size: devid(u64) + offset(u64) + dev_uuid[16].
SYS_CHUNK_ARRAY_OFFSET
Offset of the sys_chunk_array within the superblock block.
TIMESTAMP_SIZE
sizeof(btrfs_timespec) on disk: sec(u64) + nsec(u32) = 12 bytes.

Functions§

decompress_extent
Decompress one extent’s src bytes to at most ram_bytes output using algo. sectorsize is needed only for LZO’s per-sector framing.
fs_tree_root
Locate the FS_TREE (FS_TREE_OBJECTID) ROOT_ITEM by walking the root tree from the superblock’s root logical address, returning where the FS tree’s own root node lives.
list_dir
List a directory’s entries from an FS_TREE leaf: every DIR_ITEM / DIR_INDEX keyed by dir_objectid, deduplicated by name (both a DIR_ITEM and a DIR_INDEX name each child; the listing surfaces each name once).
read_by_path
Resolve a slash-separated path to (objectid, Inode) within an FS_TREE leaf, starting from the FS_TREE root directory (FS_TREE_ROOT_DIR_OBJECTID).
read_by_path_content
Resolve path from the FS_TREE root directory and read the resolved inode’s content over the whole image.
read_file
Assemble the file content for objectid ino over the whole image: locate the FS_TREE root from the root tree, read its leaf, and delegate to read_file_from_leaf.
read_file_from_leaf
Assemble the file content for objectid ino from an already-parsed FS_TREE leaf, reading regular extents from image via map.
read_inode
Read the INODE_ITEM for objectid from an FS_TREE leaf, or None if the leaf holds no inode item for it.
read_node
Read the btrfs node at logical address logical: translate it to a physical offset via chunk_map (falling back to the superblock sys_chunk_array bootstrap for addresses inside the chunk_root’s own range), slice nodesize bytes, and parse the header + items/pointers.