pub struct Filesystem<R> {
pub superblock: Superblock,
pub generation: u64,
pub nodesize: u32,
pub sectorsize: u32,
/* private fields */
}Expand description
In-memory filesystem state for a transaction session.
Holds everything needed to read and write tree blocks: the block reader (with chunk cache for logical-to-physical resolution), the superblock, all tree root pointers, the current transaction generation, and the set of dirty (modified) block addresses.
Fields§
§superblock: SuperblockParsed superblock (updated in-memory during transactions).
generation: u64Current transaction generation (superblock.generation + 1 during a transaction, or superblock.generation when idle).
nodesize: u32Tree block size in bytes.
sectorsize: u32Minimum I/O unit in bytes.
Implementations§
Source§impl<R: Read + Write + Seek> Filesystem<R>
impl<R: Read + Write + Seek> Filesystem<R>
Sourcepub fn open(handle: R) -> Result<Self>
pub fn open(handle: R) -> Result<Self>
Open a btrfs filesystem from a readable+writable+seekable handle.
Performs the full bootstrap sequence (superblock, chunk cache, root
tree), then wraps the result into an Filesystem ready for transactions.
§Errors
Returns an error if any I/O operation fails during bootstrap.
Sourcepub fn open_mirror(handle: R, mirror: u32) -> Result<Self>
pub fn open_mirror(handle: R, mirror: u32) -> Result<Self>
Open a btrfs filesystem using a specific superblock mirror.
§Errors
Returns an error if any I/O operation fails during bootstrap.
Sourcepub fn open_multi(devices: BTreeMap<u64, R>) -> Result<Self>
pub fn open_multi(devices: BTreeMap<u64, R>) -> Result<Self>
Open a multi-device btrfs filesystem from a devid -> handle map.
Every device referenced by the filesystem’s chunk tree must be
present in devices. Each device’s superblock is read and
validated against the map key; all devices must share the same
fsid. The bootstrap fails with a clear error if any of these
invariants is violated.
§Errors
Returns an error if the device map is empty, any device’s
superblock disagrees with its key or the primary’s fsid, the
chunk tree references a devid not in the map, or any I/O fails.
Sourcepub fn open_with_chunk_cache(
handle: R,
mirror: u32,
chunk_cache: ChunkTreeCache,
) -> Result<Self>
pub fn open_with_chunk_cache( handle: R, mirror: u32, chunk_cache: ChunkTreeCache, ) -> Result<Self>
Open a btrfs filesystem using a pre-built chunk cache.
Skips the chunk tree walk entirely, using the provided cache for
logical-to-physical address resolution. This is the entry point
for recovery tools like rescue chunk-recover --apply, where the
on-disk chunk tree is damaged and the cache has been reconstructed
from a raw device scan.
§Errors
Returns an error if any I/O operation fails during bootstrap.
Sourcepub fn read_block(&mut self, logical: u64) -> Result<ExtentBuffer>
pub fn read_block(&mut self, logical: u64) -> Result<ExtentBuffer>
Read a tree block at the given logical address, returning an ExtentBuffer.
If the block is already in the in-memory cache (e.g. it was COW’d or previously read in this transaction), the cached version is returned without hitting disk.
§Errors
Returns an error if the block cannot be read from disk.
Sourcepub fn write_block(&mut self, eb: &mut ExtentBuffer) -> Result<()>
pub fn write_block(&mut self, eb: &mut ExtentBuffer) -> Result<()>
Write an extent buffer to disk and mark it dirty.
The buffer’s checksum is updated before writing. The block is also stored in the in-memory cache so subsequent reads see the modification.
§Errors
Returns an error if the write fails.
Sourcepub fn mark_dirty(&mut self, eb: &ExtentBuffer)
pub fn mark_dirty(&mut self, eb: &ExtentBuffer)
Store an extent buffer in the cache and mark it dirty, without writing to disk yet. The actual disk write happens at commit time.
Sourcepub fn root_bytenr(&self, tree_id: u64) -> Option<u64>
pub fn root_bytenr(&self, tree_id: u64) -> Option<u64>
Return the root block logical address for the given tree ID.
Sourcepub fn set_root_bytenr(&mut self, tree_id: u64, bytenr: u64)
pub fn set_root_bytenr(&mut self, tree_id: u64, bytenr: u64)
Update the root block logical address for a tree.
Sourcepub fn root_node(&mut self, tree_id: u64) -> Result<ExtentBuffer>
pub fn root_node(&mut self, tree_id: u64) -> Result<ExtentBuffer>
Read the root block of the given tree as an ExtentBuffer.
§Errors
Returns an error if the tree ID is unknown or the block cannot be read.
Sourcepub fn dirty_blocks(&self) -> impl Iterator<Item = u64> + '_
pub fn dirty_blocks(&self) -> impl Iterator<Item = u64> + '_
Return an iterator over all dirty block logical addresses.
Sourcepub fn dirty_count(&self) -> usize
pub fn dirty_count(&self) -> usize
Return the number of dirty blocks.
Sourcepub fn is_written(&self, logical: u64) -> bool
pub fn is_written(&self, logical: u64) -> bool
Check whether a block has been written to stable storage during this transaction. Such blocks must be COW’d before modification even if their generation matches the current transaction.
Sourcepub fn clear_dirty(&mut self)
pub fn clear_dirty(&mut self)
Clear the dirty and written sets (used after commit or abort).
Sourcepub fn clear_cache(&mut self)
pub fn clear_cache(&mut self)
Clear the block cache (used after commit or abort to free memory).
Sourcepub fn tree_roots(&self) -> impl Iterator<Item = (u64, u64)> + '_
pub fn tree_roots(&self) -> impl Iterator<Item = (u64, u64)> + '_
Return all tree root entries as (tree_id, root_bytenr) pairs.
Sourcepub fn flush_dirty(&mut self) -> Result<()>
pub fn flush_dirty(&mut self) -> Result<()>
Flush all dirty blocks to disk.
Iterates the dirty set, checksums each cached block, and writes it.
Blocks that are dirty but not in the cache are skipped (they were
already written by write_block).
§Errors
Returns an error if any write fails.
Sourcepub fn reader_mut(&mut self) -> &mut BlockReader<R>
pub fn reader_mut(&mut self) -> &mut BlockReader<R>
Return a mutable reference to the underlying block reader.
Sourcepub fn reader(&self) -> &BlockReader<R>
pub fn reader(&self) -> &BlockReader<R>
Return a reference to the underlying block reader.
Sourcepub fn remove_root(&mut self, tree_id: u64) -> Option<u64>
pub fn remove_root(&mut self, tree_id: u64) -> Option<u64>
Remove a tree root entry.
Sourcepub fn evict_block(&mut self, logical: u64)
pub fn evict_block(&mut self, logical: u64)
Evict a block from the cache (e.g. after freeing it).
Sourcepub fn snapshot_roots(&mut self)
pub fn snapshot_roots(&mut self)
Snapshot the current roots so we can detect changes at commit time.
Called at transaction start to record the baseline state.
Sourcepub fn restore_roots_from_snapshot(&mut self)
pub fn restore_roots_from_snapshot(&mut self)
Restore the roots map to the last snapshot. Used by
Transaction::abort to roll back in-memory set_root_bytenr
changes that pointed at COWed-but-never-written bytenrs.
Sourcepub fn write_superblock_all_devices(&mut self) -> Result<()>
pub fn write_superblock_all_devices(&mut self) -> Result<()>
Write the in-memory superblock to all 3 mirrors of every open
device, with each device’s per-device dev_item spliced in.
On a multi-device filesystem each device’s superblock has its
own dev_item (devid, dev_uuid, per-device bytes_used, etc.).
Writing the primary device’s superblock verbatim to a secondary
would corrupt the secondary’s identity. This helper preserves
that per-device state by splicing the matching dev_item from
the snapshot taken at open time before serializing each
device’s variant.
§Errors
Returns an error if any device referenced by the dev-item snapshot is not open, or if any underlying write fails.
Sourcepub fn flush_writes(&mut self) -> Result<()>
pub fn flush_writes(&mut self) -> Result<()>
Flush pending writes via Write::flush() on every device.
Flushes userspace write buffers on every open device. For
file-backed storage, use Filesystem<File>::sync instead,
which also calls fsync per device.
Sourcepub fn changed_roots(&self) -> Vec<(u64, u64, u8)>
pub fn changed_roots(&self) -> Vec<(u64, u64, u8)>
Return tree IDs whose root block changed since the last snapshot.
Compares current roots against the snapshot taken at transaction start. Excludes tree IDs 1 (root tree) and 3 (chunk tree) since their root pointers live in the superblock, not in root items.
Sourcepub fn block_group_tree_id(&self) -> u64
pub fn block_group_tree_id(&self) -> u64
Return the tree id that holds BLOCK_GROUP_ITEM records.
When bg_tree_override is
set (typically by the convert-to-block-group-tree path),
returns it verbatim. Otherwise auto-detects: returns 11
(BLOCK_GROUP_TREE) if a root for tree 11 is registered,
else 2 (EXTENT_TREE).
All allocator and block-group-update code paths must consult this accessor instead of duplicating the routing logic, so that the override mechanism actually works for everything that touches block-group state.
Sourcepub fn pin_block_group_tree(&mut self, id: u64) -> BgTreeOverrideGuard<'_, R>
pub fn pin_block_group_tree(&mut self, id: u64) -> BgTreeOverrideGuard<'_, R>
Pin block_group_tree_id to
the given tree id and return a guard that restores the
previous override (typically None) when dropped.
Use this in conversion paths so that panics or ?
early-returns cannot leave the override stuck on the wrong
value.