浅谈虚拟文件系统

承上篇博文,我们今天也把虚拟文件系统唠嗑唠嗑。

虚拟文件系统

我们还是来回答两个问题:1.什么是虚拟文件系统? 2. 虚拟文件系统存在的意义。

什么是虚拟文件系统?

Linux将文件系统分为具体文件系统虚拟文件系统这两层。虚拟文件系统(VFS,Virtual File System)为用户空间程序提供了文件和文件系统相关接口。

VFS设计的关键思想是:抽象出所有文件系统都共有的部分,并且将这部分代码单独放在一层,该层调用底层的实际文件系统来具体管理数据。从用户的角度来看,只用一个文件系统层级,事实上它们是由多种(并不相容的)文件系统组成,对于用户和进程来说是不可见的。

严格说来,VFS并不是一种实际的文件系统。它只存在于内存中,不存在于任何外存空间。VFS在系统启动时建立,在系统关闭时消亡。

虚拟文件系统存在的意义

VFS使得用户可以直接使用open(),read()和 write()这样的系统调用而无须考虑具体文件系统和实际的物理介质。而且VFS的存在使得系统调用可以在这些不同的文件系统和介质之间执行,比如:我们可以使用标准的系统调用从一个文件系统拷贝或移动数据到另一个文件系统。

简单来说:VFS本质上是一个胶水层,位于内核的底层与用户层之间。它提供了各种抽象数据结构来表示文件和inode。而真实的文件系统必须填充这些结构,使得应用程序无需去考虑底层文件系统,总是可以使用同向的接口访问和操作文件。

VFS对象及其数据结构

VFS采用的是面向对象的设计思路,使用一组数据结构来代表通用文件对象。

VFS中的四个主要对象类型:

  1. 超级块对象(struct super_block),它代表一个具体的已安装文件系统(每个文件系统都必须实现超级块对象)。该对象用于存储特定文件系统的信息,通常存放在磁盘特定扇区中的文件系统超级块或文件控制块。
  2. 索引节点对象struct inode), 它代表一个具体文件。索引节点对象包含了内核在操作文件或目录时需要的全部信息。
  3. 目录项对象(struct dentry),它代表一个目录项,是路径的一个组成部分。VFS把目录当做文件对待,所以在路径/bin/vi中,bin和vi都属于文件,而bin是特殊的目录文件而vi只是一个普通的文件, 路径中的每个组成部分都由一个索引节点对象表示。虽然它们可以统一由索引节点表示,但是VFS经常需要执行目录相关操作,比如路径名查找等。路径名查找需要解析路径中的每一个组成部分,不但确保它有效,而且还需要再进一步寻找路径中的下一个部分,为了方便查找,VFS引入了目录项的概念。
  4. 文件对象(struct file),它代表由进程打开的文件。文件对象是已经打开的文件在内存中的表示,该对象是由相应的open()系统调用创建,由close()系统调用撤销,所有执行诶文件的相关调用实际上都是文件操作表中定义的方法。因为多个进程可以同时打开和操作同一文件,所以同一个文件也可能存在多个对应的文件对象。文件对象仅仅在进程观点上代表已打开的文件,它反过来指向目录项对象,其实只有目录项对象才表示已打开的实际文件。

Linux中的文件系统

Unix使用了四种和文件系统相关的传统抽象概念:文件、目录项、索引节点和安装点(mount point)。

文件系统存放于磁盘上(VFS是在系统启动的时候被加载到内存中)。多数磁盘划分为一个或多个分区,每个分区中都有一个独立的文件系统。磁盘的0号扇区称为主引导记录(Master Boot Record, MBR),用来引导计算机。在MBR的结尾是分区表。该表给出了每个分区的骑士和结束地址。表中的一个分区被标记位活动分区。在计算机被引导时,BIOS读入并执行MBR。MBR做的第一件事就是确定活动分区,它读入的第一个块,被称为引导块

引导块中的程序将装载该分区中的操作系统。除了引导块之外,第一个分区是超级块(VFS中也有这个概念),超级块包含文件系统的所有关键参数,在计算机启动时,或则在该文件首次使用时,超级块会被读入内存。超级块中的典型信息包括:确定文件系统类型用的魔数,文件系统中的块的数量以及其他重要的管理信息。

接着是文件系统空闲块的信息,再后面也许跟着是一组i节点,接着可能是根目录,它存放文件系统目录树的根部。最后,磁盘的其他部分存放了其他所有目录和文件。

unix系统将文件的相关信息文件本身这两个概念进行了严格的区分,例如访问控制权限、大小、拥有者、创建事件等信息。文化相关信息,有时被称作文件的数据元(文件的相关数据),被存储在一个单独数据结构中,有时被称为索引节点(inode,index node的缩写)。

硬链接和软连接

硬链接:和普通文件一样,都是指向磁盘上同样的位置,inode相同,当某个文件的data block增加了一个硬链接指向其inode的计数也会随之加1。

软链接:类似于Windows上的快捷方式,创建软连接时会产生新的文件,新建inodedata blockdata block的内容是源文件的路径和文件名。

硬链接与软链接的区别:

  • 硬链接不能跨文件系统创建链接,而且不能对目录创建,删除一个硬链接并不会影响其他拥有相同inode号的文件。
  • 软链接本质上就是一个普通的文件,只是数据块的内容特殊罢了。软链接是可以跨文件系统进行创建链接的,并且是可以对文件或目录创建,创建软连接时,源文件的inode的计数并不会增加。

一切皆文件

无论是普通的文件,还是特殊的目录、设备等,VFS都将它们同等看待成文件,通过同一套文件操作界面来对它们进行操作。操作文件时需先打开;打开文件时,VFS会知道该文件对应的文件系统格式;当VFS把控制权传给实际的文件系统时,实际的文件系统再做出具体区分,对不同的文件类型执行不同的操作。这也就是“一切皆是文件”的根本所在。

参考
《Linux内核设计与实现》原书第三版
《现代操作系统》原书第四版