一、Linux IO栈
一个常见Linux IO处理流程示意图如下:
这个示意图主要描述了Linux系统中I/O请求的处理流程,涉及了I/O接口、文件系统、块层、NVMe驱动等多个部分,整个IO流程处理主要概括以下步骤:
1. 应用程序(Applications)将I/O请求提交给I/O接口(Step 1)。这些请求可以是POSIX的read/write操作(如psync)、libaio、io_uring等。
2. I/O接口构建一个struct kiocb结构体,并通过VFS(虚拟文件系统)将其提交给文件系统(Step 2)。
3. 文件系统解析包含数据的块地址,构建一个struct bio请求,并通过submit_bio()函数将其提交给块层(Step 3)。
4. Linux块层将struct bio转换为struct request(Step 4),并将其放入每个核心的软件队列(Step 5)中。
5. 然后,这些请求由块I/O调度器处理,并放入硬件调度队列(Step 6-7)中。
6. 硬件调度队列中的请求将被NVMe驱动程序通过nvme_queue_rq()函数处理(Step 8)。
7. NVMe驱动程序根据请求构建一个NVMe命令(Step 9),并将其写入提交队列(SQ)(Step 10)以供设备进行处理(Step 11)。
8. 在设备处理完命令后,设备将请求写入完成队列(CQ)并生成中断(Step 12)。
9. 完成队列中的请求由nvme_process_cq函数处理,然后调用blk_mq_end_request()和bio_end_io()函数来完成bio层的请求(Step 14)。
10. 最后,应用程序将收到完成结果的通知(Step 15)。