Skip to content
LimniFS

.spec · wire-format · §4

Filesystem metadata.

Layer 2 — the POSIX-ish metadata: inodes, directory tree, xattrs, slice → drop maps. The directory tree is a deterministic Merkle B-tree: every node content-addressed, structural sharing built in for deltas.

ROOT NODEb3:1a4f…3 entries: m, s, zINTERNAL · [a–m]b3:9bc1…4 child refsINTERNAL · [n–s]b3:7e3a…4 child refsINTERNAL · [t–z]b3:c2f8…3 child refsLEAF · [a–c]b3:5d12…3 inodesapp.rb, bin/, config/LEAF · [n–p]b3:8ab7…3 inodesnotes.md, lib/, …LEAF · [t–z]b3:3e91…3 inodestest/, tmp/, …INODE (one of N in a leaf)§4.1 INODE FIELDSnumber · mode · uid · gid · mtime · ctime · atime · nlinkxattrs[] · content_handle→ slice_map → drop_id → (slab, offset, len, representation)

A deterministic Merkle B-tree. Each node is content-addressed by BLAKE3 of its sorted children. Delta that touches one leaf writes only O(log N) new nodes along the changed path.

§4.1 — Inode

An inode represents a filesystem object. Every entry in the directory tree references an inode. Fields (all exact-width):

FieldTypeNotes
numberu64 LEinode number, unique within image
modeu32 LEPOSIX mode bits (file type + permissions)
uid, gidu32 LE eachowner user / group IDs
mtime_ns, ctime_ns, atime_nsu64 LE eachtimes in ns since Unix epoch
nlinku32 LEhard-link count
xattrs[XAttr]§4.4 extended attributes
content_handleContentHandle§4.3 — slice map, redirect, or special

§4.2 — Directory representation

A directory inode’s content_handle is a Merkle B-tree node. The directory tree is a deterministic Merkle B-tree (not Prolly Tree proper, which uses content-defined chunking for boundaries — conflicts with §1.4 determinism). Split decisions are spec-pinned: split when a node has N entries.

Why a Merkle B-tree?

  • Content-addressed structural sharing. Delta touching one file writes O(log N) new nodes — unchanged subtrees are referenced, not copied.
  • Multihash-compatible. Node hashes are BLAKE3-256; display form b3:<base32> maps to IPFS/IPLD CIDs directly.
  • Stable boundaries across versions. Same content = same hash = same node, regardless of where in the tree the change happened.

§4.3 — Content handles and slice maps

A regular file inode’s content_handle is a slice map. For files above the inline-data threshold, inline_data is absent and slices contains the file’s chunks in byte order. A slice_id resolves to a (byte_range_in_slice, DropId) mapping; readers follow the chain to fetch drops.

Symlink inodes carry a redirect field with the target path. Special inodes (block, char, fifo, socket) carry the device number or pipe identifier.

§4.4 — xattrs

Extended attributes are (namespace, key, value) triples. Namespaces:

  • 0x00 — user
  • 0x01 — trusted
  • 0x02 — system
  • 0x03 — security

Readers MUST enforce the namespace policy of the host OS (e.g., security.SELinux requires privilege).

§4.5 — atime omission

Some images omit atime to save space. When omitted, readers MUST treat atime reads as returning mtime_ns and MUST NOT report the omission as an error.

§4.6 — Per-class records (Seine)

For each drop in the image, the metadata records the Seine classification (§13) so deepening (§8.4) is reproducible: same drop head bytes + same classifier registry ⇒ same class.