Linux VFS:把设备和文件统一起来的那一层
先把前面的线接上
前一篇我们已经把 fd 讲清楚了:它本质上就是一个下标,dup2 则把这个下标指向的对象换掉。重定向能跑起来,靠的就是这层关系。
dup2 容易绕,我再用一句话压一下:前一个参数是目标 fd,后一个参数是要被复制来源的 fd。你可以把它理解成'把后面的内容搬到前面去'。
接下来就轮到 Linux 里那个更抽象、但也更关键的东西了——一切皆文件。

学完这一篇,重点就三件事:
- 怎么理解'一切皆文件'
- Linux 里几个核心结构体分别干什么
- VFS 是怎么借助多态把调用分发出去的
一切皆文件,不是口号
Linux 里很多资源都被包装成了'文件'。键盘、鼠标、屏幕、磁盘、网卡,甚至进程信息、Socket、管道,最后都能落到文件接口上。

这不是为了好看,而是为了统一。
开发者不用针对每种设备单独学一套 API。读文件、读网卡数据,走的都可能是 read;往文件写内容、往终端输出,也都可能是 write。接口一旦统一,系统层和上层代码都省事不少。
如果没有这套设计,情况会很碎:
- 读磁盘要一套指令
- 读麦克风要另一套指令
- 读网络包又是另一套指令
Linux 直接把这些东西都伪装成文件,代价是抽象层多了一点,换来的好处是接口整齐得多。这个取舍我觉得很划算,尤其是系统编程里,统一接口比'看起来纯粹'更重要。
VFS 是什么
真正把这件事撑起来的,是 VFS(Virtual File System,虚拟文件系统)。它是 Linux 内核里的抽象层,上面接用户态的 open、read、write,下面兼容 ext4、NTFS、NFS、procfs 这类不同文件系统。
可以把它理解成一个中间层:上面的人只管按统一方式操作,下面的实现各干各的,VFS 负责把调用转过去。
这其实就是依赖倒置的典型味道:上层依赖抽象,不直接绑死具体实现。
VFS 的几个核心对象
理解 VFS,先认四个结构体。别急着背名字,先弄清它们各自负责哪一段。
struct super_block
它代表的是一个已经挂载的文件系统,比如一块磁盘分区、一个 U 盘,或者某个网络文件系统实例。
这里面放的是文件系统级别的元信息,比如块大小、魔数、文件系统类型、根目录位置。挂载时创建,卸载时销毁。
struct inode
它表示具体的文件或目录,是文件本体的元数据描述。
里面有大小、权限、时间戳、拥有者,以及数据块位置这些信息。它不包含文件名,这点很容易记混。名字不归 inode 管,inode 管的是'这个对象是什么'。
struct dentry
它是路径解析时的目录项,负责把'名字'和 inode 连起来。
比如 ,路径里的每一段都可以对应一个 dentry。内核还会缓存这些对象,也就是 dentry cache。这个缓存很实用,路径反复访问时能少走很多磁盘开销。真正线上排障或者高频访问场景里,这种缓存带来的收益比概念本身更值得在意。



