RK3588 kernel-6.1 fs/ext4/ioctl.c 用户态控制接口分析
1. 分析范围
rk3588/kernel-6.1/fs/ext4/ioctl.c(ext4_ioctl/ext4_compat_ioctl及若干 ioctl 辅助函数)- 入口挂载于
ext4_file_operations.unlocked_ioctl(见file.c);ext4_file_inode_operations.fileattr_get/set将 通用 fsxattr 转到本文件的ext4_fileattr_*→ext4_ioctl_setflags/ext4_ioctl_setproject
2. 代码作用(一句话)
ioctl.c 把 管理员与工具链 对 ext4 的控制请求集中到 __ext4_ioctl 的 switch:含 在线扩容、extent 迁移、延迟块刷盘、在线整理(move extent)、TRIM、卷标/UUID、加密/fsverity、getfsmap、journal checkpoint/shutdown、extent 状态缓存查询 等;并实现 超块(主+备份)批量更新、inode 标志位(chattr 语义)与 project id 的安全修改。
3. 解决了什么问题
| 问题 | 处理方式 |
|---|---|
用户态需要改 i_flags(immutable、append、extent、DAX、casefold dir 等) |
ext4_ioctl_setflags:CAP_SYS_RESOURCE 才能动 JOURNAL_DATA;DAX 与 verity/互斥标志 校验 dax_compatible;CASEFOLD 仅空目录且具备 casefold feature;EXTENTS_FL 切换可触发 migrate;改前 inode_dio_wait + 写回脏页;ext4_fileattr_set 先掩 EXT4_FL_USER_MODIFIABLE 再调 ext4_ioctl_check_immutable |
| project quota | ext4_ioctl_setproject(feature 开关下编译) |
NFS 等依赖的 i_generation |
EXT4_IOC_GET/SETVERSION(_OLD);metadata_csum 下 SET 被拒绝(-ENOTTY) 以免破坏校验模型 |
| 在线扩卷 / 加块组 | EXT4_IOC_GROUP_EXTEND、EXT4_IOC_GROUP_ADD、EXT4_IOC_RESIZE_FS:与 resize.c 协作;journal 路径 lock + flush;bigalloc 对部分命令 -EOPNOTSUPP;resize 标 fast commit ineligible |
| 间接块文件迁到 extent | EXT4_IOC_MIGRATE → ext4_ext_migrate |
| 强制落延迟分配 | EXT4_IOC_ALLOC_DA_BLKS → ext4_alloc_da_blocks |
| 交换启动扇区 inode | EXT4_IOC_SWAP_BOOT |
| 块设备 discard 告知 SSD | FITRIM → ext4_trim_fs;CAP_SYS_ADMIN;NOLOAD+有 journal 时 -EROFS |
| 把另一文件的 extent 搬到本文件(defrag) | EXT4_IOC_MOVE_EXT → ext4_move_extents;bigalloc/DAX 不支持 |
| 卷标、UUID | FS_IOC_GET/SETFSLABEL、EXT4_IOC_GET/SETFSUUID;UUID 变更在 metadata_csum 且无 csum_seed 等条件下 -EOPNOTSUPP |
| 物理块占用图 | FS_IOC_GETFSMAP → ext4_ioc_getfsmap(见 fsmap.c 文档) |
| fscrypt | FS_IOC_SET/GET_*_ENCRYPTION_*、ADD/REMOVE_ENCRYPTION_KEY 等 转 fscrypt 子系统 |
| fsverity | FS_IOC_ENABLE/MEASURE/READ_VERITY_METADATA |
| extent 预读 | EXT4_IOC_PRECACHE_EXTENTS |
| 调试/一致性:看内存 ES 缓存 | EXT4_IOC_GET_ES_CACHE(fiemap 形态)、EXT4_IOC_CLEAR_ES_CACHE |
| 超块状态查询、强制关机 | EXT4_IOC_GETSTATE、EXT4_IOC_SHUTDOWN(ext4_shutdown:默认 / flush log / no flush) |
| journal checkpoint | EXT4_IOC_CHECKPOINT(CAP_SYS_ADMIN,标志控制 flush 等) |
| 32 位兼容 ioctl 编号 | ext4_compat_ioctl:把 EXT4_IOC32_* 映射到 native 或 手工 unpack compat_ext4_new_group_input |
超块一致性: ext4_update_superblocks_fn:抢 EXT4_FLAGS_RESIZING;事务内更新 主超块 + 至多两个备份(其余备份 非日记或同步写);ext4_update_backup_sb 校验 备份超块 csum。
4. __ext4_ioctl 命令表(按功能归类)
| 类别 | 命令(节选) |
|---|---|
| 映射/空间 | FS_IOC_GETFSMAP,FITRIM |
| inode 代际 | *EXT4_IOC_GETVERSION / SETVERSION / _OLD |
| 卷管理 | EXT4_IOC_GROUP_EXTEND,EXT4_IOC_GROUP_ADD,EXT4_IOC_RESIZE_FS |
| 文件布局 | EXT4_IOC_MIGRATE,EXT4_IOC_MOVE_EXT,EXT4_IOC_PRECACHE_EXTENTS,EXT4_IOC_ALLOC_DA_BLKS |
| 启动扇区 | EXT4_IOC_SWAP_BOOT |
| 加密 | FS_IOC_ENCRYPTION |
| verity | FS_IOC_ENABLE/MEASURE/READ_VERITY_METADATA |
| ES 树 | EXT4_IOC_GET_ES_CACHE,EXT4_IOC_CLEAR_ES_CACHE |
| 运行状态 | EXT4_IOC_GETSTATE,EXT4_IOC_SHUTDOWN,EXT4_IOC_CHECKPOINT |
| 卷标识 | FS_IOC_GET/SETFSLABEL,EXT4_IOC_GET/SETFSUUID |
未在 switch 中出现的 旧式 EXT4_IOC_GET/SETFLAGS 由 VFS fileattr 路径覆盖(ext4_fileattr_get/set)。
5. 与其它文件的边界
| 需求 | 实现主体 |
|---|---|
| 实际搬 extent | move_extent.c |
| resize / group add | resize.c 等 |
| trim 算法 | mballoc.c / ioctl.c 仅转发 |
| getfsmap 遍历 | fsmap.c |
| 设置加密策略细节 | fscrypt |
6. 小结
ioctl.c 几乎不负责 「算法本身」,负责 权限、拷贝用户内存、与 mnt_want_write、日记 handle、feature 位、bigalloc/DAX 限制 的守门,并把请求 委派到 ext4 其它模块或内核通用子系统。新增 ioctl 时应在本文件 __ext4_ioctl 增加 case,并评估 compat 与 CAP_ / mnt* 语义。
正在加载留言…