Linux存储系统包括两个部分:第一部分是给在用户的角度提供读/写接口,数据以流为表现形式;第二部分是站在存储设备的角度提供读/写接口,数据以块为表现形式。文件系统位于两者中间起到承上启下的作用。
以块为表现形式,既块存储,简单来说就是使用块设备来为系统提供存储服务。本问重点在于块设备的IO栈。
文章目录
0x01 块设备基本概念
块设备将信息存储在固定大小的块中,每个块都有自己的地址。对操作系统来说,块设备是以字符设备的外观展现的,虽然对这种字符设备可以按照字节为单位进行访问,但是实际上到块设备上却是以块为单位(最小512byte,既一个扇区)。这之间的转换是由操作系统来完成的。
下面介绍块设备的基本概念:
- 扇区:磁盘盘片上的扇形区域,逻辑化数据,方便管理磁盘空间,是硬件设备数据传输的基本单位,一般为512byte。
- 块:块是VFS(虚拟文件系统)和文件系统数据传输的基本单位,必须是扇区的整数倍,格式化文件系统时,可以指定块大小。
0x02 块设备I/O栈
1 基本概念
本节介绍几个块设备I/O栈的基本概念。
- bio:bio是通用块层I/O请求的数据结构,表示上层提交的I/O求情。一个bio包含多个page(既page cache 内核缓冲页 在内存上),这些page对应磁盘上的一段连续的空间。由于文件在磁盘上并不连续存放,文件I/O提交到块这杯之前,极有可能被拆分成多个bio结构。
- request:表示块设备驱动层I/O请求,经由I/O调度层转换后(既电梯算法合并)的I/O请求,将会被发送到块设备驱动层进行处理。
- request_queue: 维护块设备驱动层I/O请求的队列,所有的request都插入到该队列,每个磁盘设备都只有一个queue(多个分区也只有一个)。
这三个结构的关系如下图所示,一个request_queue中包含多个request,每个request可能包含多个bio,请求的合并就是根据各种算法(1.noop 2.deadline 3.CFQ)将多个bio加入到同一个request中。
2. 请求处理流程
先说一个Direct I/O和Buffer I/O的区别:
- Direct I/O绕过page cache,Buffer I/O是写到page cache中表示写请求完成,然后由文件系统的刷脏页机制把数据刷到硬盘。因此,使用Buffer I/O,掉电时有可能page cache中的脏数据还未刷到磁盘上,导致数据丢失。
- Buffer I/O机制中,DMA方式可以将数据直接从磁盘读到page cache中(与直接读不同的是,不需要CPU参与),或者从page cache中将数据写回到磁盘上,而不能直