diff options
-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); |