EXT2文件系统
EXT2文件系统数据结构
虚拟磁盘布局
对文件系统而言,文件仅是一系列可读写的数据块。文件系统并不需要了解数据块应该放到物理介质上什么位置。这些都是设备驱动的任务。无论何时,只要文件系统需要从包含它的块设备中读取信息或数据,它就将请求底层的设备驱动读取一个基本块大小整数倍的数据块。EXT2文件系统将它所使用的逻辑分区划分成数据块组。每个数据块组都将那些对文件系统完整性最重要的信息复制出来,同时将实际文件盒目录看做信息与数据块。
逻辑文件系统管理的是一个逻辑空间,这个逻辑空间就像一个大的数组,数组的每个元素就是文件系统操作的基本单位——逻辑块。逻辑块是从0开始编号的,而且,逻辑块是连续的,逻辑块相对的是物理块。通常,EXT2的物理块占一个或几个连续的扇区。
超级块(Block#1)
超级块是记录整个文件系统相关信息的地方,没有superblock,就没有这个文件系统了,它记录的主要信息有:
- block与inode的总量;
- 未使用与已使用的inode/block数量;
- block与inode的大小;
- 文件系统的挂载时间、最近一次写入数据的时间、最近一次检验磁盘的时间等文件系统的相关信息;
- 一个validbit数值,若此文件系统已被挂载,则valid bit为0,若未被挂载,则valid bit为1;
块组描述符(Block#2)
EXT2将磁盘块分为几个组,每个组有8192个块,用一个块组描述符结构体来描述。
块和索引节点位图
- 块位图(Block#8),用于表示某种项的位序列;
- 索引节点位图(Block#9),代表一个文件的数据结构;
- 索引(开始)节点块(Block#10),索引节点大小用于平均分割块大小,所以每个索引节点块都包含整数个索引节点。
邮差算法的应用
- C语言中的Test-Set-Clear位
- 将索引节点号转换为磁盘上的索引节点
遍历算法
- 读取超级块。检查幻数s_magic ( OxEF53),验证它确实是EXT2FS。
- 读取块组描述符块(1+s_first_data_block),以访问组0描述符。从块组描述符的bg_inode_table条目中找到索引节点的起始块编号,并将其称为InodesBeginBlock 。
- 读取 InodeBeginBlock,获取/的索引节点,即INODE #2。
- 将路径名标记为组件字符串,假设组件数量为n。
例如,如果路径名=/a/b/c,则组件字符串是“a”"b”“c”,其中n =3。用name[0],name[1],…,name[n-1]来表示组件。 - 从根索引节点开始,在其数据块中搜索name[0]。
- 使用索引节点号ino来定位相应的索引节点。回想前面的内容,ino从1开始计数。使用邮差算法计算包含索引节点的磁盘块及其在该块中的偏移量。
- 编写搜索函数重复上两步
EXT2文件系统的结构
级别
- 第1级别:实现了基本文件系统树。用户命令程序有:mkdir,creat,mknod,rmdir,link,unlink,symlink,rm,ls,cd和pwd等;
- 第2级别:实现了文件内容读写函数;
- 第3级别:实现了文件系统的挂载、卸载和文件保护。
基本系统文件
- type.h文件:这类文件包含EXT2文件系统的数据结构类型,比如超块、组描述符、索引节点和目录条目结构。此外,它还包含打开文件表、挂载表、PROC结构体和文件系统常数。
- global.c文件:这类文件包含文件系统的全局变量。
- util.c文件:该文件包含文件系统常用的实用程序函数。最重要的实用程序函数是读/写磁盘块函数iget()、iput()和 getino()。
- mount-root.c文件:该文件包含mount_root()函数,在系统初始化期间调用该函数来挂载根文件系统。它读取根设备的超级块,以验证该设备是否为有效的EXT2文件系统。
然后,它将根设备的根 INODE ( ino = 2)加载到minode中,并将根指针设置为根minode。它还将所有进程的当前工作目录设置为根minode。
分配一个挂载表条目来记录挂载的根文件系统。根设备的一些关键信息,如 inode和块的数量、位图的起始块和inode,表,也记录在挂载表中,以便快速访问。