前言
本节从两个角度理解文件系统的结构:纵向 看各功能层次如何协同完成文件操作;横向看文件系统在外存和内存中的布局。
1. 文件系统的层次结构
文件系统从上至下分为以下几个层次,每一层负责不同的功能:
| 层次 | 主要职责 | 对应知识点 |
|---|---|---|
| 用户接口 | 向用户和应用程序提供系统调用接口(open/read/write/close 等),处理系统调用请求 | 文件的基本操作 |
| 文件目录系统 | 根据路径逐级查找目录,找到文件对应的 FCB;管理打开文件表、活跃目录表 | 文件目录 |
| 存取控制模块 | 验证用户对文件是否拥有所请求的操作权限 | 文件保护 |
| 逻辑文件系统与文件信息缓冲区 | 将记录号转换为逻辑地址;将索引表等文件信息缓冲到内存 | 文件逻辑结构 |
| 物理文件系统 | 将逻辑地址转换为实际物理地址 | 文件物理结构 |
| 辅助分配模块 | 管理磁盘存储空间,负责物理块的分配与回收 | 文件存储空间管理 |
| 设备管理模块 | 直接与磁盘硬件交互:分配设备、分配缓冲区、磁盘调度、启动/释放设备 | 磁盘管理 |
以"删除学生信息 Excel 表中最后 100 条记录"为例,各层次依次参与:
- 用户接口:接收用户发出的删除请求(系统调用)
- 文件目录系统:根据文件路径逐级查找目录,找到对应 FCB
- 存取控制模块:验证该用户是否有"删除记录"的权限
- 逻辑文件系统:将记录号转换为对应的逻辑地址(可能需要查询索引表)
- 物理文件系统:将逻辑地址转换为物理地址
- 设备管理模块:与磁盘交互,执行实际的数据删除操作
- 辅助分配模块:回收删除记录后释放的空闲磁盘块
2. 文件系统的全局结构
2.1 外存中的结构
磁盘从出厂到可用,需要经过两次格式化:
物理格式化(低级格式化)
将磁盘划分为一个个扇区,同时检测坏扇区并用备用扇区替换。坏扇区对操作系统透明------操作系统访问某扇区时,磁盘驱动器会在后台自动用备用扇区替代,操作系统感知不到坏扇区的存在。
逻辑格式化(高级格式化)
将磁盘划分为一个个分区(卷)(即 C 盘、D 盘等),分区信息由分区表记录。每个分区内可以建立独立的文件系统。
以 Unix 文件系统为例,逻辑格式化后一个分区内的布局:
css
| 引导块 | 超级块 | 空闲空间管理(位视图等)| I 结点区 | 根目录 | 其他文件和目录数据 |
| 区域 | 说明 |
|---|---|
| 引导块 | 存放启动操作系统所需的引导程序 |
| 超级块 | 记录空闲盘块的组织信息(成组链接法),用于快速找到空闲磁盘块 |
| 空闲空间管理 | 如位视图(0 表示空闲,1 表示已分配),用于快速判断某一磁盘块是否空闲 |
| I 结点区 | 连续存放所有文件的索引节点(inode),大小相同,可通过下标直接定位任意 inode |
| 根目录 | 逻辑格式化完成后即建立,文件系统以根目录为起点组织所有文件 |
| 数据区 | 存放普通文件和目录的实际数据,逻辑格式化后为空,随文件创建逐步填充 |
超级块与位视图均可标记空闲块,但作用侧重不同:超级块侧重快速找到多个空闲块,位视图侧重快速判断某块是否空闲。
2.2 内存中的结构
文件系统在内存(内核区)中维护三个重要数据结构:
| 数据结构 | 数量 | 内容 | 作用 |
|---|---|---|---|
| 目录缓存 | 全局 | 近期访问过的目录文件数据 | 避免重复读磁盘,加快目录检索速度 |
| 系统打开文件表 | 全局唯一一张 | 所有正在被进程使用的文件的 FCB 副本及打开计数器 | 统一管理已打开的文件 |
| 进程打开文件表 | 每个进程一张(存于 PCB) | 该进程已打开的文件、打开方式(读/写)、指向系统表的索引 | 记录进程的文件使用状态 |
2.3 打开并读取文件的完整流程(示例)
以 open("m/a") 后 read(fd, ...) 为例:
scss
open("m/a")
↓
① 查找目录缓存,将目录 m 的数据读入内存
↓
② 在目录 m 中找到文件 a 的目录项(FCB)
↓
③ 将 FCB 复制到系统打开文件表,打开计数器置 1
↓
④ 在进程打开文件表中新建条目(记录打开方式 + 指向系统表的索引)
↓
⑤ 返回文件描述符 fd(进程打开文件表的索引号)
read(fd, buf, n)
↓
① 通过 fd 找到进程打开文件表中对应条目
↓
② 通过索引找到系统打开文件表中对应条目,获取 FCB
↓
③ 根据 FCB 确定文件在外存中的位置
↓
④ 将数据从外存读入内存 buf
文件描述符(fd) 本质上是进程打开文件表的索引号,也称"文件句柄"。打开文件后的所有读写操作只需传入 fd,无需再提供文件路径或文件名。