Skip to content

文件系统的全局结构

2026 大纲 四(三)1 文件系统的全局结构(layout),补充说明把它切成两半:文件系统在外存中的结构、在内存中的结构。

前面那些结构,在盘上和内存里各摆在哪

到这里,文件系统的零件已经全了:目录项、inode、数据块、 还有下一节要讲的空闲空间管理结构。但它们在磁盘上是怎么排的?

不能随便排。有一条硬约束:越是必须先读到的,越要放在前面, 而且位置得是约定死的。因为读第一样东西的时候,你还什么都不知道。

顺着这条约束往下推,一个分区的布局就唯一确定了:

引导块必须在最前面——固件只会按固定位置去读它, 它自己不认识任何文件系统(操作系统引导讲过这一层)。 接着是超级块——它记着"块多大、总共几块、inode 区从哪开始、根目录是几号", 不先读它,后面几个区在哪都不知道。再往后是空闲空间管理区inode 区, 位置由超级块描述。最后数据块区吃掉剩下的全部空间。

这条链也解释了两件事。超级块坏了整个文件系统就废—— 后面所有区域的位置都靠它描述,所以实际系统会在盘上存多个副本。 inode 区的大小在格式化时定死——它是定长表项的连续数组, 长度必须写进超级块,否则 inode 号就没法由位置隐含推出; 于是会出现"磁盘还有大把空闲块,却创建不了新文件"。

内存那一侧是另一套结构,但逻辑相同:把访问频繁、每次都要读盘的东西缓存起来。 本节后半部分讲它,以及"文件系统能管什么、管不了什么"这条边界—— 它比看起来更容易答错。

一、文件系统的层次结构

层次职责
用户接口提供 open/read/write/close 等系统调用
文件目录系统管理目录,将文件名转换为 FCB/inode
存取控制模块验证访问权限
逻辑文件系统将逻辑地址转换为物理地址
物理文件系统管理磁盘块的分配和回收
设备驱动程序与磁盘硬件交互

二、文件系统在外存中的结构

磁盘 → 分区 → 文件系统这三级,是磁盘那篇"低级格式化 → 分区 → 高级格式化"三步的产物:分区在整块盘上划一次,文件系统在每个分区上各建一次。

┌─────────────┬───────────┬───────────┬──────────┐
│     MBR      │  分区1    │   分区2   │  分区3   │
│ (主引导记录) │(文件系统1)│(文件系统2)│(交换区)  │
└─────────────┴───────────┴───────────┴──────────┘

┌────────┬────────┬──────────┬───────────┬──────────────┐
│引导块   │ 超级块  │空闲空间管理│ inode 区域 │   数据块区域   │
│(Boot   │(Super  │(位图/链表)│(inode     │ (Data        │
│ Block) │ Block) │          │  Table)   │  Blocks)     │
└────────┴────────┴──────────┴───────────┴──────────────┘
区域内容说明
引导块引导程序每个分区的起始位置,用于启动该分区上的 OS
超级块文件系统元信息文件系统类型、块大小、块数量、空闲块数、inode 数等
空闲空间管理位图或链表记录哪些磁盘块/inode 是空闲的
inode 区域inode 表存放所有 inode,按编号连续排列
数据块区域文件数据存放目录和文件的实际数据

整条引导链见操作系统引导。超级块在挂载时读入内存、运行中在内存修改、卸载时写回磁盘。

inode 区大小定死会导致什么:8 GB 分区能建多少文件、什么时候先耗尽(想看清"两种资源谁是瓶颈"是怎么算出来的时展开)

自造数据:某分区容量 8 GB,块大小 4 KB,格式化时按"每 16 KB 空间配一个 inode"的比例划分 inode 区,每个 inode 占 128 B

(1)inode 个数与 inode 区大小。

inode 数=8 GB16 KB=233214=219=524288 524288×128 B=67108864 B=64 MB=64 MB4 KB=16384 

占整个分区的 64 MB8 GB=0.78%。格式化程序不知道将来会存什么文件,只能按一个经验比例来划,比例一旦定下 inode 总数就锁死了;这 0.78%无论存不存文件都固定占着的,也是"新盘刚格式化就少了一截"的来源之一。

(2)文件数上限 = inode 数 = 524 288 个。 一个文件(含目录)至少要一个 inode。注意判据是"一个 inode 对应一个文件本体"——硬链接不占新 inode(多个目录项共用一个),所以严格说上限是"文件本体数"而非"文件名数"。

(3)若平均文件只有 2 KB,谁先耗尽?

524288×2 KB=1 GB

