6.0 KiB
repo22 TC060 pathconf fix manual test report
Execution window: 2026-08-09 11:20-11:35 UTC
Exact source commit: cdba7e54fb9e9d82980a06f178e68d0bbc1663ac
Guest: FreeBSD 15.0-RELEASE-p8 amd64, QEMU TCG, port 9222
Scope and Result
TC060 is PASS. The original six-key helper returned the required values with errno 0, compatibility queries retained their previous values, an unknown name returned EINVAL, mount/read/read-only smoke passed, dmesg did not change, and final mount/md/KLD/artifact counts were zero.
This was a direct manual run. No CI, result wrapper, or historical PASS supplied
the result. WITH_ZSTDIO=1 was build-verified; runtime TC060 used
WITH_ZSTDIO=0 because pathconf is compression-independent and this avoids an
unnecessary optional runtime dependency.
Implementation Basis
FreeBSD 15 sys/kern/vfs_default.c shows that vop_stdpathconf() handles
generic _PC_ASYNC_IO, _PC_PATH_MAX, and several zero-valued optional
features, then returns EINVAL for other names. The same source tree's UFS,
tmpfs, and ext2fs vnode operations explicitly return 1 for
_PC_CHOWN_RESTRICTED and _PC_NO_TRUNC before delegating the remaining names
to vop_stdpathconf().
The EROFS fix adds only those two switch labels and retains the existing
default delegation. src/namei.c rejects components longer than
EROFS_NAME_LEN with ENAMETOOLONG, while src/erofs_vnops.c rejects uid/gid
mutation with EROFS. Linux EROFS's 255-byte name limit and ENAMETOOLONG lookup
check were reviewed only for maintenance similarity; FreeBSD VOP behavior was
authoritative.
Exact Build
The repo22 subtree was exported directly from the exact source commit. Later
current/-only reporting changes did not alter src/.
| Item | Value |
|---|---|
| Source archive SHA256 | a4c871ca7cefc49470ef0003f876792380a8d8db6cbeaefb96456d06ad946d53 |
| FreeBSD source path | /tmp/repo22-freebsd15-src |
| Compiler | FreeBSD clang 19.1.7 |
| Build command | FREEBSD_SRC=/tmp/repo22-freebsd15-src WITH_ZSTDIO=N ./build.sh |
Both clean-object builds completed with kernel -Werror:
| Configuration | Module SHA256 | Size | Undefined-symbol audit | Result |
|---|---|---|---|---|
WITH_ZSTDIO=0 |
68536e03ce93c6c04aab9cf29dab81ee5802d4b94401bd1a4bd752de40c0e504 |
73896 | no bcmp, no ZSTD_* |
PASS |
WITH_ZSTDIO=1 |
598f171d355af78c64407a6d513d20f053530620da92df7f8ccfdf9a804e463d |
78728 | no bcmp; only five expected FreeBSD ZSTD_* APIs |
PASS |
The enabled module referenced ZSTD_DCtx_setParameter,
ZSTD_createDCtx_advanced, ZSTD_decompressStream, ZSTD_freeDCtx, and
ZSTD_isError.
Fixture and Probes
| Artifact | SHA256 |
|---|---|
vfs-plain.erofs |
79f0b5f4aa8e7ea532b711ee8fb466f14f35d0952446d41ba4bbc4d6e008b8ff |
tracked g3_vfs_probe binary |
08fe3999600dd1826805c00a17af3d893d247a593c0812f767d85a2633302068 |
one-run pathconf_audit source |
c2cc69297848cad8c806d47585ef670ae5b378827450110e2cf47cf82ed527b3 |
one-run pathconf_audit binary |
17aa9d738871ac424900ed7a928cb72cc2e5a288f2c2f9744906fa139a78835b |
Both probes compiled natively with -O2 -Wall -Wextra -Werror -std=c17.
The one-run helper was kept outside the repository and only printed each
value/errno plus assertions for unknown-name and overlong-component behavior.
TC060 Values
The exact original command was:
./g3_vfs_probe pathconf /tmp/repo22-tc060-fix/mnt/testdir
It exited 0 and printed:
name_max=255 path_max=1024 filesizebits=64 link_max=2147483647
no_trunc=1 chown_restricted=1
The expanded value/errno capture was:
| Query | Actual value | errno |
|---|---|---|
_PC_NAME_MAX |
255 | 0 |
_PC_PATH_MAX |
1024 | 0 |
_PC_FILESIZEBITS |
64 | 0 |
_PC_LINK_MAX |
2147483647 | 0 |
_PC_NO_TRUNC |
1 | 0 |
_PC_CHOWN_RESTRICTED |
1 | 0 |
_PC_ASYNC_IO |
200112 | 0 |
_PC_ACL_EXTENDED |
1 | 0 |
_PC_ACL_PATH_MAX |
254 | 0 |
_PC_ACL_NFS4 |
0 | 0 |
unknown name INT_MAX |
-1 | 22 (EINVAL) |
A lookup using a 256-byte path component returned -1 with errno 63
(ENAMETOOLONG), confirming the reported no-truncation behavior.
Mount and Read Smoke
The module loaded as KLD file ID 20, module erofs, and the fixture attached
as dynamic md0. The mount line was:
/dev/md0 on /tmp/repo22-tc060-fix/mnt (erofs, local, read-only, acls)
testdir reported inode 44, mode drwxr-xr-x, and size 1039. Reading
testdir/file.txt produced repo22 G3 file payload and SHA256
523af4c899ba3b8f4fa4d854fe609590be271905b63932cf067ca9630e612687.
Opening the same file with O_RDWR returned errno 30 (EROFS) as expected.
Dmesg and Cleanup
The qualified run's dmesg had 131 lines before and after, with identical
SHA256 91bf74a3607f432b4802f143bcf9d050c2f9e741da0a54f3e6a1b47bcc996a06.
There was no new EROFS diagnostic, assertion, trap, panic, or resource warning.
Qualified cleanup returned zero for umount, md detach, and KLD unload. After removing the transferred archive and test directory, the final guest audit was:
erofs_mounts=0
md_units=
erofs_klds=0
guest_artifacts=0
Discarded Attempt
The first otherwise successful runtime pass loaded the KLD from the
non-canonical filename erofs-zstdio0.ko. Its explicit kldunload erofs
command could not resolve that filename, so the run stopped before final dmesg
and cleanup qualification. Its mount and md were already clean; KLD file ID 20
was then unloaded directly and the guest returned to zero resources. The full
test was repeated with canonical erofs.ko, and only that rerun is counted.
Independent Review
The post-test review found no lock, resource, or error-path issue:
VOP_PATHCONFis called with the vnode shared-locked; the function does not change lock state.- The new constant-return branches allocate nothing and acquire no references.
- Both normal and FIFO vnode vectors use the same filesystem-wide result.
- Existing value branches are unchanged, and unsupported names still reach
vop_stdpathconf()and return EINVAL. - The syscall copies
retvalonly on error 0, so the unknown-name error path cannot expose a stale value.