Fuchsia 块设备驱动程序与其他系统驱动程序一样,以可通过 IPC 访问的用户空间服务实现。使用块设备的程序将具有指向这些底层服务器的一个或多个句柄。与文件系统客户端类似,程序通过在 RPC 消息中对“读取”或“写入”请求进行编码,将这些请求发送到服务器。程序使用 fuchsia.storage.block.Block FIDL 协议充当块设备的客户端,该协议允许客户端查询块设备、打开块会话以及将 FIFO 事务加入队列。
fuchsia.storage.block.Block 是任何类块服务器提供的协议,而 fuchsia.hardware.block.volume.Service 是由块设备驱动程序(USB、AHCI / SATA、NVMe、SDMMC、UFS、Virtio、Ramdisk 等)公开的 FIDL 服务,其 volume 成员实现了 fuchsia.storage.block.Block。非驱动程序的块状服务器可以实现 fuchsia.storage.block.Block,而无需公开卷服务;例如,GPT 组件会为每个分区公开一个 Block 实例。驱动程序和其他块服务器都可以使用 block_server 库来实现 fuchsia.storage.block.Block。
快速块 I/O
块设备驱动程序通常负责占用大量内存,并将请求排队到特定设备,以“读入”或“写入”部分内存。将大小有限的消息从 RPC 协议传输到“I/O 事务”需要重复复制大型缓冲区才能访问块设备。
为避免此性能瓶颈,块协议不通过 FIDL RPC 传输具有大型缓冲区的“读取”或“写入”消息,而是使用基于 FIFO 的快速协议,该协议可对共享 VMO 执行操作。文件系统(或任何其他希望与块设备交互的客户端)在块设备上打开会话 (fuchsia.storage.block.Session),获取其 FIFO 句柄,并将 VMO (AttachVmo) 附加到会话。然后,客户端可以在 FIFO 上发送快速、轻量级的控制消息,指示块设备驱动程序直接对已注册的 VMO 执行操作。例如,在写入文件时,文件系统(将文件表示为 VMO)可以发送一个小型 FIFO 消息,指示“将 VMO Y 的块偏移量 X 中的 N 个块直接写入磁盘上的块偏移量 Z”,而不是通过 IPC 原语直接传递字节并将其复制到块设备内存中的新位置。与“mmap”内存映射工具结合使用时,这可在访问文件时提供从客户端程序到磁盘(或反向)的“零复制”途径。