The client-chain interoperability CI leg added in Netatalk/netatalk#3223 tests a Samba client and netatalk-client mounted on the same ea = samba volume, driving both sides with plain filesystem operations. Three AFP capabilities cannot be exercised through the FUSE mount because the client does not forward them; the leg falls back to a wire-level AFP client (afparg) for those checks. Verified against netatalk-client 0.9.5 source.
1. Byte-range locks are local-only (no FUSE .lock/.flock handler)
The fuse_operations table in fuse/fuse_int.c registers no .lock or .flock handler, so a fcntl()/flock() lock taken on an AFP mount is satisfied locally by the FUSE layer — nothing goes over the AFP wire. The lock is invisible to the AFP server, to other AFP clients, and to Samba on a dual-exported share.
This matters most on ea = samba volumes (netatalk 4.6.0 defaults strict locking = yes there): a user application locking a file region through the AFP mount believes it holds a lock, but a Samba client can write straight through it.
The plumbing largely exists: lib/lowlevel.c already calls afp_byterangelock()/afp_byterangelockext() internally. Implementing FUSE .lock (fcntl F_SETLK/F_GETLK mapped to FPByteRangeLock/FPByteRangeLockExt) would make mount-point locks real cross-protocol locks.
2. No deny-mode opens
fuse_open → ml_open maps only the POSIX open flags; there is no path to AFP's deny-read/deny-write open access modes (kFPAccessDenyRead/kFPAccessDenyWrite). POSIX open() on Linux has no deny concept, so this needs an out-of-band control (mount option for a default deny policy, or an ioctl/xattr escape hatch) if it is wanted at all — noting macOS's own AFP client had the same limitation (needs to be validated).
3. No DeleteInhibit / Finder attribute access
No filesystem operation reaches kFPDeleteInhibitBit (or the other Finder attribute bits) via FPSetFileDirParms. A special xattr namespace (e.g. org.netatalk.attributes) could expose them. Finder sets these on macOS clients.
Impact on the interop CI leg
When item 1 lands, the leg's "strict locking mirror" checks can switch from the wire client to a plain lock on the AFP mount — completing the full user-visible chain for that dimension. Items 2 and 3 are protocol concepts with no POSIX equivalent; the wire client is likely the permanent right tool there, but a decision either way would let the leg document its validation points as final.
The client-chain interoperability CI leg added in Netatalk/netatalk#3223 tests a Samba client and netatalk-client mounted on the same
ea = sambavolume, driving both sides with plain filesystem operations. Three AFP capabilities cannot be exercised through the FUSE mount because the client does not forward them; the leg falls back to a wire-level AFP client (afparg) for those checks. Verified against netatalk-client 0.9.5 source.1. Byte-range locks are local-only (no FUSE
.lock/.flockhandler)The
fuse_operationstable infuse/fuse_int.cregisters no.lockor.flockhandler, so afcntl()/flock()lock taken on an AFP mount is satisfied locally by the FUSE layer — nothing goes over the AFP wire. The lock is invisible to the AFP server, to other AFP clients, and to Samba on a dual-exported share.This matters most on
ea = sambavolumes (netatalk 4.6.0 defaultsstrict locking = yesthere): a user application locking a file region through the AFP mount believes it holds a lock, but a Samba client can write straight through it.The plumbing largely exists:
lib/lowlevel.calready callsafp_byterangelock()/afp_byterangelockext()internally. Implementing FUSE.lock(fcntl F_SETLK/F_GETLK mapped toFPByteRangeLock/FPByteRangeLockExt) would make mount-point locks real cross-protocol locks.2. No deny-mode opens
fuse_open→ml_openmaps only the POSIX open flags; there is no path to AFP's deny-read/deny-write open access modes (kFPAccessDenyRead/kFPAccessDenyWrite). POSIXopen()on Linux has no deny concept, so this needs an out-of-band control (mount option for a default deny policy, or an ioctl/xattr escape hatch) if it is wanted at all — noting macOS's own AFP client had the same limitation (needs to be validated).3. No DeleteInhibit / Finder attribute access
No filesystem operation reaches
kFPDeleteInhibitBit(or the other Finder attribute bits) viaFPSetFileDirParms. A special xattr namespace (e.g.org.netatalk.attributes) could expose them. Finder sets these on macOS clients.Impact on the interop CI leg
When item 1 lands, the leg's "strict locking mirror" checks can switch from the wire client to a plain lock on the AFP mount — completing the full user-visible chain for that dimension. Items 2 and 3 are protocol concepts with no POSIX equivalent; the wire client is likely the permanent right tool there, but a decision either way would let the leg document its validation points as final.