linux 虚拟文件系统VFS


与其它系统完美共存是linux的成功之处之一,linux可以透明挂载其它系统文件格式的磁盘或分区,如Windows的FAT32、NTFS等;


linux使用虚拟文件系统VFS(Virtual Filesystem Switch)来支持多种类型的文件系统。
VFS的思想是:将不同类型文件系统信息存放到内核中,linux所有文件系统支持的每个操作都有一个域与之对应,当读、写或其它功能调用时内核将该域替换成具体文件系统的操作。
如ext4_file_open表示EXT4文件打开操作,ntfs_file_open表示NTFS文件打开操作;域open表示所有文件系统的文件打开操作,在打开EXT4文件系统文件时将open替换成ext4_file_open,在打开NTFS文件系统文件时将open替换成ntfs_file_open;这样就能实现统一接口open打开不同格式文件系统的文件。

 

I.VFS作用
VFS提供不同文件系统的统一接口,将文件系统相关的系统调用与具体文件系统操作分开,系统调用通过VFS来操作具体文件系统的文件。

如,使用以下命令:

$ cp /floppy/TEST /tmp/test

/floppy是MS-DOS盘的挂载点,/tmp是EXT2目录;因为VFS是系统调用(应用程序)与文件系统实现之间的抽象层,所以cp不需要知道/floppy/TEST与/tmp/test的文件系统类型,只会与VFS交互。
VFS在文件拷贝过程中作用如下图:
linux 虚拟文件系统VFS_第1张图片

 

i.通用文件模型
VFS使用通用文件模型来表示所有的文件系统,所有文件系统的实现都必须将自己的物理结构转换成VFS通用文件模型。
例如,通用文件模型将目录当作内容是一系统文件和目录的文件;但是,有些非UNIX文件系统使用FAT来存储文件在目录树中的位置,这些文件系统中目录不是文件;为了遵循通用文件模型,基于FAT的文件系统必须构造目录对应的文件(这些文件只存在内核内存中)。

 

内核不能硬编码某个函数来处理read,ioctl等操作,必须使用指针指向具体文件系统相应的函数,来实现这些操作。
如系统调用read,内核会调用sys_read;进而会调用file的读操作,file->f_op->read(...),而f_op就是指向具体文件系统文件操作的指针,这样就能使用统一的文件系统接口来操作文件。
有些情况,VFS自己就能完成文件操作,而不需要依赖底层具体的文件系统;如关闭打开的文件,VFS只需要释放内存中的file对象,而不需要磁盘文件操作;同样,lseek只是改变file对象中的指针,也不需要磁盘文件操作。所以可以把VFS当做通用文件系统,如有必要VFS才会使用具体的文件系统。

 

可以把通用文件模型视作是面向对象的,使用包含数据与函数指针的结构体来实现面向对象编程。
通用文件模型主要有以下对象类型:
superblock:保存挂载的文件系统信息;基于磁盘的文件系统,superblock通常对应磁盘上的文件系统控制块
dentry:保存目录项与文件的关联信息;基于磁盘的文件系统,使用不同的方式保存该信息
inode:保存文件的信息;基于磁盘的文件系统,inode通常对应文件控制块;每个inode有一个唯一的inode number,用来标识文件系统中的文件。
file:保存进程与打开文件的交互信息;只有在进程打开文件时,内核内存中才会有file对象
下图阐述进程操作文件时这几种对象之间的关系:

linux 虚拟文件系统VFS_第2张图片

三个进程打开了相同的文件,有两个硬连接指向该文件(两个目录项指向该文件),其中两个进程使用其中一个硬连接,另一进程使用另外一个硬连接。
每个进程使用自己的file对象,2个硬连接使用2个dentry对象,2个dentry使用同一个inode;inode标识出superblock,并与superblock一起标识出磁盘文件。

 

ii.缓存加速
VFS除了提供统一的文件系统接口外,同时在系统性能上也有重要作用。
1.将最近使用的dentry对象放在dentry缓存中,来加速文件的查找;
2.将文件内容保存在页缓存中,来加速文件操作;

 

 

II.VFS数据结构
VFS对象保存在相应的数据结构中,既包含对象属性,也包含对象方法列表指针;内核会动态修改对象方法列表指针,进而实现对象的多态。
下图是VFS涉及的主要对象结构及它们之间的关系:

linux 虚拟文件系统VFS_第3张图片

你可能感兴趣的:(linux 虚拟文件系统VFS)