文件系统挂载

4.3.4 说 VFS 能让多种文件系统共存,但没说它们是怎么被接进来的。这一节就讲这最后一步:一个文件系统在能被使用之前,必须先被”挂载”到目录树的某个位置上。

挂载的本质是一次嫁接:把另一棵目录树的根,接到当前目录树的某个节点上,从此用户看到的是一棵完整的树。

机制

安装点

文件系统被安装的位置称为安装点(挂载点)。

安装点是当前目录树中一个已经存在的目录。挂载完成后,通过这个目录访问到的,就是被挂载文件系统的根目录。

例如根文件系统是 ext4,把一个 FAT32 的 U 盘挂载到 /mnt/usb 之后,/mnt/usb 这个路径下看到的就是 U 盘的内容——而用户在使用时完全感觉不到自己跨越了两个文件系统。

挂载要做的三件事

① 在 VFS 中注册新挂载的文件系统。 内存中的安装表(mount table) 包含每个已挂载文件系统的相关信息,如文件系统类型、容量大小等。这张表就是 4.3.2 中”内存里的结构”之一。

② 新挂载的文件系统要向 VFS 提供一个函数地址列表。 这正是 VFS 三个要求中的第二条落到实处——不提供这组函数,就无法接入。 有了它,VFS 才知道对这个文件系统上的文件该调用哪些实现。

③ 将新文件系统加到安装点,即把它挂在某个父目录之下。

这三步的顺序有内在逻辑:先登记”有这么个文件系统”,再拿到”怎么操作它”,最后才把它接到树上供人访问。

路径解析如何跨越挂载点

挂载之后,路径解析在走到安装点时会发生一次切换:VFS 发现这个目录是一个安装点,就不再继续在原文件系统中查找,转而从被挂载文件系统的根目录继续解析,并把后续的操作分派给新文件系统的那组函数。

这就是”统一目录树”的实现方式——树在用户看来是连续的,实际上在挂载点处换了一套实现。

边界

挂载点原有的内容会被遮蔽

这是本节最常考的一条。

若 /mnt/usb 这个目录在挂载之前本来就有一些文件,挂载之后通过 /mnt/usb 看到的将是 U 盘的根目录,原有的文件”消失”了。

但它们并没有被删除。 原目录的内容仍完好地留在原文件系统中,只是在卸载之前无法通过这条路径访问到——因为路径解析走到这里就被切换走了。卸载后它们会原样出现。

判据:挂载改变的是”这条路径通向哪里”,不改变任何磁盘上的数据。

挂载与格式化是两回事

格式化是在磁盘上建立文件系统的结构——划分引导块、超级块、inode 区、数据区,初始化空闲空间管理结构。它是一次性的、破坏性的操作,会写磁盘。

挂载只是在内存中建立映射关系,把一个已有的文件系统接入当前的目录树。它不改变磁盘上的任何内容,可以反复挂载卸载。

一句话:格式化造出文件系统,挂载让它可被访问。

挂载前的合法性检查

系统在挂载时要做几项检查,它们各自对应一种会出问题的情形:

检查文件系统类型是否被支持——内核里若没有 FAT32 的那组函数实现,就无法为它建立分派关系。

检查安装点是否存在且是一个目录——不能把文件系统挂到一个普通文件上,因为挂载后要用它作为目录来继续解析路径。

检查该安装点是否已被挂载——重复挂载会造成访问路径的歧义。

挂载与”一切皆文件”的关系

挂载机制使得”设备”这个概念在用户视野中彻底消失了。

在某些系统中,不同的磁盘有各自独立的盘符,用户必须知道文件在哪个盘上。而在 UNIX 风格的系统里,所有文件系统都被挂载进同一棵树,用户只需要知道路径。

这与 4.1.1 中”特殊文件”、4.3.4 中”/proc 以文件面貌出现”是同一个设计取向的三个侧面:把一切差异藏到统一的路径与接口之下。

对照速查

挂载的三件事内容
①在 VFS 中注册,写入内存的安装表(类型、容量等)
②新文件系统向 VFS 提供函数地址列表
③把新文件系统加到安装点(挂在某父目录下)
格式化挂载
改什么磁盘上的结构内存中的映射关系
是否破坏数据是否
可否重复会清空重建可反复挂载卸载
作用造出文件系统让它可被访问
挂载点遮蔽
现象原有内容通过该路径不可见
实质数据未被删除,只是路径被切换
卸载后原样出现

考点

  • 安装点必须是一个已存在的目录
  • 挂载三件事:注册进安装表 → 提供函数地址列表 → 接到安装点
  • 函数地址列表这一步就是 VFS 第二个要求的落实
  • 挂载点原有内容被遮蔽但未被删除,卸载后恢复(高频)
  • 格式化改磁盘,挂载改内存
  • 挂载前的三项检查:类型是否支持、安装点是否为已存在的目录、是否已被挂载

链接