Block Driver Interface

Relevant source files

Purpose and Scope

This document covers the core block storage driver interface defined in the axdriver_block crate. The interface provides a standardized abstraction for block-oriented storage devices such as disks, RAM disks, and SD cards. This page focuses specifically on the BlockDriverOps trait and fundamental block device abstractions.

For information about specific block device implementations like RAM disk and BCM2835 SDHCI drivers, see Block Device Implementations. For the foundation layer that all drivers build upon, see Foundation Layer (axdriver_base).

Trait Hierarchy and Base Integration

Block Driver Trait Structure

flowchart TD
subgraph subGraph0["Core Methods"]
    NumBlocks["num_blocks()→ u64"]
    BlockSize["block_size()→ usize"]
    ReadBlock["read_block(block_id, buf)→ DevResult"]
    WriteBlock["write_block(block_id, buf)→ DevResult"]
    Flush["flush()→ DevResult"]
end
BaseDriverOps["BaseDriverOps(from axdriver_base)"]
BlockDriverOps["BlockDriverOps(extends BaseDriverOps)"]
DeviceType["DeviceType::Block(device classification)"]
ErrorTypes["DevResult & DevError(error handling)"]

BaseDriverOps --> BlockDriverOps
BlockDriverOps --> BlockSize
BlockDriverOps --> DeviceType
BlockDriverOps --> ErrorTypes
BlockDriverOps --> Flush
BlockDriverOps --> NumBlocks
BlockDriverOps --> ReadBlock
BlockDriverOps --> WriteBlock

The BlockDriverOps trait extends the base driver interface with block-specific operations. All block drivers must implement both the base operations (device identification) and block-specific operations (storage access).

Sources: axdriver_block/src/lib.rs(L15 - L38) 

Type System Integration

ComponentPurposeSource
BlockDriverOpsMain trait for block device operationsaxdriver_block/src/lib.rs16
BaseDriverOpsInherited base driver interfaceaxdriver_block/src/lib.rs13
DevResultStandard result type for all operationsaxdriver_block/src/lib.rs13
DevErrorUnified error type across driversaxdriver_block/src/lib.rs13
DeviceTypeDevice classification enumerationaxdriver_block/src/lib.rs13

Sources: axdriver_block/src/lib.rs(L12 - L13) 

Core Interface Methods

Device Geometry Methods

The interface provides two fundamental methods for determining the storage device's physical characteristics:

flowchart TD
Device["Block Storage Device"]
NumBlocks["num_blocks()Returns: u64"]
BlockSize["block_size()Returns: usize"]
TotalSize["Total Device Size= num_blocks() × block_size()"]

BlockSize --> TotalSize
Device --> BlockSize
Device --> NumBlocks
NumBlocks --> TotalSize

The total device capacity is calculated as num_blocks() * block_size(), providing a consistent way to determine storage limits across different hardware implementations.

Sources: axdriver_block/src/lib.rs(L17 - L22) 

Data Access Methods

Block I/O Operations Flow

sequenceDiagram
    participant Client as Client
    participant BlockDriverOpsImplementation as "BlockDriverOps Implementation"
    participant StorageHardware as "Storage Hardware"

    Note over Client,StorageHardware: Read Operation
    Client ->> BlockDriverOpsImplementation: read_block(block_id, &mut buf)
    BlockDriverOpsImplementation ->> StorageHardware: Hardware-specific read
    StorageHardware -->> BlockDriverOpsImplementation: Raw data
    BlockDriverOpsImplementation -->> Client: DevResult (success/error)
    Note over Client,StorageHardware: Write Operation
    Client ->> BlockDriverOpsImplementation: write_block(block_id, &buf)
    BlockDriverOpsImplementation ->> StorageHardware: Hardware-specific write
    StorageHardware -->> BlockDriverOpsImplementation: Write acknowledgment
    BlockDriverOpsImplementation -->> Client: DevResult (success/error)
    Note over Client,StorageHardware: Flush Operation
    Client ->> BlockDriverOpsImplementation: flush()
    BlockDriverOpsImplementation ->> StorageHardware: Commit pending writes
    StorageHardware -->> BlockDriverOpsImplementation: Flush complete
    BlockDriverOpsImplementation -->> Client: DevResult (success/error)

The interface defines three primary data access operations:

Read Block Operation

  • Signature: read_block(&mut self, block_id: u64, buf: &mut [u8]) -> DevResult
  • Purpose: Reads data from storage starting at the specified block ID
  • Multi-block Support: Buffer size may exceed block size to read multiple contiguous blocks
  • Error Handling: Returns DevResult for consistent error propagation

Write Block Operation

  • Signature: write_block(&mut self, block_id: u64, buf: &[u8]) -> DevResult
  • Purpose: Writes data to storage starting at the specified block ID
  • Multi-block Support: Buffer size may exceed block size to write multiple contiguous blocks
  • Error Handling: Returns DevResult for consistent error propagation

Flush Operation

  • Signature: flush(&mut self) -> DevResult
  • Purpose: Forces all pending write operations to be committed to persistent storage
  • Consistency: Ensures data durability and consistency guarantees

Sources: axdriver_block/src/lib.rs(L24 - L37) 

Error Handling and Result Types

The block driver interface uses the unified error handling system from axdriver_base:

TypePurposeUsage Pattern
DevResultStandard result type for all operationsfn operation() -> DevResult
DevErrorUnified error enumerationConsistent error reporting across drivers

All block operations return DevResult, enabling consistent error handling across different hardware implementations and allowing higher-level code to handle errors uniformly regardless of the underlying storage technology.

Sources: axdriver_block/src/lib.rs(L13)  axdriver_block/src/lib.rs(L28)  axdriver_block/src/lib.rs(L34)  axdriver_block/src/lib.rs(L37) 

Design Patterns and Principles

Mutable Reference Pattern

All data-modifying operations (read_block, write_block, flush) require a mutable reference to self, ensuring exclusive access during I/O operations and preventing data races in concurrent scenarios.

Multi-Block Operation Support

The interface design explicitly supports multi-block operations through buffer sizing. When the provided buffer exceeds the device's block size, the implementation automatically handles reading or writing multiple contiguous blocks, improving I/O efficiency for large transfers.

Hardware Abstraction Layer

The trait provides a hardware-agnostic interface that abstracts away device-specific details while maintaining the essential block-oriented semantics that storage hardware typically provides.

Sources: axdriver_block/src/lib.rs(L15 - L38) 

Feature-Based Compilation Integration

The crate supports conditional compilation for specific implementations:


This design allows systems to include only the block driver implementations they need, reducing binary size and compilation time for embedded or specialized deployments.

Sources: axdriver_block/src/lib.rs(L6 - L10)