操作系统 (15) 目录与文件系统

275 阅读5分钟

本文引用代码及图片均来自 李治军: 操作系统32讲

目录树

操作系统 (14) 磁盘的使用 中提到文件在用户眼中是文本、图像和视频等形式,在操作系统看来则是磁盘中盘块的集合,对文件的所有操作最终都转化为对磁盘扇区的操作。为了方便用户对磁盘进行操作,操作系统抽象出文件的概念,为文本、图像、设备等建立统一的文件视图

使用文件首先得打开文件,在用户眼中文件在磁盘有序存放,只需给出路径+文件名即可打开文件

file = open('/var/temp/test.txt')

实际上磁盘只是存放了一堆盘块,操作系统需要找到文件所对应的盘块集合。操作系统使用inode记录文件内容和物理盘块的对应关系,因此只需找到文件inode即可。系统中有大量文件因此也会有大量inode,为了高效查找inode,需要将其组织成一定的形式,对于查找来说树状结构无疑是一个合适的选择,因此也就诞生了所谓的目录树

image.png

目录树是一棵节点为inode的树,系统打开文件主要就是在目录树中找到对应的inode节点

值得一提的是,目录也是一种文件(linux中一切皆文件)也有inode,它位于目录树中。不过与普通文件不同的是,目录文件中记录的不是文件内容而是目录项,目录项记录它所包含的文件或目录的名称以及对应的inode地址

查找目录树时从根目录入手,遍历根目录的目录项找到第一层目录的文件名以及对应的inode地址,然后取出inode并在其中进行第二层目录的查找,依此类推直到最后找到文件

image.png

实际上磁盘按照一定的格式组织所有的盘块,如上图中磁盘将一部分盘块用于存储所有文件的inode组成的数组,一部分盘块用于存储文件内容

根目录的inode固定在数组第一个位置,可是数组的第一个位置又在哪里呢?当然会有某个地方记录它,接着便引出下面的存储结构:

image.png

引导块,通常用于计算机启动时引导系统,可以参考 操作系统(1) 系统的启动

超级块,超级块存放了整个磁盘的全局信息包括文件格式、磁盘大小、各部分大小等,这些信息可以描述整个文件系统,其中i节点数组的起始位置就存放在超级块中。超级块的内容会被加载进内存且随着磁盘文件的创建、删除等操作而更新,内容会被定期更新回磁盘。因为超级块的内容关乎整个文件系统,所以一般都在磁盘中有备份

i节点位图和盘块位图,用于记录数组中inode节点的空闲情况和盘块的空闲情况,比如某个盘块空闲那么对应的盘块位图的那一个bit就是0,否则为1

i节点数组和盘块区就如前面所提到的那样,不再赘述,前面提到的目录项记录inode地址其实就是记录了inode在数组中的索引

我们把硬盘拔下来接入到另一台计算机,系统能够识别出磁盘并使用其中的文件就是因为磁盘总是按照一定的格式来组织盘块的,比如我们格式化硬盘的时候可以选择盘块大小,文件系统(NTFS,EXT4等)等设定,然后系统就根据设定在磁盘中构造上面提到的各种块

image.png

最后,在补上了打开文件的过程之后,结合上一篇文章来看,用户从打开文件到最后读写磁盘扇区的流程可以总结为下图:

image.png

代码实现

看看open的代码实现中是如何解析目录找到inode

image.png

open一路往下最终调用get_dir获取inode

image.png

get_dir中先判断是绝对路径相对路径并获取根目录或当前目录的inode,然后从获取的inode开始往下找。find_entry用于获取inode中保存的目录项inr保存目录项中下层目录或文件的inode在数组中的索引,然后使用iget获取下一层目录或文件对应的inode,获得inode后重新开始循环直到找到目标文件

代码来源: Bootlin

image.png

get_dirPCB中为什么直接可以获取到根目录的inode呢?可以参考 操作系统 (14) 磁盘的使用 ,其实也是从init进程中继承来的

image.png

find_entry首先在inode直接索引块(直接记录了逻辑盘块对应哪个物理盘块)里找目录项,如果没找到就会到一级索引块甚至二级索引块中找直到找到和目录或文件名对应的目录项

代码来源: Bootlin

image.png

iget首先获取一块空闲空间用于将磁盘中的inode数据读入内存,然后调用read_inode读取数据,read_inode先获取超级块中的数据,计算出目录项中索引对应的inode的位置并获取inode

image.png

上图中2引导块超级块占用的盘块数,然后加上inode位图盘块位图的长度,再换算每个盘块存几个inode之类的数据得出应该读取哪个盘块,读取出盘块后因为每个盘块保存多个inode,还得根据索引再计算一次得出目标inode的具体位置才能获得正确的inode

至此,open如何解析目录获取文件inode的流程便清晰了

参考文献