Linux Unix 文件系统 与 VFS 对象
一、基石:Unix 的四种核心抽象
Unix 文件系统的设计始于四个简洁而强大的概念,它们共同构建了一个统一的树形世界:
- 文件被视为一个简单的有序字节序列,这种极简的抽象牺牲了复杂结构,换来了巨大的灵活性。
- 目录在本质上被当作一种特殊文件,其中记录着其包含的文件和子目录列表,从而实现层次化组织。
- 索引节点(inode) 是一个关键设计,它将文件的元数据(如权限、大小)与文件数据本身分离存储,文件本身不保存在 inode 中。
- 安装点是全局目录树中的一个锚点,通过它可以将一个完整的文件系统“挂载”进来,使得所有存储设备最终都融入单一的命名空间,这与 Windows 依赖盘符(如 C:)的方式截然不同。
二、粘合剂:VFS 的面向对象模型
为了让 Ext4、NTFS 等不同文件系统都能适配上述 Unix 抽象,Linux 内核引入了虚拟文件系统。VFS 采用面向对象的思想,用 C 语言结构体定义了四种核心对象作为通用模板:
- 超级块对象:代表一个已安装的文件系统实例,存储其全局信息。
- 索引节点对象:代表内核中的一个文件,是内存中的 inode。
- 目录项对象:代表路径解析中的一个组成部分(例如
/home/user中的home),用于快速定位,是构建目录树的核心。 - 文件对象:代表一个被进程打开的文件,保存了打开时的状态,如读写位置。
这里有一个精妙之处:VFS 将目录视为文件,所以没有独立的“目录对象”。目录项对象描述的是路径组件,而目录本身则由一个索引节点对象(表示目录文件)和多个目录项对象(表示其内容)共同描述。
三、灵魂:操作方法集
上述每个核心对象都关联着一个操作对象,它本质上是一组函数指针,定义了能对这个对象执行什么操作:
super_operations: 包含针对整个文件系统的操作,如写入 inode、同步文件系统。inode_operations: 包含针对文件的操作,如创建、链接。dentry_operations: 包含针对目录项的操作,如比较、删除。file_operations: 包含进程对已打开文件的操作,如读、写。
这是 VFS 实现多态和统一接口的关键。一个具体的文件系统(如 Ext4)需要提供这些函数的具体实现。当应用程序执行read()时,VFS 会调用对应文件对象的file_operations->read()函数指针,从而跳转到具体文件系统的实现代码。
四、支撑:整个生态系统
除了四大对象,VFS 还依赖其他结构体共同工作:
file_system_type: 描述一种文件系统类型(如“ext4”)。vfsmount: 描述一个具体的安装点实例。fs_struct: 记录进程的文件系统上下文,如根目录、当前工作目录。file结构体: 存在于每个进程的打开文件表中,记录进程对文件的使用状态。
留下评论