4.9 KiB
Pre10 Batch B: Bounded Metadata Helpers
Scope and baseline
Batch B is a source-only extraction based on commit
3c7c774b296a2ee90578a78f372aad5fd2edbec6. It changes only
src/super.c, src/data.c, and src/inode.c, plus this report. No build,
QEMU smoke, or feature test was run.
The extraction keeps ownership at the original FreeBSD lifecycle boundaries:
erofs_mountfs()still owns mount allocation, the primary GEOM transfer, extent-cache lifecycle, device scanning, internal inode setup, publication, and the singleerofs_sb_free()failure path.erofs_map_dev()still owns device selection, range and overflow checks, flat-device behavior, and allENODEV/EINTEGRITYreturns.erofs_vget()still owns vnode allocation, locking, mount association, hash insertion, construction state, publication, and failure cleanup.
Superblock helper
erofs_read_superblock() now reads the on-disk superblock into a temporary
buffer, copies the fixed 144-byte structure to caller-owned stack storage,
releases the temporary buffer, and performs the existing validation and field
decode in the original order. It also retains the existing device-size,
checksum, generation-seed, metabox-NID, and compression-configuration checks.
The helper does not allocate or publish the mount, open extra devices, create
internal inodes, initialize xattrs, or own failure cleanup. erofs_mountfs()
still calls, in order:
z_erofs_extent_cache_init
erofs_read_superblock
erofs_scan_devices
shared-EA/metabox combination check
erofs_init_packed_inode
erofs_init_metabox_inode
erofs_xattr_prefixes_init
mount publication and flag setup
All prior superblock outcomes remain at the same semantic boundary:
| Condition | Preserved result |
|---|---|
| read failure | underlying erofs_bread() error |
| invalid magic or block geometry | EINVAL |
| unsupported directory blocks or feature bits | EOPNOTSUPP |
| invalid xattr, timestamp, or metabox metadata | EINTEGRITY |
| invalid device geometry | existing EINVAL, EINTEGRITY, or ENXIO |
| checksum mismatch | EINTEGRITY |
| generation/config read failure | existing underlying error |
Copying the superblock before releasing its read buffer makes its lifetime
explicit. The copy remains available to erofs_scan_devices() and volume-name
publication, while checksum and compression configuration reads continue to
use their existing independent I/O helpers.
Device-map helper
erofs_fill_map_dev() is a pure assignment helper for m_em, m_dif, and
m_pa. It has no branches, errors, allocation, I/O, or ownership effects.
The caller retains all explicit-device and unified-range selection, arithmetic overflow checks, physical range validation, flat-device handling, and external device availability checks. In particular:
- flat explicit mappings still use the primary device and add the unified offset to the existing physical address;
- flat implicit mappings still retain the primary device and unified address;
- non-flat explicit mappings select the requested extra device only after all validation succeeds; and
- non-flat implicit misses still return success with the initial primary map.
Vnode helper
erofs_fill_vnode() sets only the inode-derived vnode type, FIFO operation
vector, and VV_ROOT flag. It runs after erofs_read_inode() succeeds and
immediately before VSTATE_CONSTRUCTED, while erofs_vget() still holds the
exclusive vnode lock.
Hash lookup/insertion, allocation, insmntque(), locking, race handling,
failure vgone()/vput(), shared-lock downgrade, and *vpp publication remain
in erofs_vget() in their original order.
Known pre-existing risk
The insmntque() failure branch remains unchanged. FreeBSD's insmntque() may
reclaim and release the vnode on failure, while the existing EROFS branch then
accesses vp->v_data. This possible use-after-release is outside a helper-only
batch and was deliberately not mixed into this commit. Consequently, this
report does not claim that the pre-existing vnode cleanup path is correct.
Static validation
| Check | Result | Evidence |
|---|---|---|
| Changed-path allowlist | PASS | Only three allowed source files and this report changed. |
| Helper ownership | PASS | Each helper is static and has one direct caller. |
| Mount lifecycle order | PASS | Cache init, device scan, internal inode/xattr setup, publication, and erofs_sb_free() remain in erofs_mountfs(). |
| Device-map errors | PASS | All range, overflow, device-selection, ENODEV, and EINTEGRITY branches remain in erofs_map_dev(). |
| Vnode lifecycle order | PASS | insmntque(), hash insertion, inode read, construction, downgrade, and publication retain their order. |
git diff --check |
PASS | No whitespace errors. |
| Build/QEMU/feature test | NOT RUN | Reserved for later aggregate Pre10 validation. |
The pre-existing insmntque() concern is deferred; no new errno, logging,
ABI, Linux lifecycle facade, or Pre9 decoded-cache change was introduced.