RK3588 kernel-6.1 fs/ext4 源码目录架构详解

RK3588 kernel-6.1 fs/ext4 源码目录架构详解

本文基于 Linux 6.1 树中 rk3588/kernel-6.1/fs/ext4 目录,从 VFS 注册、内存与磁盘结构、各 .c 文件职责、子系统协作 四个维度给出可对照源码阅读的说明,便于在 RK3588(eMMC/UFS 等块设备上常用 ext4)上做调试与裁剪。


1. 目录与构建

1.1 源文件清单(与 Makefile 一致)

ext4 驱动在 fs/ext4/Makefile 中链接为单一模块对象 ext4.o,由以下 核心 .o 组成(必选):

对象 源文件 主要职责
balloc.o balloc.c 传统/compat 块分配、块位图与组内计数(与 mballoc 配合)
bitmap.o bitmap.c 块组位图、inode 位图读校验与内存侧辅助
block_validity.o block_validity.c 系统块区域 rbtree,防止数据块与元数据区重叠
dir.o dir.c 目录项(非(htree)线性部分)、readdir、目录块 I/O
ext4_jbd2.o ext4_jbd2.c JBD2 日志对接:事务、handle、元数据提交
extents.o extents.c extent 树 读写、分裂合并、与 map_blocks 核心逻辑
extents_status.o extents_status.c ES 树:内存中逻辑块→物理/状态的缓存,优化延迟分配与回写
file.o file.c open/read_iter/write_iter/mmap/fallocate、DAX/iomap、ioctl(部分)、O_DIRECT
fsmap.o fsmap.c FS_IOC_GETFSMAP 块设备映射查询
fsync.o fsync.c fsync/fdatasync、journal 与 data=ordered 语义
hash.o hash.c 目录 htree 哈希(与 namei 配合)
ialloc.o ialloc.c inode 分配、inode 位图、组内策略
indirect.o indirect.c 非 extent 兼容路径下的间接块映射(老格式)
inline.o inline.c 内联数据(小文件数据在 inode 内)
inode.o inode.c inode 读写、时间戳、ext4_map_blocks、页缓存配合、truncate 协作
ioctl.o ioctl.c ext4_ioctl:标签、feature、group desc、迁移、物理整理等
mballoc.o mballoc.c 多块分配器 (mballoc):buddy、预分配、CR 扫描策略
migrate.o migrate.c extent 与 non-extent 间迁移等
mmp.o mmp.c Multi-Mount Protection,防同一设备被并发挂载损坏
move_extent.o move_extent.c EXT4_IOC_MOVE_EXT:块在文件间交换(高级维护)
namei.o namei.c 路径解析、lookup/create/link/unlink/rename、htree
page-io.o page-io.c 元数据页/日志相关页写下的 bio 提交封装
readpage.o readpage.c address_space read_folio/readahead 与extent 预读
resize.o resize.c 在线扩容:组描述符、位图增长
super.o super.c 挂载/卸载、fill_super、super 读写、feature 检查、file_system_type
symlink.o symlink.c 符号链接 inode 与快/慢路径
sysfs.o sysfs.c sysfs 导出统计与可调参数
xattr.o + hurd/trusted/user xattr*.c 扩展属性后端(内部块、trusted、user、hurd)
fast_commit.o fast_commit.c 快速提交:增量 journal 路径
orphan.o orphan.c orphan 文件/链表:崩溃恢复时截断已删仍打开的 inode

