This commit is contained in:
2026-08-18 09:20:44 +02:00
commit b826cd721a
522 changed files with 93730 additions and 0 deletions
@@ -0,0 +1,85 @@
# Test Case: HEAD2, Interlaced, and Extent Mapping
**Overall Status Rule**: **PARTIAL** when HEAD2 and interlaced pass but the
explicit mapped-payload subscenario remains **SHELVED**; see
`issues/extent-metadata-fixture-unavailable.md`
**Test ID**: TC146-head2-interlaced-extent-mapping
**G5 fixture contract**: Use [G5-MANUAL-SETUP.md](G5-MANUAL-SETUP.md).
Its generated paths, source comparisons, structured corruption offsets, and
cleanup rules supersede placeholder examples in this file.
**Category**: Compression Mapping
**Priority**: Critical
**Regression**: New compressed mapping formats
## Objective
Verify FreeBSD kernel reads for HEAD2 and interlaced pclusters, and independently
review extent-record mapping when erofs-utils 1.8.6 cannot generate that format.
## Preconditions
- FreeBSD 15 guest and repo22 module.
- HEAD2 fixture with byte-level assertions:
- incompat bit `EROFS_FEATURE_INCOMPAT_COMPR_HEAD2` is set;
- `Z_EROFS_ADVISE_BIG_PCLUSTER_2` is set;
- a proven full-index HEAD record type is changed from HEAD1 to HEAD2;
- the high algorithm nibble names the decoder used by HEAD2;
- CRC32C is recomputed.
- Interlaced fixture generated by erofs-utils 1.8.6:
```sh
mkfs.erofs -zlz4 -C4096 -Efragments -T0 \
interlaced.erofs source-dir
```
`dump.erofs -e` must show real 4096-byte plain extents interspersed with
compressed extents.
## HEAD2 and Interlaced Steps
1. Prove the HEAD2 feature, map-header advise bits, algorithm nibbles, and HEAD2
record before guest transfer.
2. Mount the HEAD2 image, hash the full file, and compare a read crossing the
first logical pcluster boundary recorded by the manifest. Do not assume the
logical boundary is 65536 merely because the physical pcluster limit is
65536.
3. Read the targeted corrupted HEAD2 copy and record errno.
4. Mount the erofs-utils 1.8.6 interlaced image, hash the full file, and compare
a range crossing the first compressed/plain transition.
5. Compare pre/post `dmesg` and clean all resources.
## Extent Metadata Static Review
Run these checks against exactly erofs-utils 1.8.6 and both reference trees:
```sh
mkfs.erofs -V
grep -R -E 'Z_EROFS_ADVISE_EXTENTS|z_erofs_extent_recsize|struct z_erofs_extent[[:space:]]*\{' \
/work/build/erofs-utils-v1.8.6-source/include \
/work/build/erofs-utils-v1.8.6-source/lib
grep -n "struct z_erofs_extent\|z_erofs_extent_recsize" \
src/erofs_fs.h /work/dev-src-linux/fs/erofs/erofs_fs.h
grep -n "z_erofs_map_blocks_ext" \
src/zmap.c /work/dev-src-linux/fs/erofs/zmap.c
```
Review all four record sizes (4, 8, 16, 32 bytes):
- 4-byte records use the initial 64-bit physical base and accumulated `plen`;
- 8-byte records carry per-record 32-bit physical starts;
- 16/32-byte records use explicit extent counts and binary search by logical
start, with 32-byte records adding `lstart_hi`;
- `plen` format, partial-reference, interlaced/shifted, and final fragment
encodings are decoded in Linux order;
- metadata reads route through the metabox when the inode NID has bit 63;
- malformed zero-count explicit tables and fragment bounds fail closed.
## Expected Results
- HEAD2 and interlaced full SHA256 and boundary reads match source bytes.
- Targeted HEAD2 corruption returns errno 5 (`EIO`) without a panic/trap.
- Explicit mapped-payload result is **SHELVED**, not PASS, because erofs-utils
1.8.6 has no extent-record generator or on-disk extent structure and the
structured helper cannot validate a relocated mapped payload.
- The static FreeBSD/Linux format and control-flow review is recorded
separately from guest results.
- TC146 overall is **PARTIAL** unless all three subscenarios have dynamic
positive coverage.
## Cleanup
Unmount all images, detach md units, unload by exact module ID, and verify no
new `dmesg` lines.