It is curious as to why nfs server figures out that exclusive is set, then clears va_mode?
Oh yeah, this came screaming back to me. So when NFS has to do exclusive, it attempts to create the file with metadata cleared, that is va_mode 0, and time. It uses atime to hold a create_verf (probably IP and counter), then uses getattr() to confirm the create_verf is matching (this client won). (va_flags has VA_UTIMES_NULL).
If that goes well, it calls setattr() with the correct information.
# We are about to create the file, with O_EXCL, no existing file.
0 nfsrv_create:entry
0 zfs_vnop_getattr:entry
0 zfs_vnop_getattr:return 0 nfsd
0 zfs_vnop_getattr:entry
0 zfs_vnop_getattr:return 0 nfsd
0 zfs_vnop_getattr:entry
0 zfs_vnop_getattr:return 0 nfsd
0 zfs_vnop_getattr:entry
0 zfs_vnop_getattr:return 0 nfsd
0 zfs_vnop_getattr:entry
0 zfs_vnop_getattr:return 0 nfsd
# Which finally calls our vnop_create
0 zfs_vnop_create:entry
# we have created it!
0 zfs_vnop_create:return 0 nfsd
# nfsrv_create now calls setattr - probably to set atime
0 zfs_vnop_setattr:entry
0 zfs_vnop_setattr:return 0 nfsd
# done, and some getattr verify
0 zfs_vnop_getattr:entry
0 zfs_vnop_getattr:return 0 nfsd
0 zfs_vnop_getattr:entry
0 zfs_vnop_getattr:return 0 nfsd
0 zfs_vnop_getattr:entry
0 zfs_vnop_getattr:return 0 nfsd
# send reply code to client
0 nfsrv_rephead:entry
0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
0: 00 00 00 00 ....
# nfsrv_create returns success! We have created the file
0 nfsrv_create:return 0 nfsd
# this setattr appears to be the next client request, unsure where it is from
# but probably to set mode/uid/gid
0 nfsrv_setattr:entry
0 zfs_vnop_getattr:entry
0 zfs_vnop_getattr:return 0 nfsd
0 zfs_vnop_getattr:entry
0 zfs_vnop_getattr:return 0 nfsd
0 zfs_vnop_getattr:entry
0 zfs_vnop_getattr:return 0 nfsd
# nfsrv_setattr calls mac_vnode_check_open
0 mac_vnode_check_open:entry
0 zfs_vnop_getattr:entry
0 zfs_vnop_getattr:return 0 nfsd
0 zfs_vnop_getattr:entry
1 zfs_vnop_getattr:return 0 nfsd
# this setattr is about to fail.
1 hook_vnode_check_open:return 2 nfsd
1 hook_vnode_check_open:return 0 nfsd
1 vng_vnode_check_open:return 0 nfsd
1 mac_vnode_check_open:return 2 nfsd
1 mac_vnode_check_open:return 2 nfsd
# mac_vnode_check_open failed, error = ESTALE
1 zfs_vnop_getattr:entry
1 zfs_vnop_getattr:return 0 nfsd
1 nfsrv_rephead:entry
0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
0: 46 00 00 00 F...
I guess if I knew where hook_vnode_check_open() is defined, I can perhaps figure out
what goes wrong, but I get a bit lost in the MACF macros.
Topic:
App & System Services
SubTopic:
Core OS
Tags: