# repo22 partial-reference fix manual report

- Date: 2026-08-08 UTC
- Source baseline: `616d23e59b2bc16d9735ca5ad07502a21153bc0a`
- FreeBSD guest: 15.0-RELEASE-p8 amd64, QEMU TCG
- Module SHA256: `0270671fd73c4ee604294a5f94863f1fc8cc9a63083a4c83f89887891f06f1b2`
- Scope: partial-reference output range and LZ4 regression only

## Root cause and fix

`zmap.c` correctly marked the reused extent with `EROFS_MAP_PARTIAL_REF`, but
`zdata.c` always decompressed the complete mapped logical length and passed
`partial=false`. Linux keeps such pclusters in partial-decoding mode and sets
the decompressor output size to the highest byte needed by the current read.

The synchronous FreeBSD path now preserves that behavior. For a partial
reference, it decodes only through `mapoff + want`, passes `partial=true`, and
copies exactly the requested `want` bytes beginning at `mapoff`. Non-partial
extents still require full logical output and retain strict LZ4 trailing-data
validation.

## Results

| Test | Mount | Full SHA256 | Boundary read | Result |
|---|---:|---|---|---|
| Partial reference `/b.dat` | PASS | `61b17076c2dfae88da7912d00df534b894cf6d27178863c6d8e91f8617ebb91e` matches | offset 641020, 128 bytes: `941b6e3cb9a7384428d93ca248eb9630782538e04caba30dbfbe31baacca8f60` matches | **PASS** |
| Legacy full index `/shape.dat` | PASS | `370eb0a8df86868c4842ca535ed64670f0277ea2ed47a703f089bbb13ee4ac52` matches | smoke only | **PASS** |
| Compact index `/shape.dat` | PASS | `370eb0a8df86868c4842ca535ed64670f0277ea2ed47a703f089bbb13ee4ac52` matches | smoke only | **PASS** |

`./build.sh`, `kldload`, and exact-name `kldunload` passed. The isolated dmesg
delta was empty, with no panic, trap, integrity diagnostic, or decompression
error. Build objects, kernel module output, images, and VM overlays were not
staged for commit.
