update
This commit is contained in:
@@ -0,0 +1,480 @@
|
||||
# Pre11 Completion and Smoke Report
|
||||
|
||||
## Status
|
||||
|
||||
Pre11 is complete for its approved mechanical maintenance scope.
|
||||
|
||||
- Final implementation commit tested: `040fc69025c5031436205c3acd421be1d95fe86b`
|
||||
- Final `repo-pre-11` tree: `f0cca92670c76ab13cc5b9353d5aeb993effa6e2`
|
||||
- Final `repo-pre-11/src` tree: `c4aac4d69cb25a4b049239d0c1f422dcb89465d6`
|
||||
- Static review: `ACCEPT`, with no P0-P3 findings in the included changes
|
||||
- FreeBSD KLD build: `PASS`, using `WITH_ZSTDIO=0`
|
||||
- Targeted plain/LZ4/LZMA QEMU smoke: `PASS`
|
||||
- Full feature test and `test_all.py`: `NOT RUN`
|
||||
|
||||
This report does not claim full feature validation. Pre11 deliberately contains
|
||||
mechanical naming, responsibility, dead-scaffolding, file-layout, and cleanup
|
||||
changes that could be reviewed for behavioral equivalence and then covered by a
|
||||
focused build and smoke run. Behavior changes requiring purpose-built fixtures
|
||||
remain deferred.
|
||||
|
||||
## Snapshot and Planning
|
||||
|
||||
Pre11 was created from the completed Pre10 tree in:
|
||||
|
||||
```text
|
||||
0483dcb41c2a980badb829ff4d17361bd1fec930
|
||||
snapshot: create repo-pre-11 from repo-pre-10
|
||||
```
|
||||
|
||||
At the snapshot boundary, `repo-pre-10/src` and `repo-pre-11/src` were both:
|
||||
|
||||
```text
|
||||
ec684d8dbd7662070234da1fe947aba48a293db8
|
||||
```
|
||||
|
||||
The executable Pre11 plan was added in:
|
||||
|
||||
```text
|
||||
9ad1fa0cf8ba251b574da033bf0c9fad83acaa38
|
||||
docs: add pre11 execution plan
|
||||
```
|
||||
|
||||
The original plan included several candidates that would have changed visible
|
||||
filesystem behavior. An independent boundary review narrowed the release in:
|
||||
|
||||
```text
|
||||
c89c228ac1817cfd0337905b39247245eaa67f3b
|
||||
docs: narrow pre11 execution boundaries
|
||||
```
|
||||
|
||||
The narrowed scope retained only work that could preserve control flow, errno,
|
||||
on-disk interpretation, vnode and GEOM ownership, iterator order, decompressor
|
||||
semantics, and cache lifetime. The following candidates were removed from
|
||||
implementation because honest validation would require targeted feature tests:
|
||||
|
||||
- root vnode type rejection;
|
||||
- zero-length mapping behavior in the UIO reader;
|
||||
- header-only xattr semantics;
|
||||
- duplicate or missing `device.N` behavior;
|
||||
- direct propagation of `vnode_create_vobject()` errors;
|
||||
- broad map, inode, directory, and name-lookup interface reshaping.
|
||||
|
||||
This narrowing allowed Pre11 to remain a comparatively large maintenance
|
||||
release without mixing low-risk structural alignment with unvalidated semantic
|
||||
changes.
|
||||
|
||||
## Batch A: Type and Vocabulary Alignment
|
||||
|
||||
Commit:
|
||||
|
||||
```text
|
||||
b4e38c9fb15df127470d70bc144404f1f3afa2af
|
||||
pre11: align mount and device helper vocabulary
|
||||
```
|
||||
|
||||
Exact changes:
|
||||
|
||||
- renamed `struct erofs_mount.block_bits` to `blkszbits` across its consumers;
|
||||
- renamed the private `erofs_fill_map_dev()` helper to
|
||||
`erofs_fill_from_devinfo()`;
|
||||
- added the Batch A implementation report.
|
||||
|
||||
Linux-maintenance benefit:
|
||||
|
||||
- `blkszbits` matches established EROFS vocabulary and makes comparisons with
|
||||
Linux mount geometry code more direct;
|
||||
- `erofs_fill_from_devinfo()` describes the same responsibility as the Linux
|
||||
helper without importing Linux block-device objects into FreeBSD.
|
||||
|
||||
BSD invariants retained:
|
||||
|
||||
- field type, width, units, expressions, overflow handling, and structure
|
||||
layout were unchanged;
|
||||
- the helper remained a private FreeBSD device-map field filler;
|
||||
- GEOM provider selection, range checks, flat-device behavior, errno, and
|
||||
physical I/O remained unchanged;
|
||||
- no broad or search-driven integer type replacement was performed.
|
||||
|
||||
Static checks confirmed 48 intended `block_bits` replacements, zero remaining
|
||||
old identifiers, four helper-name replacements, zero stale helper references,
|
||||
and a source diff containing only the approved identifier changes.
|
||||
|
||||
## Batch B: Vnode Operation Scaffolding
|
||||
|
||||
Commit:
|
||||
|
||||
```text
|
||||
67625d3afebb9142e69b19afd08cdfc1d2adaac5
|
||||
refactor: clean up vnode operation scaffolding
|
||||
```
|
||||
|
||||
Exact changes:
|
||||
|
||||
- removed the unused `EROFS_MOUNT_XATTR_USER` option bit;
|
||||
- removed the zero-consumer `erofs_node.vnode` member and its only assignment;
|
||||
- grouped VOP declarations and `erofs_vnodeops` initializers by responsibility;
|
||||
- added the Batch B implementation report.
|
||||
|
||||
Linux-maintenance benefit:
|
||||
|
||||
- removes misleading compatibility-shaped state that had no consumer;
|
||||
- presents vnode operations in a responsibility-oriented order that is easier
|
||||
to compare with upstream filesystem responsibilities while retaining the
|
||||
native FreeBSD operation table.
|
||||
|
||||
BSD invariants retained:
|
||||
|
||||
- no VOP function definition or registration changed;
|
||||
- `erofs_vnodeops` retained 24 unique `field=value` entries;
|
||||
- `erofs_fifoops` retained 14 unique entries and its original sequence;
|
||||
- `fifo_specops`, vnode locking, hash insertion, reclaim, pager behavior, and
|
||||
`vnode_create_vobject()` errno translation were unchanged.
|
||||
|
||||
The removed symbols had no reads, address consumers, initializer dependencies,
|
||||
offset consumers, or external ABI use.
|
||||
|
||||
## Batch C: ACL Parsing Responsibilities
|
||||
|
||||
Commit:
|
||||
|
||||
```text
|
||||
a86b5cac4d193d131de8870bca4132fdc881f992
|
||||
erofs: split ACL parsing responsibilities
|
||||
```
|
||||
|
||||
Exact changes:
|
||||
|
||||
- extracted private `erofs_posix_acl_from_xattr()` from `erofs_get_acl()`;
|
||||
- changed the private mode fallback helper to receive the inode mode directly;
|
||||
- left xattr acquisition and all FreeBSD VOP/UIO responsibilities in the
|
||||
caller;
|
||||
- added the Batch C implementation report.
|
||||
|
||||
Linux-maintenance benefit:
|
||||
|
||||
- separates wire-format ACL parsing from filesystem acquisition and VOP glue,
|
||||
matching the upstream responsibility split more closely;
|
||||
- gives maintainers a bounded parser to compare without introducing Linux ACL
|
||||
objects, RCU, xattr handlers, or inode lifecycle assumptions.
|
||||
|
||||
BSD invariants retained:
|
||||
|
||||
- mount-option checks, ACL type validation, default-ACL directory checks,
|
||||
namespace selection, both `erofs_getxattr()` stages, UIO setup, and `ENOATTR`
|
||||
fallback remain in `erofs_get_acl()`;
|
||||
- parser validation order, positive errno, tag phases, duplicate ID checks,
|
||||
`UINT32_MAX` handling, partial ACL writes, and final
|
||||
`acl_posix1e_check()` ordering remain unchanged;
|
||||
- input storage remains caller-owned stack memory, with no new allocation or
|
||||
cleanup path;
|
||||
- `erofs_xattr_load_body()` and the known header-only xattr behavior were not
|
||||
changed.
|
||||
|
||||
Static comparison confirmed equivalent branch, error, phase-transition, and
|
||||
ACL-population behavior.
|
||||
|
||||
## Batch D: LZ4 Backend File Responsibility
|
||||
|
||||
Commit:
|
||||
|
||||
```text
|
||||
e631e33a1b8c053ebcb2d737af33e363cba48b34
|
||||
erofs: align LZ4 backend file responsibility
|
||||
```
|
||||
|
||||
Exact changes:
|
||||
|
||||
- renamed `src/lz4.c` to `src/decompressor_lz4.c`;
|
||||
- updated the Makefile source entry;
|
||||
- updated current architecture documentation references;
|
||||
- added the Batch D implementation report.
|
||||
|
||||
Linux-maintenance benefit:
|
||||
|
||||
- makes the filename communicate that the translation unit is the LZ4 codec
|
||||
backend beside `decompressor_lzma.c`, `decompressor_deflate.c`, and
|
||||
`decompressor_zstd.c`;
|
||||
- reduces unnecessary file-layout differences when maintainers inspect codec
|
||||
implementations across the independent Linux and FreeBSD repositories.
|
||||
|
||||
BSD invariants retained:
|
||||
|
||||
- Git identified a 100% rename;
|
||||
- the old and new source blobs are both
|
||||
`2cc19f5eb0c283e12ba0a3a4334b8817a1686888`;
|
||||
- function bodies, request ABI, descriptor registration, input/output bounds,
|
||||
partial decode behavior, and error normalization were unchanged;
|
||||
- historical reports and historical test evidence were not rewritten.
|
||||
|
||||
## Batch E: Mount Device Argument Cleanup
|
||||
|
||||
Commit:
|
||||
|
||||
```text
|
||||
040fc69025c5031436205c3acd421be1d95fe86b
|
||||
erofs: consolidate mount device argument cleanup
|
||||
```
|
||||
|
||||
Exact changes:
|
||||
|
||||
- consolidated caller-owned copied `device.N` argument release into one
|
||||
`out_args` exit in `erofs_mount()`;
|
||||
- removed two impossible NULL checks immediately following
|
||||
`M_WAITOK | M_ZERO` allocations;
|
||||
- added the Batch E implementation report.
|
||||
|
||||
Linux-maintenance benefit:
|
||||
|
||||
- makes mount setup ownership and cleanup easier to audit by reducing repeated
|
||||
release sites;
|
||||
- removes defensive branches that contradict the FreeBSD `M_WAITOK` contract,
|
||||
keeping BSD-specific allocation behavior explicit instead of emulating a
|
||||
nullable Linux allocation path.
|
||||
|
||||
BSD invariants retained:
|
||||
|
||||
- operation order remains parse, filter, get option, open primary, update I/O
|
||||
size, mount setup, free copied arguments, publish mounted-from, and statfs;
|
||||
- parse failure still returns before caller ownership exists;
|
||||
- `out_args` releases only copied arguments and never releases `primary`;
|
||||
- `erofs_mountfs()` still takes ownership of `primary` at entry;
|
||||
- `erofs_mountfs()`, `erofs_sb_free()`, reverse external-device cleanup, errno,
|
||||
and mount error text are unchanged;
|
||||
- duplicate and missing external-device slot behavior remains deferred.
|
||||
|
||||
## Static Review
|
||||
|
||||
Independent reviews were performed after the individual batches and again over
|
||||
the complete source range from `0483dcb` through `040fc690`.
|
||||
|
||||
The final review found no P0-P3 issue in the included Pre11 source changes and
|
||||
accepted all five batches. It confirmed:
|
||||
|
||||
- the source changes were confined to the approved Batch A-E paths;
|
||||
- no deferred behavior fix entered the source;
|
||||
- old identifiers had no stale consumers and new private helpers had unique
|
||||
definitions and expected call counts;
|
||||
- both VOP vectors retained the same registration mappings;
|
||||
- ACL acquisition, parsing, fallback, errno, and partial-write behavior were
|
||||
preserved;
|
||||
- the LZ4 backend was a byte-identical rename and the Makefile contained the
|
||||
new filename once;
|
||||
- mount cleanup retained error order and GEOM ownership;
|
||||
- uncompressed mapping interfaces, directory/name lookup, decompressor request
|
||||
ABI, LZMA cache policy, disk structures, and Linux reference sources were not
|
||||
changed;
|
||||
- `git diff --check` passed and the implementation worktree was clean before
|
||||
runtime validation.
|
||||
|
||||
The final source delta from the snapshot contains 202 insertions and 188
|
||||
deletions across ten source paths, including the 100% LZ4 file rename. Much of
|
||||
that textual delta is identifier replacement, declaration/vector reordering,
|
||||
or moved ACL parser code rather than new behavior.
|
||||
|
||||
## First Smoke Attempt: Infrastructure Failure
|
||||
|
||||
Evidence directory:
|
||||
|
||||
```text
|
||||
/work/tests-dev/temp/pre11-smoke-final-20260813T122923Z
|
||||
```
|
||||
|
||||
Result: `FAIL`, specifically an infrastructure failure before DUT transfer or
|
||||
execution.
|
||||
|
||||
The guest reached FreeBSD and two SSH identity probes succeeded, but the first
|
||||
runner opened an SSH ControlMaster using a detached invocation. The open command
|
||||
returned success and created the control socket, then the master terminated or
|
||||
lost its connection before the immediate health check. The check failed with:
|
||||
|
||||
```text
|
||||
Control socket connect(.../control.sock): Connection refused
|
||||
```
|
||||
|
||||
The test stopped before source transfer, KLD build, module load, or any EROFS
|
||||
mount. Therefore this attempt is not a PASS, but it is also not evidence of a
|
||||
Pre11 build or driver failure. Its source archive SHA was:
|
||||
|
||||
```text
|
||||
5bbffb101364f350fe1a3771b6f018bc10a68785d8c55cc2a186273a074e9182
|
||||
```
|
||||
|
||||
The owned QEMU stopped, port `10043` was released, its overlay was removed, the
|
||||
base image remained unchanged, and the retained guard VM remained reachable.
|
||||
The run's cleanup status was nonzero only because closing the already-dead
|
||||
ControlMaster returned an error.
|
||||
|
||||
## Corrected Smoke Retry
|
||||
|
||||
Evidence directory:
|
||||
|
||||
```text
|
||||
/work/tests-dev/temp/pre11-smoke-retry-final-20260813T124214Z
|
||||
```
|
||||
|
||||
Result: `PASS`.
|
||||
|
||||
The retry used an SSH master process in normal foreground mode but launched it
|
||||
in the runner shell background, without `ssh -f`. The runner captured the real
|
||||
master PID, repeatedly required both `kill -0` and `ssh -O check` to succeed,
|
||||
and refused to transfer sources unless the master remained alive. Long build
|
||||
work ran inside the guest with a completion sentinel, so one long SSH command
|
||||
was not treated as the build lifetime.
|
||||
|
||||
Tested identities:
|
||||
|
||||
```text
|
||||
commit: 040fc69025c5031436205c3acd421be1d95fe86b
|
||||
repo-pre-11 tree: f0cca92670c76ab13cc5b9353d5aeb993effa6e2
|
||||
src tree: c4aac4d69cb25a4b049239d0c1f422dcb89465d6
|
||||
source archive: 179b80365c26295770afab58f1209ae3fffd73182ada0bcf97ea027904f781e9
|
||||
guest: FreeBSD 15.0-RELEASE-p8
|
||||
```
|
||||
|
||||
The archive hashes differ between attempts because separately generated gzip
|
||||
archives are not required to be byte-reproducible. Both identity files name the
|
||||
same committed repository and source trees; only the passing retry is used as
|
||||
runtime evidence.
|
||||
|
||||
## Build and Module Lifecycle
|
||||
|
||||
The committed `repo-pre-11` archive was transferred to the disposable guest,
|
||||
validated there, extracted, and built with:
|
||||
|
||||
```sh
|
||||
make WITH_ZSTDIO=0
|
||||
```
|
||||
|
||||
Results:
|
||||
|
||||
- guest build return code: `0`;
|
||||
- `erofs.ko` SHA256:
|
||||
`77ce41bff5cb7d7c934dd9dba20ba06c20b660ad15ebfc4210f86f6473dffbf7`;
|
||||
- `kldload /root/pre11-smoke/erofs.ko`: success;
|
||||
- `kldstat -n erofs`: success, reporting `erofs.ko` loaded;
|
||||
- all smoke mounts and md providers were released;
|
||||
- `kldunload erofs`: success;
|
||||
- the post-unload `kldstat -n erofs` check confirmed the module was absent.
|
||||
|
||||
`WITH_ZSTDIO=1` was not built and is not claimed as tested.
|
||||
|
||||
## Smoke Cases
|
||||
|
||||
Each case used an independently attached vnode-backed md provider, required a
|
||||
successful EROFS mount to be visible in `mount -p`, computed the complete target
|
||||
file hash, then unmounted and detached the provider before the next case.
|
||||
|
||||
| Case | Target SHA256 | Elapsed | Provider | Result |
|
||||
| --- | --- | ---: | --- | --- |
|
||||
| Plain | `056f8f7585667dc695e2edf936deaf84cfee0f88671ba6cd5be22ce890763433` | 0 s | `md70` | PASS |
|
||||
| LZ4 | `3ff012b76087c4da65ce0b69813a76f47ea367e95782edf8b8cd6cd3ec4d1880` | 5 s | `md71` | PASS |
|
||||
| LZMA | `ddda39737f0f6093e828a032ec161511fefbb1fa361bc6cbffdbc91e48e4c461` | 2 s | `md72` | PASS |
|
||||
|
||||
The LZMA case hashed the complete file. No timeout, mount failure, hash mismatch,
|
||||
unmount failure, or md detach failure occurred.
|
||||
|
||||
## Kernel Messages and Cleanup
|
||||
|
||||
The runner captured `dmesg` before loading the module and after all smoke cases.
|
||||
The delta contained no EROFS error, decompression failure, panic, or assertion;
|
||||
the suspect-output file is empty.
|
||||
|
||||
Cleanup evidence records:
|
||||
|
||||
```text
|
||||
qemu_stopped=1
|
||||
port_released=1
|
||||
overlay_removed=1
|
||||
base_mode_after=444
|
||||
base_sha_after=67f359621f23a1d745f0889370cbb99a096cee3e99a0b2f3bb18fc7a91bf6fef
|
||||
guard_unchanged_and_reachable=1
|
||||
body_rc=0
|
||||
cleanup_rc=0
|
||||
```
|
||||
|
||||
The test owned only port `10044`, its QEMU PID, its ControlMaster PID, and its
|
||||
overlay. All were closed or removed. The permanent base image was never booted
|
||||
directly and retained mode `0444` and its original SHA256. The retained guard VM
|
||||
PID `26318` kept start time `1102996924`, an identical command line, and a
|
||||
reachable forwarded SSH port at `9222`.
|
||||
|
||||
## Feature-Test Decision
|
||||
|
||||
No feature test and no `test_all.py` run was performed.
|
||||
|
||||
That decision is appropriate for the included Pre11 scope because:
|
||||
|
||||
- Batch A changed only private identifiers;
|
||||
- Batch B removed proven dead state and reordered designated VOP initializers
|
||||
without changing their mappings;
|
||||
- Batch C mechanically moved parser statements while retaining inputs, outputs,
|
||||
writes, error order, and ownership;
|
||||
- Batch D was a byte-identical file rename;
|
||||
- Batch E consolidated one caller-owned cleanup action and removed checks that
|
||||
cannot be reached after `M_WAITOK` allocation.
|
||||
|
||||
Static equivalence review plus the FreeBSD build and plain/LZ4/LZMA smoke is
|
||||
sufficient evidence for these changes. It is not sufficient for the deferred
|
||||
behavior changes below, and this report does not claim otherwise.
|
||||
|
||||
## Deferred Behavior and Required Targeted Tests
|
||||
|
||||
### Non-directory root
|
||||
|
||||
The current root path does not add a new rejection for a root NID that resolves
|
||||
to a non-directory vnode. A future fix requires a purpose-built image and checks
|
||||
for mount errno, vnode release, mount error text, and complete cleanup.
|
||||
|
||||
### Zero-length internal run
|
||||
|
||||
The uncompressed UIO reader's existing `run_len == 0` behavior was not changed.
|
||||
A future fix requires a corrupt mapping fixture that reaches a zero-length run
|
||||
while the request remains inside the file, with exact comparison to the
|
||||
contiguous-buffer path and expected `EINTEGRITY`.
|
||||
|
||||
### Header-only xattr
|
||||
|
||||
The existing behavior for an ibody containing only the xattr header was not
|
||||
changed. Targeted coverage must distinguish zero and nonzero shared counts,
|
||||
name filters, get/list results, ACL mode fallback, and corruption results.
|
||||
|
||||
### Duplicate or missing device slots
|
||||
|
||||
`device.N` slot parsing behavior and diagnostics were not changed. Future tests
|
||||
must cover duplicate, out-of-order, missing, excessive, and malformed slots,
|
||||
flat and non-flat device tables, exact errno and mount error text, and GEOM
|
||||
cleanup.
|
||||
|
||||
### `insmntque()` race closure
|
||||
|
||||
The earlier ownership fix remains accepted by static lifecycle review but is
|
||||
not runtime-closed by ordinary smoke. A dedicated mount/unmount or forced
|
||||
unmount race must stress vnode creation and inspect panic, use-after-free, lock,
|
||||
reference, and cleanup behavior.
|
||||
|
||||
### Explicit mapped extent fixtures
|
||||
|
||||
Positive payload fixtures are still unavailable for explicit mapped extent
|
||||
records of 4, 8, 16, and 32 bytes. No restructuring or coverage claim should be
|
||||
made until validated mappings and file hashes exist.
|
||||
|
||||
### `vnode_create_vobject()` errno
|
||||
|
||||
Pre11 intentionally retains the current conversion of a nonzero
|
||||
`vnode_create_vobject()` result to `ENOMEM`. Direct propagation is a visible
|
||||
behavior change and requires controlled pager failure or fault injection that
|
||||
verifies the caller-visible errno and vnode state.
|
||||
|
||||
## Final Conclusion
|
||||
|
||||
Pre11 completed all five narrowed maintenance batches, passed independent
|
||||
static review, built successfully as a FreeBSD KLD, and passed the required
|
||||
plain, LZ4, and full-file LZMA smoke. The first smoke attempt was correctly
|
||||
classified as an infrastructure failure before DUT transfer or build; the
|
||||
corrected retry provides the runtime evidence.
|
||||
|
||||
Pre11 improves cross-repository maintainability without replacing native
|
||||
FreeBSD vnode, GEOM, UIO, pager, ACL, or synchronous decompression contracts.
|
||||
Full feature validation remains outside this release and must not be inferred
|
||||
from the targeted smoke result.
|
||||
Reference in New Issue
Block a user