第十一章 EXT2文件系统
以下内容是我对本章部分内容的学习总结
一、EXT2文件系统数据结构
1、虚拟磁盘布局
每当文件系统需要从包含它的块设备中读取信息或数据,就将请求底层的设备驱动读取一个基本块大小整数倍的数据块。
EXT2文件系统将它所使用的逻辑分区划分成数据块组。
每个数据块组都将那些对文件系统完整性最重要的信息复制出来,同时将实际文件盒目录看做信息与数据块。
逻辑文件系统管理的是一个逻辑空间,这个逻辑空间就像一个大的数组,数组的每个元素就是文件系统操作的基本单位——逻辑块。
逻辑块是从0开始编号的,是连续的;逻辑块相对的是物理块。通常,EXT2的物理块占一个或几个连续的扇区。
2、超级块
超级块Block#1:(在硬盘区分中字节偏移量为1024)B1是超级块,用于容纳整个文件系统的信息
其主要记录的以下内容:
- block与inode的总量;
- 未使用与已使用的inode/block数量;
- block与inode的大小;
- 文件系统的详细信息——挂载时间、最近一次写入数据的时间、最近一次检验磁盘的时间等文件系统的相关信息等
3、块组描述符
EXT2将磁盘块分为几个组,每个组有8192个块,用一个块组描述符结构体来描述。
- Block#2:块组描述符块(硬盘上的s_first_data_block+1)
- Block#8:块位图
- Block#9:索引节点位图
二、遍历算法
- 读取超级块;
- 读取块组描述符块(1+s_first_data_block),以访问组0描述符;
- 读取InodeBeginBlock,获取/的索引节点,即INODE#2;
- 将路径名标记为组件字符串,假设组件数量为n;
- 从3中的根索引节点开始,在其数据块中搜索name[0];
- 使用索引节点号ino来定位相应的索引节点。Ino从1开始计数,使用邮差算法计算包含索引节点的磁盘块及其在该块中的偏移量;
- 由于5~6步将会重复n次,所以最好编写一个搜索函数。
三、EXT2文件系统的结构
- 第1级别:实现了基本文件系统树。用户命令程序有:mkdir,creat,mknod,rmdir,link,unlink,symlink,rm,ls,cd和pwd等;
- 第2级别:实现了文件内容读写函数;
- 第3级别:实现了文件系统的挂载、卸载和文件保护。
四、EXT2文件系统的实现
- 当前运行进程的PROC结构体。在实际系统中,每个文件操作都是由当前执行的进程决定的。每个进程都有一个cwd,指向进程当前工作目录(CWD)的内存索引节点。它还有一个文件描述符数组fd],指向打开的文件实例。
- 文件系统的根指针。它指向内存中的根索引节点。当系统启动时,选择其中一个设备作为根设备,它必须是有效的EXT2文件系统。根设备的根索引节点(inode#2)作为文件系统的根(1)加载到内存中。该操作称为“挂载根文件系统”。
- openTable条目。当某个进程打开文件时,进程fd数组的某个条目会指向openTable,openTable指向打开文件的内存索引节点。
- 内存索引节点。当需要某个文件时,会把它的索引节点加载到minode 槽中以供使用。因为索引节点是唯一的,所以在任何时候每个索引节点在内存中都只能有一个副本。在minode中,(dev,ino)会确定索引节点的来源,以便将修改后的索引节点写回磁盘。refCount字段会记录使用minode的进程数。
- dirty字段,表示索引节点是否已被修改,挂载标志表示索引节点是否已被挂载,如果已被挂载,mntabPtr将指向挂载文件系统的挂载表条目。lock字段用于确保内存索引节点一次只能由一个进程访问,例如在修改索引节点时,或者在读/写操作过程中。
- 已挂载的文件系统表。对于每个挂载的文件系统,挂载表中的条目用于记录挂载的文件系统信息,例如挂载的文件系统设备号。在挂载点的内存索引节点中,挂载标志打开,mntabPtr指向挂载表条目。在挂载表条目中,mntPointPtr指向挂载点的内存索引节点。
五、文件系统与系统项目扩展
- type.h文件:这类文件包含EXT2文件系统的数据结构类型,比如超块、组描述符、索引节点和目录条目结构。此外,它还包含打开文件表、挂载表、PROC结构体和文件系统常数。
- global.c文件:这类文件包含文件系统的全局变量。
- util.c文件:该文件包含文件系统常用的实用程序函数。最重要的实用程序函数是读/写磁盘块函数iget()、iput()和 getino()。
- mount-root.c文件:该文件包含mount_root()函数,在系统初始化期间调用该函数来挂载根文件系统。
简单的EXT2文件系统使用1KB块大小,只有一个磁盘块组它可以轻松进行以下扩展。
-
多个组:组描述符的大小为32字节对于1KB大小的块,一个块可能包含1024/32=32组描述符。32个组的文件系统大小可以扩展为32*8=256MB
-
4KB大小的块:对于4KB大小的块和一个组,文件系统大小应为4*8=32MB。对于一个组描述符块,文件系统可能有128个组,可将文件系统大小扩展到128×32=4GB,对于2个组描述符块,文件系统大小为8GB等。大多数扩展都很简单,适合用于编程项目。
-
管道文件:管道可实现为普通文件,这些文件遵循管道的读/写协议。此方案的优点是:它统一了管道和文件索引节点,并允许可被不相关进程使用的命名管道。为支持快速读/写操作,管道内容应在内存中,比如在 RAMdisk中。必要时,读者可将命名管道实现为FIFO文件。
-
I/O缓冲:在编程项目中,每个磁盘块都是接读写的。这会产生过多的物理磁盘I/O操作。为提高效率,实际文件系统通常使用一系列I缓冲区作为磁盘块的缓存内存。文件系统的IO缓冲将会在第12章中讨论,但是可把它合并到文件系统.
实践环节
- free命令:查看文件操作系统
- df(disk free):用于显示目前在Linux系统上的文件系统磁盘使用情况统计。
- du:查看目录和文件容量