RK3588 kernel-6.1 fs/ext4/fast_commit.c 快速提交(Fast Commit)分析

RK3588 kernel-6.1 fs/ext4/fast_commit.c 快速提交(Fast Commit)分析

1. 分析范围

  • rk3588/kernel-6.1/fs/ext4/fast_commit.c(Ext4 细粒度日志 与 JBD2 fast commit 对接:跟踪、落盘、恢复)
  • 盘上 TLV 布局与 tag 定义:fs/ext4/fast_commit.h(注释要求与 e2fsprogs 同源头文件 字节一致
  • JBD2 侧:jbd2_fc_begin_commit / jbd2_fc_end_commit / fallback、replay 回调注册等(本文件只实现 ext4 策略与 j_fc_replay_callback

2. 代码作用(一句话)

在挂载选项允许时,把一次事务里对元数据的改动记成 TLV(tag-length-value)增量日志 追加进 journal 的 fast commit 区;fsync/事务提交时优先只刷这些增量与用户数据,再写 TAIL(CRC + TID) 保证原子可见性;恢复阶段按 TLV 重放目录项、inode 体、extent 增删等 终态,无法覆盖的操作则 ext4_fc_mark_ineligible 回退 完整 jbd2 commit


3. 解决了什么问题

问题 处理方式
传统 full commit 对小块元数据也要整块/大批 buffer 记账,延迟与 I/O 放大 符合条件 的事务只写 紧凑 TLV 序列 + 相关 inode 数据刷盘,减少相对 full commit 的工作量(具体收益依赖负载)
仍需与现有 jbd2 事务模型兼容 ext4_fc_commitjbd2_fc_begin_commit 栅栏内工作;失败走 jbd2_fc_end_commit_fallback → 等价于完成 full transaction
部分 VFS/元数据操作难以表达为安全增量 ext4_fc_mark_ineligible 设置 EXT4_MF_FC_INELIGIBLEs_fc_ineligible_tid,此后直到对应 TID 的提交只做 full commit(见 fast_commit.hEXT4_FC_REASON_*)
崩溃后如何认定一段 fast commit 有效 每条 fast commit 以 EXT4_FC_TAG_TAIL 结束,内含 事务 TID从头到尾 CRCreplay 仅当校验通过;日志里可存在 多个 TAIL(多次 fsync 的示意见文件头注释)
重放须幂等 不记「过程」而记 可重复的终态(如 rename 记成 link/unlink + inode 片段);文件开头用 rm/mv 例子说明
CREATE 需先有 inode 再有目录项 ext4_fc_commit_dentry_updatesCREAText4_fc_write_inode / ext4_fc_write_inode_data 再写 dentry TLV,恢复时可当「无名 inode 再链接」
ADD_RANGE 重放时分配器可能占掉将被指派的块 SCAN 阶段 ext4_fc_record_regions 收集 (ino, lblk, pblk, len)ext4_fc_replay_check_excluded 在回放分配路径中排除这些物理块
与并发更新的竞态 ext4_fc_start_update / ext4_fc_stop_update:某 inode 若在本次 fast commit 列表中,通过 EXT4_STATE_FC_COMMITTING + 等待队列,避免 提交过程中继续改同一 inodeext4_fc_track_templatei_sync_tid 区分同一事务内首次/更新跟踪
日志与数据设备分离 ext4_fc_perform_commit 在写 fast commit 块前对 journal->j_fs_dev blkdev_issue_flush,避免数据未落盘而元数据日志已可见
inode / extent / ES 树在重放时的语义 重放期间 **`s_mount_state

4. TLV 类别(与 fast_commit.h 一致)

Tag 含义(概要)
HEAD feature 掩码 + 本段 fast commit 起始 TID
UNLINK / LINK / CREAT 目录项删除、添加、创建(值体 ext4_fc_dentry_info:父 ino、子 ino、名字)
ADD_RANGE 某 inode 新增 extent(盘上 12 字节 ext4_extent 嵌入)
DEL_RANGE 逻辑块区间删除
INODE 需回放的 raw inodeiblocks 等由重算而非直接信任)
PAD 对齐填充
TAIL CRC + TID,标识本段 fast commit 完整结束

5. 提交路径概要(ext4_fc_perform_commit

文件头注释给出的顺序与实现对应关系:

  1. ext4_fc_submit_inode_data_all / ext4_fc_wait_inode_data_all:参与本次提交的 inode 用户数据先下发并等待(ordered 语义相关)。
  2. 外挂 journal 时 flush 文件系统设备
  3. 若本 TID 下首次 fast commit,写 HEAD TLV。
  4. ext4_fc_commit_dentry_updates:目录项队列刷成 TLV(CREAT 先 inode 再 dentry)。
  5. 遍历 s_fc_q[FC_Q_MAIN]FC_COMMITTING 的 inode:数据inode TLV。
  6. ext4_fc_write_tail:写 TAIL,固化 CRC。

入口 ext4_fc_commitjbd2_fc_begin_commit → 检查 ineligibleext4_fc_perform_commitjbd2_fc_wait_bufsjbd2_fc_end_commit;任一步失败则 jbd2_fc_end_commit_fallback 并更新统计为 FAILED/INELIGIBLE

队列 staging: 若在 full / fast commit 正在进行JBD2_FULL_COMMIT_ONGOING / JBD2_FAST_COMMIT_ONGOING),新跟踪的 inode 与 dentry 进入 FC_Q_STAGING,在 ext4_fc_cleanupspliceMAIN


6. 跟踪入口(与 namei/写路径的关系)

  • ext4_fc_track_link / track_unlink / track_create:目录操作时入 s_fc_dentry_q;加密目录名导致 -EOPNOTSUPPEXT4_FC_REASON_ENCRYPTED_FILENAME
  • ext4_fc_track_inode:inode 元数据变化。
  • ext4_fc_track_range:extent 层逻辑块区间增删。
  • 以上经 ext4_fc_track_template 可将 inode 挂入 s_fc_q,并与 当前 handle 的 TID 绑定。

7. 恢复路径(ext4_fc_replay

  1. PASS_SCANext4_fc_replay_scan 顺序解析 TLV,维护 滚动 CRC,遇到合法 TAILTID/CRC 匹配 则确定 fc_replay_num_tagsADD_RANGE 同时 ext4_fc_record_regions。异常短包/未知 tag 等返回 STOP 或错误码,由 JBD2 决定是否中止本段。
  2. 重放 pass:逐 tag 调用 ext4_fc_replay_*unlink / link / create / add_range / del_range / inode)。计数耗尽后 ext4_fc_set_bitmaps_and_counters 等收尾。
  3. ext4_fc_init:即使 未启用 fast commit 挂载选项,仍注册 j_fc_replay_callback,以便挂载 旧日志 时仍能重放曾写入的 fast commit 块。

清理与 EXT4_FC_REPLAY 复位见 ext4_fc_replay_cleanup(在文件后部,与卸载/重放结束配合)。


8. 文件内记载的 TODO / 限制(阅读源码时值得注意)

  • Replay 路径若全面用 journal handle 做原子化、以及在重放前持久化 FC_REPLAY 超块状态,可进一步加固 重放中途崩溃 的场景(注释 TODO 0)。
  • Fast commit 提交路径曾注释 全文件系统级锁 的代价;后续可更多把 ext4_fc_start/stop_updatejournal_start/stop 对齐以缩小锁粒度(TODO 1)。
  • 更多 ineligible 场景 待覆盖(TODO 2)。

9. 小结

fast_commit.c 不是替代 ext4 的 extent/目录 实现,而是在 JBD2 之上增加一条 「记录终态增量」 的快速提交通道:目录与 inode 变更 + 块区间增删 可在一次 fsync 相关提交中以较少日志体积落盘;通过 TAIL CRC幂等 TLV 设计回放前 SCAN块排除列表 控制正确性;不适用的操作统一 ext4_fc_mark_ineligible 回退 full journal commit。分析某条元数据路径是否走 fast commit,应在业务代码中搜索 ext4_fc_track_*ext4_fc_mark_ineligible,并与本文件的 commit/replay 流程对照。

文章互动

阅读 --

留言

0 条留言

正在加载留言…