12 KiB
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:
- Use existing semantic scalar aliases where their width and signedness are exactly equivalent.
- Use FreeBSD unaligned little-endian readers for raw on-disk bytes.
- Use the FreeBSD POSIX.1e ACL mode conversion facility.
- Introduce a Linux-comparable private compression header.
- Remove an unreachable ZSTD lower-bound condition.
- Align codec descriptor ownership while preserving FreeBSD behavior.
- Align exact macro vocabulary and remove one zero-consumer alias.
- Align one xattr helper's file order through a byte-identical block move.
- Remove include duplication introduced by the compression-header work.
- 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/le32decinputs 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
0000through0777:1536/1536tag/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:
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:
/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:
/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./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
10048released. - Test overlay removed.
- Guest test mounts and
md70/md71/md72devices were removed. - The retained guard QEMU remained unchanged and reachable at PID
26318, port9222, with process start ticks1102996924. - The base image remained mode
0444, size16515530752bytes, and mtime1786418212. Its retained SHA-256 record is67f359621f23a1d745f0889370cbb99a096cee3e99a0b2f3bb18fc7a91bf6fef; the final run intentionally did not repeat the expensive 16 GB hash. - At validation completion,
HEADandxdm/mainboth identifieda55e42a117e504f6ece49be3c2a2d81603031ea3, 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 == 0behavior;- header-only xattr behavior;
- duplicate or missing
device.Nbehavior; insmntquerace closure;- explicit extent and explicit mapped-extent fixtures;
vnode_create_vobjecterrno 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.