当前位置: 首页 > news >正文

【Note】《深入理解Linux内核》 第十八章:深入理解 ext2 与 ext3 文件系统

《深入理解Linux内核》 第十八章:深入理解 ext2 与 ext3 文件系统

关键词:ext2、ext3、inode、超级块、块组、目录项、日志、文件块映射、文件系统挂载、文件系统操作接口、VFS挂钩


一、背景与简介

1.1 ext2 简介

ext2(第二扩展文件系统)是 Linux 长期使用的经典文件系统,拥有:

  • 简单高效的设计;
  • 灵活的元数据结构;
  • 良好的性能。

ext2 由于不支持日志机制,在非正常断电情况下存在一致性问题。

1.2 ext3 简介

ext3 是 ext2 的直接扩展:

  • 增加日志(journaling)功能
  • 提高文件系统一致性;
  • 保持与 ext2 完全兼容(可以直接挂载为 ext2);
  • 三种日志模式:journal、ordered(默认)、writeback。

二、磁盘结构布局

ext2/ext3 文件系统的磁盘结构分为若干块组(block group),每组包含以下信息:

Superblock
|
+-- Block Group Descriptors|+-- Block Bitmap+-- Inode Bitmap+-- Inode Table+-- Data Blocks

2.1 超级块(Superblock)

每个ext2/ext3文件系统都以一个超级块开始,包含整个文件系统的全局信息。

struct ext2_super_block {__u32 s_inodes_count;__u32 s_blocks_count;__u32 s_free_blocks_count;__u32 s_first_data_block;__u32 s_log_block_size;...
};

关键字段:

  • 总 inode / block 数量;
  • 空闲块/空闲 inode;
  • 每块大小(通过 s_log_block_size 计算);
  • 魔数验证(0xEF53);

2.2 块组描述符(Group Descriptor)

描述每个块组的结构布局:

struct ext2_group_desc {__u32 bg_block_bitmap;__u32 bg_inode_bitmap;__u32 bg_inode_table;__u16 bg_free_blocks_count;...
};

2.3 inode 表与数据块

每个块组有一个 inode 表(array of inodes)和 bitmap:

  • inode bitmap:标记当前组中哪些 inode 被占用;
  • block bitmap:标记数据块使用状态;
  • inode table:真正的 inode 存储区;
  • 数据块区:实际内容所在。

三、inode 与文件结构

3.1 inode 结构

每个文件或目录由一个 inode 表示:

struct ext2_inode {__u16 i_mode;__u16 i_uid;__u32 i_size;__u32 i_blocks;__u32 i_block[15];  // 数据块地址数组...
};

关键字段:

  • i_mode:文件类型与权限;

  • i_uid / i_gid:所有者信息;

  • i_size:文件大小;

  • i_block:最多可直接寻址12个块;

    • i_block[12]:一级间接块;
    • i_block[13]:二级间接;
    • i_block[14]:三级间接;

3.2 文件内容寻址

基于 inode 中的 i_block[]

  • 小文件(< 48KB):直接块(12个);
  • 中等文件(48KB~4MB):一级间接;
  • 大文件(4MB~数百MB):二级、三级间接;
  • 使用块缓存+缓冲区头缓存加速访问。

四、目录实现

4.1 ext2 目录项结构

struct ext2_dir_entry {__u32 inode;__u16 rec_len;__u8 name_len;__u8 file_type;char name[EXT2_NAME_LEN];
};

说明:

  • inode:文件 inode 编号;
  • rec_len:目录项实际长度;
  • name_len:文件名长度;
  • name:实际文件名;

4.2 目录遍历机制

  • 线性结构;
  • 不排序;
  • 查找复杂度 O(n);
  • 新版(ext3/ext4)引入 HTree 改进目录查找效率。

五、ext3 日志机制(Journaling)

5.1 为什么需要日志

ext2 文件系统在写操作崩溃时可能导致元数据损坏,需要使用 fsck 工具修复,代价高昂。

ext3 通过将元数据写入日志区,再写入真实数据区,实现原子性。

5.2 ext3 日志格式

  • 日志在文件系统中作为一个特殊 inode 管理;

  • 日志项包括:

    • transaction ID
    • block number
    • commit records
  • 日志使用循环缓冲结构。

5.3 日志模式

  • journal:数据和元数据都写入日志;
  • ordered:先写数据再写元数据(默认);
  • writeback:无顺序保证,性能最高,安全性最低。

5.4 日志恢复

