深入剖析 Linux Ext 系列文件系统:从磁盘物理架构到逻辑组织
1. 磁盘存储的物理与逻辑基础
理解文件系统的前提是了解其底层载体——磁盘。磁盘的物理结构由多个盘片组成,每个盘片正反两面均可存储数据,并对应独立的读写磁头。
物理寻址:CHS 模式
在物理层面,定位数据的过程被称为 CHS 定址:
- Cylinder(柱面):首先确定磁头所在的半径位置。
- Head(磁头):确定具体的盘面。
- Sector(扇区):盘片高速旋转,磁头在特定轨迹上读取目标扇区。
逻辑抽象:LBA 模式
为了方便操作系统管理,物理上的圆形磁道被抽象为线性的逻辑空间,即 LBA (Logical Block Address)。这类似于将卷起来的磁道"拉直"成一个巨大的一维数组。
操作系统与磁盘交互时,通常不以 512 字节的扇区为单位,而是以"块(Block)"为基本单位(常见为 4KB,即连续的 8 个扇区)。以下是 LBA 与 CHS 的逻辑转换关系(简化表达):
// 逻辑地址计算示例
LBA = (柱面号 * 总磁头数 * 每磁道扇区数) + (磁头号 * 每磁道扇区数) + (扇区号 - 1);
// CHS 解析示例
磁头号 = (LBA / 每磁道扇区数) % 总磁头数;
柱面号 = LBA / (总磁头数 * 每磁道扇区数);
扇区号 = (LBA % 每磁道扇区数) + 1;
2. 文件系统的核心概念
块 (Block)
块是文件存储的最小逻辑单位。即使文件只有 1 字节,也会占用一个完整的块。可以使用 stat 命令查看块占用情况:
$ stat my_data.txt
File: ‘my_data.txt’
Size: 1024 Blocks: 8 IO Block: 4096 regular file
Device: fd01h/64769d Inode: 256123 Links: 1
...
inode:文件的身份标识
Linux 系统将文件的"内容"与"属性"分开存储。每个文件都有一个唯一的 inode(index node),用于记录文件的元数据(如大小、权限、所有者、所属组、时间戳以及数据块的指针)。
struct inode_metadata {
uint16_t mode; // 权限与类型
uint32_t uid; // 所有者ID
uint32_t size; // 文件大小
uint32_t atime; // 最后访问时间
uint32_t block_ptr[15]; // 指向数据块的指针
uint32_t inode_id; // inode 编号
};
注意:文件名并不存储在 inode 中,而是存储在目录的数据块中。
3. Ext2 文件系统布局
为了高效管理大规模磁盘空间,Ext2 文件系统将分区划分为多个块组 (Block Group)。典型的块组结构如下:
- Super Block (超级块):保存整个文件系统的全局信息(如块总量、空闲块数、挂载信息等)。为了防止损坏,超级块通常在多个块组中存有备份。
- Group Descriptor Table (GDT):存储块组的描述信息,指示 inode 表和数据块的具体位置。
- Block/Inode Bitmap:位图结构,记录哪些数据块或 inode 已被占用,哪些是空闲的。
- Inode Table:连续存储 inode 结构的区域。
- Data Blocks:实际存放文件内容的区域。
关于格式化:格式化的实质是初始化这些元数据区域(如清空位图),而不是物理擦除数据块,因此删除数据通常很快。
4. 目录与路径解析
在 Linux 中,目录也是一种文件。它的"内容"是文件名与对应 inode 编号的映射表。
当用户通过路径 /home/user/test.c 访问文件时,内核的操作流程如下:
- 从根目录
/的 inode 开始,在根目录的数据块中查找home的 inode。 - 进入
home目录的数据块,查找user的 inode。 - 以此类推,最终找到
test.c的 inode,进而读取其数据块。
为了提高效率,内核会使用 struct dentry(目录项)缓存这些路径信息,形成一棵内存中的树状结构。
挂载 (Mounting)
一个分区被格式化为特定文件系统后,必须挂载到现有的目录树中才能被访问。通过挂载点(目录路径前缀),内核可以识别该请求应当转发给哪个分区的文件系统驱动处理。
5. 软链接与硬链接
硬链接 (Hard Link)
硬链接是多个文件名指向同一个 inode 编号。它们在底层是平等的。
# 创建硬链接
$ ln source_file link_name
- 特点:inode 编号相同;删除其中一个文件名,文件内容依然存在,直到硬链接计数归零。
- 限制:不允许跨分区创建;为了防止目录环路,用户不能手动对目录创建硬链接。
软链接 (Symbolic Link)
软链接是一个独立的文件,拥有自己的 inode。它的内容存储的是指向目标文件的路径字符串。
# 创建软链接
$ ln -s /path/to/source symlink_name
- 特点:类似于 Windows 的快捷方式;inode 编号不同。
- 应用:可以跨分区创建;可以对目录进行链接。
通过 ls -li 可以清晰地看到 inode 的差异:
$ ls -li
1315789 -rw-r--r-- 2 root root 0 Mar 3 10:00 hard_link_sample
1315789 -rw-r--r-- 2 root root 0 Mar 3 10:00 original_file
1315800 lrwxrwxrwx 1 root root 13 Mar 3 10:01 soft_link_sample -> original_file