参考链接:
https://www.linuxidc.com/Linux/2019-08/159814.htm
https://www.linuxidc.com/Linux/2019-08/159815.htm
1. 文件系统的概念
文件系统是操作系统用于明确存储设备(常见的是磁盘,也有基于NAND Flash的固态硬盘)或分区上的文件的方法和数据结构;即在存储设备上组织文件的方法。操作系统中负责管理和存储文件信息的软件机构称为文件管理系统,简称文件系统。文件系统由三部分组成:文件系统的接口,对对象操纵和管理的软件集合,对象及属性。从系统角度来看,文件系统是对文件存储设备的空间进行组织和分配,负责文件存储并对存入的文件进行保护和检索的系统。具体地说,它负责为用户建立文件,存入、读出、修改、转储文件,控制文件的存取,当用户不再使用时撤销文件等。(摘抄自百度百科)
2. Linux EXT2文件系统
磁盘是用来储文件的,但是必须先把磁盘格式化为某种格式的文件系统,才能存储文件。文件系统的目的就是组织和管理磁盘中的文件。在 Linux 系统中,最长见的是 ext2 系列的文件系统。其早期版本为 ext2,后来又发展出 ext3 和 ext4。ext3 和 ext4 虽然对 ext2 进行了增强,但是其核心设计并没有发生变化,所以仍是以较老的 ext2 作为学习对象。
2.1 基本结构
Ext2 文件系统在格式化的时候一般会包含多个区块群组(blockgroup)。Ext2 格式化后有点像下面这样:
2.2 逻辑块(Block)
逻辑块存在的意义?
硬盘的最小读写单位是扇区,而现实中数据的读写单位并不是扇区的大小,原因是使用扇区的大小为单位来读写数据的效率实在是太低了。因为一个扇区只有 512 个字节,而磁头是一个扇区一个扇区的读取数据,也就是说,如果文件有 10M,那么读取这个文件磁头就要进行 20480 次读取操作(I/O)。
为了提升效率,就有了逻辑块(Block)的概念。逻辑块是在分区进行文件系统的格式化时所指定的"最小存储单位",这个最小存储单位以扇区的大小为基础(因为扇区为硬盘的最小物理存储单位),大小为扇区大小的 2ⁿ 倍。此时,磁头一次可以读取一个逻辑块。指定逻辑块的大小为 4KB(即由连续的 8 个扇区构成的一个块),那么,同样读取一个 10M 的文件,磁头要读取的次数则大幅下降为 2560 次,这样就大大提高了文件的读取效率。
Ext2 文件系统的 block 主要有下面一些特点:
- block 的大小与数量在格式化完就不能够再改变了(除非重新格式化)
- 每个 block 内最多只能够放置一个文件的数据
- 如果文件大于 block 的大小,则一个文件会占用多个 block 数量
- 若文件小于 block,则该 block 的剩余容量就不能够再被使用了
2.3 boot block
每个磁盘分区的开头 1024 字节大小都预留为分区的启动扇区,存放引导程序和数据,所以又叫引导块。引导块在第一个 Block,即 Block 0 中存放,但是未必占满这个 Block,原因是 Block 的大小可能大于 1024 字节。
这里是存放开机管理程序的地方,这是个非常重要的设计。因为这样使得我们能够把不同的开机管理程序安装到每个文件系统的最前端,而不用覆盖整颗磁盘唯一的 MBR,这样就能支持多系统启动了。
2.4 block group
Block 在逻辑上被划分为多个 Block Group,每个 Block Group 包含的 Block 数量相同,具体是在 SuperBlock 中通过 s_block_per_group 属性定义的(最后一个 Block Group 除外,最后剩下的 Block 数量可能小于 s_block_per_group,这些 Block 会被划分到最后一个 Block Group 中)。
如上图所示,每个 Block Group 都由下面几个组成部分:
- Superblock(超级块)
- Group Description(组描述)
- Block bitmap(块位图)
- Inode bitmap(inode 位图)
- Inode table(inode 表)
- Data Blocks(数据块)
2.4.1 Superblock(超级块)
Superblock 是记录整个 filesystem 相关信息的地方,其实上除了第一个 block group 内会含有 superblock 之外,后续的 block group 不一定都包含 superblock,如果包含,也是做为第一个 block group 内 superblock 的备份。superblock 记录的主要信息有:
- block 与 inode 的总量
- 未使用与已使用的 inode/block 数量
- block 与 inode 的大小(block 为 1,2,4K,inode 为 128 Bytes 或 256 Bytes)
- filesystem 的挂载时间、最近一次写入数据的时间、最近一次检验磁盘(fsck)的时间等文件系统的相关信息
- 一个 valid bit 数值,若此文件系统已被挂载,则 valid bit 为 0,若未被挂载,则 valid bit 为 1
Superblock 的大小为 1024 Bytes,它非常重要,因为分区上重要的信息都在上面。如果 Superblock 挂掉了,分区上的数据就很难恢复了。
2.4.2 Group Description(组描述)
Group Description 用来描述每个 group 的开始与结束位置的 block 号码,以及说明每个块(superblock、bitmap、inodemap、datablock) 分别介于哪一个 block 号码之间。
2.4.3 Block bitmap(区块对照表)
在创建文件时需要为文件分配 block,届时就会选择分配空闲的 block 给文件使用。如何查看 block 是否已经被使用了呢?此时就需要借助于 block bitmap 了。通过 block bitmap 可以知道哪些 block 是空的,因此系统就能够很快地找到空闲空间来分配给文件。同样的,在删除某些文件时,文件原本占用的 block 号码就要释放出来,此时在 block bitmap 当中相对应到该 block 号码的标志就需要修改成"空闲"。这就是 block bitmap 的作用。
2.4.4 Inode bitmap(inode 对照表)
inode bitmap 与 block bitmap 的功能类似,只是 block bitmap 记录的是使用与未使用的 block 号,而 inode bitmap 则记录的是使用与未使用的 inode 号。
2.4.5 Inode table
Inode table 中存放着一个个 inode,inode 的内容记录文件的属性以及该文件实际数据是放置在哪些 block 内,inode 记录的主要的文件属性如下:
- 该文件的读写权限(rwx)
- 该文件的拥有者和所属组(owner/group)
- 该文件的容量
- 该文件的 ctime(创建时间)
- 该文件的 atime(最近一次的读取时间)
- 该文件的 mtime(最近修改的时间)
- 该文件的特殊标识,比如 SetUID 等
- 该文件真正内容的指向(pointer)
inode 的数量与大小也是在格式化时就已经固定了的,另外 inode 还有如下特点:
- 每个 inode 大小均固定为 128 Bytes(新的 ext4 为 256 Bytes)
- 每个文件都仅会占用一个 inode
- 文件系统能够创建的文件数量与 inode 的数量相关
- 系统读取文件时需要先找到 inode,并分析 inode 所记录的权限与使用者是否符合,若符合才能够开始读取 block 的内容
2.4.6 Data block
Data block 是用来存放文件内容的地方,Ext2 文件系统 1K、2K 和 4K 大小的 block。在格式化文件系统时 block 的大小就确定了,并且每个 block 都有编号。需要注意的是,由于 block 大小的差异,会导致文件系统能够支持的最大磁盘容量和最大单个文件的大小并不相同。下表描述了 block 大小与文件系统以及单个文件大小的关系:
此外 Ext2 文件系统的 block 还有下面一些限制:
- block 的大小与数量在格式化后就不能再改变了(除非重新格式化)
- 每个 block 内最多只能够放置一个文件的数据
- 如果文件大于 block 的大小,那么一个文件会占用多个 block
- 若文件小于 block,则该 block 的剩余容量也不能再被使用了(磁盘空间被浪费)
删除一个文件的时候,其实只是将inode bit map和block bit map位翻转了