# ZVFS 分阶段改造计划(可重入,用户验收版) > 目标:把当前实现改造成可并发扩展、高性能且语义完整的架构。 > 约束:我无法使用 root,所有阶段验收由你执行。 ## 通用约定(所有阶段) - 建议先记录基线:`git rev-parse --short HEAD`。 - 每阶段都保持“可编译 + 可回归”。 - 每阶段完成后打一个里程碑 tag(例如 `phase1-done`),中断后可从最近 tag 继续。 - 验收命令默认: ```bash make -C zvfs -j4 make -C test -j4 env LD_PRELOAD=/home/lian/share/10.1-spdk/zvfs/zvfs/libzvfs.so ./test/bin/test_phase2_posix /zvfs ``` ## 已落地变更(2026-03-03) 1. **stale blob 自愈修复(已完成)** - `open(O_CREAT)` 遇到元数据引用失效 blob 时自动重建并回写元数据。 - `unlink/close(rename 覆盖)` 删除失效 blob 时容忍 `ENOENT/EINVAL`,避免误报 `EIO`。 2. **小块写合并(已完成)** - hook 层新增 per-fd writeback buffer(默认 128KB),连续小写先合并再 `pwrite`。 - 在 `read/pread/lseek/fsync/fdatasync/close/ftruncate/fallocate/unlink/rename/sync_file_range` 前补齐 flush,保证可见性。 3. **当前观察** - 小块写已提升,但小块读仍偏低;读优化作为后续阶段重点。 --- ## Phase 0:基线与护栏 ### 要做的事情 1. 固化当前行为基线:功能、性能、CPU 占用。 2. 在代码中加入轻量统计框架(计数器/延迟桶/开关),不改变行为。 3. 增加最小并发回归入口(并行跑现有测试)。 ### 用户验收 ```bash make -C zvfs -j4 && make -C test -j4 env LD_PRELOAD=/home/lian/share/10.1-spdk/zvfs/zvfs/libzvfs.so ./test/bin/test_phase2_posix /zvfs env LD_PRELOAD=/home/lian/share/10.1-spdk/zvfs/zvfs/libzvfs.so ./test/bin/test_single_file_perf /zvfs env LD_PRELOAD=/home/lian/share/10.1-spdk/zvfs/zvfs/libzvfs.so ./test/bin/test_single_file_random_perf /zvfs ``` ### 通过标准 - 功能测试通过。 - 有一份可复用的“基线性能记录”(IOPS/BW/延迟)。 ### 可重入说明 - 仅增量加观测代码,可重复执行,不影响后续阶段。 --- ## Phase 1:全局运行时与并发安全 ### 要做的事情 1. 引入 `zvfs_runtime_t`,统一管理 mount/init 状态与全局资源。 2. 用 `pthread_once + mount mutex` 保护初始化/挂载过程。 3. 给 inode/path/fd/dirs 操作补齐锁(rwlock + 细粒度 mutex)。 4. 保持接口不变:`open/read/write/...` 行为兼容。 ### 用户验收 ```bash make -C zvfs -j4 && make -C test -j4 env LD_PRELOAD=/home/lian/share/10.1-spdk/zvfs/zvfs/libzvfs.so ./test/bin/test_phase2_posix /zvfs for i in $(seq 1 8); do env LD_PRELOAD=/home/lian/share/10.1-spdk/zvfs/zvfs/libzvfs.so ./test/bin/test_dual_open_same_file /zvfs & done wait ``` ### 通过标准 - 无崩溃/死锁。 - 并发场景不出现随机 EBADF/ENOENT/元数据错乱。 ### 可重入说明 - 锁与 runtime 框架可独立提交;若中断,重新进入本阶段不会破坏状态。 --- ## Phase 2:Worker 化 IO 通路(替换单 global_thread) ### 要做的事情 1. 实现 worker 池(默认 N:M,支持配置 1:1)。 2. 每 worker 持有独立 `spdk_thread + io_channel`。 3. read/write/pread/pwrite 路径改为“提交到绑定 worker 执行”。 4. 保留同步 POSIX 语义,但去掉全局单线程瓶颈。 ### 用户验收 ```bash make -C zvfs -j4 && make -C test -j4 env LD_PRELOAD=/home/lian/share/10.1-spdk/zvfs/zvfs/libzvfs.so ./test/bin/test_phase2_posix /zvfs for i in $(seq 1 4); do env LD_PRELOAD=/home/lian/share/10.1-spdk/zvfs/zvfs/libzvfs.so ./test/bin/test_single_file_random_perf /zvfs & done wait ``` ### 通过标准 - 功能与 Phase 1 一致。 - 并发压测吞吐明显高于基线(目标 >= 1.5x,先达成趋势)。 ### 可重入说明 - worker 与旧路径可通过编译开关共存,出现问题可快速切回旧路径继续调试。 --- ## Phase 3:完成等待机制与批处理 ### 要做的事情 1. 用“提交队列 + 完成通知”替换纯 busy-poll `waiter`。 2. 增加批量 poll 与背压(队列满、超时、错误传播)。 3. 补齐延迟与队列深度指标,定位长尾。 4. 引入读路径流水线(允许并发 in-flight read),把有效 QD 从 1 提升到可配置值。 ### 用户验收 ```bash make -C zvfs -j4 && make -C test -j4 env LD_PRELOAD=/home/lian/share/10.1-spdk/zvfs/zvfs/libzvfs.so ./test/bin/test_single_file_perf /zvfs env LD_PRELOAD=/home/lian/share/10.1-spdk/zvfs/zvfs/libzvfs.so ./test/bin/test_single_file_random_perf /zvfs ``` ### 通过标准 - 在同等负载下 CPU 空转显著下降。 - P99 延迟较 Phase 2 收敛(无明显长尾恶化)。 ### 可重入说明 - 队列与等待层可单独演进;可先只替换 read,再替换 write。 --- ## Phase 4:页缓存与写回合并 ### 要做的事情 1. 引入 per-inode 4KB 页缓存(dirty/clean 状态)。 2. 小写走 cache + 延迟刷盘,大写/顺序写支持直写或批量写。 3. 引入 flush 策略:阈值、定时、fsync 强制。 4. 缩减 `resize + sync_md` 频率(chunk 预分配)。 5. 读性能专项: - 增加顺序读 readahead(如 128KB~1MB 窗口自适应)。 - 对齐读支持“直接读到用户缓冲”快路径,减少一次 memcpy。 - 引入 clean page cache(读热点复用,避免重复 blob read)。 ### 用户验收 ```bash make -C zvfs -j4 && make -C test -j4 env LD_PRELOAD=/home/lian/share/10.1-spdk/zvfs/zvfs/libzvfs.so ./test/bin/test_phase2_posix /zvfs env LD_PRELOAD=/home/lian/share/10.1-spdk/zvfs/zvfs/libzvfs.so ./test/bin/test_single_file_random_noaligned_perf /zvfs ``` ### 通过标准 - 功能语义不回退(truncate/sparse/rename/fstat 通过)。 - 小块随机写吞吐继续提升,写放大降低。 ### 可重入说明 - cache 可先只支持 write-through,再切 write-back;两步都可单独验收。 --- ## Phase 5:元数据日志化与 fsync 语义闭环 ### 要做的事情 1. `meta_save/load` 从文本快照升级为 WAL + checkpoint(带 CRC/版本)。 2. 明确并实现 `fdatasync/fsync` 语义: - fdatasync 保证数据持久化; - fsync 额外保证必要元数据持久化。 3. 补齐崩溃恢复流程(checkpoint + replay)。 ### 用户验收 ```bash make -C zvfs -j4 && make -C test -j4 env LD_PRELOAD=/home/lian/share/10.1-spdk/zvfs/zvfs/libzvfs.so ./test/bin/test_phase2_posix /zvfs # 建议补充一次“异常退出后重启读取”的恢复验证(手工执行) ``` ### 通过标准 - 重启后目录项与文件大小不丢失、不错乱。 - 数据库关键路径(fsync/fdatasync)语义满足预期。 ### 可重入说明 - WAL 与 checkpoint 支持并存迁移;可先双写验证,再切主读路径。 --- ## Phase 6:性能收敛与上线门槛 ### 要做的事情 1. 清理临时开关,保留必要调优参数。 2. 整理性能报告(与 Phase 0 基线对比)。 3. 做最终回归矩阵(功能 + 并发 + 性能 + 恢复)。 ### 用户验收 ```bash make -C zvfs -j4 && make -C test -j4 env LD_PRELOAD=/home/lian/share/10.1-spdk/zvfs/zvfs/libzvfs.so make -C test run-test env LD_PRELOAD=/home/lian/share/10.1-spdk/zvfs/zvfs/libzvfs.so ./test/bin/test_single_file_perf /zvfs env LD_PRELOAD=/home/lian/share/10.1-spdk/zvfs/zvfs/libzvfs.so ./test/bin/test_single_file_random_perf /zvfs ``` ### 通过标准 - 全量功能测试通过。 - 多线程性能达到 `codexplan.md` 目标(或给出量化偏差与原因)。 ### 可重入说明 - 本阶段仅收敛与验收,不引入架构性变更;可反复执行直到指标稳定。 --- ## 附:root 权限与运行建议 - 若 NVMe/SPDK 环境需要 root,请在你本机按现有流程执行验收。 - 若希望无 root 回归,建议补一个 `Malloc` bdev 的 JSON 配置,并将 bdev 名改为可配置(环境变量优先)。