# repo22 Review Fixes Manual Test Report

Started: 2026-08-09 05:31 UTC

Completed: 2026-08-09 05:57 UTC

Parent commit: `077b37ab44780a31f6cd76045afe6e0a92f3a5be`

Guest: FreeBSD 15.0-RELEASE-p8 amd64, QEMU TCG

## Scope and Result

| Test | Result | Evidence |
|---|---|---|
| TC154 per-inode NFS generation | PASS | Same-image remount, same-superblock replacement, malformed replacement |
| TC155 explicit extent `pa + plen` overflow | PASS | Repeated `ERR#97` and DTrace device-I/O observation |
| TC156 inode timestamp validation | PASS | Five compact/extended corruption fixtures returned `ERR#97` |

## Build Results

Both builds ran natively in the guest with
`FREEBSD_SRC=/tmp/repo22-freebsd15-src` and completed with kernel `-Werror`.

| Configuration | Module SHA256 | Result |
|---|---|---|
| `WITH_ZSTDIO=0` | `d6e755c7a75dd5043b603d58215ae3e7c8f29318b31dc1885aa9bb070d6e57a5` | PASS |
| `WITH_ZSTDIO=1` | `b442f9f05af1d1a76801690c83c9a40ec6fc739adb0663e7dacaf837eeb2ecf3` | PASS |

The disabled module had no undefined `ZSTD_*` or `bcmp` symbol. The enabled
module referenced only the expected FreeBSD kernel ZSTD API symbols and no
`bcmp`.

## Fixture Reproduction

`python3 tests/review_fixtures.py make` was run twice in independent empty
directories with erofs-utils 1.8.6. All nine images were byte-identical between
runs, and both `SHA256SUMS` files self-verified.

| Fixture | SHA256 |
|---|---|
| `nfs-inode-a.erofs` | `307879542d5bb52ff02fdb12553fee9a94cd1360b99752ebd08bedf9c9dc1c8c` |
| `nfs-inode-b.erofs` | `64ddb0efcb3c5bd092710a3d3a5ea7aaf637c070e2e061dbf9d4538262fa2f49` |
| `nfs-inode-corrupt.erofs` | `5f49bcd9361531c53f6435f53fb10acc579a8ff7fb6716d78da9dff60f7e8539` |
| `extent-pa-wrap.erofs` | `1e49ecf1917265fde9b606e80f7dbae8b14aca8c6f149128b31d6c825da546dd` |
| `compact-epoch-range.erofs` | `3e031196266fe308f5443878cea7afd775c797856dfb4e9ed28d14bf71d81abb` |
| `compact-epoch-wrap.erofs` | `2c3971c42a85494a75317c05b6da3669ea17a0301b7aa36517048d5e6de60259` |
| `compact-nsec-invalid.erofs` | `b7137b4b18c121c613689c308d5938339ea3e867723046e268d1949e8328c27b` |
| `extended-nsec-invalid.erofs` | `2d8a05d993155895feba67b2ff2dcad224a590c798925c31708c1b284c7c7ef3` |
| `extended-seconds-range.erofs` | `aa9675ac3e857892d182b033bb9f96424364aace84a877d2001f47fa32503e45` |

## TC154

Image A reported FID `len=16`, `pad=0`, NID 452, and generation
`3895653226`; `fhstat`, `stat -f %v`, and the fixture manifest agreed. Reusing
md90 for an unchanged-image remount preserved the complete handle and the old
handle remained readable.

Image B retained fsid `00000034:000000e0` and NID 452 but reported generation
`548470773`. Both `fhstat` and `fhopen` on A's handle returned `ESTALE`; B's
handle succeeded. With the malformed replacement, both old-handle operations
returned positive FreeBSD errno 45 (`EOPNOTSUPP`).

## TC155

The fixture mounted and `stat` reported the 1 MiB target. Two direct reads at
logical offset 4096 exited 1; both independent truss runs showed:

```text
read(..., 1) ERR#97 'Integrity check failed'
```

An `io:::start` DTrace positive control captured a raw md90 read at physical
offset 4096. The failing EROFS read produced no md90 I/O event, proving the
wrapped physical address did not reach the provider.

## TC156

`compact-epoch-wrap` and `compact-nsec-invalid` failed mount directly with rc 1
and traced `nmount(...)=ERR#97`. `compact-epoch-range` mounted with root mtime
`INT64_MAX`, while target stat returned `ERR#97`. Both extended target fixtures
mounted successfully and returned `ERR#97` for invalid nanoseconds and
`INT64_MAX+1` seconds. Every failing operation was executed directly and again
under truss.

## Harness Notes

The first build invocation used absent `/usr/src` and was rerun with the actual
guest source path. One test attempt used an overly narrow KLD filename match and
executed no TC step. A second attempt discarded `truss`'s zero wrapper status;
the qualified runs record direct command status separately from traced syscall
errno. None of these discarded attempts is counted as PASS evidence.

## Cleanup

Each qualified run ended with unchanged dmesg line count (`123 -> 123`), zero
EROFS mounts, no md provider, and zero EROFS modules. Raw transcripts, build
objects, modules, and generated images remain outside the repository under
`/work/build` and guest `/tmp` only.
