什么是vfs以及vfs的作用

vfs(虚拟文件系统)是什么?

我们知道文件系统的种类有很多。除了Linux标准的文件系统Ext2/Ext3/Ext4外,还有很多种文件系统 。linux通过叫做VFS的中间层对这些文件系统提供了完美的支持。在大部分情况下,用户通过libc和kernel的VFS交互,不需要关心底层文件系统的具体实现。

我的理解,vfs就是对各种文件系统的一个抽象,它为各种文件系统提供了一个通用的接口,类似于c++中虚基类的作用,而每一种具体的文件系统则将其物理组织结构转换为虚拟文件系统的通用模型。

vfs的作用

vfs所隐含的思想是把表示很多不同种类文件系统的共同信息放入内核;其中有一个字段或函数来支持Linux所支持的所有实际文件系统所提供的任何操作。对所调用的每个读、写或其他函数,内核都能把它们替换成支持本地Linux文件系统、NTFS文件系统,或者文件所在的任何其他文件系统的实际函数。

有了vfs,就能很容易实现不同文件系统之间的数据读写,因为它们对外接口都是一样的,都是vfs导出的通用接口。
以下ulk3书上的例子:
例如,假设一个用户输入以下shell命令:
$ cp /floppy/TEST /tmp/test

其中/floppy是MS-DOS磁盘的一个安装点,而/tmp是一个标准的第二扩展文件系统(second Extended Filesystom, Ext2)的目录。正如图(a)所示,VFS是用户的应用程序与文件系统实现之间的抽象层。因此,cp程序并不需要知道/floppy/TEST 和 /tmp/test是什么文件系统类型。相反,cp程序直接与VFS交互,这是通过Unix程序设计人员都熟悉的普通系统调用来进行的。cp的执行代码如图(b)所示:
这里写图片描述

vfs支持的文件系统的类型

  1. 磁盘文件系统 这类文件系统数目最多,最常见:ext2/ext3/ext4文件系统(关注重点)
  2. 特殊文件系统。如/proc文件系统
  3. 网络文件系统,如NFS

VFS存在的意义

  • 向上,对应用层提供一个标准的文件操作接口;
  • 对下,对文件系统提供一个标准的接口,以便其他操作系统的文件系统可以方便的移植到Linux上;

通用文件模型

前面提过vfs所隐含的思想是把表示很多不同种类文件系统的共同信息放入内核,vfs通过引入一个通用文件模型来表示所有支持的文件系统。要实现每个具体的文件系统,必须将其物理组织结构转换为虚拟文件系统的通用文件模型。

通用文件模型由下列对象类型组成:

  • 超级块对象(superblock object):存放已安装文件系统的有关信息。对基于磁盘的文件系统,这类对象通常对应于存放在磁盘上的文件系统控制块(filesystem control block)。
  • 索引节点对象(inode object):存放关于具体文件的一般信息。对基于磁盘的文件系统,这类对象通常对应于在磁盘上的文件控制块(file control block)。每个索引节点对象都有一个索引节点号,这个节点号唯一地标识文件系统中的文件。
    inode由两个主要部分组成:
    1. 描述文件状态的元数据,文件元数据包括文件大小,权限,类型,时间;
    2. 文件数据描述,则用来定义文件数据在磁盘上的存放位置。
  • 文件对象(file object):存放打开文件与进程之间进行交互的有关信息。这类信息仅当进程访问文件期间在于内核内存中
  • 目录项对象(dentry object):存放目录项(也就是文件的特定名称)与对应文件进行链接的有关信息。每个磁盘文件系统都以自己特有的方式将该类信息存在磁盘上。底层文件系统的许多操作严重依赖文件的inode,在进行文件操作前,我们需要根据路径名找到文件对应的inode。我们知道文件系统是树状结构的,因此需要从根目录通过目录树找到要操作的文件或目录,这个遍历过程涉及到磁盘操作,非常耗时。根据局部性原理,很有必要把这个查找过程cache起来,dentry就是为了加快目录遍历操作引入的数据结构。

(第一次看到这些概念,可能你也很懵逼,很正常,后面看了具体的数据结构代码可能会好点)
下图所示是一个简单的示例,说明进程怎样与文件进行交互。
这里写图片描述
三个不同进程已经打开同一个文件,其中两个进程使用同一个硬链接(我觉得是打开同一路径名文件)。在这种情况下,其中的每个进程都使用自己的文件对象,但只需要两个目录项对象,每个硬链接对应一个目录项对象。这两个目录项对象指向同一个索引节点对象,该索引节点对象标识超级块对象,以及随后的普通磁盘文件。

链接

软链接

软链接又称为符号链接,软链接文件内容指向一个文件路径,也就是文件真实位置,软链接指向的文件也可以是软链接。

硬链接

硬链接是两个文件共享同一个inode。

注意的地方

在处理文件时,应用空间和内核空间使用的对象是不同的。对应用程序来说,文件描述符用来表示一个文件,这个文件描述符是打开文件时内核分配给这个文件的一个整数,注意,这个文件描述符只在本进程内有效;而对于内核来说,则使用一个inode来表示一个文件,这个inode可能对应着应用层多个进程内的多个文件描述符。
文件在内核内存中是由一个file数据结构来表示的。这种数据结构中包含一个称为f_op的字段,该字段中包含一个指向所访问文件的函数指针,当然还包括读文件的函数。sys_read()查找到指向该函数的指针,并调用它。这样一来,应用程序的read()就被转化为相对间接的调用:file->f_op->read(…);
与之类似,write()操作也会引发一个与输出文件相关的Ext2写函数的执行。简而言之,内核负责把一组合适的指针分配给与每个打开文件相关的file变量,然后负责调用针对每个具体文件系统的函数(由f_op字段指向)。

  • 12
    点赞
  • 55
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值