虚拟文件系统VFS

现代操作系统必须同时支持多个文件系统,操作系统如何将多个文件系统整合成一个目录结构?用户如何在访问文件系统空间时可以无缝地在文件系统类型之间移动呢?

绝大多数操作系统包括UNIX都使用面向对象技术来简化、组织和模块化实现过程,使用这些方法允许不同文件系统类型可通过同样结构来实现,这也包括了网络文件系统类型如NFS,这样用户可以轻松的访问位于本地磁盘的多个文件系统类型,甚至位于网络上的文件系统

NFS(Network FileSystem)文件系统,它的最大功能是可以通过网络让不同的机器,不同的操作系统彼此共享文件(sharefiles)——可以通过NFS挂载远程主机的目录,访问该目录就像访问本地目录一样

文件系统的实现主要分为三个主要层次

第一层为文件系统接口

包括open()、read()、write()和close()调用以及文件描述符

这里写图片描述

第二层称为虚拟文件系统(VFS)层

虚拟文件系统(Virtual File System)是 Linux 内核中的一个软件层,用于给用户空间的程序提供文件系统接口,系统中所有的文件系统不但依赖 VFS 共存,而且也依靠 VFS 协同工作。为了能够支持各种实际文件系统,VFS 定义了所有文件系统都支持的基本的、概念上的接口和数据 结构,同时实际文件系统也提供 VFS 所期望的抽象接口和数据结构,将自身的诸如文件、目录等概念在形式 上与VFS的定义保持一致。换句话说,一个实际的文件系统想要被 Linux 支持,就必须提供一个符合VFS标准 的接口,才能与 VFS 协同工作。实际文件系统在统一的接口和数据结构下隐藏了具体的实现细节

  • VFS层通过定义一个清晰的VFS接口,以将文件系统的通用操作和具体实现分开,多个VFS接口的实现可以共存在同一台机器上,它允许访问已安装在本地的多个类型的文件系统
  • VFS提供了在网上上唯一标识一个文件的机制。VFS基于称为vnode的文件表示结构,该结构包括一个数值标识符以表示位于整个网络范围内的唯一文件(UNIX 索引结点inode在文件系统内是唯一的),该网络范围的唯一性用来支持网络文件系统。内核中为每个活动结点(文件或目录)保存一个vnode结构

VFS能区分本地文件和远程文件,根据文件系统类型可以进一步区分不同本地文件

VFS可以根据文件系统类型调用特定的文件类型操作以处理本地请求,通过调用NFS协议程序来处理远程请求,文件句柄可以从相应的vnode中构造,并作为参数传递给程序

第三层实现文件系统类型或远程文件系统协议

下面在看下关于Linux中VFS的结构,VFS主要定义的4种主要对象类型如下所示

  • 索引节点对象(inode object),表示一个单独的文件
  • 文件对象(file object),表示一个打开的文件
  • 超级块对象(superblock object),表示整个文件系统
  • 目录条目对象(dentry object),表示一个单独的目录条目

VFS对每种类型的对象都定义了一组必须实现的操作。这些类型的每一个对象都包含了一个指向函数表的指针。函数表列出了对象的操作函数,下面就看下对文件对象中定义的一些函数

  • int open(…):打开一个文件
  • ssize_t read(…):读文件
  • ssize_t write(…):写文件
  • int mmap(…):内存映射一个文件

一个特定文件类型的文件对象必须要去实现文件对象定义中的每个函数,VFS可以通过调用对象函数表中的合适函数来对对象进行操作,而不需要事先知道对象的实现类型也就是说VFS不关心一个索引点代表的是一个磁盘文件、一个目录文件、还是一个远程文件,实现read操作的合适函数总是被放在函数表中的相同位置,VFS软件层调用这些函数,而不关心数据是如何读取的