Linux I/O 栈深度实战:从 write() 到 NVMe 硬件的完整链路剖析
引言
当我们调用这样的代码时:
write(fd, buf, 4096);
这 4KB 的数据经历了怎样的旅程才最终落到 SSD 的闪存颗粒上?这条路径跨越用户空间、内核 VFS 层、文件系统层、通用块层、I/O 调度器、设备驱动层,最终触及 NVMe 硬件的门铃寄存器。每一层都有自己的优化策略与权衡哲学。
本文将以数据流动为经、以性能优化为纬,彻底拆解 Linux I/O 栈的每一层机制,涵盖 VFS 抽象、Page Cache 脏页回写、ext4 与 xfs 的差异、块层多队列 blk-mq、I/O 调度算法,以及 NVMe 的多队列并行模型和 SPDK 用户态 I/O 的最新进展。
第一章:VFS——统一抽象的入口
1.1 从 write() 到 vfs_write()
用户空间的 write() 系统调用通过 SYSCALL_DEFINE3 宏进入内核,最终调用 vfs_write()。VFS(Virtual Filesystem Switch)是整个 I/O 栈的门面,它的核心职责是屏蔽底层文件系统的差异,提供统一的文件操作接口。
关键数据结构关系:
struct file {
struct path f_path; // 指向 dentry
struct inode *f_inode; // 关联的 inode
const struct file_operations *f_op; // 文件操作函数表
loff_t f_pos; // 当前文件偏移
struct address_space *f_mapping; // 页缓存映射表
};
struct inode {
struct address_space *i_mapping; // inode 的地址空间
const struct inode_operations *i_op;
const struct file_operations *i_fop;
struct super_block *i_sb; // 所属超级块
};
struct address_space {
struct inode *host; // 所属 inode
struct radix_tree_root page_tree; // 页缓存的基数树(XArray)
struct rw_semaphore i_mmap_rwsem;
const struct address_space_operations *a_ops;
};
vfs_write() 的核心流程:
- 权限检查:验证文件打开标志是否包含 O_WRONLY 或 O_RDWR
- 文件操作分发:调用 file-

发表评论 取消回复