文件系统与磁盘
这一支考了 10 道,和 虚拟内存 是操作系统两道综合题的另一半。题面花样多(目录、inode、FAT、位图、磁盘调度、格式化),但问的东西只有三类:占多大、要读几块、要走多少磁道。
知识框架概要
一、一次文件访问只有一条路径
路径名 → 目录文件(一个个目录项) → inode / FCB → 数据块号 → 数据块
每经过一层就是一次访盘,已经在内存里的层不算。目录项和 inode 的分工见 目录概念、inode 表、文件元信息。
二、物理结构决定「块号从哪来」,也就决定了一切计算
| 结构 | 块号怎么得到 | 能随机访问吗 | 见 |
|---|---|---|---|
| 连续分配 | 起始块号 + 逻辑块号 | 能 | 连续分配 |
| 链式分配 | 顺着每块末尾的指针走 | 不能 | 链式分配 |
| FAT | 在内存的表里顺着簇号跳 | 能(表在内存) | 文件分配表 |
| 索引 / 混合索引 | 查索引块 | 能 | 索引分配、混合索引 |
三、空闲空间管理只考位图
位图一位对应一块,所以「位图占多大」= 块数 ÷ 8 字节,见 位图法。其余三种(空闲表法、空闲链表法、成组链接法)只在选择题里出现。
四、磁盘是独立的一段:先算距离,再算时间
调度算法只数磁头移动的磁道数,见 机械硬盘调度算法;时间四项齐全,见 磁盘性能指标。CHS 换算属于驱动程序的活,见 CHS 地址。
五、格式化与引导是两串固定顺序
制盘:物理格式化(划分扇区) → 分区 → 逻辑格式化(建引导记录、FAT/inode 区、根目录、数据区) → 装操作系统
引导:ROM 引导程序 → 磁盘引导程序 → 分区引导程序 → 操作系统初始化
解题注意点
前四条围着索引和位图转,最后一条的磁盘部分和它们没有关系,按小问挑着用。
先算「一块能放几个地址项」
这个数(记作 N)是索引类题目的全部起点:
N = 块大小 ÷ 地址项长度
2018#46 与 2022#45 都是 4KB ÷ 4B = 1024。反过来问「索引项至少几字节」,就先由 总容量 ÷ 块大小 得块总数,再取 ⌈log₂块总数⌉ ÷ 8——2012#46 由此得 4B。
最大文件长度按级数拆开写
最大长度 = (直接项数 + N + N² + N³) × 块大小
分级写、不要合成一个数,2018#46 的答案就写成 32KB + 4MB + 4GB + 4TB。另外两种结构各有自己的算法:
- 链接分配要扣掉指针:每块可用
块大小 − 指针长度,2014#46 是 1024 − 4 = 1020B,答 4G × 1020B; - FAT 由表项位宽定表项数
2^位宽,最大文件 = 表项数 × 簇大小,而 FAT 自身长度 = 表项数 × 表项字节,两个别混(2016#47)。
问「用到哪几级索引」就把文件块数夹进前缀和之间:2022#45 的 6MB 是 1536 块,10 + 1024 < 1536 < 10 + 1024 + 1024²,所以用到一级和二级。
访盘次数按路径逐层数
一层一块,读写分开数:
| 场景 | 怎么数 | 出处 |
|---|---|---|
| 连续分配中间插一条记录 | 每搬一条 = 读 1 + 写 1,再加写入新记录 1 次 | 2014#46:29 × 2 + 1 = 59 |
| 链接分配中间插一块 | 顺链找到前驱(只读)+ 写新块 1 + 改前驱指针写回 1 | 2014#46:29 + 2 = 31 |
| 给了字节偏移读一个字节 | 先算逻辑块号,再看它落在第几级索引 | 2026#46:一级间接 1 + 数据块 1 = 2 |
| 目录已在内存 | 只数 inode 所在块 + 数据块 | 2022#45:2 块 |
逻辑块号 = ⌊字节偏移 ÷ 块大小⌋,块内偏移 = 字节偏移 mod 块大小
inode 所在盘块号 = inode 区起始块号 + ⌊inode 号 ÷ (块大小 ÷ inode 大小)⌋
FAT 题还要记住一句:下一簇号存在当前簇号的表项里。2016#47 里簇 106 的号存在 100 号表项中。
位图和 inode 位图分别清零
删除操作按「先递归删子文件,再删自己」,每个对象固定三个动作(2026#46):
- 释放它的数据块(间接索引块本身也要释放),在磁盘位示图里清零;
- 它的 inode 在 inode 位示图里清零;
- 在父目录的数据块里删掉这一条目录项。
位图自身的大小:位图字数 = 块数 ÷ 字长,2010#45 是 16384 ÷ 32 = 512 字 = 2KB,正好装得下。要定位某一块在位图的第几个字第几位,用
所在盘块号 = 起始块号 + ⌊块号 ÷ (每块字节数 × 8)⌋
块内字节号 = ⌊(块号 mod (每块字节数 × 8)) ÷ 8⌋
要位号就不除最后那个 8,要字节号才除——这一步是选择题的常见坑。
磁盘时间三段分行写
移动时间 = 移动磁道总数 × 单磁道时间
旋转延迟 = 请求数 × (60 ÷ 转速) ÷ 2
传输时间 = 请求数 × 一转时间 ÷ 每道扇区数
2010#45 的 C-SCAN 走了 170 个磁道,加 4 个请求的 20ms 旋转延迟和 0.4ms 传输,合计 190.4ms。介质换成闪存就答 FCFS 更好,理由固定:没有寻道时间和旋转延迟。
簇号型的调度题要先把当前柱面折算成簇号区间再比距离:2019#44 每柱面 1000 个簇,85 号柱面就是簇 85000~85999。CHS 换算三行:
柱面号 = ⌊簇号 ÷ 每柱面簇数⌋
磁道号 = ⌊(簇号 mod 每柱面簇数) ÷ 每磁道簇数⌋
扇区号 = (柱面内余数 × 每簇扇区数) mod 每磁道扇区数
历年题索引
上面这几条覆盖了绝大多数小问,下面这张表只用来查「某一年额外拐了什么弯」。
| 真题 | 主线 | 这一年特别问了什么 |
|---|---|---|
| 2010#45 | 位图管理 + 磁盘调度 | 2KB 内存能不能管 16384 块;C-SCAN 总时间;闪存该用 FCFS |
| 2011#46 | 物理结构选型 + FCB | 一次写入不可改,该选哪种结构;FCB 要加什么字段 |
| 2012#46 | 索引分配的最大文件长度 | 索引项最少几字节;<起始块号, 块数> 混合结构怎么划分最优 |
| 2014#46 | 插入记录的访盘次数 | 插第 30 条各要访盘几次;链接式的最大文件长度 |
| 2016#47 | FAT + 目录文件内容 | 写出目录文件的内容;某簇号存在哪个 FAT 表项里 |
| 2018#46 | 混合索引 + inode 数量 | 最大长度的表达式;能存几个 5600B 的文件 |
| 2019#44 | 磁盘容量 + SSTF + CHS | 簇号转 CHS,以及这个转换由谁完成 |
| 2021#46 | 引导流程 + 磁盘格式化 | 四个操作的正确顺序;扇区划分和根目录各在哪一步 |
| 2022#45 | 目录项 + 硬链接 + 间接索引 | 两个目录项 inode 号相同求块号;6MB 用到哪几级 |
| 2026#46 | inode 定位 + 位示图 + 删目录 | inode 号推盘块号;删一个目录要改哪些元数据 |
2021#46 的第 1 问其实是系统引导,2019#44 的第 3 问跨到组成原理的 CHS 与 I/O 软件层次,两处都在上面的框架第四、五条里。
易错清单
- 链接分配忘了扣指针。每块可用 1020B 而不是 1024B,2014#46 的评分说明写明按 1024 算只给 1 分。
- 访盘次数把读写混算。搬一条记录是 2 次(读 + 写),顺链查找只算读,改指针写回只算 1 次。
- FCB 的变化写不全。2014#46 要求同时点名起始块号和文件长度,少写一项不给分。
- 文件个数只看一个上限。要同时受 inode 总数和数据块数限制、取小者,且文件大小要向上取整成整簇(2018#46)。
- 索引项字节数和索引项个数弄混。前者由磁盘总块数推出,后者由索引表区大小推出(2012#46)。
- 两个目录项 inode 号相同还另算一遍块号。那就是硬链接、同一个文件,块号照抄(2022#45)。
- 位图定位时该要位号却除了 8。除以 8 得到的是字节号。