Files
erofs-freebsd-out-tree/docs/pre12-final-report.md
T
2026-08-18 09:20:44 +02:00

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:

  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:

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:

  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.