虚拟文件系统
虚拟文件系统VFS是Linux内核的一个子系统,提供了一个通用文件系统模型,该模型概括了所能见到的文件系统常用功能和行为,并为应用程序提供一致性的文件系统接口
虚拟文件系统分为三层
- 应用层:VFS使得用户可以直接使用标准UNIX文件系统调用来操作文件,无需考虑具体文件系统特性和物理存储介质。
- 虚拟层:在对所有具体文件系统的共同特性进行抽象的基础上,形成一个与具体文件系统实现无关的虚拟层,并在此层次上定义与用户的一致性接口。
- 实现层:使用 类似开关表技术进行具体文件系统转接,实现各种具体文件系统的细节。
这个模型是对要支持的文件系统的一种抽象,对于UNIX系列的,直接就可以很好地支持;对于没有目录文件的文件系统,比如FAT系列,Linux需要能够快速建立对应于目录的文件
VFS数据对象类型
描述各对象的数据结构
- 超级块对象super_block
- 索引节点对象inode
- 文件对象file
- 目录项对象dentry
超级块对象super_block 代表一个文件系统。存放已安装的文件系统的信息,如果是基于磁盘的文件系统,该对象对应于存放在磁盘上的文件系统控制块,每个文件系统对应一个超级控制块
超级块对象
struct super_block {
struct list_head s_list; /*文件系统链表*/
kdev_t s_dev; /*设备标识符*/
unsigned long s_blocksize; /*文件系统的块大小*/
unsigned char s_blocksize_bits; /*块大小的位数*/
unsigned char s_dirt; /*文件系统修改标志*/
unsigned long long s_maxbytes; /* 最大文件大小*/
struct file_system_type *s_type; /*文件系统类型*/
struct super_operations *s_op; /*超级块的操作函数集合*/
struct dquot_operations *dq_op; /*文件系统的其他操作函数集合*/
...
void *s_fs_info /*各个具体文件系统私有的数据结构*/
struct list_head s_files /*分配给超级块的文件对象链表*/
};
所有超级块对象由循环双链表组成,首元素s_list
超级块操作在s_op中
索引节点对象inode
(1)inode对象包含了内核在操作文件或目录时需要的全部信息,文件名可以更改,inode对文件是唯一的,随文件的存在而存在。
(2)inode 信息可以从磁盘inode直接读入VFS的inode 对象中,如果一个文件系统没有inode 信息,文件系统必须从磁盘上提取这些信息,构造它的inode 。
分为三类,每一类均组织成双向循环链表,由inode.i_list连接
- 未使用的索引节点
- 正在使用的索引节点
- 脏索引节点
索引节点对象组织成inode_hashtable散列表,冲突的节点组成链表,由inode.i_hash连接
目录项对象dentry
代表路径的一个组成部分。存放目录项与对应文件进行链接的各种信息。VFS把最近最常使用的 dentry对象放在目录项高速缓存中,加快文件路径名搜索过程。
- 目录项用于建立与索引节点的联系,在磁盘上没有映像
目录项对象的四种状态
- 空闲:未关联索引节点
- 未使用:关联索引节点,但未被内核使用
- 正在使用:关联索引节点,且正被使用
- negative:关联的索引节点不存在
文件对象file 代表进程已打开的一个文件。存放已打开的文件与进程的交互信息,这些信息仅当进程访问文件期间才存于主存中。文件对象在执行open()时创建,执行系统调用close()时撤销。
文件系统缓存机制
VFS i_node 缓存
散列技术: 根据文件系统所在的超级块和i_node号计算出每个已分配的i_node的散列值。具有相同散列值的i_node被链入同一个队列中,系统建立一张散列表,其中每项包含一个指向VFS inode散列队列的头指针
路径名查找
要考虑的问题:
- 进程是否有权限读取目录的内容
- 目录是否为符号链接
- 符号链接导致的循环引用问题
- 文件名是否是已安装文件系统的安装点
内核模块操作proc文件系统
/proc文件系统不是普通意义上的文件系统,它是一个伪文件系统。之所以称为伪文件系统是因为它没有任何一部分与磁盘相关,只存在内存中,而不占用外存空间。它是一个到运行中进程地址空间的访问接口,通过/proc,可以用标准Unix系统调用(比如open()、read()、write()、 ioctl()等等)访问进程地址空间。
当然/proc文件系统与文件系统有很多相似之处,例如以伪文件的方式为访问系统内核数据的操作提供接口,而且可以用所有的文件工具操作。像可以用cat、more等命令查看/proc文件中的信息。
更重要的是用户和应用程序可以通过/proc得到系统的信息,并可以改变内核的某些参数。
/proc是动态地从系统内核读出所需信息并提交的。当调试程序或者试图获取指定进程状态的时候,/proc文件系统将是你强有力的支持者。通过它可以创建更强大的工具,获取更多信息。