test code v1
This commit is contained in:
@@ -0,0 +1,142 @@
|
||||
# repo22 multi-device review findings manual test report
|
||||
|
||||
Date: 2026-08-08 21:14 UTC
|
||||
Baseline: `2354b4487c84458c1e447f4d0bb7b55daebcca26` plus this review fix
|
||||
Guest: FreeBSD 15.0-RELEASE-p8 amd64, QEMU TCG
|
||||
Linux reference: 7.1-rc1 `/work/dev-src-linux/fs/erofs`
|
||||
Host tools: erofs-utils 1.8.6
|
||||
|
||||
## Result
|
||||
|
||||
**PASS**. All five multi-device review findings were fixed and exercised with
|
||||
deterministic positive and negative fixtures. A real two-block LZ4 pcluster
|
||||
was read from an external provider and the complete 1 MiB output matched the
|
||||
source SHA256. Multi-device NFS reads and forced-device-removal behavior also
|
||||
passed.
|
||||
|
||||
## Source changes validated
|
||||
|
||||
- Non-zero device IDs accept a slot with `uniaddr=0`; unified device-ID-0
|
||||
lookup skips such slots.
|
||||
- `devt_slotoff=0` reads the table from byte offset zero, as Linux 7.1 does.
|
||||
- Device mapping carries the requested extent length. Flatdev reads must fit
|
||||
wholly in the primary range or one non-zero unified slot; gaps, adjacent-slot
|
||||
crossings, and pcluster crossings fail closed.
|
||||
- Declared image and slot bounds are checked before physical media size, so
|
||||
format corruption is `EINTEGRITY` and a genuinely short provider is
|
||||
`ENXIO`.
|
||||
- Primary and external `namei()` failures preserve `ENOENT`; omitted required
|
||||
`device.N` options still return `ENXIO`.
|
||||
|
||||
The NFS file-handle ABI, `VFS_FHTOVP`, inode bounds, readdir cookies, and GEOM
|
||||
orphan lifecycle from `2354b448` were not changed.
|
||||
|
||||
## Build
|
||||
|
||||
Commands:
|
||||
|
||||
```sh
|
||||
git diff --check
|
||||
./build.sh
|
||||
nm -u build/erofs.ko | awk '$NF == "bcmp" {bad=1} END {exit bad}'
|
||||
sha256sum build/erofs.ko
|
||||
```
|
||||
|
||||
Results:
|
||||
|
||||
- Cross-build: PASS.
|
||||
- `git diff --check`: PASS.
|
||||
- Unresolved `bcmp`: none.
|
||||
- Module SHA256:
|
||||
`b85c429fa73e6cebc10e6e3941575a6ca170306ab4fa9ccca4006c922971acb8`.
|
||||
- FreeBSD `kldload` and `kldunload`: PASS.
|
||||
|
||||
## Fixture construction
|
||||
|
||||
The chunk fixtures derive from the checksum-valid TC094 images recorded in the
|
||||
19:37 multi-device report. The patcher asserted the original table values
|
||||
`slot1=(blocks=19, uniaddr=2)`, `slot2=(blocks=25, uniaddr=21)`, and the first
|
||||
32 KiB chunk index `(device_id=2, startblk=9)` before each change.
|
||||
|
||||
The compressed baseline was generated from the deterministic `shape.dat`:
|
||||
|
||||
```sh
|
||||
mkfs.erofs -T0 -U00000000-0000-0000-0000-000000000000 \
|
||||
--all-root -E legacy-compress -zlz4 -C65536 \
|
||||
lz4-full-64k.erofs src-big64k
|
||||
dump.erofs --path=/shape.dat -e lz4-full-64k.erofs
|
||||
```
|
||||
|
||||
The baseline contains one 1 MiB logical extent backed by an 8192-byte physical
|
||||
pcluster. Its HEAD pblk was changed from block 1 to unified block 4; the two
|
||||
compressed blocks were copied to a two-block external provider and zeroed in
|
||||
the primary image. A checksum-valid device table declared
|
||||
`slot1=(blocks=2, uniaddr=4)`.
|
||||
|
||||
For the crossing negative, the same pcluster was placed across adjacent
|
||||
`slot1=[4,5)` and `slot2=[5,6)`. The flatdev contains both real compressed
|
||||
blocks, proving that failure is caused by the declared slot boundary rather
|
||||
than absent data.
|
||||
|
||||
erofs-utils 1.8.6 parses the external compressed extent but its userspace
|
||||
compressed read path does not propagate the unified slot ID to `erofs_dev_read`;
|
||||
therefore userspace extraction of this layout is tool-unavailable. The
|
||||
FreeBSD kernel full-file SHA256 is the authoritative read validation.
|
||||
|
||||
## Fixture hashes
|
||||
|
||||
| Fixture | SHA256 |
|
||||
|---|---|
|
||||
| zero-uniaddr primary | `d38935291fb2ee756e0c192d1b0d39b4f4f5b4047aa37c2de44cad91a55fa018` |
|
||||
| zero-uniaddr device-ID-0 control | `fac9db7631cd06d17212cbe3e7b1d681766f031d1e41e443f71f1bad39f9b960` |
|
||||
| slotoff-zero primary | `39e3e8c60bea962f1200550316be87ec7da7b15c0ba11c6e5edf05f0715db451` |
|
||||
| cross-slot primary | `edd0cba92a26bc9a7a59561732fb8e045b2e1565d18d9f9b3143f86f64649dee` |
|
||||
| cross-slot flatdev | `6e2834450081d778cee37fa3e050249f04927def205d6816aab814a2912744bc` |
|
||||
| gap flatdev | `5bc07b66f7b0f83e9568ba781dcc78a08d45e617dc27bb365ed3ee2c12353218` |
|
||||
| external-compressed primary | `5625612426d68624c77dd94b09754da583fc6bd90767e9e9d958e4fc89131a4d` |
|
||||
| external-compressed blob | `0d71102ce471af0a30d4d61a1fbeef1fc33437c85651d7c7f9c60ebd305ec9d0` |
|
||||
| cross-pcluster primary | `2bce4a91c1aedc4bab2e65582ef9cb465094f825a051c0203d52b3d18bb17ed8` |
|
||||
| cross-pcluster flatdev | `bc07fb06ca5c6bb60ef1a989eecbd3d714450092ba756f85f5b060c8b8b2ec3a` |
|
||||
|
||||
Source `shape.dat` SHA256:
|
||||
`370eb0a8df86868c4842ca535ed64670f0277ea2ed47a703f089bbb13ee4ac52`.
|
||||
|
||||
## FreeBSD result matrix
|
||||
|
||||
| Test | Actual | Status |
|
||||
|---|---|---|
|
||||
| slot 1 `uniaddr=0`, explicit device ID 1 | complete striped and second-file SHA256 matched | PASS |
|
||||
| slot 1 `uniaddr=0`, device ID 0 control | slot skipped; primary-bound `EINTEGRITY` | PASS |
|
||||
| `devt_slotoff=0` | mount and complete striped SHA256 matched | PASS |
|
||||
| nonexistent primary path | `ENOENT` / `No such file or directory` | PASS |
|
||||
| nonexistent external path | `ENOENT` / `No such file or directory` | PASS |
|
||||
| omitted slot option | `ENXIO` / `Device not configured` | PASS |
|
||||
| flatdev chunk crosses adjacent slots | read returned `EINTEGRITY` | PASS |
|
||||
| device-ID-0 chunk starts in a gap | read returned `EINTEGRITY` | PASS |
|
||||
| explicit chunk exceeds declared slot and media | `EINTEGRITY`, not `ENXIO` | PASS |
|
||||
| real external 64 KiB LZ4 pcluster | complete 1 MiB SHA256 matched | PASS |
|
||||
| flatdev pcluster crosses adjacent slots | read returned `EINTEGRITY` | PASS |
|
||||
| explicit pcluster crosses two providers | read returned `EINTEGRITY` | PASS |
|
||||
|
||||
## NFS smoke
|
||||
|
||||
The external-compressed image was exported read-only over local NFSv3/TCP.
|
||||
The NFS client read the complete `shape.dat`; SHA256 matched the source.
|
||||
|
||||
The zero-uniaddr two-slot image was then exported. The client obtained stable
|
||||
inode and size data for a cold slot-2 file, slot 2 was forcibly orphaned, and
|
||||
the same NFS pathname still resolved to identical metadata. Its first cold data
|
||||
read failed with the underlying device error. This preserves the `2354b448`
|
||||
contract: file-handle resolution is not misreported as `ESTALE`, while missing
|
||||
external data remains an I/O/device failure.
|
||||
|
||||
## Cleanup
|
||||
|
||||
All EROFS and NFS mounts were unmounted, NFS services stopped, `/etc/exports`
|
||||
cleared, md providers detached, and the module unloaded. No image, overlay,
|
||||
fixture, or build artifact is part of this commit.
|
||||
|
||||
A final representative rerun covered the external-compressed positive, the
|
||||
flatdev-gap negative, and the offset-zero table positive. The dmesg SHA256 was
|
||||
unchanged before and after:
|
||||
`897003051a6a50875d49715bfa27907611cedac9e42e0a06ca7377105ac695ae`.
|
||||
Reference in New Issue
Block a user