freebsd-dev/sys/nfsserver
Alexander Kabaev 7d464bbf38 Change nfsserver slightly so that it does not trip over the timestamp
validation code on ZFS.

Problem: when opening file with O_CREAT|O_EXCL NFS has to jump through
extra hoops to ensure O_EXCL semantics. Namely, client supplies of 8
bytes (NFSX_V3CREATEVERF) bytes of verification data to uniquely
identify this create request. Server then creates a new file with access
mode 0, copies received 8 bytes into va_atime member of struct vattr and
attempt to set the atime on file using VOP_SETATTR. If that succeeds, it
fetches file attributes with VOP_GETATTR and verifies that atime
timestamps match.  If timestamps do not match, NFS server concludes it
has probbaly lost the race to another process creating the file with the
same name and bails with EEXIST.

This scheme works OK when exported FS is FFS, but if underlying
filesystem is ZFS _and_ server is running 64bit kernel, it breaks down
due to sanity checking in zfs_setattr function, which refuses to accept
any timestamps which have tv_sec that cannot be represented as 32bit
int. Since struct timespec fields are 64 bit integers on 64bit platforms
and server just copies NFSX_V3CREATEVERF bytes info va_atime, all eight
bytes supplied by client end up in va_atime.tv_sec, forcing it out of
valid 32bit range.

The solution this change implements is simple: it treats
NFSX_V3CREATEVERF as two 32bit integers and unpacks them separately into
va_atime.tv_sec and va_atime.tv_nsec respectively, thus guaranteeing
that tv_sec remains in 32 bit range and ZFS remains happy.

Reviewed by: kib
2008-12-03 17:54:09 +00:00
..
nfs_fha.c Range-check NFSv2 procedure numbers before converting to NFSv3. 2008-11-07 10:43:01 +00:00
nfs_fha.h Implement support for RPCSEC_GSS authentication to both the NFS client 2008-11-03 10:38:00 +00:00
nfs_serv.c Change nfsserver slightly so that it does not trip over the timestamp 2008-12-03 17:54:09 +00:00
nfs_srvcache.c Implement support for RPCSEC_GSS authentication to both the NFS client 2008-11-03 10:38:00 +00:00
nfs_srvkrpc.c Use the remote address for access control, not the local address. This fixes 2008-11-13 14:36:52 +00:00
nfs_srvsock.c Implement support for RPCSEC_GSS authentication to both the NFS client 2008-11-03 10:38:00 +00:00
nfs_srvsubs.c In the nfsrv_fhtovp(), after the vfs_getvfs() function found the pointer 2008-11-29 13:34:59 +00:00
nfs_syscalls.c Implement support for RPCSEC_GSS authentication to both the NFS client 2008-11-03 10:38:00 +00:00
nfs.h Switch the default rpc implementation for NFS back to the new code. I believe 2008-11-14 11:27:53 +00:00
nfsm_subs.h Implement support for RPCSEC_GSS authentication to both the NFS client 2008-11-03 10:38:00 +00:00
nfsrvcache.h Implement support for RPCSEC_GSS authentication to both the NFS client 2008-11-03 10:38:00 +00:00
nfsrvstats.h /* -> /*- for license, minor formatting changes 2005-01-07 01:45:51 +00:00