虚拟文件系统Virtual File System及其作用
作者:互联网
目录
vfs(虚拟文件系统)是什么?
我们知道文件系统的种类有很多。除了Linux标准的文件系统Ext2/Ext3/Ext4外,还有很多种文件系统 。linux通过叫做VFS的中间层对这些文件系统提供了完美的支持。在大部分情况下,用户通过libc和kernel的VFS交互,不需要关心底层文件系统的具体实现。
我的理解
vfs就是对各种文件系统的一个抽象,它为各种文件系统提供了一个通用的接口,类似于c++中虚基类的作用,而每一种具体的文件系统则将其物理组织结构转换为虚拟文件系统的通用模型。
vfs的作用
根目录下的文件,对应的分区可能不一样,那么文件系统的类型(文件存储的方式)不一样
这就造成了访问文件也不同,对程序员编程访问不同分区不同类比的文件的时候就很麻烦,没办法辺统一化。
读ext4 vfat等的方法完全不一样,对我们来说开发的工作量会很大
vfs解决了这个问题
示例
例如,假设一个用户输入以下shell命令:
$ cp /floppy/TEST /tmp/test
其中/floppy是MS-DOS磁盘的一个安装点,而/tmp是一个标准的第二扩展文件系统(second Extended Filesystom, Ext2)的目录。正如左图所示,VFS是用户的应用程序与文件系统实现之间的抽象层。
因此,cp程序并不需要知道/floppy/TEST 和 /tmp/test是什么文件系统类型。
相反,cp程序直接与VFS交互,这是通过Unix程序设计人员都熟悉的普通系统调用来进行的。cp的执行代码如右图所示:
总结
作用是简化上层应用程序员的开发
不管是打开文件,还是打开硬件,都由vfs来分配
就算是ipc都是由vfs来分配的,只是分派到的是内核态中的某些服务
vfs支持的文件系统的类型
- 磁盘文件系统 这类文件系统数目最多,最常见:ext2/ext3/ext4文件系统(关注重点)
- 特殊文件系统。如/proc文件系统
- 网络文件系统,如NFS
VFS存在的意义
- 向上,对应用层提供一个标准的文件操作接口;
- 对下,对文件系统提供一个标准的接口,以便其他操作系统的文件系统可以方便的移植到Linux上;
通用文件模型
前面提过vfs所隐含的思想是把表示很多不同种类文件系统的共同信息放入内核,vfs通过引入一个通用文件模型来表示所有支持的文件系统。
要实现每个具体的文件系统,必须将其物理组织结构转换为虚拟文件系统的通用文件模型。
通用文件模型由下列对象类型组成:
- 超级块对象(superblockobject):存放已安装文件系统的有关信息。对基于磁盘的文件系统,这类对象通常对应于存放在磁盘上的文件系统控制块(filesystemcontrol block)。
- 索引节点对象(inodeobject):存放关于具体文件的一般信息。对基于磁盘的文件系统,这类对象通常对应于在磁盘上的文件控制块(file controlblock)。每个索引节点对象都有一个索引节点号,这个节点号唯一地标识文件系统中的文件。
inode由两个主要部分组成:
1、描述文件状态的元数据,文件元数据包括文件大小,权限,类型,时间;
2、文件数据描述,则用来定义文件数据在磁盘上的存放位置。 - 文件对象(file object):存放打开文件与进程之间进行交互的有关信息。这类信息仅当进程访问文件期间在于内核内存中。
- 目录项对象(dentry
object):存放目录项(也就是文件的特定名称)与对应文件进行链接的有关信息。每个磁盘文件系统都以自己特有的方式将该类信息存在磁盘上。底层文件系统的许多操作严重依赖文件的inode,在进行文件操作前,我们需要根据路径名找到文件对应的inode。我们知道文件系统是树状结构的,因此需要从根目录通过目录树找到要操作的文件或目录,这个遍历过程涉及到磁盘操作,非常耗时。根据局部性原理,很有必要把这个查找过程cache起来,dentry就是为了加快目录遍历操作引入的数据结构。
(第一次看到这些概念,可能你也很懵逼,很正常,后面看了具体的数据结构代码可能会好点)
实例
下图所示是一个简单的示例,说明进程怎样与文件进行交互。
三个不同进程已经打开同一个文件,其中两个进程使用同一个硬链接(我觉得是打开同一路径名文件)。在这种情况下,其中的每个进程都使用自己的文件对象,但只需要两个目录项对象,每个硬链接对应一个目录项对象。这两个目录项对象指向同一个索引节点对象,该索引节点对象标识超级块对象,以及随后的普通磁盘文件。
链接
https://blog.csdn.net/qq_28258885/article/details/110631562
参考我写的博客
注意的地方
在处理文件时,应用空间和内核空间使用的对象是不同的。对应用程序来说,文件描述符用来表示一个文件,这个文件描述符是打开文件时内核分配给这个文件的一个整数,注意,这个文件描述符只在本进程内有效;而对于内核来说,则使用一个inode来表示一个文件,这个inode可能对应着应用层多个进程内的多个文件描述符。
文件在内核内存中是由一个file数据结构来表示的。这种数据结构中包含一个称为f_op的字段,该字段中包含一个指向所访问文件的函数指针,当然还包括读文件的函数。sys_read()查找到指向该函数的指针,并调用它。这样一来,应用程序的read()就被转化为相对间接的调用:file->f_op->read(…);
与之类似,write()操作也会引发一个与输出文件相关的Ext2写函数的执行。简而言之,内核负责把一组合适的指针分配给与每个打开文件相关的file变量,然后负责调用针对每个具体文件系统的函数(由f_op字段指向)。
标签:文件,对象,System,Virtual,文件系统,内核,File,磁盘,vfs 来源: https://blog.csdn.net/qq_28258885/article/details/110633338