# Pre12 Final Report Date: 2026-08-13 ## Conclusion and scope Pre12 is complete for its deliberately limited scope. The final result is **PASS** for the planned static review, both FreeBSD KLD build configurations, KLD load/status/unload, and the ordinary Plain/LZ4/LZMA QEMU smoke cases. This PASS is not a claim of complete EROFS feature validation. No feature test, `test_all.py`, new fixture, ZSTD data test, DEFLATE data test, ACL runtime test, explicit-extent test, or multi-device test was run. The included changes were selected as low-side-effect maintenance work and did not require a full feature suite after their static proofs and final build/smoke matrix. Deferred behavior work remains unresolved and is listed below. The validated device-under-test identity is: | Identity | Value | | --- | --- | | Commit | `a55e42a117e504f6ece49be3c2a2d81603031ea3` | | `repo-pre-12` tree | `9161671bd0e855faa52c37e24fe8efcd6ddd71e0` | | `repo-pre-12/src` tree | `d63c45c7872dcf9dd84007c8883cf9fbe0f9467d` | | Source archive SHA-256 | `bb7e7f0383be29102475575e130e0b19a48452d20520c94059dc6ef128d0c7ce` | ## Goals Pre12 continued the staged effort to reduce unnecessary maintenance differences from Linux EROFS without importing Linux-only memory, I/O, device, or concurrency models into FreeBSD. Its concrete scope was nine core batches and one conditional maintenance closeout: 1. Use existing semantic scalar aliases where their width and signedness are exactly equivalent. 2. Use FreeBSD unaligned little-endian readers for raw on-disk bytes. 3. Use the FreeBSD POSIX.1e ACL mode conversion facility. 4. Introduce a Linux-comparable private compression header. 5. Remove an unreachable ZSTD lower-bound condition. 6. Align codec descriptor ownership while preserving FreeBSD behavior. 7. Align exact macro vocabulary and remove one zero-consumer alias. 8. Align one xattr helper's file order through a byte-identical block move. 9. Remove include duplication introduced by the compression-header work. 10. Review Makefile readability and make no change when no useful grouping was found. The work explicitly excluded broad file reordering, catch-all style cleanup, Linux page/folio/bio/workqueue infrastructure, and behavior changes requiring specialized feature fixtures. ## Batch results | Batch | Commit | Result and summary | | --- | --- | --- | | 01 | `bb28c47bdf4de777febde05ebb333c420ea1e9b9` | Replaced the planned NID, block-number, and byte-offset declarations with existing equal-width unsigned `erofs_nid_t`, `erofs_blk_t`, and `erofs_off_t` aliases. Field order, layout, ABI width, expressions, on-disk types, and control flow were unchanged. | | 02 | `76a655788538f2270626cff1ca91b8c47700d536` | Replaced exactly three potentially unaligned typed loads with `le16dec`/`le32dec` in xattr, inode, and block-map decoding. | | 03 | `35bde15f5242f84a6343cc9e96519fcce4eeca90` | Replaced three manual ACL mode shifts with `acl_posix1e_mode_to_perm` for owner, group, and other entries. | | 04 | `b591751f90e62bc0ec54d3f34c724f698c99813d` | Added `src/compress.h` for private decompressor request, descriptor, and backend declarations; public entry points and runtime enum remained in `internal.h`. | | 05 | `aaa3c5db40745ee558e6fcf6375d60e044217df9` | Removed only the unreachable `zstd_windowlog + 10 < 10` subcondition; the upper bound, zero-output check, disabled stub, errno behavior, and resource handling remained unchanged. | | 06 | `6748d58f7e15927321f44a83d81a6c697c1185ae` | Moved LZMA, DEFLATE, and ZSTD descriptors into their backends, kept LZ4 and plain transforms central, and changed the central descriptor table to the pointer table `z_erofs_decomp`. All six normalized descriptor tuples and indices remained unchanged. | | 07 | `292da21bd9288cac4a8b280bb67970c8b9058550` | Renamed `EROFS_ALL_SUPPORTED_INCOMPAT` to Linux's `EROFS_ALL_FEATURE_INCOMPAT` at its definition and sole source use, and removed zero-consumer `EROFS_CHUNK_FORMAT_INDEXES_FLAG`. | | 08 | `0be5642d917104f1904bcfadaea803c9845c7a5c` | Moved the complete `erofs_listxattr_foreach` static function block before `erofs_getxattr_foreach`; the block SHA-256 remained `0541c211f78a19f39caeebdafe73bdd0a7064e996686a7b45c9c651160ed98ae`. | | 09 | `e5315489eb5ed08884d5d5f2645264067e36838e` | Removed five direct `internal.h` includes made redundant by `compress.h`; declaration visibility and the acyclic include graph were preserved. | | 10 | `a55e42a117e504f6ece49be3c2a2d81603031ea3` | Conditional Makefile readability closeout: honest no-op. The source list and Makefile remained byte-for-byte unchanged because no non-redundant grouping comment was justified. | Batch 10 is not counted among the nine core source workflows. Batch 09 did produce a precise cleanup diff, while Batch 10 records the required review without manufacturing source churn. ## Static review The final static review found no source-blocking issue. In particular, it did not find a regression in declaration/definition matching, include ownership or graph shape, descriptor indices and callback ownership, errno paths, resource release, in-memory ABI/layout, endian decoding, ACL construction, macro values, or the byte-identical xattr function move. The important proofs were: - The three semantic scalar aliases are direct unsigned 64-bit aliases; the approved substitutions preserve size, alignment, signedness, structure layout, parameter representation, and arithmetic width. - The three `le16dec`/`le32dec` inputs are raw little-endian disk bytes of the required length; the decoded values are equivalent while avoiding typed unaligned loads. - ACL owner/group/other conversion was exhaustively compared across modes `0000` through `0777`: `1536/1536` tag/mode combinations were equivalent, with zero mismatches. - The compression include graph remained acyclic and each migrated or private symbol retained one authoritative declaration/definition relationship. - The six codec descriptor tuples, indices, names, config callbacks, decompress callbacks, and ZSTD conditional ownership remained equivalent. - The removed ZSTD lower bound is unreachable because the field is `uint8_t`; its promoted value plus 10 cannot be less than 10. - Macro expressions and values were unchanged, and the deleted chunk-format alias had no source, build, documentation-interface, or preprocessor consumer in the target tree. - The moved xattr function block retained its exact SHA-256 and conditional context. The Batch 06 record originally used wording that could imply an actual `WITH_ZSTDIO=0` build had already occurred during that batch. It has been corrected to state that only the static conditional path was validated then. Final validation subsequently built both configurations successfully. ## KLD build matrix The valid final run used FreeBSD `15.0-RELEASE-p8`, amd64, with `/usr/src/sys` and the in-tree FreeBSD ZSTD headers present. The extracted source archive matched SHA-256 `bb7e7f0383be29102475575e130e0b19a48452d20520c94059dc6ef128d0c7ce`. For each configuration, the guest executed: ```sh timeout -k 10s 120s make "WITH_ZSTDIO=<0-or-1>" clean timeout -k 10s 600s make "WITH_ZSTDIO=<0-or-1>" ``` | Configuration | Clean exit | Build exit | Module SHA-256 | | --- | ---: | ---: | --- | | `WITH_ZSTDIO=0` | 0 | 0 | `96dc276c6c3f68943e68a144cc2ea138ffc215b62c7392cad9688ec45c9fc2fb` | | `WITH_ZSTDIO=1` | 0 | 0 | `4d879c0b7ebc653e915a3e41863f74d6d5b5f18aa81c5178579368048d1b6ee3` | The enabled build compiled `decompressor_zstd.c` with `-DZSTDIO` and linked `erofs.ko`. These builds prove both compile-time configurations close and link; they do not prove ZSTD or DEFLATE data-path correctness. ## KLD and smoke results The valid run loaded the `WITH_ZSTDIO=1` artifact under the standard module name `erofs.ko`. | Check | Result | | --- | --- | | `kldload` | exit 0 | | `kldstat -n erofs.ko` | present as `erofs.ko`, module id 5 | | Loaded module SHA-256 | `4d879c0b7ebc653e915a3e41863f74d6d5b5f18aa81c5178579368048d1b6ee3` | | `kldunload erofs.ko` | exit 0 | | Post-unload `kldstat` | module absent, as expected | All ordinary read cases matched their complete expected hashes: | Case | Exit | Expected SHA-256 | Actual SHA-256 | Elapsed | | --- | ---: | --- | --- | ---: | | Plain | 0 | `056f8f7585667dc695e2edf936deaf84cfee0f88671ba6cd5be22ce890763433` | `056f8f7585667dc695e2edf936deaf84cfee0f88671ba6cd5be22ce890763433` | 593 ms | | LZ4 | 0 | `3ff012b76087c4da65ce0b69813a76f47ea367e95782edf8b8cd6cd3ec4d1880` | `3ff012b76087c4da65ce0b69813a76f47ea367e95782edf8b8cd6cd3ec4d1880` | 6822 ms | | LZMA | 0 | `ddda39737f0f6093e828a032ec161511fefbb1fa361bc6cbffdbc91e48e4c461` | `ddda39737f0f6093e828a032ec161511fefbb1fa361bc6cbffdbc91e48e4c461` | 3418 ms | The dmesg delta was zero bytes and the suspect-filter output was zero bytes. No new panic, trap, or EROFS error was observed. ## Evidence and invalid attempts The only final valid evidence directory is: ```text /work/tests-dev/temp/pre12-smoke-direct-20260813T165639Z/ ``` Its `final-summary.txt`, guest build logs, module hashes, case records, dmesg files, and cleanup record form the accepted evidence set. Two earlier infrastructure attempts are explicitly invalid and contribute no source result and no test pass: 1. `/work/tests-dev/temp/pre12-build-20260813T154900Z/` is **INFRA-FAIL**. The SSH password expanded to an empty string, so there were zero successful SSH sessions and neither build began. Its QEMU and temporary resources were cleaned. This is neither a DUT failure nor a test success. 2. `/work/tests-dev/temp/pre12-final-smoke-20260813T160957Z/` stopped while redundantly hashing the 16 GB base image. Five nested Codex CLI sessions were discovered and all were terminated or had exited; no QEMU, SSH, guest build, KLD action, or smoke case started. Its partial files are not test evidence and it is neither a DUT failure nor a test success. The final accepted run was performed by a single direct execution layer and did not start a nested agent or Codex process. One intermediate runner revision attempted to query KLD using the renamed artifact filename rather than the module's standard name. That was a test-period runner issue, not a DUT issue. Only the temporary runner copy under `tests-dev/temp` was corrected: the successful `WITH_ZSTDIO=1` artifact was copied to `erofs.ko`, then the complete KLD and Plain/LZ4/LZMA sequence was rerun. No `repo-pre-12` source or build file was modified to make the test pass. ## Cleanup and repository state The accepted run completed cleanup successfully: - Owned QEMU stopped. - SSH ControlMaster stopped. - Test port `10048` released. - Test overlay removed. - Guest test mounts and `md70`/`md71`/`md72` devices were removed. - The retained guard QEMU remained unchanged and reachable at PID `26318`, port `9222`, with process start ticks `1102996924`. - The base image remained mode `0444`, size `16515530752` bytes, and mtime `1786418212`. Its retained SHA-256 record is `67f359621f23a1d745f0889370cbb99a096cee3e99a0b2f3bb18fc7a91bf6fef`; the final run intentionally did not repeat the expensive 16 GB hash. - At validation completion, `HEAD` and `xdm/main` both identified `a55e42a117e504f6ece49be3c2a2d81603031ea3`, and the worktree was clean. This report is documentation-only and does not alter the validated DUT source tree `d63c45c7872dcf9dd84007c8883cf9fbe0f9467d`. ## Deferred feature work The following issues remain unresolved and require dedicated behavior design, fixtures, or feature tests before any future implementation can be accepted: - inode decode split or rewrite; - map request interface conversion; - directory/namei control flow, qstr, cookies, namecache, and lock behavior; - metadata reader consolidation; - rejection or handling of a non-directory root; - `run_len == 0` behavior; - header-only xattr behavior; - duplicate or missing `device.N` behavior; - `insmntque` race closure; - explicit extent and explicit mapped-extent fixtures; - `vnode_create_vobject` errno behavior. No claim is made that these issues were fixed or covered by the ordinary smoke run. The final PASS is limited to the Pre12 static review, both KLD build configurations, KLD lifecycle, and the Plain/LZ4/LZMA smoke cases recorded in the accepted evidence directory.