Linux 核心--10.文件系统( 五 )


图9.4 虚拟文件系统的逻辑示意图

图9.4给出了Linux核心中虚拟文件系统和实际文件系统间的关系 。此虚拟文件系统必须能够管理在任何时刻mount到系统的不同文件系统 。它通过维护一个描叙整个虚拟文件系统和实际已安装文件系统的结构来完成这个工作 。

容易让人混淆的是VFS使用了和EXT2文件系统类似的方式:超块和inode来描叙文件系统 。象EXT2 inode一样 VFS inode描叙系统中的文件和目录以及VFS中的内容和拓扑结构 。从现在开始我将用VFS inode和VFS超块来将它们和EXT2 inode和超块进行区分 。

文件系统初始化时将其自身注册到VFS中 。它发生在系统启动和操作系统初始化时 。这些实际文件系统可以构造到核心中也可以设计成可加载模块 。文件系统模块可以在系统需要时进行加载,例如VFAT就被实现成一个核心模块,当mount VFAT文件系统时它将被加载 。mount一个基于块设备且包含根文件系统的文件系统时,VFS必须读取其超块 。每个文件系统类型的超块读取例程必须了解文件系统的拓扑结构并将这些信息映射到VFS超块结构中 。VFS在系统中保存着一组已安装文件系统的链表及其VFS超块 。每个VFS 超块包含一些信息以及一个执行特定功能的函数指针 。例如表示一个已安装EXT2文件系统的超块包含一个指向EXT2相关inode读例程的指针 。这个EXT2 inode读例程象所有文件系统相关读例程一样填充了VFS inode中的域 。每个VFS超块包含此文件系统中第一个VFS inode的指针 。对于根文件系统此inode表示的是"/"目录 。这种信息映射方式对EXT2文件系统非常有效但是对其它文件系统要稍差 。

系统中进程访问目录和文件时将使用系统调用遍历系统的VFS inode 。

例如键入ls或cat命令则会引起虚拟文件系统对表示此文件系统的VFS inode的搜寻 。由于系统中每个文件与目录都使用一个VFS inode来表示,所以许多inode会被重复访问 。这些inode被保存在inode cache中以加快访问速度 。如果某个inode不在inode cache中则必须调用一个文件系统相关例程来读取此inode 。对这个inode 的读将把此它放到inode cache中以备下一次访问 。不经常使用的VFS inode将会从cache中移出 。

所有Linux文件系统使用一个通用buffer cache来缓冲来自底层设备的数据以便加速对包含此文件系统的物理 设备的存取 。

这个buffer cache与文件系统无关并被集成到Linux核心分配与读写数据缓存的机制中 。让Linux文件系统独立于底层介质和设备驱动好处很多 。所有的块结构设备将其自身注册到Linux核心中并提供基于块的一致性异步接口 。象SCSI设备这种相对复杂的块设备也是如此 。当实际文件系统从底层物理磁盘读取数据时,块设备驱动将从它们所控制的设备中读取物理块 。buffer cache也被集成到了块设备接口中 。当文件系统读取数据块时它们将被保存在由所有文件系统和Linux核心共享的全局buffer cache中 。这些buffer由其块号和读取设备的设备号来表示 。所以当某个数据块被频繁使用则它很可能能从buffer cache而不是磁盘中读取出来,后者显然将花费更长的时间 。有些设备支持通过预测将下一次可能使用的数据提前读取出来 。

VFS还支持一种目录cache以便对经常使用的目录对应的inode进行快速查找 。我们可以做一个这样的实验,首先我们对一个最近没有执行过列目录操作的目录进行列目录操作 。第一次列目录时你可能发现会有较短的停顿但第二次操作时结果会立刻出现 。目录cache不存储目录本身的inode;这些应该在inode cache中,目录cache 仅仅保存全目录名和其inode号之间的映射关系 。

推荐阅读