When running AJA System Test for my custom filesystem, the write and read tests get stuck intermittently.
I didn't observe any error codes being returned by my vnop_read/write or sock_receive/send functions.
Dtrace(1)'ing the vnops being called by AJA System Test for smbfs revealed that amongst other things vnop_advlock is being called:
0 -> smbfs_vnop_advlock ajasystemtest -> smbfs_vnop_advlock(ajatest.dat, op: 0x2, fl->l_start: 0, fl->l_len: 0, fl->l_pid: 0, fl->l_type: 2, fl->l_whence: 0, flags: 0x40, timeout: 0)
0 <- smbfs_vnop_advlock ajasystemtest -> smbfs_vnop_advlock(ajatest.dat) -> -1934627947504
op: 0x2
#define F_SETFD 2 /* set file descriptor flags */
fl->l_len: 0 ;len = 0 means until end of file
fl->l_type: 2 ;#define F_UNLCK 2 /* unlock */
fl->l_whence: 0 ;#define SEEK_SET 0 /* set file offset to offset */
flags: 0x40 ;#define F_POSIX 0x040 /* Use POSIX semantics for lock */
As my filesystem didn't implement vnop_advlock, I thought I'd explore that avenue.
My vnop_advlock simply returns KERN_SUCCESS.
Both f_capabilities.valid and f_capabilities.capabilities of struct vfs_attr have VOL_CAP_INT_ADVLOCK and VOL_CAP_INT_FLOCK set.
Yet, vnop_advlock doesn't get called for my filesystem when running AJA System Test.
Any tips on what could be amiss there would be much appreciated.
I disabled local locking and implemented a vnop_advlock of my own.
As a quick side not, keep in mind that POSIX locking is not widely used on macOS. There may be other reasons why this support is important to you, but you should not expect this to provide "general" protection against write collisions. macOS apps simply don't really use this mechanism.
AJAsystemtest issues a POSIX advlock request with vnop_advlock_args.a_flags being set to F_POSIX.
Have you written your own test and/or do you have the source to the test(s) you're using? The first step here it so make sure you understand exactly what the client did before you assume that there is any actually "issue" at work here. To put that another way, what you're reporting here is basically a "user level issue" ("my app doesn't work"), not an actual software problem ("this particular function is not behaving the way I'd expect").
Part of your basic development process here needs to be a complete set of tests tools/apps that specifically test every single operation your file system supports. Often these eventually become unit tests used to ensure ongoing correctness, but in the initial development process they're simply the basic tool you use to ensure your file system actually does what you think it should.
What I don't understand is why I'm only getting F_UNLCKs, but no F_SETLKs.
Please refer to the POSIX specification:
https://pubs.opengroup.org/onlinepubs/9699919799/functions/fcntl.html
Quick summary, "F_UNLCK" and "F_SETLK" are not "peer" operations. F_UNLCK is a lock type, while F_SETLK is used to modify the lock state. In terms of what "AJAsystemtest" is actually doing, my guess is that they're simply checking the lock state but not taking the lock themselves but that's only a guess. My actual answer is that apps do all sorts of odd nonsense with the file system, which is why you need to write your own tests.
__
Kevin Elliott
DTS Engineer, CoreOS/Hardware