文件系统布局

前面所有内容讲的都是”文件系统怎么工作”,这一节讲”文件系统这些东西本身存在磁盘的哪里”。

疑问点:文件系统布局的具体形态

文件系统布局这一节较为抽象,其具体内容是什么。

这一节之所以显得抽象,是因为它常被当成一张需要死记的区域清单来读。 换一个读法就具体了:把它读成”计算机开机后,系统是怎样一步步找到你的文件的”——每一个区域都是这条路径上必须经过的一站,谁在前谁在后完全由这条路径决定。下面就按这个顺序展开。

机制

磁盘上的布局

磁盘的第 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 的四层

链接