From b454c48bc7151d6c450684de8ab2cef965daa2a7 Mon Sep 17 00:00:00 2001 From: dillon Date: Thu, 4 Jan 2001 22:45:19 +0000 Subject: [PATCH] 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. --- sys/nfs/nfs_vnops.c | 15 ++++++++++++++- 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 e5d3e4f445c5..37b977ca53d5 100644 --- a/sys/nfs/nfs_vnops.c +++ b/sys/nfs/nfs_vnops.c @@ -1459,8 +1459,21 @@ nfs_create(ap) } 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 e5d3e4f445c5..37b977ca53d5 100644 --- a/sys/nfsclient/nfs_vnops.c +++ b/sys/nfsclient/nfs_vnops.c @@ -1459,8 +1459,21 @@ nfs_create(ap) } 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);