文件系统布局
前面所有内容讲的都是”文件系统怎么工作”,这一节讲”文件系统这些东西本身存在磁盘的哪里”。
疑问点:文件系统布局的具体形态
文件系统布局这一节较为抽象,其具体内容是什么。
这一节之所以显得抽象,是因为它常被当成一张需要死记的区域清单来读。 换一个读法就具体了:把它读成”计算机开机后,系统是怎样一步步找到你的文件的”——每一个区域都是这条路径上必须经过的一站,谁在前谁在后完全由这条路径决定。下面就按这个顺序展开。
机制
磁盘上的布局

磁盘的第 0 号扇区称为主引导记录(MBR),用来引导计算机。 MBR 的末尾包含分区表,该表给出每个分区的起始和结束地址,表中的一个分区被标记为活动分区。
计算机被引导时,BIOS 读入并执行 MBR。MBR 做的第一件事是确定活动分区,读入它的第一个块——即引导块——并执行之。 引导块中的程序将负责装载该分区中的操作系统。
为统一起见,每个分区都从一个引导块开始,即使它并不含有可启动的操作系统。这解释了引导块为什么排在最前面:它必须在系统还什么都不知道的时候就被找到。
引导块之后的各区域依次是:
超级块——包含文件系统的所有关键参数:文件系统的类型、块的数量、块的大小、总块数与空闲块数、inode 的总数与空闲数、根目录的位置,以及空闲空间管理结构在哪里。在计算机启动、或该文件系统首次使用时,超级块会被读入内存。
空闲空间管理区——记录哪些块、哪些 inode 还空闲,具体方法见 4.3.3。
inode 区——每个文件一个 inode,保存文件的全部属性与数据块地址。
根目录——存放目录树的根部。它必须被单独指出位置,因为路径解析的起点就是它——没有根目录,一个绝对路径无从走起。
数据区——存放其余所有的目录和文件。注意目录文件的数据块也在这里,只有根目录因为是起点而被特殊对待。
这个顺序为什么是这个顺序
把上面的区域和开机过程对上,顺序就不需要背了:
BIOS 什么都不知道 → 只能去固定位置(0 号扇区)找 MBR → MBR 找到活动分区的引导块 → 引导块装入操作系统 → 操作系统要认识这个文件系统,先读超级块 → 超级块告诉它块多大、根目录在哪、空闲空间表在哪 → 从根目录出发,就能解析任何路径了。
每一步都只依赖前一步已经获得的信息,这条依赖链决定了物理上的先后。
内存中的结构
文件系统不只在磁盘上有结构,运行时在内存中同样维护着一组结构,它们是为了避免反复读盘而存在的:
内存中的安装表(mount table)——记录每个已挂载文件系统的信息,见 4.3.5。
目录结构的缓存——保存近来访问过的目录信息,即 4.2.4 提到的目录项缓存。
系统打开文件表与进程打开文件表——见 4.1.3。
此外还有读写文件时使用的缓冲区。
打开与读取的完整链路
把磁盘结构与内存结构串起来,就得到本章两条最完整的流程。
打开文件:根据文件名检索目录(先查目录缓存,未命中则读磁盘上的目录文件)→ 把找到的 FCB / inode 复制到内存 → 在系统打开文件表中建项(或找到已有项使打开计数加一)→ 在进程打开文件表中建项 → 返回文件描述符。
读文件:由 fd 查进程打开文件表得到读写指针与系统表索引 → 经系统打开文件表找到内存 inode → 由 inode 中的地址信息把逻辑块号翻译成物理块号 → 向磁盘发出读请求 → 数据经缓冲区送到用户空间。
注意这条链路恰好穿过了 4.3.1 的四个层次:检索目录与权限检查在逻辑文件系统,地址翻译在文件组织模块,发出块读请求在基本文件系统,实际驱动磁头在 I/O 控制层。
边界
引导块不等于超级块
这是本节最常考的一对,两者虽然相邻,职责却毫不相干:
引导块面向”启动”,里面是程序——一段负责把操作系统装入内存的代码。它服务于计算机,而不是服务于文件系统。
超级块面向”文件系统本身”,里面是参数——块大小、总块数、inode 数、根目录位置。它服务于文件系统,与启动无关。
判据:引导块里是代码,超级块里是数据;每个分区都有引导块(哪怕不可启动),但只有超级块能告诉你这个文件系统怎么读。
主引导记录与引导块也不是一回事
MBR 只有一个,位于整个磁盘的 0 号扇区,它管的是”有哪些分区、哪个是活动分区”。
引导块每个分区各有一个,位于该分区的开头,它管的是”怎么把本分区的操作系统装起来”。
层级关系是:MBR → 选出活动分区 → 该分区的引导块 → 操作系统。
超级块不描述任何单个文件
超级块是整个文件系统的总账,它记录的全是”总量”和”位置”:一共多少块、还剩多少块、inode 区在哪、根目录在哪。
单个文件的属性和数据块地址一律由 inode 负责,超级块里一个字节都没有。
这条边界的实际意义:超级块损坏会导致整个文件系统无法挂载(不知道块多大、根在哪),而单个 inode 损坏只影响那一个文件。正因为超级块如此关键,实际文件系统通常在磁盘上散布多个超级块副本。
根目录区与”所有目录集中存放”
只有根目录被单独安排位置,其余目录都是普通的目录文件,其数据块散落在数据区中。
不要把”根目录区”理解成”所有目录都集中存在一个区域”。 根目录之所以特殊,唯一原因是它是路径解析的起点,必须能在不解析任何路径的情况下被找到——这是一个”先有鸡还是先有蛋”的问题,只能靠在超级块里记死它的位置来打破。
数据区里既有文件内容也有目录项
由于目录也是文件,数据区中的一个块可能装着用户数据,也可能装着一串目录项,还可能装着一个符号链接的目标路径。
| 文件类型 | 它的数据块里是什么 |
|---|---|
| 普通文件 | 用户数据 |
| 目录文件 | 目录项(文件名 → inode 号) |
| 符号链接 | 目标路径字符串 |
对照速查
| 磁盘布局(自前向后) | 内容 | 作用 |
|---|---|---|
| 主引导记录 MBR | 整盘唯一,0 号扇区 | 含分区表,确定活动分区 |
| 引导块 | 每个分区一个,含程序 | 装载本分区的操作系统 |
| 超级块 | 含参数 | 类型、块大小、总块数/空闲数、inode 数、根目录位置 |
| 空闲空间管理区 | 位图 / 空闲表 / 成组链接 | 记录哪些块空闲 |
| inode 区 | 每文件一个 inode | 单个文件的属性与地址 |
| 根目录 | 目录树的根 | 路径解析的起点 |
| 数据区 | 文件与目录的数据块 | 内容 |
| 内存中的结构 | 作用 |
|---|---|
| 安装表 | 记录已挂载的文件系统 |
| 目录结构缓存 | 缓存近来访问的目录信息 |
| 系统打开文件表 | 每个被打开的文件一项 |
| 进程打开文件表 | 每次 open 一项 |
| 易混三者 | 数量 | 内容 | 面向 |
|---|---|---|---|
| MBR | 整盘 1 个 | 分区表 | 分区管理 |
| 引导块 | 每分区 1 个 | 程序 | 启动 |
| 超级块 | 每文件系统 1 个(常有副本) | 参数 | 文件系统本身 |
考点
- MBR 在 0 号扇区,含分区表,确定活动分区
- 每个分区都从引导块开始,即使不可启动
- 超级块含根目录位置,是挂载文件系统的前提;损坏则整个文件系统不可用
- 引导块里是代码,超级块里是数据(高频辨析)
- 超级块不描述任何单个文件
- 只有根目录被单独定位,其余目录的数据块都在数据区
- 内存中的四类结构:安装表、目录缓存、系统打开文件表、进程打开文件表
- 打开与读取的完整链路,恰好穿过 4.3.1 的四层
链接
- 🏠 返回总览:操作系统第 4 章:文件管理总览
- ⬅️ 上一节:4.3.1 文件系统结构
- ➡️ 下一节:4.3.3 文件存储空间管理
- 🔗 打开文件表的细节,见 4.1.3 文件的操作
- 📖 名词库:第 4 章名词库