文件系统实现——ext2/ext4
文件系统实现——ext2/ext4
复习定位
磁盘上的文件系统不是存储文件内容那么简单——它必须有严谨的元数据布局才能做到快速查找、分配、释放和恢复。ext2/3/4系列是Linux最典型的本地文件系统。超级块是文件系统的"身份证"——块组将磁盘划分为管理单元——位图跟踪块和inode分配——日志(journal)确保崩溃后元数据一致性。
磁盘布局
ext2/3/4将磁盘划分为多个块组(Block Group)——每个块组独立管理一部分磁盘空间——含有自己的元数据副本——一旦主超级块损坏——可以通过备份恢复。
一个块组包含:
- 超级块(Super Block)副本(在块组0中包含且在其他块组也有备份)——文件系统的核心元数据:块大小(通常4KB)、每个块组包含多少块、inode总数、卷标、状态、特征标志(如是否支持Flexible Block Group)等。
- 块组描述符表(GDT, Group Descriptor Table)——描述每个块组:该块组的块位图起始块、inode位图起始块、inode表起始块、空闲块数、空闲inode数等。
- 块位图(Block Bitmap)——记录该块组中每个数据块是否空闲(1表示已分配、0表示空闲)。
- inode位图(inode Bitmap)——记录该块组中每个inode是否空闲。
- inode表(inode Table)——存放该块组的所有inode结构体(每个inode128或256字节一一对应文件元数据)。
- 数据块(Data Blocks)——存储实际的文件数据。
超级块内容
dumpe2fs /dev/sda1可以查看文件系统的超级块信息。关键字段:
- inode数量、块数量、保留块数量(供root用的保留空间)。
- 每个块组的块数、inode数。
- 首次挂载时间、上次写入时间、挂载计数。
- 特征标志(是否启用了日志、是否使用扩展属性、是否准备Flexible Block Group)。
- 文件系统创建时间。
日志(Journal)
现代文件系统(ext3/4)在修改元数据之前——先将要执行的元数据更新操作写入日志(WAL预订)——日志提交后再执行实际元数据更新。如果系统在更新过程中崩溃——重启后系统从日志中重放未完成的操作——将文件系统恢复到一致状态——而不需要漫长的fsck扫描。
ext4提供三种日志模式:journal(记录元数据和数据——最安全最慢)、ordered(只记录元数据但保证数据先于元数据写入磁盘——默认)、writeback(只记录元数据——最快但不保证数据写入顺序——可能造成已写入的日志引用的数据不完整)。
VFS(虚拟文件系统)
VFS是Linux内核中的一个抽象层——它定义了所有文件系统实现必须遵循的标准接口——使应用程序可以统一使用open/read/write操作不同的文件系统(ext4, NTFS, FUSE, NFS)。VFS引入了四个核心对象——超级块(super_block)——代表一个已挂载的文件系统;inode(inode)——代表一个文件或目录;dentry(目录项)——代表路径名与inode的映射;file(文件)——代表一个打开的文件实例(包含文件指针偏移)。
复习检查
ext2/3/4将磁盘划分为块组——为什么一个文件系统在块组0的超级块损坏后仍可能恢复(通过块组1和其他块组中的超级块备份)。
块位图和inode位图的作用——跟踪该组中哪些数据块和inode已被分配——当新文件创建时——在该组中分配空闲inode和数据块。
日志(Journal)如何确保文件系统崩溃后的快速恢复——将先写入日志的事务记录——再修改主文件系统结构——崩溃后重启时检查日志——回放未完成的提交事务——恢复一致性。
ext4的三种日志模式的差异——journal模式记录元数据和数据——最安全但每写就写两遍数据(日志+实际数据存储)最慢——ordered模式只记录元数据但强制数据先落盘——writeback不保证顺序——最快但是文件内容可能包含垃圾数据。
VFS的dentry缓存——加速路径解析——最近访问过的目录项路径存储在内存dentry cache中——下次访问同一路径时不必从磁盘读取目录文件逐一查询。