1.fdisk -l 查看块大小:
[root@localhost alice]# fdisk -l
Disk /dev/sda:300 GiB,322122547200 字节,629145600 个扇区
单元:扇区 / 1 * 512 = 512 字节
扇区大小(逻辑/物理):512 字节 / 512 字节
I/O 大小(最小/最佳):512 字节 / 512 字节
磁盘标签类型:dos
磁盘标识符:0xece8cb44
2.
[root@localhost alice]# stat /
文件:/
大小:237 块:0 IO 块:4096 目录
设备:fd00h/64768d Inode:128 硬链接:17
权限:(0555/dr-xr-xr-x) Uid:( 0/ root) Gid:( 0/ root)
环境:system_u:object_r:root_t:s0
最近访问:2023-11-30 07:49:27.453607895 -0500
最近更改:2023-11-12 03:27:36.961555919 -0500
最近改动:2023-11-12 03:27:36.961555919 -0500
创建时间:-
3.
[root@localhost alice]# blockdev --getbsz /dev/sda
4096
查到上述结果后,我不仅要问:他m的到底一个块多大?512kb byte or 4096 byte?
系统中能够随机(不需要按顺序)访问固定大小数据片(chunks)的硬件设备称作块设备,这些固定大小的数据片就称作块。最常见的块设备为硬盘,其他的还有软盘驱动器、闪存等,它们都是以安装文件系统的方式使用的。
另一种基本的设备类型是字符设备。字符设备按照字符流的方式被有序访问,像串口和键盘就属于字符设备。
对于这两种类型的设备,它们的区别在于是否可以随机访问数据。内核对块设备的管理需要有一个专门提供服务的子系统,对字符设备的管理则不需要。
一、剖析一个块设备
块设备中最小的可寻址单位是扇区。扇区大小一般是 2 的整数倍,最常见的是 512 字节。扇区的大小是设备的物理属性。
在软件层面上,最小逻辑可寻址单元为块。块是文件系统的一种抽象,只能基于块来访问文件系统。虽然物理磁盘寻址是按照扇区进行的,但是内核执行的所有操作都是按照块进行的。所以块不能比扇区还小,只能倍数于扇区大小。
总之,扇区是设备的最小寻址单元,也被称为 “硬扇区” 或 “设备块”;同样地,块是文件系统的最小寻址单元,也被称为 “文件块” 或 “I/O 块”。
二、缓冲区和缓冲区头
当一个块被调入内存时(在读入后或等待写出时),它要存储在一个缓冲区中。每个缓冲区与一个块对应,它相当于是磁盘块在内存中的表示。一个页可以容纳一个或多个内存中的块。由于内核在处理数据时需要一些相关的控制信息(比如一个块属于哪个块设备,块对应于哪个缓冲区等),所以每一个缓冲区都有一个对应的描述符 buffer_head 结构体,称为缓冲区头,定义在
但是,将缓冲区头作为 I/O 操作单元带来了两个弊端:
缓冲区头是一个很大且不容易控制的数据结构体,而且缓冲区头对数据的操作既不方便也不清晰。
它仅能描述单个缓冲区,缓冲区头会促使内核八大块数据的 I/O 操作分解为多个 buffer_head 结构体进行操作。
所以后面为块 I/O 操作引入了一种新型、灵活并轻量级的容器——bio 结构体。
三、bio 结构体
目前内核中块 I/O 操作的基本容器由 bio 结构体表示,定义在
bio 结构体定义于
使用 bio 结构体的目的主要是代表正在现场执行的 I/O 操作,所以该结构体中的主要域都是用来管理相关信息的:
bi_io_vec 域指向一个 bio_vec 结构体数组,该结构体链表包含了一个特定 I/O 操作所需要使用到的所有片段。每个 bio_vec 结构都是一个形式为
总之,每一个块 I/O 请求都通过一个 bio 结构体表示,每个请求包含一个或多个块,这些块存储在 bio_vec 结构体数组中,bio_vec 结构体描述了每个片段在物理页中的实际位置,并且像向量一样被组织在一起。
bio 结构体代表的是 I/O 操作,它包含内存中的一个或多个页;而 buffer_head 结构体代表的是一个缓冲区,它描述的仅仅是磁盘中的一个块。
四、请求队列
块设备将它们挂起的块 I/O 请求保存在请求队列中,该队列由 request_queue 结构体表示,定义在文件
队列中的请求由结构体 request 表示,一个请求可能要操作多个连续的磁盘块,所以每个请求可以由多个 bio 结构体组成。
五、I/O 调度程序
磁盘寻址是整个计算机中最慢的操作之一,为了缩短寻址时间,Linux 引入了 I/O 调度程序。
I/O 调度程序将磁盘 I/O 资源分配给系统中所有挂起的块 I/O 请求。I/O 调度程序通过两种方法减少磁盘寻址时间:合并与排序。
合并指将两个或多个请求结合成一个新请求,即如果两个请求访问的磁盘扇区相邻,那么可以把两个请求合并为一个请求,这样可以将 I/O 多次请求的开销压缩成一次请求的开销。
排序指将整个请求队列按扇区增长方向有序排列,通过保持磁盘头以直线方向移动,从而缩短所有请求的磁盘寻址时间。这种 I/O 调度程序也被称为电梯调度。
Linux 实际使用的 I/O 调度程序有如下几种:
Linux 电梯
最终期限 I/O 调度程序
预测 I/O 调度程序
完全公正的排队 I/O 调度程序
空操作的 I/O 调度程序