# repo22 压缩功能手工测试报告

- 执行日期：2026-08-08（UTC）
- 执行时段：约 12:58-13:07 UTC
- 测试对象：`/work/repo-community/repo22`
- 测试提交：`f230129565677e602510347a55a80856237fe909`
- 远端基线：执行前 `xdm/main` 指向同一提交
- FreeBSD VM：15.0-RELEASE-p8 amd64，QEMU TCG，SSH `127.0.0.1:9222`
- 镜像工具：erofs-utils 1.8.6
- 执行方式：逐条 host/guest shell 命令、SSH/SCP、`mdconfig` 和真实内核挂载；未实现 CI 或测试 wrapper
- 总体结论：**压缩功能不可验收。真实 compact LZ4 镜像可挂载，但首个 4 KiB 数据读取返回 `EINTEGRITY`，输出 0 字节。**

## 状态定义

| 状态 | 含义 |
|---|---|
| PASS | 该步骤已经在本轮实际执行，结果符合预期 |
| KERNEL-FAIL | 真实镜像进入 FreeBSD 内核路径后失败 |
| MKFS-UNAVAILABLE | erofs-utils 1.8.6 不能直接生成测试要求的镜像 |
| TEST-DOC | 当前 Markdown 的命令或预期不能可靠验证目标行为 |
| NOT RUN | 已准备 fixture，但收到立即停止新增测试的指令后未进入对应内核路径 |

## 最先出现的内核失败

使用 erofs-utils 1.8.6 生成根目录单文件 compact LZ4 镜像：

```sh
mkfs.erofs -T0 --all-root --ignore-mtime -x-1 -Uclear \
  -zlz4 -C4096 lz4-root-compact-4k.erofs src-root-lz4
```

`dump.erofs` 确认该文件不是 plain fallback：

```text
Filesystem features: sb_csum mtime 0padding
Path : /test-lz4.txt
Size: 1048576  On-disk size: 8192  regular file
NID: 39   Layout: 3   Compression ratio: 0.78%
Ext 0: logical 0..639004, physical 4096..8192, physical length 4096
Ext 1: logical 639004..1048576, physical 8192..12288, physical length 4096
```

Guest 中模块加载和挂载成功：

```text
SHA256 (/root/erofs.ko) = c81957971e670c8b8cc45d5119f568eb84adb6114699538588e5a842ea4d97b3
kldload_rc=0
5  1  0xffffffff82822000  8468  erofs.ko
/dev/md0 on /mnt/repo22-test (erofs, local, read-only)
```

文件 lookup 和 `stat` 成功后，第一次读取即失败：

```text
$ sha256 /mnt/repo22-test/test-lz4.txt
sha256: /mnt/repo22-test/test-lz4.txt: Integrity check failed
read_rc=1

$ dd if=/mnt/repo22-test/test-lz4.txt of=/tmp/repo22-first4k bs=4096 count=1
dd: /mnt/repo22-test/test-lz4.txt: Integrity check failed
0+0 records in
0+0 records out
0 bytes transferred
first_read_rc=1
```

因此首个确定性压缩内核失败是：

- fixture：真实 `mkfs.erofs 1.8.6` compact LZ4，Layout 3；
- mount：PASS；
- lookup/stat：PASS；
- 首个 4 KiB read：**KERNEL-FAIL / `EINTEGRITY`**；
- 用户缓冲区：0 字节，没有把部分输出误判为成功；
- 稳定性：命令后 VM 仍响应，时间为 `2026-08-08T13:06:43Z`，未观察到 panic 或 hang。

并发静态审查已经指出 compact 索引位置按 filesystem block size 计算，而不是按 compact index pack 大小计算；本轮失败与该问题相符，但手工测试本身只证明“真实 compact LZ4 首读失败”，不单独宣称完成了代码级根因证明。

## 已尝试 TC 结果

| TC | 状态 | 本轮证据 |
|---|---|---|
| TC003-lz4-compressed-read | **KERNEL-FAIL** | 真实 compact LZ4 镜像 mount PASS；完整 hash 与首个 4 KiB read 都返回 `EINTEGRITY` |
| TC084-lz4-basic | **KERNEL-FAIL** | 与 TC003 共用的最小真实 LZ4 基础读路径失败，无法进行透明解压和内容比较 |
| TC086-lz4-sequential-read | **TEST-DOC** | 用例要求不存在的 `vfs:erofs::read` DTrace provider，并把 TCG VM 上固定吞吐量当功能判据 |
| TC088-lz4-config-handling | **TEST-DOC** | 4K/64K/256K fixture 均生成；“pcluster 越大则镜像必然更小、随机读必然更慢”不是对任意语料都成立的功能断言 |
| TC090-lz4-pcluster-64k | **TEST-DOC** | 步骤 4 把 `dd ... of=/tmp/out` 再 pipe 给 `tail/head`，pipe 中没有文件数据，无法验证跨边界读取 |
| TC098-fragments-support | **TEST-DOC** | EROFS fragments 使用 packed inode，不是 Markdown 所写的独立 fragment device；`-o device=/dev/md1` 验证的是多设备而非 fragments |
| TC101-unified-address-mapping | **TEST-DOC** | 前置要求多设备，但 mount 命令只提供 device0；`ktrace` 也不能直接证明驱动选中了正确 EROFS device id |
| TC110-lzma-corrupt | **TEST-DOC** | 固定覆盖 image offset 8192 没有先定位目标文件的 compressed extent，可能破坏无关数据或元数据，不能确定性验证 LZMA 错误路径 |
| TC115-unsupported-algorithm | **MKFS-UNAVAILABLE** | mkfs 1.8.6 只提供 lz4/lz4hc/lzma/deflate/libdeflate/zstd，不能直接生成 future algorithm ID；需要有校验意识的定向 ABI patch fixture |
| TC116-truncated-compressed | **TEST-DOC** | 盲目从镜像末尾截去 4096 字节不保证命中目标 compressed extent；可能只移除 padding、其他文件或元数据 |

