目录
[1. 引言](#1. 引言)
[2. ext2的整体布局](#2. ext2的整体布局)
[3. 超级块(Super Block)](#3. 超级块(Super Block))
[4. 块组描述符表(GDT)](#4. 块组描述符表(GDT))
[5. 位图(Bitmap)](#5. 位图(Bitmap))
[6. inode表(Inode Table)](#6. inode表(Inode Table))
[7. 数据块(Data Blocks)](#7. 数据块(Data Blocks))
[8. inode与数据块的映射------直接、间接块索引](#8. inode与数据块的映射——直接、间接块索引)
[9. 创建一个新文件的过程(以touch abc为例)](#9. 创建一个新文件的过程(以touch abc为例))
[10. 删除文件的过程](#10. 删除文件的过程)
[11. 小结](#11. 小结)
1. 引言
ext2是Linux经典的日志文件系统之一,ext3/ext4在其基础上增加了日志功能和大文件支持,但核心磁盘布局保持一致。本文将详细拆解ext2文件系统的块组结构,分析超级块、块组描述符、位图、inode表和数据块的作用,并解释inode如何通过直接、间接块索引找到文件数据。
2. ext2的整体布局
一个ext2分区被划分为若干个块组(Block Group),每个块组的大小相等。块组的目的是将磁盘分组管理,避免超级块等元数据过于集中,提高可靠性。
每个块组包含以下部分(按顺序排列):
| 组件 | 作用 |
|---|---|
| 超级块(Super Block) | 描述整个文件系统的全局信息 |
| 块组描述符表(GDT) | 每个块组一个描述符,记录该组的位图、inode表位置等 |
| 块位图(Block Bitmap) | 标记该组数据块是否空闲 |
| inode位图(Inode Bitmap) | 标记该组inode是否空闲 |
| inode表(Inode Table) | 连续存放该组所有inode结构 |
| 数据块(Data Blocks) | 实际存储文件内容或目录项 |
注意:超级块和GDT在每个块组的开头都有备份(第一个块组必须有,后面的可选),以防损坏。
3. 超级块(Super Block)
超级块存储文件系统的全局元数据,如:
-
inode总数、空闲inode数
-
数据块总数、空闲块数
-
块大小、每块组块数、每块组inode数
-
文件系统状态、最后挂载时间等
内核中struct ext2_super_block定义了这些字段(详见文档)。超级块损坏会导致整个文件系统无法挂载。
4. 块组描述符表(GDT)
每个块组在GDT中有一个struct ext2_group_desc条目,包含:
-
bg_block_bitmap:块位图所在的块号 -
bg_inode_bitmap:inode位图所在的块号 -
bg_inode_table:inode表起始块号 -
bg_free_blocks_count:该组空闲块数 -
bg_free_inodes_count:该组空闲inode数 -
bg_used_dirs_count:该组目录数
通过GDT,操作系统可以快速定位每个块组的管理信息。
5. 位图(Bitmap)
-
块位图:每个bit对应一个数据块,1表示已分配,0表示空闲。
-
inode位图:每个bit对应一个inode,1表示已使用,0表示空闲。
创建新文件时,文件系统会在位图中查找空闲inode和空闲数据块,分配后置位。
6. inode表(Inode Table)
-
连续存储一组inode结构(每个inode固定大小,如128字节)。
-
inode号从1开始,全局唯一(整个分区内)。inode号可以计算出它属于哪个块组以及在该组inode表中的偏移。
inode与块组的对应关系:
设每个块组有inodes_per_group个inode,则inode号N属于块组(N-1) / inodes_per_group,组内索引为(N-1) % inodes_per_group。
7. 数据块(Data Blocks)
-
存储文件的实际内容(普通文件)或目录项列表(目录文件)。
-
文件系统使用块号访问数据,块号是相对于分区起始的,不能跨分区。
8. inode与数据块的映射------直接、间接块索引
每个inode中包含15个i_block指针(EXT2_N_BLOCKS = 15),它们组成一个多级索引结构:
text
i_block[0] ───► 直接块(12个)
i_block[1]
...
i_block[11]
i_block[12] ───► 一级间接块(指向一个数据块,该块内存储多个块号)
i_block[13] ───► 二级间接块
i_block[14] ───► 三级间接块
计算最大文件大小(以4KB块、4字节块号为例):
-
直接块:12 * 4KB = 48KB
-
一级间接:一个块可存放 4KB/4 = 1024 个块号 → 1024 * 4KB = 4MB
-
二级间接:1024 * 1024 * 4KB = 4GB
-
三级间接:1024 * 1024 * 1024 * 4KB = 4TB
因此ext2支持的最大文件大小为4TB(受限于块号和块大小)。
9. 创建一个新文件的过程(以touch abc为例)
-
分配inode:扫描inode位图,找到空闲inode(如inode 263466),将其标记为使用,并将文件属性(大小、权限、时间等)写入inode表。
-
分配数据块 :根据文件内容大小,从块位图中找空闲块(如300、500、800),将这些块号填入inode的
i_block数组(或间接块)。 -
记录分配:将块号列表写入inode的块指针区域。
-
添加目录项 :在当前目录的数据块中增加一条记录,包含文件名
abc和inode号263466。
10. 删除文件的过程
-
在目录中找到文件名对应的inode号。
-
将该inode的硬链接计数减1(
i_links_count--)。 -
若硬链接计数变为0,则释放inode(清空inode位图),并释放所有数据块(清空块位图)。
-
从目录中删除目录项。
这就是为什么
rm删除文件后,数据可能还能恢复(只要块未被覆盖)。
11. 小结
ext2文件系统通过块组、位图、inode表和多级索引实现了对磁盘空间的高效管理。理解这些结构是掌握文件恢复、磁盘修复、性能调优的基础。下一篇我们将讨论目录的实现、路径解析、挂载以及软硬链接。