# repo22 G8 Documentation, NFS, and Integrity Manual Regression Date: 2026-08-09 13:07-13:56 UTC Executor: G8 manual agent Source baseline: `f11fff5b8e8050e1017ed86f0bcf71042b2b45aa` Exact scope: `TC111`, `TC131`-`TC133`, `TC154`-`TC156` (7 IDs) ## Result All seven requested test cases passed. There are no KFAIL, SHELVED, or ENV results, no duplicate IDs, and no omitted IDs. | Status | Count | | --- | ---: | | PASS | 7 | | KFAIL | 0 | | SHELVED | 0 | | ENV | 0 | | Duplicate | 0 | | Omitted | 0 | | Test ID | Status | Manual evidence | | --- | --- | --- | | TC111 | PASS | Audited current source and documentation against real generic `/sbin/mount`; corrected helper and writable-request claims. | | TC131 | PASS | Real mountd/nfsd NFSv3 export, four vnode types, read-only behavior, 16-byte handle resolution, and RPC statistics. | | TC132 | PASS | Handle ABI/classes, stable remount, replacement `ESTALE`, metabox and external-provider regressions, and nfsd restart. | | TC133 | PASS | Exact 12,050-name READDIRPLUS lists, five cold remounts, 20 individually waited workers, and zero RPC errors. | | TC154 | PASS | Same-superblock/UUID/NID replacement changed per-inode generation; unchanged remount stayed stable. | | TC155 | PASS | Explicit-extent physical-address wrap returned `EINTEGRITY` on both direct reads and in `truss`. | | TC156 | PASS | Compact/extended epoch, `time_t`, and nanosecond boundary corruptions returned `EINTEGRITY`. | No kernel source changed. No kernel failure remained, so no issue file was created. ## Isolated Environment - Worktree: `/work/build/repo22-manual-g8-20260809T130723Z`, branch `manual-g8-20260809T130723Z`, created directly from the source baseline. - VM: independent qcow2 overlay backed by the clean FreeBSD development base; QEMU TCG, 6144 MB, 4 vCPUs, SSH only on `127.0.0.1:9228`. - Guest: FreeBSD `15.0-RELEASE-p8` amd64, `releng/15.0-n281036-53054229dcb3`, OSREL `1500068`. - Guest kernel SHA256: `b9abf7b58f9dd4d87f14d2fbc306cf255e6eadc47b8ae885a230f65e28be4562`. - Host erofs-utils: 1.8.6. - No CI, runner, or test wrapper was used. Markdown procedures were issued manually through SSH, with direct command status kept separate from tracing tool status. ## Exact Build The repo22 source archive came from the exact baseline commit. The matching tracked FreeBSD build input was `dev-freebsd-releng/sys`, identified by `REVISION="15.0"` and `BRANCH="RELEASE-p9"`. The build ran natively in the guest as: ```sh FREEBSD_SRC=/root/freebsd-src WITH_ZSTDIO=1 ./build.sh ``` The compile command contained `-DZSTDIO` and kernel `-Werror`. The module had the five expected `ZSTD_*` kernel references and no unresolved `bcmp`. | Object | SHA256 | | --- | --- | | repo22 source archive | `2f76ef7df9117c6e7d62ad41809638ad306e676191346083bf95fe551f7df515` | | FreeBSD 15 `sys` archive | `cd806ac4d6aee5d7ceb6a2f9603020b48b5012835bc8c7f2ec0985572fcd0262` | | `erofs.ko` | `e8cd4839328de089355505efb1629c835d2f93faad2e14f63c6e6cb844ce9589` | | `nfs_fh_tool` | `db704f67d718d04b84ed32b5cdbecb93a99c5fe3b4ab238d603a10e005d790e3` | The guest kernel is p8 and the tracked source is p9, but both use the FreeBSD 15.0 OSREL ABI. The exact module loaded and unloaded successfully. ## Fixture Qualification `tests/review_fixtures.py` generated two independent output directories. Their manifests and checksum inventories were byte-identical, and all nine image checksums self-verified. Its structured assertions recorded: - target NID 452 at inode offset 14464 after checksum block 4096; - identical complete superblock block and UUID for NFS images A and B; - generations `3895653226 -> 548470773` from the changed raw inode; - explicit extent base `0xfffffffffffff000`, `plen0=8192`, `plen1=4096`, and wrap before logical cluster 4096; - compact epoch wrap/range, compact nanoseconds 1000000000, extended nanoseconds 1000000000, and extended seconds `INT64_MAX+1`. Review generator SHA256 was `b92fd6b6122d55882998138efc0109e24b236f9e877405dbff7914284a18c124`; manifest SHA256 was `be0836043d172b34eb625e5259f7e6cb9a8992ff74e7d1a5cdc10d69282e2335`. The NFS stress image was generated from a fresh deterministic tree containing 12,050 `bigdir` files, 256 concurrent-read files, four basic vnode types, and a 22,020,096-byte throughput file. Image A SHA256 was `88721877dc3762c8eafdf3bcca2653787cdcf41983978ab159705761abefac37`; image B was `964b3d75579740c9b08bc9cae8329e3d641d3c505e9391de3ab9f5d24fbecd17`. The expected sorted-name list SHA256 was `4fbf1b6103e8884223629c3fd03f4ec36061e65cd2a1becfc96670daa96f9d71`. Fresh structured metabox and multidevice helpers also self-verified the two TC132 regression inputs. The metabox image SHA256 was `dd7b04097d1bfe283b65c95d759acd2176beb7cb0f1fe9d5ddbc0694b5acba9d`; the multidevice primary/slot hashes were `918aa3a64e8861011914d967912909ce9de98418cff711cfbf8f91c0c7717f72`, `4e31d95a12405f2f1396fb926a6854c591fc335eade8944f73fdc7fe6758aee6`, and `355a74880bd3648dea22ad18e19f809cee12303ceed2a99f53094c2b66563a11`. ## TC111 `/sbin/mount_erofs` was absent and `command -v mount_erofs` returned 127. Generic `/sbin/mount -t erofs` mounted the image successfully without `-o ro`. The following real behavior was recorded: - the default mount was read-only and `touch` failed with `EROFS`; - `-o rw` returned 0 but the resulting mount was still read-only; - `-o ro,noexec,nosuid` returned 0 and all three flags appeared; - non-export `mount -u` returned `EOPNOTSUPP`; - an unknown filesystem option returned direct rc 1, with `nmount(..., MNT_RDONLY) ERR#22`, and created no mount. Current `src`, `README.md`, `docs/features.md`, `docs/architecture.md`, `docs/erofs.5`, and current progress material were checked. `README.md`, `docs/erofs.5`, and the test procedure now describe the generic frontend and the forced-read-only `rw` behavior accurately. The man page's split-device example was also exercised by the TC132 multidevice mount. SEE ALSO entries absent from the qualified guest were removed; `mandoc -Tlint -Werror` and ASCII rendering both returned 0 in that guest. ## TC131 The direct EROFS line lacked `NFS exported` before mountd. After installing the loopback export and reloading mountd, `showmount -e` listed the exact path and the direct mount gained `NFS exported`. `rpcinfo` showed NFSv3 and mountd over TCP and UDP. The NFSv3 TCP client negotiated `rdirplus`. Regular file content, directory, symlink target, FIFO type, and inode number matched the direct EROFS mount. `touch` failed with `Read-only file system`. Local `fhstat` and `fhopen` resolved the regular handle with `len=16`, `pad=0`, NID 116, and generation 2068234290. After basic operations client READDIRPLUS was 2. Server Write and Create were both 0. TimedOut, Invalid, X Replies, and Retries were all 0. ## TC132 Regular, directory, symlink, and FIFO handles all had `len=16`, `pad=0`, full 64-bit NIDs, and nonzero generations matching `st_gen`. Bad length/pad returned `EINVAL`; bad generation/NID returned `ESTALE` through both `fhstat` and `fhopen`. The unchanged image remounted on md80 preserved the complete handle SHA256 `9e1df1952b43d383fea295301525ede7a69b7d57e5f60a75a6d7f1531e13df0a`, and the old handle still read the file. Replacement B retained fsid and NID 116 but changed generation `2068234290 -> 857800581`; both old-handle paths returned `ESTALE` while B resolved. The metabox handle preserved NID `0x8000000000000010`; invalid metabox NID and generation returned `ESTALE`. After forced orphaning of external slot 2, the valid file handle still resolved metadata and the read returned `ENXIO(6)`, not `ESTALE`. An NFS client descriptor remained open across `service nfsd onerestart 3<&-`. The old descriptor and a new path read both returned SHA256 `3e2d0b4971e1f4bf00c3562a8bf9c5d85378c9de054f3da89541f49f2b449a7b`; the export and all RPC registrations remained live. ## TC133 Requested readdir sizes 512, 1024, and 4096 were all clamped by the FreeBSD client to 8192; the default remained 65536. This is the recorded client floor. Every one of the four mounts returned exactly 12,050 unique expected names. Every sorted list, plus all five cold-remount lists, had SHA256 `4fbf1b6103e8884223629c3fd03f4ec36061e65cd2a1becfc96670daa96f9d71`. The `ls -a1` list contained 12,052 entries, with `.` and `..` exactly once. All 12 traversal workers were waited by PID and returned 0. All four parallel cat workers and four parallel stat workers were also waited by PID and returned 0. The informational 22,020,096-byte read completed in 14.51 seconds. Final client/server READDIRPLUS was 3420. TimedOut, Invalid, X Replies, and Retries remained 0. Server Write, WriteRPC, Create, and Commit remained 0. There were no new stale-handle, timeout, retry, panic, trap, assertion, watchdog, or EROFS error lines. ## TC154 Image A produced fsid `00000034:000000e0`, `len=16`, `pad=0`, NID 452, and generation 3895653226. `nfs_fh_tool`, `stat st_gen`, and the fixture manifest agreed. The unchanged remount preserved complete handle SHA256 `79f2f4b8e354af0ae369849d7f66a739162ffadc4a5689c09643c9949b548de1` and the old handle remained readable. Image B retained the complete superblock block, UUID, fsid, NID, and content, but generation became 548470773. Both old-handle paths returned `ESTALE`; B's handle resolved. The malformed same-NID replacement returned positive errno 45 through both paths. ## TC155 The self-checked fixture SHA256 was `1e49ecf1917265fde9b606e80f7dbae8b14aca8c6f149128b31d6c825da546dd`. The image mounted and target `stat` reported inode 40, size 1,048,576. Two direct one-byte reads at logical offset 4096 returned rc 1 and `Integrity check failed`; the traced read was `ERR#97`. The repeat exercised the cached vnode. A DTrace `io:::start` positive control observed one raw `md90 offset=4096 bytes=4096` event. A separate trace around the failing EROFS read observed zero md90 events, proving the wrapped address did not reach the provider. No panic or resource remained. ## TC156 Both compact root corruptions failed `nmount` with `ERR#97`. The compact range image mounted with root mtime `INT64_MAX`; target stat returned `ERR#97` for `INT64_MAX+1`. Both extended images mounted, and target stat returned `ERR#97` for nanoseconds 1000000000 and seconds `INT64_MAX+1`. Every failure was run directly and again under `truss`; no panic or resource remained. ## Cleanup and Restoration Before NFS setup, `/etc/exports` did not exist; rpcbind, mountd, and nfsd were stopped; and `rpcbind_enable`, `mountd_enable`, and `nfs_server_enable` were all `NO`. Cleanup unmounted every loopback client while nfsd was alive, cleared and reloaded exports, stopped nfsd/mountd/rpcbind, then removed the direct EROFS mount, md42, and the module. Final state exactly matched the baseline: `/etc/exports` absent, all three services stopped with rc 1, all three rc settings `NO`, zero NFS/EROFS mounts, zero md providers, no EROFS KLD, no service process, and `rpcinfo` refused the connection because rpcbind was stopped. The complete NFS-period dmesg delta had zero anomaly lines. The retained guest evidence archive is outside the repository at `/work/build/repo22-manual-g8-20260809T130723Z-vm/evidence/`: | Artifact | SHA256 | | --- | --- | | `final-guest-evidence.txt` | `eb67210818e663c15e4670ada9ba63b82b44e9ed3a9486c575df3a71ed3f0522` | | `TC155-dtrace-assert.txt` | `f8b52985a74c8c777b3b830c39749be65c613165ffbcde6d0018dc471018c433` | | `final-post-dtrace-cleanup.txt` | `90f04d8f5a4ae35c87cc3adb1aeb939c7cc5534233ed63e9ff4501c83fd857d2` | | `repo22-g8-evidence.tar.gz` | `9a378fd619f9bca21f40689d746308933aa22e440f7201104732f91634c21290` | ## Non-Qualified Attempts One TC131 setup command stopped at the expected nonzero service-status probe because that probe was mistakenly under `set -e`; it occurred before module, exports, or service changes. One TC133 attempt stopped after the four exact lists because a shell-quoted dot assertion matched zero; the three added clients were unmounted and the complete procedure was rerun from the start. Tracing wrappers returned 0 even when their child failed, so all error claims use separate direct statuses plus syscall errno. None of these discarded attempts is counted as PASS evidence. Two initial DTrace specifications used field names from other provider ABIs and failed at compile time before any probe I/O. The qualified specification used FreeBSD `struct devstat` and `struct bio` fields. Its first assertion used a line anchor even though the format emitted a literal `\\n`; substring counts then proved one positive md90 event and zero failing-read md90 events. DTrace's automatically loaded module set was unloaded as a unit and the original KLD set was reverified. ## Issues None.