@toc
  **团队博客:** \*\*汽车电子社区\*\*(https://bbs.csdn.net/forums/automotive-electronics)
1. 概述
  Block模块是Linux内核I/O子系统的核心组件,负责管理块设备的I/O操作。该模块提供标准化的接口来处理块设备的读写请求,支持多种I/O调度算法、块设备管理、分区处理和高级功能如完整性校验和加密。
2. 软件架构图
```mermaid
graph TB
subgraph "用户空间"
U1文件系统
U2存储管理工具
U3性能监控工具
U4系统管理工具
end
subgraph "内核空间"
subgraph "Block核心"
B1blk-core.c\
核心API
B2blk-settings.c\
设备设置
B3blk-sysfs.c\
系统接口
B4blk-mq.c\
多队列核心
end
subgraph "请求处理"
R1blk-merge.c\
请求合并
R2blk-softirq.c\
软中断处理
R3blk-timeout.c\
超时处理
R4blk-iopoll.c\
I/O轮询
end
subgraph "I/O调度"
S1blk-mq-sched.c\
MQ调度框架
S2deadline-iosched.c\
Deadline调度器
S3bfq-iosched.c\
BFQ调度器
S4kyber-iosched.c\
Kyber调度器
end
subgraph "块设备管理"
D1genhd.c\
通用块设备
D2partition-generic.c\
分区管理
D3ioctl.c\
IO控制
D4bdev.c\
块设备操作
end
subgraph "高级功能"
A1blk-integrity.c\
完整性校验
A2blk-crypto.c\
块加密
A3blk-cgroup.c\
控制组
A4blk-throttle.c\
I/O节流
end
subgraph "统计与监控"
M1blk-stat.c\
I/O统计
M2blk-mq-debugfs.c\
调试接口
M3blk-trace.c\
I/O跟踪
M4blk-rq-qos.c\
QoS控制
end
end
subgraph "文件系统"
F1ext4
F2xfs
F3btrfs
F4vfs
end
subgraph "设备驱动"
Dev1NVMe驱动
Dev2SATA驱动
Dev3SCSI驱动
Dev4虚拟设备
end
U1 --> B1
U2 --> B1
U3 --> M1
F1 --> B1
F2 --> B1
F3 --> B1
B1 --> R1
B1 --> S1
B1 --> D1
B1 --> A1
S1 --> S2
S1 --> S3
S1 --> S4
D1 --> D2
D1 --> D3
A1 --> A2
B1 --> M1
Dev1 --> B4
Dev2 --> B4
Dev3 --> B4
style B1 fill:#e1f5fe
style S1 fill:#f3e5f5
style F1 fill:#fff3e0
```
3. 调用流程图
```mermaid
sequenceDiagram
participant FS as 文件系统
participant Block as Block核心
participant Scheduler as I/O调度器
participant Device as 块设备驱动
participant Completion as 完成处理
FS->>Block: 提交I/O请求
Block->>Block: 创建请求对象
Block->>Scheduler: 请求入队
Scheduler->>Scheduler: 调度算法处理
Scheduler->>Block: 返回处理后请求
Block->>Device: 发送请求到设备
Device->>Device: 执行实际I/O
Device->>Completion: I/O完成通知
Completion->>Block: 完成处理
Block->>FS: 返回I/O结果
Note right of Scheduler: 多种调度算法可选
Note right of Device: 支持多队列并发
Note right of Completion: 软中断或轮询处理
```
4. Block子系统架构类图
```mermaid
classDiagram
class blk_core {
+blk_queue_make_request()
+blk_queue_bio()
+blk_queue_cleanup()
+blk_start_queue()
+blk_stop_queue()
+blk_queue_bounce()
+blk_queue_dma_alignment()
+blk_queue_max_segments()
+blk_queue_max_discard_segments()
+blk_queue_max_write_zeroes_segments()
}
class blk_mq {
+blk_mq_alloc_tag_set()
+blk_mq_free_tag_set()
+blk_mq_init_queue()
+blk_mq_alloc_request()
+blk_mq_free_request()
+blk_mq_submit_bio()
+blk_mq_map_queue()
+blk_mq_queue_tag_busy_iter()
+blk_mq_complete_request()
+blk_mq_start_request()
+blk_mq_end_request()
}
class blk_merge {
+blk_merge_requests()
+blk_attempt_req_merge()
+blk_attempt_plug_merge()
+blk_rq_merge_ok()
+blk_rq_mergeable()
+blk_rq_pos_less()
+blk_rq_bytes_less()
+blk_rq_sectors_less()
+blk_rq_cmp()
+blk_rq_is_passthrough()
}
class blk_softirq {
+blk_softirq_init()
+blk_softirq_exit()
+blk_softirq_run()
+blk_complete_request()
+blk_done_softirq()
+blk_complete_request_async()
+blk_complete_request_sync()
+blk_complete_request_flush()
}
class blk_timeout {
+blk_add_timer()
+blk_delete_timer()
+blk_rq_timed_out()
+blk_rq_timed_out_timer()
+blk_rq_check_expired()
+blk_rq_reset_timer()
+blk_rq_init_timer()
+blk_rq_timeout()
+blk_rq_timeout_handler()
}
class blk_iopoll {
+blk_iopoll_init()
+blk_iopoll_exit()
+blk_iopoll_sched()
+blk_iopoll_run()
+blk_iopoll_complete()
+blk_iopoll_disable()
+blk_iopoll_enable()
+blk_iopoll_queue()
+blk_iopoll_softirq()
}
class blk_integrity {
+blk_integrity_register()
+blk_integrity_unregister()
+blk_integrity_compare()
+blk_integrity_add()
+blk_integrity_merge()
+blk_integrity_split()
+blk_integrity_clone()
+blk_integrity_prep()
+blk_integrity_complete()
+blk_integrity_endio()
}
class blk_crypto {
+blk_crypto_register()
+blk_crypto_unregister()
+blk_crypto_start_using()
+blk_crypto_stop_using()
+blk_crypto_evict_key()
+blk_crypto_keyslot_program()
+blk_crypto_keyslot_evict()
+blk_crypto_keyslot_find()
+blk_crypto_keyslot_alloc()
+blk_crypto_keyslot_free()
}
class blk_cgroup {
+blk_cgroup_init()
+blk_cgroup_exit()
+blk_cgroup_add()
+blk_cgroup_remove()
+blk_cgroup_path()
+blk_cgroup_css()
+blk_cgroup_bio_start()
+blk_cgroup_bio_end()
+blk_cgroup_throttle()
+blk_cgroup_io_stat()
}
class blk_throttle {
+blk_throttle_init()
+blk_throttle_exit()
+blk_throttle_bio()
+blk_throttle_drain()
+blk_throttle_update_limits()
+blk_throttle_dispatch()
+blk_throttle_charge_bio()
+blk_throttle_uncharge_bio()
+blk_throttle_wait()
+blk_throttle_schedule_delayed()
}
class blk_stat {
+blk_stat_init()
+blk_stat_exit()
+blk_stat_add()
+blk_stat_get()
+blk_stat_reset()
+blk_stat_alloc()
+blk_stat_free()
+blk_stat_show()
+blk_stat_start()
+blk_stat_end()
}
class blk_mq_debugfs {
+blk_mq_debugfs_init()
+blk_mq_debugfs_exit()
+blk_mq_debugfs_register()
+blk_mq_debugfs_unregister()
+blk_mq_debugfs_queue_add()
+blk_mq_debugfs_queue_remove()
+blk_mq_debugfs_hctx_add()
+blk_mq_debugfs_hctx_remove()
+blk_mq_debugfs_ctx_add()
+blk_mq_debugfs_ctx_remove()
}
class blk_trace {
+blk_trace_init()
+blk_trace_exit()
+blk_trace_startstop()
+blk_trace_setup()
+blk_trace_remove()
+blk_trace_ioctl()
+blk_trace_shutdown()
+blk_trace_free()
+blk_trace_run()
+blk_trace_dump()
}
class blk_rq_qos {
+blk_rq_qos_init()
+blk_rq_qos_exit()
+blk_rq_qos_add()
+blk_rq_qos_remove()
+blk_rq_qos_throttle()
+blk_rq_qos_merge()
+blk_rq_qos_split()
+blk_rq_qos_clone()
+blk_rq_qos_prep()
+blk_rq_qos_complete()
}
blk_core --> blk_mq : uses
blk_core --> blk_merge : uses
blk_core --> blk_softirq : uses
blk_core --> blk_timeout : uses
blk_core --> blk_iopoll : uses
blk_core --> blk_integrity : uses
blk_core --> blk_crypto : uses
blk_core --> blk_cgroup : uses
blk_core --> blk_throttle : uses
blk_core --> blk_stat : uses
blk_core --> blk_mq_debugfs : uses
blk_core --> blk_trace : uses
blk_core --> blk_rq_qos : uses
blk_mq --> blk_mq_tag_set : manages
blk_cgroup --> blk_throttle : uses
blk_stat --> blk_trace : uses
```
5. 状态机分析
5.1. Block请求处理状态机
```mermaid
stateDiagram-v2
\* --> REQUEST_CREATED: 请求创建
REQUEST_CREATED --> REQUEST_QUEUED: 请求入队
REQUEST_QUEUED --> REQUEST_MERGED: 请求合并
REQUEST_MERGED --> REQUEST_SCHEDULED: 调度处理
REQUEST_SCHEDULED --> REQUEST_DISPATCHED: 请求分发
REQUEST_DISPATCHED --> REQUEST_ACTIVE: 设备处理
REQUEST_ACTIVE --> REQUEST_COMPLETED: 处理完成
REQUEST_COMPLETED --> REQUEST_FINISHED: 完成处理
REQUEST_FINISHED --> \*
note right of REQUEST_QUEUED : 进入I/O调度器队列
note right of REQUEST_MERGED : 与相邻请求合并
note right of REQUEST_SCHEDULED : 调度算法处理
note right of REQUEST_DISPATCHED : 发送到设备驱动
note right of REQUEST_COMPLETED : 设备完成通知
```
5.2. Block I/O调度状态机
```mermaid
stateDiagram-v2
\* --> SCHEDULER_IDLE: 调度器空闲
SCHEDULER_IDLE --> REQUEST_ARRIVED: 请求到达
REQUEST_ARRIVED --> MERGE_CHECK: 合并检查
MERGE_CHECK --> REQUEST_MERGED: 合并成功
MERGE_CHECK --> QUEUE_INSERT: 无法合并
REQUEST_MERGED --> QUEUE_INSERT: 插入队列
QUEUE_INSERT --> SCHEDULE_DECISION: 调度决策
SCHEDULE_DECISION --> REQUEST_DISPATCHED: 请求分发
REQUEST_DISPATCHED --> WAIT_COMPLETION: 等待完成
WAIT_COMPLETION --> COMPLETION_ARRIVED: 完成到达
COMPLETION_ARRIVED --> SCHEDULER_IDLE: 返回空闲
note right of MERGE_CHECK : 检查前向/后向合并
note right of SCHEDULE_DECISION : 算法特定的调度逻辑
note right of WAIT_COMPLETION : 可能使用轮询或中断
```
5.3. Block设备管理状态机
```mermaid
stateDiagram-v2
\* --> DEVICE_UNREGISTERED: 设备未注册
DEVICE_UNREGISTERED --> DEVICE_REGISTERING: 注册开始
DEVICE_REGISTERING --> DEVICE_REGISTERED: 注册完成
DEVICE_REGISTERED --> DEVICE_ACTIVE: 设备激活
DEVICE_ACTIVE --> DEVICE_SUSPENDED: 设备挂起
DEVICE_SUSPENDED --> DEVICE_ACTIVE: 设备恢复
DEVICE_ACTIVE --> DEVICE_REMOVING: 设备移除
DEVICE_REMOVING --> DEVICE_UNREGISTERED: 移除完成
note right of DEVICE_REGISTERING : 分配设备号和资源
note right of DEVICE_ACTIVE : 处理I/O请求
note right of DEVICE_SUSPENDED : 电源管理状态
note right of DEVICE_REMOVING : 清理资源和队列
```
5.4. Block多队列处理状态机
```mermaid
stateDiagram-v2
\* --> MQ_INITIALIZING: 多队列初始化
MQ_INITIALIZING --> MQ_READY: 多队列就绪
MQ_READY --> MQ_ACTIVE: 多队列激活
MQ_ACTIVE --> MQ_QUEUEING: 请求入队
MQ_QUEUEING --> MQ_DISPATCHING: 请求分发
MQ_DISPATCHING --> MQ_COMPLETING: 完成处理
MQ_COMPLETING --> MQ_ACTIVE: 继续处理
MQ_ACTIVE --> MQ_SUSPENDING: 多队列挂起
MQ_SUSPENDING --> MQ_SUSPENDED: 多队列挂起完成
MQ_SUSPENDED --> MQ_ACTIVE: 多队列恢复
note right of MQ_INITIALIZING : 创建硬件/软件上下文
note right of MQ_QUEUEING : 请求分配到特定队列
note right of MQ_DISPATCHING : 并发处理多个请求
note right of MQ_SUSPENDING : 停止新请求入队
```
6. 源码分析
6.1. 核心数据结构分析
6.1.1 request_queue结构体分析
  request_queue是Block模块请求队列的核心数据结构:
```c
struct request_queue {
struct request *last_merge; // 最后合并的请求
struct elevator_queue *elevator; // I/O调度器
struct blk_mq_tag_set *tag_set; // 多队列标签集
struct list_head queue_head; // 请求队列头
struct blk_queue_stats stats; // 队列统计
unsigned int nr_requests; // 请求数量
struct rcu_head rcu_head; // RCU回调
struct kobject kobj; // 内核对象
};
```
  该结构体管理所有I/O请求的队列和调度。
6.1.2 request结构体分析
  request定义了I/O请求的具体内容:
```c
struct request {
struct request_queue *q; // 所属队列
struct bio *bio; // 关联的bio
struct bio *biotail; // bio链表尾
struct list_head queuelist; // 队列链表节点
unsigned int cmd_flags; // 命令标志
sector_t __sector; // 起始扇区
unsigned int __data_len; // 数据长度
struct gendisk *rq_disk; // 目标磁盘
blk_status_t errors; // 错误状态
refcount_t ref; // 引用计数
};
```
  该结构体表示单个I/O请求的完整信息。
6.1.3 bio结构体分析
  bio定义了块I/O的基本单位:
```c
struct bio {
struct bio *bi_next; // 下一个bio
struct block_device *bi_bdev; // 块设备
struct bio_vec *bi_io_vec; // I/O向量数组
struct bio_vec bi_inline_vecs4; // 内联向量
bio_end_io_t *bi_end_io; // 完成回调
void *bi_private; // 私有数据
unsigned short bi_vcnt; // 向量数量
unsigned short bi_max_vecs; // 最大向量数
unsigned int bi_opf; // 操作标志
sector_t bi_iter.bi_sector; // 当前扇区
};
```
  该结构体表示块I/O操作的基本单位。
6.1.4 gendisk结构体分析
  gendisk定义了通用磁盘的抽象:
```c
struct gendisk {
int major; // 主设备号
int first_minor; // 起始次设备号
int minors; // 次设备号数量
char disk_name32; // 磁盘名称
struct block_device_operations *fops; // 操作函数
struct request_queue *queue; // 请求队列
struct disk_part_tbl *part_tbl; // 分区表
struct hd_struct *part0; // 整体分区
struct rcu_head rcu_head; // RCU回调
unsigned int flags; // 磁盘标志
sector_t capacity; // 容量
};
```
  该结构体表示物理或虚拟磁盘设备。
6.2. 核心算法分析
6.2.1 请求合并算法
  请求合并的高效算法:
```c
bool blk_attempt_req_merge(struct request_queue *q, struct request *rq,
struct request *next){
if (!blk_rq_merge_ok(rq, next))
return false;
if (blk_rq_pos_less(rq, next)) {
// 后向合并
if (blk_rq_sectors_less(rq, next) &&
(rq->cmd_flags & REQ_NOMERGE) == 0) {
if (blk_rq_mergeable(rq, next))
return blk_rq_merge(rq, next);
}
} else {
// 前向合并
if (blk_rq_sectors_less(next, rq) &&
(next->cmd_flags & REQ_NOMERGE) == 0) {
if (blk_rq_mergeable(next, rq))
return blk_rq_merge(next, rq);
}
}
return false;
}
```
  该算法实现请求的前向和后向合并。
6.2.2 I/O调度算法
  I/O调度的核心算法:
```c
void elv_dispatch_sort(struct request_queue *q, struct request *rq)
{
struct elevator_queue *e = q->elevator;
struct list_head *entry;
if (e->ops->elevator_dispatch_fn)
return e->ops->elevator_dispatch_fn(q, rq);
// 默认调度逻辑
list_for_each_prev(entry, &q->queue_head) {
struct request *pos = list_entry_rq(entry);
if (blk_rq_pos_less(pos, rq))
break;
}
list_add(&rq->queuelist, entry->next);
}
```
  该算法实现请求的调度和排序。
6.2.3 多队列分配算法
  多队列请求分配算法:
```c
struct blk_mq_hw_ctx *blk_mq_map_queue(struct request_queue *q,
unsigned int flags,
const struct blk_mq_queue_data *qd)
{
struct blk_mq_tag_set *set = q->tag_set;
struct blk_mq_hw_ctx *hctx;
int cpu;
// 获取当前CPU
cpu = blk_mq_get_cpu(q, qd);
// 映射到硬件上下文
hctx = set->ops->map_queue(q, cpu);
if (!hctx || !blk_mq_hw_queue_mapped(hctx))
hctx = blk_mq_find_hctx(q, cpu);
return hctx;
}
```
  该算法实现请求到多队列的映射。
6.3 核心函数分析
6.3.1 blk_queue_make_request函数分析
  请求创建的核心实现:
```c
blk_qc_t blk_queue_make_request(struct request_queue *q, struct bio *bio)
{
struct request *rq;
int el_ret;
// 创建请求对象
rq = blk_get_request(q, bio_data_dir(bio), bio->bi_opf);
// 初始化请求
for_each_bio(bio)
blk_rq_bio_prep(q, rq, bio);
// 合并检查
el_ret = elv_merge(q, &rq, bio);
if (el_ret == ELEVATOR_BACK_MERGE)
return BLK_QC_T_NONE;
// 添加到调度器
if (!blk_rq_merge_ok(rq, bio))
elv_insert(q, rq, el_ret);
// 触发调度
__blk_run_queue(q);
return BLK_QC_T_NONE;
}
```
  该函数实现请求的完整创建流程。
6.3.2 blk_mq_submit_bio函数分析
  多队列bio提交的核心实现:
```c
blk_qc_t blk_mq_submit_bio(struct bio *bio)
{
struct request_queue *q = bdev_get_queue(bio->bi_bdev);
struct blk_mq_hw_ctx *hctx;
struct request *rq;
blk_qc_t cookie;
// 获取硬件上下文
hctx = blk_mq_map_queue(q, 0, &bio->bi_qd);
// 创建请求
cookie = blk_mq_get_tag(hctx, bio, &rq);
if (blk_qc_t_is_internal(cookie))
return cookie;
// 初始化请求
blk_mq_init_request(rq, bio, cookie);
// 提交请求
blk_mq_put_tag(hctx, cookie);
blk_mq_run_hw_queue(hctx, true);
return cookie;
}
```
  该函数实现多队列bio的提交流程。
6.3.3 blk_mq_run_hw_queue函数分析
  硬件队列运行的核心实现:
```c
void blk_mq_run_hw_queue(struct blk_mq_hw_ctx *hctx, bool async)
{
int srcu_idx;
// 获取SRCU索引
srcu_idx = srcu_read_lock(&hctx->queue_rq_srcu);
// 处理队列
if (!blk_mq_hw_queue_mapped(hctx)) {
srcu_read_unlock(&hctx->queue_rq_srcu, srcu_idx);
return;
}
// 调度请求
if (hctx->run_work) {
if (!async)
hctx->run_work->func(hctx->run_work);
} else {
__blk_mq_run_hw_queue(hctx);
}
srcu_read_unlock(&hctx->queue_rq_srcu, srcu_idx);
}
```
  该函数实现硬件队列的运行和调度。
6.4 事件处理流程分析
6.4.1 请求完成处理
  请求完成的事件处理流程:
```c
void blk_complete_request(struct request *rq)
{
struct request_queue *q = rq->q;
unsigned long flags;
// 完成请求
if (blk_rq_is_passthrough(rq))
blk_end_request_all(rq);
else
__blk_end_request_all(rq, rq->errors);
// 更新统计
blk_account_io_completion(rq, rq->nr_sectors);
// 触发后续处理
if (q->mq_ops)
blk_mq_complete_request(rq);
else
__blk_complete_request(rq);
// 释放请求
blk_put_request(rq);
}
```
  该流程处理请求的完成和资源释放。
6.4.2 超时处理
  请求超时的事件处理:
```c
void blk_rq_timed_out(struct request *rq)
{
struct request_queue *q = rq->q;
enum blk_eh_timer_return ret;
// 检查超时
if (blk_rq_check_expired(rq))
return;
// 调用超时处理
ret = q->mq_ops->timeout(rq, true);
if (ret == BLK_EH_DONE)
return;
// 重置定时器
blk_rq_reset_timer(rq);
// 重试或错误处理
if (ret == BLK_EH_RESET_TIMER)
blk_add_timer(rq);
else
blk_rq_timeout(rq);
}
```
  该流程处理请求的超时和错误恢复。
7. 设计模式
7.1 策略模式(Strategy Pattern)
  Block模块使用策略模式处理不同的I/O调度算法:
```c
// I/O调度策略接口
struct elevator_type {
struct list_head list;
struct elevator_ops *ops;
struct kobj_type *elevator_ktype;
struct module *elevator_owner;
};
// Deadline策略实现
static struct elevator_type elevator_deadline = {
.ops = {
.elevator_merge_fn = deadline_merge,
.elevator_dispatch_fn = deadline_dispatch,
.elevator_add_req_fn = deadline_add_request,
.elevator_remove_req_fn = deadline_remove_request,
.elevator_requeue_req_fn = deadline_requeue_request,
.elevator_drain_elevator_fn = deadline_drain_elevator,
},
.elevator_ktype = &deadline_kobj_ktype,
.elevator_owner = THIS_MODULE,
};
// BFQ策略实现
static struct elevator_type elevator_bfq = {
.ops = {
.elevator_merge_fn = bfq_merge,
.elevator_dispatch_fn = bfq_dispatch,
.elevator_add_req_fn = bfq_add_request,
.elevator_remove_req_fn = bfq_remove_request,
.elevator_requeue_req_fn = bfq_requeue_request,
.elevator_drain_elevator_fn = bfq_drain_elevator,
},
.elevator_ktype = &bfq_kobj_ktype,
.elevator_owner = THIS_MODULE,
};
```
  不同I/O调度算法使用不同的处理策略。
7.2 工厂模式(Factory Pattern)
  Block模块使用工厂模式创建请求对象:
```c
struct request *blk_get_request(struct request_queue *q, unsigned int op,
blk_mq_req_flags_t flags)
{
struct request *rq;
// 分配请求结构
rq = blk_mq_alloc_request(q, op, flags);
if (!rq)
return ERR_PTR(-ENOMEM);
// 初始化请求
blk_rq_init(q, rq);
rq->cmd_flags = op;
// 根据类型初始化
switch (op) {
case REQ_OP_READ:
case REQ_OP_WRITE:
// 普通I/O请求
break;
case REQ_OP_DISCARD:
case REQ_OP_SECURE_ERASE:
// 抛弃/安全擦除请求
break;
case REQ_OP_FLUSH:
case REQ_OP_FUA:
// 刷新请求
break;
default:
// 其他类型请求
break;
}
return rq;
}
```
  工厂方法创建不同类型的请求对象。
7.3 观察者模式(Observer Pattern)
  Block模块实现观察者模式处理I/O事件:
```c
// I/O事件观察者
struct blk_io_observer {
void (*io_start)(struct request *rq);
void (*io_complete)(struct request *rq);
void (*io_error)(struct request *rq, blk_status_t status);
struct list_head list;
};
// 注册观察者
int blk_register_io_observer(struct blk_io_observer *observer)
{
mutex_lock(&blk_io_mutex);
list_add(&observer->list, &blk_io_observers);
mutex_unlock(&blk_io_mutex);
return 0;
}
// 通知观察者
static void blk_notify_io_event(enum blk_io_event event, struct request *rq)
{
struct blk_io_observer *observer;
mutex_lock(&blk_io_mutex);
list_for_each_entry(observer, &blk_io_observers, list) {
switch (event) {
case BLK_IO_START:
if (observer->io_start)
observer->io_start(rq);
break;
case BLK_IO_COMPLETE:
if (observer->io_complete)
observer->io_complete(rq);
break;
case BLK_IO_ERROR:
if (observer->io_error)
observer->io_error(rq, rq->errors);
break;
}
}
mutex_unlock(&blk_io_mutex);
}
```
  观察者模式通知I/O事件变更。
7.4 组合模式(Composite Pattern)
  Block模块使用组合模式组织请求和bio:
```c
// 请求组合结构
struct request {
struct bio *bio; // bio链表头
struct bio *biotail; // bio链表尾
};
// 叶子节点:bio结构
struct bio {
struct bio *bi_next; // 下一个bio
struct bio_vec *bi_io_vec; // I/O向量数组
};
// 组合操作
int blk_rq_append_bio(struct request *rq, struct bio *bio)
{
// 添加bio到请求
if (rq->biotail)
rq->biotail->bi_next = bio;
else
rq->bio = bio;
rq->biotail = bio;
rq->__data_len += bio->bi_iter.bi_size;
return 0;
}
```
  组合模式统一管理请求和bio的层次结构。
7.5 模板方法模式(Template Method Pattern)
  Block模块使用模板方法处理I/O操作:
```c
int blk_execute_rq_template(struct request_queue *q, struct request *rq,
int at_head, blk_end_io_fn *done)
{
int ret;
// 1. 准备操作(钩子方法)
ret = blk_prepare_rq(q, rq);
if (ret)
return ret;
// 2. 执行I/O操作(抽象方法)
ret = q->mq_ops->queue_rq(q, rq);
if (ret)
goto cleanup;
// 3. 等待完成(钩子方法)
if (done)
rq->end_io = done;
// 4. 发送通知(钩子方法)
blk_notify_io_start(rq);
return 0;
cleanup:
// 5. 清理操作(钩子方法)
blk_cleanup_rq(q, rq);
return ret;
}
```
  模板方法定义I/O操作的标准流程。
7.6 单例模式(Singleton Pattern)
  Block模块使用单例模式管理全局请求队列:
```c
static struct request_queue *blk_get_queue(dev_t dev)
{
static DEFINE_MUTEX(init_mutex);
static struct request_queue *queue;
mutex_lock(&init_mutex);
if (!queue) {
queue = blk_alloc_queue(GFP_KERNEL);
if (queue)
blk_queue_init(queue);
}
mutex_unlock(&init_mutex);
return queue;
}
```
  确保请求队列的全局唯一性。
8. 总结
  Block模块作为Linux内核I/O子系统的核心组件,成功实现了块设备的统一管理和高效I/O处理。通过精心设计的请求队列管理、I/O调度框架和多队列支持,Block模块提供了从传统单队列到现代多队列的完整演进路径。