diff options
author | dillon <dillon@FreeBSD.org> | 2001-01-04 22:45:19 +0000 |
---|---|---|
committer | dillon <dillon@FreeBSD.org> | 2001-01-04 22:45:19 +0000 |
commit | 7fdb864af77f4df5a2cd92c362d93dd5d2d10f49 (patch) | |
tree | 612a5d1a2d2c4c59c6d3177c7a90c74f6cf5bee7 /sys | |
parent | efbf261c68397211840db4989230161c3217ffb4 (diff) | |
download | FreeBSD-src-7fdb864af77f4df5a2cd92c362d93dd5d2d10f49.zip FreeBSD-src-7fdb864af77f4df5a2cd92c362d93dd5d2d10f49.tar.gz |
NFS O_EXCL file create semantics temporarily uses file attributes to store
the file verifier. The NFS client is supposed to do a SETATTR after a
successful O_EXCL open/create to clean up the attributes. FreeBSD's
client code was generating a SETATTR rpc but was not generating an access
or modification time update within that rpc, leaving the file with a
broken access time that solaris chokes on (and it doesn't look very
nice when you ls -lua under FreeBSD either!). Fixed.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/nfs/nfs_vnops.c | 15 | ||||
-rw-r--r-- | sys/nfsclient/nfs_vnops.c | 15 |
2 files changed, 28 insertions, 2 deletions
diff --git a/sys/nfs/nfs_vnops.c b/sys/nfs/nfs_vnops.c index e5d3e4f..37b977c 100644 --- a/sys/nfs/nfs_vnops.c +++ b/sys/nfs/nfs_vnops.c @@ -1459,8 +1459,21 @@ again: } if (newvp) vput(newvp); - } else if (v3 && (fmode & O_EXCL)) + } else if (v3 && (fmode & O_EXCL)) { + /* + * We are normally called with only a partially initialized + * VAP. Since the NFSv3 spec says that server may use the + * file attributes to store the verifier, the spec requires + * us to do a SETATTR RPC. FreeBSD servers store the verifier + * in atime, but we can't really assume that all servers will + * so we ensure that our SETATTR sets both atime and mtime. + */ + if (vap->va_mtime.tv_sec == VNOVAL) + vfs_timestamp(&vap->va_mtime); + if (vap->va_atime.tv_sec == VNOVAL) + vap->va_atime = vap->va_mtime; error = nfs_setattrrpc(newvp, vap, cnp->cn_cred, cnp->cn_proc); + } if (!error) { if (cnp->cn_flags & MAKEENTRY) cache_enter(dvp, newvp, cnp); diff --git a/sys/nfsclient/nfs_vnops.c b/sys/nfsclient/nfs_vnops.c index e5d3e4f..37b977c 100644 --- a/sys/nfsclient/nfs_vnops.c +++ b/sys/nfsclient/nfs_vnops.c @@ -1459,8 +1459,21 @@ again: } if (newvp) vput(newvp); - } else if (v3 && (fmode & O_EXCL)) + } else if (v3 && (fmode & O_EXCL)) { + /* + * We are normally called with only a partially initialized + * VAP. Since the NFSv3 spec says that server may use the + * file attributes to store the verifier, the spec requires + * us to do a SETATTR RPC. FreeBSD servers store the verifier + * in atime, but we can't really assume that all servers will + * so we ensure that our SETATTR sets both atime and mtime. + */ + if (vap->va_mtime.tv_sec == VNOVAL) + vfs_timestamp(&vap->va_mtime); + if (vap->va_atime.tv_sec == VNOVAL) + vap->va_atime = vap->va_mtime; error = nfs_setattrrpc(newvp, vap, cnp->cn_cred, cnp->cn_proc); + } if (!error) { if (cnp->cn_flags & MAKEENTRY) cache_enter(dvp, newvp, cnp); |