Skip to content

第六章 文件系统:持久化的抽象


1. 为什么应用不直接读写磁盘块

进入三大主线的最后一条:持久化。内存断电即失,重要数据必须落到磁盘。但磁盘的原始接口极其简陋:它只认识"读第 x 块、写第 y 块",每块固定 512 字节或 4KB。如果让应用直接面对这个接口,每个程序都要自己回答一堆难题:

  1. 我的数据放在哪些块上?块号自己记?
  2. 两个程序都想用第 100 块怎么办?
  3. 别的用户能不能偷看我的块?
  4. 断电时写到一半怎么办?

操作系统的回答是再造一层抽象——文件系统。它把"编号的块的海洋"包装成两个友好概念:

  • 文件:一段有名字的、长度可变的字节序列。应用只管按名字打开、按偏移读写,数据具体落在哪些块由文件系统记账。
  • 目录:把文件组织成树,提供"路径名"这种人类友好的定位方式。目录本质上也是一种文件,内容是"名字 → 文件元数据位置"的对照表。

一句话点透:文件系统之于磁盘,就像页表之于内存——都是把"用户看到的连续逻辑空间"映射到"零散的物理空间"的翻译账本。

2. 文件的逻辑结构与物理结构

先分清两个"结构":逻辑结构是用户看到的文件内部组织(流式的无结构文件、有格式的记录式文件);物理结构是文件的字节实际怎样摆到磁盘块上。考试重头戏是物理结构的三种分配方式。

2.1 三种分配方式

连续分配:文件占据磁盘上一段连续的块,账本只需记"起始块 + 长度"。

链接分配:文件的块散落各处,每块尾部存一个指针指向下一块(隐式链接);或把所有指针集中到一张表里(显式链接,FAT 文件分配表就是这个思路)。

索引分配:为每个文件建一个索引块,把它所有数据块的块号列成清单。想读第 i 块,查索引清单第 i 项即可。

对比项连续分配链接分配索引分配
顺序访问极快可以,逐块跟指针
随机访问极快,起始块加偏移直接算很慢,必须从头顺藤摸瓜快,查索引表直达
文件增长困难,后面没空位就得整体搬家容易,链上再挂一块容易,索引表加一项
碎片产生外碎片无外碎片无外碎片
额外开销几乎没有每块一个指针;显式链接需整张 FAT 常驻内存每个文件一个索引块,小文件也要付这笔账
可靠性一个指针坏,后半截全丢索引块坏则全文件丢,通常有备份

记忆抓手:连续分配像一排连号座位,链接分配像寻宝游戏每站给下一站地址,索引分配像目录页直接列出所有座位号

2.2 UNIX 多级索引:inode 的直觉

索引分配有个尴尬:索引块大小固定,大文件的块号清单装不下。UNIX 的 inode(索引节点,每个文件一个,存放文件的所有元数据和索引信息)用分级解决:

设计动机很漂亮:绝大多数文件很小,少数文件很大。小文件只用直接块,零额外开销;文件越大,才逐级动用间接块,支持的容量按"每级乘以每块可存的块号数"指数扩张。这和多级页表是同一个思想——按需展开的树。

顺带一个高频计算题型:块大小 1KB、块号 4 字节,则一个间接块可存 256 个块号;一级间接支持 256KB,二级间接支持 256 × 256KB = 64MB,以此类推。

3. 目录实现与路径解析

4. 空闲空间管理

5. 磁盘结构与磁盘调度算法

5.1 一次磁盘访问的时间构成

5.2 四种调度算法与手算例题

6. RAID 概念级一览

7. 文件权限与常见文件系统家族

8. 本章要点回顾

9. 做题提醒