Iomap、Direct I/O 与 DAX
1. Iomap
fs/iomap/ 用 struct iomap 描述文件逻辑范围到后端的映射:
- mapped;
- hole;
- delalloc;
- unwritten;
- inline;
- extent offset/length/address/flags。
文件系统实现 iomap_ops->iomap_begin/end,公共层实现 buffered I/O、direct I/O、seek、fiemap、swapfile 和 writeback helper。
2. Buffered iomap
iomap_file_buffered_write():
- 请求当前 extent iomap;
- 获取/创建 page-cache folio;
- 准备部分块;
- copy user data;
- mark dirty;
- iomap_end 提交文件系统状态。
XFS 等深度使用 iomap,ext4 部分路径也逐步采用。
3. Direct I/O
传统 direct-io.c 与 iomap DIO 均绕过 page cache 数据缓存:
1 | read/write_iter IOCB_DIRECT |
Direct I/O 不是“无缓存”:设备、控制器仍有 cache,metadata 也可能缓存。
4. Buffered 与 DIO 一致性
同一范围混用必须处理:
- flush/invalidate page cache;
- wait writeback;
- inode lock;
- outstanding DIO (
inode_dio_begin/end/wait); - truncate/punch hole;
- unwritten extent conversion。
应用随意混用 buffered 和 O_DIRECT 可能产生性能抖动。
5. Alignment
O_DIRECT 的地址、长度、offset 约束依文件系统和设备 logical block。错误通常 EINVAL,不要硬编码 4 KiB;可查询 statx DIO alignment(若支持)或按设备/文件系统要求。
6. DAX
dax.c 让持久内存/内存型块设备绕过 page cache 和传统 block I/O,CPU 直接访问映射:
- DAX fault 建立 PFN 映射;
- iomap 获取物理 extent;
dax_iomap_rw直接 copy/flush;- 与 truncate、reflink、GUP、memory failure 协同。
普通 eMMC/NVMe SSD 不等于 DAX 设备。RK3588 通常不使用 FS-DAX,除非平台有符合要求的内存型后端或特定 Rockchip ramdisk 配置。
7. 持久性
DAX 避免 page cache,但持久性仍要求:
- 正确 cache line flush;
- ordering/barrier;
- filesystem transaction;
- fsync/msync 语义;
- 设备 persistence domain。
8. 性能选择
| 模式 | 优点 | 代价 |
|---|---|---|
| buffered | readahead、write coalescing、低对齐要求 | 双重缓存/回写延迟 |
| direct | 应用控制缓存、减少 page cache 污染 | 对齐、并发和小 I/O 成本 |
| DAX | 直接 load/store、无 page cache | 硬件限制、fault/持久性复杂 |
应按真实 workload 测试,不能把 O_DIRECT 当作通用加速开关。
正在加载留言…