RK3588 kernel-6.1 fs/ext4/inline.c 内联数据与内联目录分析

RK3588 kernel-6.1 fs/ext4/inline.c 内联数据与内联目录分析

1. 分析范围

  • rk3588/kernel-6.1/fs/ext4/inline.csmall file / symlink / directoryinode 体内 存放数据或目录项;与 xattr.cinode.cdir.ciomap.c 协作)
  • 盘上表示:EXT4_INODE_INLINE_DATA;内容分为 ext4_inode->i_block 前一段固定长度 + 可选 system xattr "data" 的值域(见 EXT4_XATTR_SYSTEM_DATA

2. 代码作用(一句话)

inline.ci_extra_isize 与 inode 内 xattr 空间 允许时,把 小文件数据、快符号链接文本或整块小目录 塞进 inode 块;通过 ext4_find_inline_data_nolockiget 时定位 "data" xattr 与 i_inline_off/i_inline_size;读路径 readpage/iomapinline 映射为 IOMAP_INLINE 或填充第 0 页;写/增长若超出 ext4_get_max_inline_sizeext4_convert_inline_data_to_extent 等形式 转 extent + 普通块;目录在 i_block 里编码 .. 与线性 ext4_dir_entry_2,满则 ext4_convert_inline_data_nolock 落盘为传统目录块。


3. 解决了什么问题

问题 处理方式
极小文件仍占一整数据块,浪费空间与元数据 I/O inline data:数据在 i_block[] + xattr 扩展区;ext4_try_to_write_inline_data 优先扩 xattr,失败再 转换
符号链接目标短却占块 ext4_read_inline_link 等从 inline 区域读 快链 内容
空/小目录仅含少量项却要数据块 inline diri_block 头存 .. 的 ino,后继 ext4_dir_entry_2ext4_try_add_inline_entry 先塞 inode 内槽,再尝试 xattr 扩容,再 ext4_convert_inline_data_nolock
与 extent/块映射路径统一 超过容量或 ext4_prepare_inline_data 返回 -ENOSPCext4_convert_inline_data_to_extentext4_destroy_inline_data_nolock__block_write_begin + ext4_get_block 写道 → 置 extent;失败走 orphan + ext4_truncate_failed_write
延迟分配与 inline 交织 ext4_da_write_inline_data_begin / ext4_da_convert_inline_data_to_extentext4_convert_inline_dataMAY_INLINE 已清filemap_flush 收尾中途转换
readdir/htree 与 inline 目录 ext4_read_inline_dirext4_inlinedir_to_tree:合成 ./.. 假项,校验 ext4_check_dir_entry,向 fname 树 填哈希项(与 dir.c 一致)
iomap/DIO 需知道数据在 inode 里 ext4_inline_data_iomapIOMAP_INLINEaddr 指向 盘上 inode 缓冲区内 i_block 偏移
截断缩短 inline 文件 ext4_inline_data_truncate:同步缩 xattr 值i_block 尾部;必要时 ext4_es_remove_extent 清 stale ES
xattr 与 inline 空间竞争 get_max_inline_xattr_value_size:在 ibody xattr 布局下算 剩余可用值大小ext4_get_max_inline_size = 该值 + EXT4_MIN_INLINE_DATA_SIZE
外部 xattr inode 不允许挂 inline ext4_find_inline_data_nolocke_value_inum 非 0 → -EFSCORRUPTED
加密目录名等 inline 路径仍走 ext4_filename / fscrypt 与上层 namei(本文件侧重 存储格式

4. 存储布局(概念)

区域 含义
raw_inode->i_blockEXT4_MIN_INLINE_DATA_SIZE 文件/链接:内联数据前段;目录:前 EXT4_INLINE_DOTDOT_*.. parent ino,后方为目录项区起始
system xattr "data" 额外内联字节;i_inline_off 指向 xattr 项在 inode 映像中的偏移i_inline_size = 固定头 + xattr 值长

ext4_has_inline_dataEXT4_INODE_INLINE_DATA 等标志(定义见 ext4.h)。


5. 核心入口(导航)

符号 用途
ext4_get_max_inline_size / ext4_find_inline_data_nolock 容量与 iget 时发现 inline
ext4_create_inline_data / ext4_update_inline_data / ext4_prepare_inline_data 新建或扩容 inline
ext4_destroy_inline_data* 去掉 "data" xattr 与标志,恢复 extent 可建
ext4_readpage_inline / ext4_read_inline_data 读页/内存拷贝
ext4_try_to_write_inline_data / ext4_write_inline_data_end 缓冲写路径
ext4_convert_inline_data_to_extent 同步转块
ext4_try_add_inline_entry / ext4_delete_inline_entry / empty_inline_dir 目录项增删与空目录判断
ext4_try_create_inline_dir 创建时尝试 inline 目录
ext4_read_inline_dir / ext4_inlinedir_to_tree 遍历 / htree 装树
ext4_inline_data_iomap / ext4_inline_data_truncate / ext4_convert_inline_data iomap、截断、强制转换

6. 锁与兼容性

  • xattr_sem 保护 inline 元数据与 xattr 布局ext4_write_lock_xattr 在修改 xattr/inline 时用。
  • i_data_sem截断 等与 extent 共享逻辑时使用。
  • EXT4_STATE_MAY_INLINE_DATA尚允许继续 inlineENOSPCDIO 路径(见 file.c)可 清除,迫使 走块设备

feature:需 inline_data 等与 足够大的 s_inode_size/extra isizebigalloc 与旧式 indirect 组合由其它文件约束,inline 转换后统一走 extent 映射


7. 小结

inline.c「元数据即数据」 做到极致,显著减少 小文件/小目录/短 symlink块分配与碎片;代价是实现 与 xattr、日记、page cache、extent、目录哈希、加密 的多路径桥接。分析某 inode 是否 inline,看 EXT4_INODE_INLINE_DATAext4_has_inline_data;分析读写失败是否 触发转换,搜索 ext4_convert_inline 调用链。

文章互动

阅读 --

留言

0 条留言

正在加载留言…