1.综述
linux虚拟文件系统(vfs)是一种管理文件系统的抽象层,它通过在内核中实现一组统一的文件系统接口和数据结构,使不同的文件系统具有一致的接口和行为,从而实现各个文件系统之间的可互用性。其中还包括一些虚拟文件的特殊类型,如/proc(描述进程信息和状况)/sys(描述系统信息和硬件信息)等,虚拟文件系统为不同格式的文件系统交互提供了方便,例如:在linux系统中执行cp命令将ext4文件系统上的内容拷贝到U盘(FAT文件系统)
2 vfs的实现原理
VFS提供了标准的文件操作接口,如open、read、write、seek等函数。这些函数在调用时会根据文件的类型(如普通文件、目录文件、字符设备等)分别调用相应的文件系统驱动程序来进行处理。
2.1 VFS将所有的文件系统都看作是一个树形结构,以根节点为起点向下展开,每个节点代表一个文件或目录。不同类型的文件系统有不同的挂载点和根目录,但它们都遵循VFS定义的规范,因此可以在同一棵树中共存,数据结构是引用链和图。
2.2 VFS提供了虚拟文件系统操作层(VOP),它通过一系列的回调函数来实现文件系统的各种操作,如创建文件、删除文件、读取目录等。这些回调函数是由不同类型的文件系统驱动程序来实现的,因此可以根据需要对其进行扩展和定制。
2.3 VFS还提供了一组虚拟文件系统对象(Vnode),用于表示文件系统中的一个节点。每个Vnode对象包含一个指向对应文件系统驱动程序的指针,并且具有与文件系统操作相关的状态信息,如文件打开标志、文件大小、访问时间等。
2.4 VFS通过一系列的系统调用函数来与用户空间交互,如open、read、write等。这些系统调用函数将用户请求转换为VFS定义的标准操作接口,并且将其传递给相应的文件系统驱动程序进行处理。通过这种方式,用户可以方便地进行文件和目录管理,而无需考虑底层文件系统的具体实现细节。
3.虚拟文件系统的一系列操作实际是通过对四个对象(super_block,inode,dentry,file)一系列操作来实现的。
超级块(Superblock)
:存放系统中已安装文件系统的有关信息,其中数据结构如下:文件索引节点(inode)
:存放关于具体文件的一般信息。- typedef uint32_t inode_num_t; //unique within a filesystem
- Map<string,inode_num_t> dirs //map file path to inode number
- Map<inode_num_t,string> files //map inode number to content
- Map<inode_num_t,File> files //each inode is a file <多个文件可以指向同一个inode,例如dirA/dirB/.. dirA/dirC/.. inode相同的链接叫做硬链接>
目录项对象(dentry)
:存放目录项与对应文件进行链接的信息。文件对象(file)
:存放打开文件与进程之间进行交互的有关信息。
3.1 超级块(Superblock)
内核在对一个文件系统进行初始化和注册时 在内存为其 分配一个超级块 。此时的超级块为 VFS 超级块 。也就是说,VFS 超级块是各种具体文件系统在安装时建立的,并在这些文件系统卸载时被自动删除。 VFS 超级块只存放在内存中 。
对于每个具体的文件系统来说,都有各自的超级块,如 Ext2 超级块和 Ext3 超级块,它存放在磁盘上,内容包括:文件系统的大小、空闲块数目、空闲块索引表、空闲i节点数目、空闲i节点索引表、封锁标记等。超级块是系统为文件分配存储空间、回收存储空间的依据。这一部分的拓扑结构如下图:
其中Block Group
存储的各部分含义如下:
- indoe bitmap (indoe对照表): 用来记录当前文件系统的indoe哪些是已经使用的,哪些又是未使用的。
- block bitmap (块对照表): 用来记录当前文件系统哪些block已经使用,哪些又是未使用的。
- inode table (inode 表格):inode是用来记录文件的属性以及该文件实际数据所在的block的号码。
- GDT(Global Descriptor Table):用来描述每个block group开始和结束的block号码以及每个区段位于哪一个block号码之间。相当于文件系统描述的是每个block group的信息。
- data blocks:数据块,用于存放数据