Linux 的块设备(Block Device)是操作系统中非常核心的子系统,它提供了对存储设备(如 HDD、SSD、NVMe、虚拟块设备)的统一访问接口。块设备以块(block)为单位进行 I/O 操作,每个块通常为 512B 或 4KB。理解块设备架构对于性能优化、驱动开发和存储系统设计至关重要。
1. 块设备概念与分类
1.1 块设备 vs 字符设备
在 Linux 内核中,设备分为字符设备(Character Device)和块设备(Block Device):
区别表:
| | |
|---|
| | |
| | 内核缓存(Page Cache + Buffer Cache) |
| | |
| | |
1.2 块设备分类
块设备主要包括:
物理块设备(Physical Block Device)
SATA/SCSI/IDE 硬盘
NVMe SSD
eMMC / UFS
虚拟块设备(Virtual Block Device)
网络块设备(Network Block Device, NBD)
2. Linux 块设备层次架构
Linux 块设备体系可以概括为 应用层 → VFS → 块层(Block Layer) → 调度器(IO Scheduler) → 驱动层。
+-------------------+| 应用程序 |+-------------------+| VFS |+-------------------+| Page Cache |+-------------------+| 块层(Block Layer)|+-------------------+| I/O 调度器 |+-------------------+| 块设备驱动(BLK) |+-------------------+| 物理设备硬件 |+-------------------+
2.1 VFS 与块设备
VFS(Virtual File System)提供统一接口给上层应用。块设备被 VFS 封装为 struct block_device,文件系统通过 struct inode 与 struct super_block 间接访问物理设备。
2.2 Page Cache
Page Cache 是内核缓存层,主要用于减少物理 I/O。块 I/O 首先会尝试在 Page Cache 命中,否则才提交到底层设备。
3. 核心数据结构解析
Linux 块设备有几个关键结构:
3.1 struct block_device
struct block_device { dev_t bd_dev; /* 设备号 */ struct inode *bd_inode; /* 关联 inode */ struct request_queue *bd_queue; /* I/O 队列 */ fmode_t bd_mode; /* 打开模式 */};
3.2 struct request_queue
struct request_queue { spinlock_t queue_lock; /* 队列锁 */ struct list_head queue; /* 请求链表 */ struct elevator_queue *elevator; /* 调度器 */};
3.3 struct bio
BIO(Block I/O)是 Linux 块层最底层的 I/O 描述单元:
struct bio { struct block_device *bi_bdev; sector_t bi_sector; int bi_size; struct bio_vec *bi_io_vec;};
BIO 与请求队列、Page Cache 紧密关联,用于一次或多次块传输。
4. I/O 请求流程解析
Linux 块设备 I/O 流程可分为以下步骤:
应用程序 read/write ↓ VFS ↓ Page Cache (cache miss?) ↓ submit_bio() ↓ request_queue ↓ IO Scheduler (排序、合并) ↓ 驱动层 queue_rq() ↓ 硬件 DMA 传输 ↓ 完成中断 ↓ end_request()
4.1 BIO 到 Request
每个 BIO 会被转换成一个 struct request
Request 会进入 request_queue,调度器对请求进行排序和合并
典型调度器:mq-deadline, bfq, kyber(多队列设备)
4.2 调度器工作原理
调度器作用:
合并相邻请求(merge)
按顺序重排(sort),减少磁头寻道或 PCIe NVMe 命令延迟
延迟提交(I/O batching)
Time →Req1 ────────┐Req2 ────────┼─> [Scheduler Merge & Sort] ─> HWReq3 ────────┘
5. 多队列块设备 (Multi-Queue Block Device)
现代 NVMe/SSD 支持多队列 I/O,Linux 通过 blk-mq(Multi-Queue Block Layer)实现:
CPU0 ─> Queue0 ┐CPU1 ─> Queue1 ├─> NVMe ControllerCPU2 ─> Queue2 ┘
6. 高级特性与优化策略
I/O 合并:减少小块随机 I/O,增加顺序性
IO 调度策略优化:不同存储类型选择不同调度器
队列深度调整:影响吞吐和延迟
使用 Direct I/O 或 O_DIRECT:绕过 Page Cache,减少内存占用
内核调优参数:
7. 总结
Linux 块设备架构提供了从用户态到硬件的完整 I/O 管道。核心思想:
分层抽象:VFS、Page Cache、块层、调度器、驱动
数据结构核心:struct block_device, struct request_queue, struct bio
性能优化:调度器策略、队列管理、多队列支持、内核参数调优
掌握 Linux 块设备架构对于优化文件系统性能、开发高性能存储驱动、分析 I/O 性能瓶颈非常重要。