按 Kconfig 条件编译:

  • acl.o:POSIX ACL(CONFIG_EXT4_FS_POSIX_ACL
  • xattr_security.o:SELinux 等安全标(CONFIG_EXT4_FS_SECURITY
  • verity.o:fsverity(CONFIG_FS_VERITY
  • crypto.o:fscrypt 加密(CONFIG_FS_ENCRYPTION
  • inode-test.o:KUnit(CONFIG_EXT4_KUNIT_TESTS

头文件要点:ext4.h(超级块/inode 内存结构、宏与内联)、ext4_extents.hext4_jbd2.hmballoc.hxattr.hacl.hfsmap.htruncate.h

1.2 Kconfig 依赖

CONFIG_EXT4_FSselect JBD2CRC16CRYPTOCRYPTO_CRC32CFS_IOMAP 等;可选 EXT4_USE_FOR_EXT2 在禁用独立 ext2 驱动时用 ext4 同时注册 ext2。详见 fs/ext4/Kconfig


2. VFS 注册与挂载路径

2.1 file_system_type

super.c 中定义 ext4 文件类型并注册:

1
2
3
4
5
6
7
8
static struct file_system_type ext4_fs_type = {
.owner = THIS_MODULE,
.name = "ext4",
.init_fs_context = ext4_init_fs_context,
.parameters = ext4_param_specs,
.kill_sb = kill_block_super,
.fs_flags = FS_REQUIRES_DEV | FS_ALLOW_IDMAP,
};
  • init_fs_context:挂载参数解析(fs_context_operationsparse_paramget_treereconfigurefree)。
  • get_tree:典型为 get_tree_bdev(fc, ext4_fill_super)(6.1 新挂载 API)。
  • kill_sb:通用 kill_block_supersuper.c 释放块设备与 super)。

同一文件中还注册 ext3;在 EXT4Use_FOR_EXT2 且未编 ext2 时可注册 ext2 别名。

2.2 模块初始化顺序(子系统就绪)

ext4_init_fs() 中顺序(摘自 super.c 尾部逻辑):
ratelimitext4_init_es(extent status)→ ext4_init_pendingext4_init_post_read_processingext4_init_pageioext4_init_system_zoneext4_init_sysfsext4_init_mballocinit_inodecachefast commit dentry cache → 注册 ext3/ext2 → register_filesystem(&ext4_fs_type)

卸载时按相反顺序撤销。理解此顺序有助于排查 初始化失败 时哪一步返回错误。

2.3 锁顺序(官方注释)

super.c 文件头给出 ext4 在 缺页、缓冲写、truncate、DIO、writepages 上的锁依赖,调试死锁时应优先对照:

1
2
3
4
5
6
7
8
9
10
11
* Lock ordering
*
* page fault path:
* mmap_lock -> sb_start_pagefault -> invalidate_lock (r) -> transaction start
* -> page lock -> i_data_sem (rw)
*
* buffered write path:
* sb_start_write -> i_mutex -> mmap_lock
* sb_start_write -> i_mutex -> transaction start -> page lock ->
* i_data_sem (rw)
* ... (truncate / direct IO / writepages)

3. 核心数据结构(内存与磁盘)

3.1 struct ext4_inode_info

每个 VFS struct inode 通过 EXT4_I(inode) 得到 ext4_inode_info,挂载在 inode 尾部 vfs_inode。要点(见 ext4.h):

  • i_data[]:未转换的 15 项传统块指针(与 extent 共存时代的兼容/起点)。
  • i_block_group:inode 所在块组,用于 局部性分配
  • i_disksize vs i_sizei_disksize 表示 盘上 已提交长度,truncate 与恢复关键。
  • i_data_sem:截断与 get_block/extent 修改之间的串行。
  • i_es_tree / i_es_lockextent status 缓存树。
  • i_prealloc_*mballoc 预分配 链表与锁。
  • i_fc_*fast commit 跟踪。
  • xattr_sem:扩展属性与数据写分离锁。
  • jinode:JBD2 对该 inode 的附加信息。

3.2 struct ext4_sb_info

EXT4_SB(sb) 指向 per-mount 的超级块运行态:s_es 指向磁盘 super 在 buffer_head 中的镜像;s_journals_mount_opt(s)mballoc 的 s_group_info/s_mb_*s_es_shrinkerquota/fscrypt/dax 等均在此。细节字段见 ext4.hstruct ext4_sb_info(篇幅长,适合按需 grep)。

3.3 磁盘布局(概念)

  • 超级块 + 块组描述符表 + 每块组:块位图、inode 位图、inode 表、数据区。
  • extent:大部分现代 ext4 文件用 extent B+ 树 描述 (logical block → physical block, len)
  • bigalloccluster(多 block 为分配单位),宏 EXT4_CLUSTER_*ext4.h
  • journal:默认 JBD2ext4_jbd2.c 包装 start_commitext4_journal_get_write_access 等。

4. 子系统协作(数据路径)

4.1 块映射总线:ext4_map_blocksinode.c

用户读写、缺页、get_block 最终都汇聚到 逻辑块 → 物理块 映射:

  • 查/更新 extent 树extents.c);
  • 参考 extent statusextents_status.c)避免重复扫描、支持 DELALLOC;
  • 延迟分配:可先只更新 ES 与 inode,稍后 mballoc 落地;
  • 未写 extent: unwritten 标记,回写后转换。

4.2 块分配:mballoc.c + balloc.c

  • mballoc 为主路径:按 buddy、per-group 信息、prealloc 做高性能分配;
  • balloc 补充位图读写、计数维护及与老接口的衔接。

4.3 日志:ext4_jbd2.c + ext4_jbd2.h

  • 元数据块通过 journal 先行记录 再写原位;
  • data=ordered / writeback / journal 等 data 模式影响 数据块 与日志顺序;
  • fast_commitfast_commit.c)在支持的配置上减少全事务开销。

4.4 目录与 Htree:namei.c + dir.c + hash.c

  • namei.cVFS inode_operationslookup/mkdir/...、rename 复杂路径;
  • dir.c目录块 格式、readdir
  • hash.chtree 哈希与冲突处理。

4.5 页缓存与 I/O:readpage.cfile.cpage-io.cfsync.c

  • 缓冲 I/Oaddress_space_operationsinode.c/readpage.c 等分散设置;
  • file.ciomap/daxext4_iomap_ops、Direct I/O、fallocate
  • page-io.c:下层 bio 提交与日志相关的页写出;
  • fsync.c:保证 journal + 脏页序。

4.6 扩展属性与安全:xattr*.cacl.cxattr_security.c

  • xattr.c:EA 与 inode、块存储格式;
  • acl.c:POSIX ACL 与 generic_acl 桥接;
  • xattr_security.c:安全模块使用的 xattr 名空间。

4.7 运维与特性:ioctl.cresize.cmmp.csysfs.c

  • ioctl.c:在线 resize 协助、feature 操作、组参数、物理丢弃/搬迁等 EXT4_IOC_*
  • resize.c:扩容时增长 group desc、位图;
  • mmp.c:多挂载防护周期写块;
  • sysfs.c:导出 mballoc 等统计与参数。

4.8 仅当配置开启

  • crypto.cfscrypt: per-file/目录密钥、块内加密;
  • verity.c:merkle 树校验只读内容;
  • veritydaxs_daxdevext4_sb_info):读路径旁路页缓存需与 extent/一致性小心配合。

