Skip to main content

BlockReader

Struct BlockReader 

Source
pub struct BlockReader<R> { /* private fields */ }
Expand description

A block reader that resolves logical addresses through a chunk cache.

Holds one I/O handle per device, keyed by devid. For single-device filesystems the map has a single entry. For RAID1 / RAID1C3 / RAID1C4 / RAID10 / DUP, each stripe’s devid (from the chunk cache) is used to look up the handle. SINGLE and DUP work with a one-entry map.

Implementations§

Source§

impl<R> BlockReader<R>

Source

pub fn new( handle: R, devid: u64, nodesize: u32, chunk_cache: ChunkTreeCache, ) -> Self

Create a single-device block reader.

devid is the device id (superblock.dev_item.devid) under which this handle is registered. Stripe lookups for this device must resolve to this devid.

Source

pub fn new_multi( devices: BTreeMap<u64, R>, nodesize: u32, chunk_cache: ChunkTreeCache, ) -> Self

Create a multi-device block reader.

devices maps each device id to its I/O handle. Every devid referenced by the chunk cache must be present.

Source

pub fn devices(&self) -> &BTreeMap<u64, R>

Return the per-devid handle map.

Source

pub fn devices_mut(&mut self) -> &mut BTreeMap<u64, R>

Return the per-devid handle map mutably.

Used by transaction commit / sync / flush paths that need to flush every device. For ordinary reads/writes prefer read_block, read_data, or write_block which route by devid via the chunk cache.

Source

pub fn single_device_mut(&mut self) -> &mut R

Return the underlying handle for a single-device filesystem.

Convenience for offline tools (btrfs-tune, btrfs filesystem resize on a regular file) that operate on one device at a time and need raw file access (e.g. set_len or full-file scans).

§Panics

Panics if more than one device is open. Multi-device callers must use devices_mut and route by devid explicitly.

Source§

impl<R: Read + Seek> BlockReader<R>

Source

pub fn read_block(&mut self, logical: u64) -> Result<Vec<u8>>

Read raw bytes at a logical address, resolving to physical via the chunk cache.

§Errors

Returns an error if the logical address is unmapped, the resolved device id is not in the handle map, or the underlying read fails.

Source

pub fn read_tree_block(&mut self, logical: u64) -> Result<TreeBlock>

Read and parse a tree block at a logical address.

§Errors

Returns an error if the logical address is unmapped or the underlying read fails.

Source

pub fn chunk_cache(&self) -> &ChunkTreeCache

Return a reference to the chunk cache.

Source

pub fn chunk_cache_mut(&mut self) -> &mut ChunkTreeCache

Return a mutable reference to the chunk cache.

Source

pub fn nodesize(&self) -> u32

Return the nodesize.

Source

pub fn read_data(&mut self, logical: u64, len: usize) -> Result<Vec<u8>>

Read arbitrary data at a logical address (not limited to nodesize).

Unlike read_block which always reads nodesize bytes, this reads exactly len bytes. Used for reading file data extents.

Uses ChunkTreeCache::plan_read internally so reads on striped profiles (RAID0 / RAID10 / RAID5 / RAID6) that span multiple rows assemble the bytes from the correct devices in order. RAID5/RAID6 reads route to the data column owning each row’s bytes, ignoring parity (degraded reads are out of scope).

§Errors

Returns an error if the logical address is unmapped, the request extends past the chunk, or the underlying read fails.

Source§

impl<R: Read + Write + Seek> BlockReader<R>

Source

pub fn write_block(&mut self, logical: u64, buf: &[u8]) -> Result<()>

Write raw bytes to a logical address, routing to the correct per-device locations based on the chunk’s RAID profile.

Uses ChunkTreeCache::plan_write internally. For DUP / RAID1 / RAID1C3 / RAID1C4 every mirror receives the same bytes; for RAID0 each row goes to exactly one device; for RAID10 each row goes to one mirror pair; for RAID5/RAID6 the executor prereads every data column slot of every touched row, mixes in caller bytes, computes parity, then writes data + parity. Writes larger than stripe_len on a striped profile are split into per-row segments automatically.

§Errors

Returns an error if the logical address is unmapped, the request extends past the chunk, any referenced device is not open, or any underlying read/write fails.

Auto Trait Implementations§

§

impl<R> Freeze for BlockReader<R>

§

impl<R> RefUnwindSafe for BlockReader<R>
where R: RefUnwindSafe,

§

impl<R> Send for BlockReader<R>
where R: Send,

§

impl<R> Sync for BlockReader<R>
where R: Sync,

§

impl<R> Unpin for BlockReader<R>

§

impl<R> UnsafeUnpin for BlockReader<R>

§

impl<R> UnwindSafe for BlockReader<R>
where R: RefUnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.