挂载文件系统时,ext3 会自动检查日志区域并进行回滚或提交。


六、挂载流程

ext3_fill_super()└── ext3_get_sb()└── mount_bdev()└── get_sb_bdev()└── fill_super()└── ext3_setup_super()

关键点:

  • 检查超级块魔数;
  • 分配 super_block/inode 结构;
  • 初始化缓存;
  • 挂载点结构挂接到 VFS。

七、VFS 与 ext2/ext3 接口挂钩

7.1 注册文件系统

register_filesystem(&ext3_fs_type);

ext3 提供以下方法集:

struct file_system_type ext3_fs_type = {.name = "ext3",.mount = ext3_mount,.kill_sb = kill_block_super,
};

7.2 inode 操作集

struct inode_operations ext3_dir_inode_operations = {.lookup = ext3_lookup,.create = ext3_create,.unlink = ext3_unlink,...
};

7.3 file_operations

针对普通文件:

struct file_operations ext3_file_operations = {.read_iter = generic_file_read_iter,.write_iter = generic_file_write_iter,.fsync = ext3_fsync,
};

八、性能与限制

8.1 ext2/ext3 的优点

  • 简洁稳定;
  • 支持大文件;
  • 写入性能优秀;
  • ext3 日志机制显著提升可靠性。

8.2 缺点

  • 不支持延迟分配;
  • inode 静态分配;
  • ext2 无日志机制;
  • ext3 不支持动态元数据扩展(如 inode 数目);
  • ext3 性能与功能逐渐落后于 ext4、XFS、Btrfs。

九、调试与用户工具

  • tune2fs:调整参数(日志模式等);
  • fsck.ext2/ext3:文件系统检查;
  • dumpe2fs:查看文件系统内部结构;
  • debugfs:文件系统调试工具;
  • /proc/fs/ext3/:内核态调试信息导出接口;

十、源码路径参考

路径说明
fs/ext2/ext2 文件系统实现
fs/ext3/ext3 文件系统实现
include/linux/ext2_fs.h结构定义(超级块、inode)
fs/ext3/super.c挂载、卸载、日志挂钩
fs/ext3/inode.cinode 读写、写回逻辑
fs/ext3/dir.c目录项处理
fs/ext3/balloc.c块分配逻辑

十一、小结

  • ext2 是 Linux 的经典文件系统,设计简洁;
  • ext3 在 ext2 基础上增加了日志机制;
  • 块组结构设计优化了磁盘寻址;
  • inode 结构支持多层间接寻址;
  • ext3 的 ordered 模式在安全与性能之间取得良好平衡;
  • 它们是理解 Linux 文件系统层与 VFS 协作的极好切入点。
http://www.xdnf.cn/news/1082665.html

相关文章:

  • 每日学习问题记录
  • CppCon 2018 学习:STATE MACHINES BATTLEFIELD NAIVE VS STL VS BOOST
  • python实现简单的地图绘制与标记20250705
  • 智链万物:人工智能驱动的产业智能化革命
  • RocketMQ面试题
  • React Hooks全面解析:从基础到高级的实用指南
  • 『 C++入門到放棄 』- string
  • Python关键字梳理
  • 【MySQL进阶】错误日志,二进制日志,mysql系统库
  • React Native 开发环境搭建--mac--android--奔溃的一天
  • virtualbox+vagrant私有网络宿主机无法ping通虚拟机问题请教
  • Java创建型模式---单例模式
  • 如何在idea里快速地切换Windows CMD、git bash、powershell
  • Spring boot之身份验证和访问控制
  • 人工智能学习70-Yolo损失函数
  • Ubuntu:Mysql服务器
  • 08_容器化与微服务:构建弹性架构
  • 【Linux】自旋锁和读写锁
  • (LeetCode 面试经典 150 题) 14. 最长公共前缀 (字符串)
  • JVM与JMM
  • 全素山药开发指南:从防痒处理到高可用食谱架构
  • 虚拟机网络编译器还原默认设置后VMnet8和VMnet1消失了
  • 2025最新软件测试面试八股文
  • WPF学习笔记(24)命令与ICommand
  • 【Oracle专栏】分区表增加分区
  • 【机器学习深度学习】模型参数量、微调效率和硬件资源的平衡点
  • Linux:多线程---深入互斥浅谈同步
  • vue中添加原生右键菜单
  • LucidShape 2024.09 最新
  • FreeCAD傻瓜教程-拉簧拉力弹簧的画法及草图的附着位置设定和Part工作台中形体构建器的妙用