4.5 KiB
TC060 Standard pathconf Values
Status: RESOLVED - standard FreeBSD pathconf values validated
Last updated: 2026-08-09
Resolved: 2026-08-09
Priority: High
Implementation status: Fixed by cdba7e54fb9e9d82980a06f178e68d0bbc1663ac
and dynamically validated
Problem
The exact repo22 9ae22009f KLD returns EINVAL for two standard pathconf names on an otherwise valid mounted EROFS directory:
- _PC_NO_TRUNC
- _PC_CHOWN_RESTRICTED
The same call correctly returns NAME_MAX=255, PATH_MAX=1024, FILESIZEBITS=64, and LINK_MAX=2147483647. TC060 therefore fails at the kernel behavior level; this is not a missing guest tool or fixture limitation.
Trigger and Evidence
Environment:
- FreeBSD 15.0-RELEASE-p8 amd64 guest on port 9222.
- Exact source commit: 9ae22009f23a65320730072a780998e80aa9b728.
- KLD SHA256: 19ad086bd2508cbb4c57b1a51f38c93057d438b84fbcfa2e637ff2519f5bc590.
- Fixture: vfs-plain.erofs SHA256 79f0b5f4aa8e7ea532b711ee8fb466f14f35d0952446d41ba4bbc4d6e008b8ff.
Direct command:
/tmp/repo22-g3/g3_vfs_probe pathconf \
/tmp/repo22-g3/mnt/testdir
Observed output and process status:
name_max=255 path_max=1024 filesizebits=64 link_max=2147483647 \
no_trunc=error:22 chown_restricted=error:22
g3_vfs_probe: unexpected EROFS pathconf values
probe_status=1
The test used a fresh dynamic md0, a read-only EROFS mount, and the exact KLD. After capture, umount and md detach both returned zero. Final guest state was zero EROFS mounts, zero md units, and no loaded EROFS KLD.
Analysis
erofs_pathconf() handles NAME_MAX, PATH_MAX, FILESIZEBITS, LINK_MAX, and ACL queries directly, then delegates other names to vop_stdpathconf(). In this FreeBSD 15 configuration the delegation returns EINVAL for both names above. The mounted filesystem is immutable and enforces 255-byte names, so reporting NO_TRUNC=1 and CHOWN_RESTRICTED=1 is consistent with the implemented behavior and with the TC contract.
This failure affects applications that use pathconf(2) to discover pathname truncation and ownership-change restrictions. It does not affect the four values that repo22 already handles directly.
Original Required Resolution
Add explicit FreeBSD vnode pathconf handling for both standard names, then rerun TC060 with the direct syscall helper. Acceptance requires both values to be 1, all six queries to have errno 0, unchanged mount/read behavior, no new dmesg diagnostics, and complete mount/md/KLD cleanup.
Resolution
FreeBSD 15's vop_stdpathconf() intentionally provides only generic values
such as _PC_ASYNC_IO, _PC_PATH_MAX, and zero-valued optional features; its
default case returns EINVAL. UFS, tmpfs, and ext2fs therefore implement
_PC_CHOWN_RESTRICTED and _PC_NO_TRUNC in their filesystem pathconf methods
before delegating all remaining names to vop_stdpathconf().
EROFS now follows that FreeBSD pattern: the two names return 1, while the
existing NAME_MAX, PATH_MAX, FILESIZEBITS, LINK_MAX, and ACL cases remain
unchanged and the default branch still calls vop_stdpathconf(). This matches
the implemented filesystem behavior: uid/gid mutation is rejected with EROFS,
and lookup of a component longer than EROFS_NAME_LEN returns ENAMETOOLONG.
No lock, allocation, reference, or cleanup path was added.
Linux EROFS was used only as a maintenance comparison for the 255-byte name limit and ENAMETOOLONG behavior. FreeBSD 15 VOP and syscall semantics were the authority for the returned values and errno behavior.
Qualified Retest
The exact source archive for the fix commit built natively on FreeBSD
15.0-RELEASE-p8 with kernel -Werror in both configurations:
WITH_ZSTDIO=0: KLD SHA25668536e03ce93c6c04aab9cf29dab81ee5802d4b94401bd1a4bd752de40c0e504.WITH_ZSTDIO=1: KLD SHA256598f171d355af78c64407a6d513d20f053530620da92df7f8ccfdf9a804e463d.
The dependency-minimal WITH_ZSTDIO=0 KLD and the original TC060 helper
reported:
name_max=255 path_max=1024 filesizebits=64 link_max=2147483647
no_trunc=1 chown_restricted=1
All six queries had errno 0. Additional direct checks returned ASYNC_IO=200112,
ACL_EXTENDED=1, ACL_PATH_MAX=254, and ACL_NFS4=0 with errno 0. An unknown name
returned -1/EINVAL(22), and a 256-byte component returned
ENAMETOOLONG(63). The mounted file hash and read-only EROFS behavior were
unchanged, dmesg was byte-identical before and after, and final mount/md/KLD
and guest artifact counts were zero.
Complete build, value, smoke, discarded-attempt, review, and cleanup evidence
is in
tests/results/manual/2026-08-09T1120Z-tc060-fix/manual-test-report.md.