用完全部 inode 时数据才占 1 GB,加上 inode 区的 64 MB,分区里还有约 6.9 GB 是空的,但一个新文件也建不了。把两种资源各自的消耗速度算出来比一比,就能看出谁是瓶颈由文件的平均大小决定——这也是格式化时那个比例要按用途选择的原因:放海量小文件的分区要把比例调密。

三、文件系统在内存中的结构

外存那一半解决"数据在哪",内存这一半解决"怎么不必每次都去外存问":

数据结构什么时候建立什么时候销毁每个"什么"一份
内存超级块该文件系统被挂载该文件系统被卸载时(先写回磁盘)每个已挂载的文件系统一份
内存 inode 表某个文件第一次被打开时读入该文件的引用计数降为 0 时(脏则先写回)每个正被打开的文件一份
系统打开文件表每次 open 一个尚未被打开的文件该表项的打开计数降为 0每次"打开事件"一份(同一文件被多次 open 时可能多份)
进程打开文件表进程被创建时建表,每次 open 增加一项进程退出时整表销毁,close 时删一项每个进程一张表
目录项缓存(dentry cache)路径解析经过某个目录项时顺手缓存内存紧张时按替换策略淘汰(可随时丢弃每个最近用过的路径分量一项

open 的五步和这几张表对起来,就知道它们各自为什么存在:

一句话:目录项缓存服务第 ① 步(找 inode 号)、内存 inode 表服务第 ② 步(拿元数据)、两张打开文件表服务第 ④⑤ 步(记住这次打开)。

内存 inode 表与系统打开文件表:分工边界

这两张表最容易混成一张,分工边界只有一条:内存 inode 表描述"文件本体",系统打开文件表描述"一次打开事件"。 由这一条推出全部差别:

内存 inode 表系统打开文件表
一项代表什么一个文件(对应磁盘上一个 inode)一次打开(一次 open 调用的结果)
同一文件被 open 两次仍然只有 1 项(引用计数 = 2)视实现可有 2 项
存的字段磁盘 inode 的全部内容 + 引用计数、脏位、锁、设备号打开计数、文件锁、指向内存 inode 表项的指针
硬链接的两个名字被分别打开共用同一项(它们本来就是同一个 inode)各有各的项
计数归零时写回磁盘 inode 并释放释放表项,并使内存 inode 的引用计数减 1

判据:问"这个信息是文件本身的,还是这次打开才有的"——大小、权限、块指针是文件本身的 → 内存 inode 表;读写位置、以什么模式打开的是这次打开才有的 → 打开文件表(本站按通行口径放在进程打开文件表,教材口径的分歧见文件的操作第五节)。

目录项缓存解决什么问题

它解决的是路径解析的重复代价:按目录那篇的结论,解析深度 n 的路径要 2n 次磁盘 I/O,而真实系统里路径的前缀高度重复(在 /home/alice/project/ 下工作时几乎每条路径前 3 级都一样),同一路径又被反复访问(编译一次要打开同一批头文件几十遍)。命中一级就省掉那一级的两次磁盘 I/O(读该目录的 inode + 读它的数据块)。

四、文件系统管什么,管不了什么

有一类题专门考这条边界:给一个功能,问它归文件系统还是归别人。 判据一句话:这件事跟具体是什么硬件有关吗?有关的就不归文件系统。

文件系统是逻辑层,它对下只假设"有一片可按块编号读写的存储", 不假设那是磁片还是闪存。所以:

功能归谁为什么
确定盘块大小文件系统盘块是文件系统的逻辑分配单位(把若干连续扇区合成一块),格式化时选定。同一块盘可以格式化成 1 KB / 4 KB / 8 KB 任选,与硬件类型完全无关
划分扇区硬件机械盘在低级格式化时划、SSD 由控制器决定,文件系统只能接受既成事实
降低寻道时间磁盘调度(I/O 章)它优化的是磁头的机械移动,而 SSD 根本没有寻道这回事
实现均衡磨损SSD 控制器的 FTL它是为闪存"擦写次数有限"这个物理特性设计的,机械盘不需要

后三项各自只对某一类硬件有意义,所以都不可能是"文件系统能为两种盘都提供的功能"。 只有盘块大小这一项,是文件系统自己定的、且对哪种盘都一样。

考点速记

  1. 外存布局按"越必须先读到的越靠前"排引导块 → 超级块 → 空闲空间管理区 → inode 区 → 数据块区
  2. MBR 只有一个、引导块每分区一个MBR 负责"从哪个分区启动",引导块负责"这个分区怎么启动"。三条理由——数量不同、所知范围不同(MBR 那 446 字节不认识任何文件系统)、更新频率不同。
  3. 超级块存:魔数、块大小、总块数、空闲块数、总/空闲 inode 数、根目录 inode 号、空闲块管理结构的位置。⚠️它一坏整个文件系统就废(后面所有区域的位置都靠它描述),因此常存多个副本。
  4. inode 区大小在格式化时定死——它是定长表项的连续数组,长度必须写进超级块。由此出现"磁盘还有大量空闲块却创建不了新文件";谁先耗尽由平均文件大小决定
  5. 内存五组结构里,内存 inode 表描述文件本体、系统打开文件表描述一次打开事件;三层引用 进程表项 → 系统表项 → 内存 inode → 磁盘 inode 每层可多对一。⚠️只有目录项缓存是外存已有信息的纯副本,因而唯一可以随时丢弃
  6. 逻辑格式化(高级格式化)建的是:引导记录(PBR)、根目录空闲空间管理结构、FCB/inode 表。⚠️分区在它之前、扇区划分与校验码位数属物理格式化。
  7. 判"归不归文件系统"的判据:这件事跟具体是什么硬件有关吗。 有关的不归——划分扇区归硬件、降低寻道时间归磁盘调度、均衡磨损归 SSD 的 FTL;确定盘块大小归文件系统
  8. 提高文件访问速度的四条路都成立提前读(预测下一块并提前调入)、为文件分配连续的簇(减少寻道)、延迟写(合并多次写、命中缓冲区就不落盘)、磁盘高速缓存(把常用块留在内存)。

这一节在真题里被考过的形式

三道题,都在考"这件事归谁做"这一类边界判断,没有计算。

  • 问文件系统能为温彻斯特硬盘(机械盘)和固态硬盘都提供的功能(2025-32)。答确定盘块大小。⚠️ 另三项各自只对一类硬件有意义:划分扇区归硬件、降低寻道时间对 SSD 无意义(它没有寻道)、实现均衡磨损对机械盘无意义(它不怕擦写次数)。判据就是速记第七条——题干里"为两种盘都提供"这半句,本身就是在要求这个功能与硬件无关
  • 问磁盘逻辑格式化程序所做的工作(2017-29,与目录共享)。答建立文件系统的根目录 + 对保存空闲磁盘块信息的数据结构进行初始化。⚠️ 分区在逻辑格式化之前、确定扇区校验码所占位数属于物理格式化。完整的制盘四步顺序在操作系统引导
  • 问哪些优化方法可以提高文件访问速度(2018-31)。答四条全部:提前读、为文件分配连续的簇、延迟写、采用磁盘高速缓存。⚠️ 唯一可能犹豫的是延迟写——它看起来是"推迟"而不是"加快",但推迟的是落盘,而应用看到的 write 立刻就返回了,且多次写同一块最终只产生一次磁盘写。判据是"它减不减少实际的磁盘 I/O 次数或等待时间",四条都减。

复习优先级必须拿满,全是判据题。 第七条那条"跟硬件有关吗"的判据是本节最有价值的一句, 它同时能解 2025-32 和 2017-29 的一半。第一条的布局顺序要能默写出来, 第四条(inode 区定死)在 inode 已经出现过一次,是同一条结论。

易错:认为划分扇区是文件系统做的。那是硬件——机械盘低级格式化、SSD 由控制器决定。

易错:认为降低寻道时间是文件系统提供的功能。它归磁盘调度,而且 SSD 根本没有寻道

易错:认为均衡磨损是文件系统的职责。它归 SSD 控制器的 FTL,机械盘不需要。

易错:把分区算进逻辑格式化。分区在它之前;扇区划分与校验码位数属物理格式化。

易错:认为延迟写会拖慢文件访问。它推迟的是落盘write 立刻返回,且多次写同一块只产生一次磁盘写。

易错:认为超级块只是一堆统计信息。后面所有区域的位置都靠它描述,坏了整个文件系统就废。

易错:认为磁盘有空闲块就一定能建文件。inode 区在格式化时定死,inode 用完就建不了。

教材出处
  • 汤小丹《计算机操作系统》印刷版 p234:磁盘索引结点与内存索引结点的字段差别(内存索引结点额外增加索引结点编号、状态、访问计数),是本篇"内存 inode 表存什么"的依据。
  • 孙钟秀、费翔林《操作系统教程》(第 6 版)印刷版 p176:系统"为每个用户进程建立一张活动文件表(又称打开文件表)",打开时"将该文件有关的目录信息复制到指定的主存区域",后续访问"无须重复遍历相关子目录路径,而是通过访问活动文件表项来快速获得相应信息"——这正是内存中这几张表存在的理由。

相关知识

硬链接和软链接外存空闲空间管理文件元数据与索引节点文件的操作文件系统挂载虚拟文件系统磁盘

真题练习