@[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核心"
B1[blk-core.c<br/>核心API]
B2[blk-settings.c<br/>设备设置]
B3[blk-sysfs.c<br/>系统接口]
B4[blk-mq.c<br/>多队列核心]
end
subgraph "请求处理"
R1[blk-merge.c<br/>请求合并]
R2[blk-softirq.c<br/>软中断处理]
R3[blk-timeout.c<br/>超时处理]
R4[blk-iopoll.c<br/>I/O轮询]
end
subgraph "I/O调度"
S1[blk-mq-sched.c<br/>MQ调度框架]
S2[deadline-iosched.c<br/>Deadline调度器]
S3[bfq-iosched.c<br/>BFQ调度器]
S4[kyber-iosched.c<br/>Kyber调度器]
end
subgraph "块设备管理"
D1[genhd.c<br/>通用块设备]
D2[partition-generic.c<br/>分区管理]
D3[ioctl.c<br/>IO控制]
D4[bdev.c<br/>块设备操作]
end
subgraph "高级功能"
A1[blk-integrity.c<br/>完整性校验]
A2[blk-crypto.c<br/>块加密]
A3[blk-cgroup.c<br/>控制组]
A4[blk-throttle.c<br/>I/O节流]
end
subgraph "统计与监控"
M1[blk-stat.c<br/>I/O统计]
M2[blk-mq-debugfs.c<br/>调试接口]
M3[blk-trace.c<br/>I/O跟踪]
M4[blk-rq-qos.c<br/>QoS控制]
end
end
subgraph "文件系统"
F1[ext4]
F2[xfs]
F3[btrfs]
F4[vfs]
end
subgraph "设备驱动"
Dev1[NVMe驱动]
Dev2[SATA驱动]
Dev3[SCSI驱动]
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_vecs\[4\]; // 内联向量 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_name\[32\]; // 磁盘名称 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模块提供了从传统单队列到现代多队列的完整演进路径。