前言
本文主要会介绍笔者在学习Linux VFS时所总结的知识点,其中会涉及到VFS抽象出的通用模型
等方面的相关内容。
笔者也会将自己的理解在文中进行阐述,这也算是在和大家交流心得的一个过程。若文中有错误的理解和概念,请大家及时纠正;吸纳大家的建议,对于我来说也是很重要的学习过程之一。
1.概念
VFS 是一个内核抽象层。其能够隐藏具体文件系统的实现细节,从而给用户态进程提供一套统一的 API 接口。
Tips: 即VFS是对文件系统的一种抽象产物。
VFS 使用了一种通用文件系统的设计,即其设计了一种通用文件系统模型
。
具体的文件系统只要实现了 VFS 的设计接口就能够注册到 VFS 中,从而使内核可以读写这种文件系统。 这种设计理念即是面向对象设计中的抽象类与子类之间的关系,抽象类负责对外接口的设计,子类负责具体的实现。
Tips: VFS本身就是用C语言实现的一套面向对象的接口。
2.通用文件系统模型
VFS 通用文件模型中包含以下四种元数据结构。
2.1 超级块对象(superblock object)
superblock用于存放已经注册的文件系统的信息,即superblock保存的是文件系统的元数据
。比如ext2,ext3等这些基础的磁盘文件系统,还有用于读写socket的socket文件系统,以及当前的用于读写cgroups配置信息的 cgroups 文件系统等。
2.2 索引节点对象(inode object)
inode用于存放具体文件的信息,即inode保存的是文件的元数据
。其中比较重要的一个部分是 inode_operations 的结构体,该结构体定义了在具体文件系统中创建文件,删除文件等的具体实现。
对于一般的磁盘文件系统而言,inode 节点中一般会存放文件在硬盘中的存储块等信息。例如对于socket文件系统,inode会存放socket的相关属性。cgroups的inode会存放与 cgroup 节点相关的属性信息。
2.3 文件对象(file object)
一个文件对象表示进程内打开的一个文件
,文件对象是存放在进程的文件描述符表里面的。其中重要的部分是file_operations 的结构体,这个结构体描述了具体的文件系统的读写实现。当进程在某一个文件描述符上调用读写操作时,实际调用的是 file_operations 中定义的方法。
对于普通的磁盘文件系统,file_operations 中定义的就是普通的块设备读写操作。例如对于socket文件系统,file_operations 中定义的就是 socket 对应的 send/recv 等操作。cgroups的file_operations 中定义的是操作 cgroup 结构体等具体的实现。
2.4 目录项对象(dentry object)
在每个文件系统中,内核在查找某一个路径中的文件时会为内核路径上的每一个分量都生成一个目录项对象,通过目录项对象能够找到对应的 inode 对象
。目录项对象一般会被缓存,从而提高内核查找速度。