## 已生成但按停止指令未运行的 fixture

以下 fixture 的 `mkfs.erofs` 和目标布局检查已经成功，但没有据此把对应 TC 标为 PASS：

| TC 范围 | Fixture 准备结果 | TC 状态 |
|---|---|---|
| TC004、TC108、TC109 | 101 MiB MicroLZMA/LZMA level 6；Layout 3；19 个真实 compressed extents | NOT RUN |
| TC085、TC087、TC089 | 256 MiB/50 MiB/4K LZ4 corpus；compact 4K 与 legacy full 镜像均生成 | NOT RUN |
| TC090 | compact 64K big-pcluster 镜像生成，superblock 含 `compr_cfgs big_pcluster` | TEST-DOC，未运行内核读 |
| TC091、TC092 | `-Eztailpacking` 镜像生成，superblock 含 `ztailpacking` | NOT RUN |
| TC093、TC095 | single-device 1 MiB chunk 与 512 KiB chunk-index 镜像生成，Layout 4 | NOT RUN |
| TC094、TC096、TC099 | main image + 5 MiB external blob 生成；首次必须预创建 blob 文件后 mkfs 才成功 | NOT RUN |
| TC097、TC100 | 没有生成确定性 invalid table 或四外部设备 fixture | NOT RUN |
| TC102-TC104 | DEFLATE level 1/6/9 镜像均生成，file1m 为真实 Layout 3 | NOT RUN |
| TC105-TC107 | ZSTD level 1/15/22 镜像均生成，file1m 为真实 Layout 3 | NOT RUN |

收到“立即停止新增测试”指令后，没有继续 mount/read 上述镜像，也没有继续制作 corruption、unsupported algorithm、interlaced、extent 或 partial-ref 变体。

## Fixture 审核摘要

本轮生成并由 `dump.erofs` 确认的主要布局：

| 镜像 | 关键特征 |
|---|---|
| `lz4-compact-4k.erofs` | Layout 3 compact；`sb_csum mtime 0padding` |
| `lz4-full-4k.erofs` | Layout 1 full；`-Elegacy-compress` |
| `lz4-compact-64k.erofs` | Layout 3；`compr_cfgs big_pcluster`；真实物理 extent 最大 53248 字节 |
| `lz4-compact-256k.erofs` | Layout 3；`compr_cfgs big_pcluster` |
| `lz4-ztailpacking.erofs` | `ztailpacking` incompat feature |
| `lz4-fragments.erofs` | `fragments dedupe`，目标文件物理长度由 packed inode 提供 |
| `lzma-level6.erofs` | 101 MiB 逻辑文件，126976 字节 on-disk，Layout 3 |
| `deflate-level{1,6,9}.erofs` | 三个等级均为真实 compressed Layout 3 |
| `zstd-level{1,15,22}.erofs` | 三个等级均为真实 compressed Layout 3 |
| `chunk-single-1m.erofs` | `chunked_file`，Layout 4，三个 1 MiB extent |
| `chunk-index-512k.erofs` | `chunked_file`，Layout 4，8-byte chunk index fixture |
| `chunk-multidev-main.erofs` + `.blob` | 4 KiB metadata image + 5 MiB external blob |

所有镜像、source corpus、VM overlay 和模块 build 产物仅位于 `/work/build`、guest `/root` 或 repo22 忽略的 `build/`，没有加入 Git。

## 其他观察

1. 多文件嵌套目录镜像首次直接 lookup `/files/test-lz4.txt` 偶发返回 `ENOENT`；先执行目录枚举后 `stat` 可成功。根目录单文件 fixture 消除了该前置干扰，并稳定进入压缩 read 后返回 `EINTEGRITY`。
2. FreeBSD `ls -l` 对 EROFS 条目打印 `Operation not supported`，同时仍能列出项目；这看起来来自 ACL/扩展属性查询，不应当被误记为目录读取失败。
3. dmesg 中的 `bcmp undefined` 是前一轮旧模块的历史日志；本轮 canonical `/root/erofs.ko` 的 `kldload` 返回 0，且模块 SHA-256 为新的 `c819...97b3`。
4. 并发静态审查另报 incompat `0x8`、64K `clusterofs` 截断、通用剥前导零和短输出泄漏。本轮遵照停止指令没有再构造独立运行时 fixture 复核这些问题。

## 结论

`f2301295` 的压缩重构已经达到“模块可加载、真实压缩镜像可挂载”的阶段，但尚未达到“可读取最基本 compact LZ4 文件”的最低 feature gate。应先修复 compact zmap/read 闭环，并针对静态审查列出的五个确定性阻断补足定向手测，再恢复其余算法和高级布局验证。