5. 整体数据流简图

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
用户 read/write/mmap
|
V
VFS (file_operations / address_space)
|
v
file.c / inode.c / readpage.c
|
v
ext4_map_blocks + extents + extents_status
|
+--> mballoc/balloc (新块)
|
v
page cache / bio 或 iomap DIO
|
v
ext4_jbd2 (+ fast_commit) 元数据顺序
|
v
块设备 (eMMC/UFS/NVMe/...)

6. RK3588 相关注意点

  • 根文件系统 / userdata:RK 方案常见 ext4 + f2fs;ext4 多用于 boot、vendor、system 等只读/读写分区。
  • 性能与磨损:关注 barrier/nobarrier(随内核演进注意语义变化)journal_async_commitdelalloc、挂载选项与存储控制器 cache;MMP 在生产上避免双挂同卷。
  • 裁剪:若不需要 ACL/security/verity/encryption,可在 Kconfig 关掉对应选项以减小 ext4 模块体积。
  • 调试CONFIG_EXT4_DEBUG、tracepoints(CREATE_TRACE_POINTS + trace/events/ext4.h)、sysfs 统计。

7. 推荐阅读顺序(读源码)

  1. super.cext4_fill_superext4_parse_paramext4_reconfigure、feature 与错误处理。
  2. ext4.hext4_inode_infoext4_sb_infoext4_map_blocks
  3. inode.cext4_map_blocks、dirty 与 writeback 交互。
  4. extents.c + extents_status.c:现代 ext4 的核心。
  5. mballoc.c + balloc.c:分配策略。
  6. ext4_jbd2.c + fast_commit.c:一致性与性能。
  7. namei.c + dir.c:目录与 rename。
  8. file.c:mmap/DIO/fallocate。
  9. 按需:resize.cioctl.corphan.cmmp.c

8. 小结

fs/ext4 是完整的 fourth extended 实现:在 VFS 层注册为块设备文件系统,通过 ext4_sb_info / ext4_inode_info 维护挂载与 inode 状态;extent + extent status + mballoc + JBD2(及 fast commit) 构成现代数据与元数据路径;namei/dir/hash 负责命名空间;xattr/acl/security/verity/crypto 提供策略与保密完整性;resize/ioctl/sysfs/mmp/orphan 覆盖工程与可靠性需求。上述与 Makefile 中 .o 列表一一对应,可按表索骥阅读。


文档对应内核树路径:rk3588/kernel-6.1/fs/ext4/。生成位置:linuxDoc/fs/ext4/

文章互动

阅读 --

留言

0 条留言

正在加载留言…