Files
erofs-freebsd-out-tree/issues/TC060-pathconf-standard-values.md
T
2026-08-18 09:20:44 +02:00

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 SHA256 68536e03ce93c6c04aab9cf29dab81ee5802d4b94401bd1a4bd752de40c0e504.
  • WITH_ZSTDIO=1: KLD SHA256 598f171d355af78c64407a6d513d20f053530620da92df7f8ccfdf9a804e463d.

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.