Skip to content

BlockDeviceLayer

opencode-agent[bot] edited this page May 10, 2026 · 1 revision

BlockDeviceLayer

Abstraction layer for block devices with alignment and partition support.

Overview

The BlockDeviceLayer is the JNode subsystem that provides a unified interface for block device operations, abstracting hardware-specific details and enabling filesystems to work with various storage devices. It forms the foundation of JNode's storage stack, sitting between physical device drivers and the VFS/filesystem layer.

The layer is built around three core interfaces: BlockDeviceAPI for raw read/write/flush, PartitionableBlockDeviceAPI for devices with partition tables, and FSBlockDeviceAPI for virtual partition children. Wrapper classes inject cross-cutting concerns (block alignment, offset mapping) without modifying the underlying driver, keeping physical device specifics isolated from higher-level code.

This design allows filesystems to operate generically across IDE disks, SCSI devices, USB storage, RAMdisks, and floppy drives, each with their own alignment requirements.

Key Components

Class / File Role
fs/src/driver/org/jnode/driver/block/BlockDeviceAPI.java Base block I/O interface: read, write, flush, getLength
fs/src/driver/org/jnode/driver/block/FSBlockDeviceAPI.java Filesystem-facing device interface
fs/src/driver/org/jnode/driver/block/PartitionableBlockDeviceAPI.java Adds partition table access and sector size
fs/src/driver/org/jnode/driver/block/BlockAlignmentSupport.java Sector-aligned read/write wrapper
fs/src/driver/org/jnode/driver/block/MappedBlockDeviceSupport.java Virtual sub-device via offset/length mapping
fs/src/driver/org/jnode/driver/block/ide/disk/IDEDiskPartitionDriver.java Driver that maps a physical partition into a virtual device

How It Works

API Hierarchy

DeviceAPI
    └── BlockDeviceAPI
            ├── PartitionableBlockDeviceAPI<PTE>
            └── FSBlockDeviceAPI

Physical drivers (IDE, SCSI, USB) implement PartitionableBlockDeviceAPI, exposing getPartitionTable() which reads the MBR/GPT. Each PartitionTableEntry becomes a virtual child device created via MappedFSBlockDeviceSupport, presenting FSBlockDeviceAPI with a pre-adjusted offset so callers see the partition's address space starting at zero.

Alignment Handling

The BlockAlignmentSupport wrapper decomposes unaligned I/O requests into HEAD, BODY, and TAIL operations against the underlying aligned device. The read/write methods classify buffers as EMPTY, ALIGNED, CONTAINED, or CROSSED and handle each accordingly:

  • EMPTY: zero-length, no I/O
  • ALIGNED: direct pass-through to device
  • CONTAINED: read-modify-write a single aligned block
  • CROSSED: HEAD + BODY + TAIL, minimizing buffer copies (at most 2 auxiliary operations)

Filesystem Probing

Filesystems are instantiated via FileSystemType.create(device, readOnly). The filesystem implementation probes the device by reading its superblock and checking known magic bytes. Concrete FSBlockDeviceAPI implementations include FileDevice (host OS file), JarFileDevice (JAR entry), and MappedFSBlockDeviceSupport (partition view).

Gotchas

  • FSBlockDeviceAPI vs PartitionableBlockDeviceAPI are parallel hierarchies: physical partitioned devices implement PartitionableBlockDeviceAPI; their virtual partition children implement FSBlockDeviceAPI. Filesystem drivers should expect FSBlockDeviceAPI.
  • Offset translation: Offsets passed to MappedBlockDeviceSupport are relative to the partition start, not the whole device. The mapping handles offset + devOffset transparently.
  • Alignment is not automatic: Drivers must be explicitly wrapped with BlockAlignmentSupport or FSBlockAlignmentSupport to enforce sector alignment.
  • ByteArrayDevice: Read operation copies bytes directly from the array. Cannot address byte ranges beyond Integer.MAX_VALUE.

Related Pages

Clone this wiki locally