核心 05-文件系统与存储 预计 25 分钟 kp-023

经典文件系统布局:超级块、位图与 ext4 日志

文件系统是磁盘上的元数据组织方案:超级块记录全局参数、位图跟踪空闲块与空闲 inode、inode 表存放文件元数据、数据区存放内容;ext4 在此之上用日志(journal)解决多块更新的原子性。

学习状态:

一句话定义

文件系统是磁盘上的元数据组织方案:超级块记录全局参数、位图跟踪空闲块与空闲 inode、inode 表存放文件元数据、数据区存放内容;ext4 在此之上用日志(journal)解决多块更新的原子性。

为什么重要

这是"把抽象落到扇区"的关键一跃:kp-021 讲 inode 是什么,本节讲 inode 们放在盘上哪里、坏了怎么发现、写一半断电怎么办。读懂布局图,就能读懂 fsck 在修什么、 dumpe2fs 在展示什么、以及 kp-024 崩溃一致性的全部前提。

前置知识

kp-021(inode 与目录项);kp-022(块与扇区)。

核心概念

  • 超级块(superblock):文件系统身份证:总块数、块大小、inode 总数、挂载状态、特性标志。
  • 位图(bitmap):每块一位/每 inode 一位的占用表,分配与释放的 O(1) 记账。
  • 块组(block group):把盘切成多个自包含单元,各带自己的位图与 inode 表,让相关数据物理邻近。
  • extent:ext4 的连续区间指针(起始块+长度),替代 ext2/3 的多级间接块。
  • HTree 目录:大目录的哈希 B 树索引,避免线性扫描。
  • 日志(journal):把元数据改动先顺序写入日志区再落盘原位,崩溃后可重放。
  • VFS(虚拟文件系统):内核的统一接口层,ext4/XFS/btrfs 实现同一组操作表。

原理与机制

简化布局(经典 vsfs 模型,8 个块为例):

块:   [0][1][2][3][4][5][6][7]
      超S|i位图|d位图|i表|i表|数据|数据|数据
        ^S=超级块   ^inode表2块,每块4个inode   ^数据块3个
读 /a.txt: 读超级块(已知位置) -> 读i位图/d位图找空闲 -> 读inode表[2]
           -> 得数据块指针 -> 读数据[5]
创建文件:  位图标位(1个写) + inode 初始化(1个写) + 目录项写入(1个写)
           -> 3+ 次离散写, 任何两次之间断电 = 元数据不一致   <-- 日志的动机

ext4 日志的三种模式:journal(数据+元数据都进日志,最安全最慢)、ordered(默认:先写数据、再提交元数据日志,折中)、writeback(只日志元数据,最快但崩溃后旧数据可能出现在新文件里)。日志提交流程:把事务写入日志区 → 写校验和提交记录 → checkpoint(把改动搬回原位)→ 日志区循环复用。因为日志写入是顺序的,它同时是 HDD 时代为数不多的"顺序化"收益点(呼应 kp-022)。

图示

创建文件的三处改动:   位图[1改成1]  inode[新内容]  目录[新增项]
无日志:  任一处写后断电 -> 位图说占用/数据说空闲 等不一致 -> fsck 全盘扫描(小时级)
有日志:  改动先写日志 -> 提交点后崩溃 -> 挂载时重放日志 -> 秒级恢复

直观类比

超级块像商场的总导览图,位图像每个车位的占用指示灯,inode 表是商户登记簿,数据区是货架。日志像商场的施工日志本:今天所有改动先记在本子上,抄录到正式台账(checkpoint)之前断电,开业时照本子补抄一遍即可。

实例或案例

df -T                          # 各挂载点文件系统类型
dumpe2fs -h /dev/sda1          # 只读超级块摘要: 块大小/特性/日志模式
tune2fs -l /dev/sda1 | grep -i "block\|journal"   # 元数据全景
debugfs -R "stat /etc/hostname" /dev/sda1        # 直接读某文件 inode(只读操作)
cat /proc/fs/ext4/sda1/options  # 运行时日志选项(内核版本相关)

常见误区

  • 认为 ext4 默认配置保证"数据不丢":默认 data=ordered 只保证元数据一致,写入的数据仍可能丢,见 kp-024 的 fsync 语义。
  • 把日志当备份:日志只覆盖崩溃窗口内的未完成事务,误删文件日志管不了。
  • 认为 SSD 上日志纯亏:原子性与顺序写减少随机写放大,journal 依然是收益项。

与其他知识点的关系

崩溃窗口的细节展开为 kp-024;本节的"日志思想"在 kp-025 中长成 LSM 树与 COW 快照;VFS 统一接口连接 kp-026 的驱动模型。

延伸阅读

《操作系统导论》"File System Implementation"章(vsfs 完整推演);Rosenblum & Ousterhout 1991 LFS 论文(把"全部顺序写"推到极致的另一种答案)。

自测题

  1. 创建一个新文件至少要写哪几处元数据?

答:数据块位图(若写数据)、inode 位图标位、inode 初始化、父目录新增目录项——分散在盘上多处,故存在崩溃一致性问题。

  1. ext4 的 data=ordered 模式保证了什么、没保证什么?

答:保证崩溃后文件系统元数据自洽(无悬空块、无错配 inode);不保证用户数据在断电时已落盘,应用必须用 fsync 表达持久化意图。

  1. 为什么位图分配在 HDD 时代还要配合块组?

答:块组让一个文件的 inode、位图与数据物理邻近,既缩短寻道(kp-022)又降低位图锁争用,是空间局部性在盘上的布局化。

标签:#文件系统 #ext4 #超级块 #位图 #extent #日志