diff --git a/sys/fs/nfs/nfs_commonsubs.c b/sys/fs/nfs/nfs_commonsubs.c index e79f7373948..3c9af40253a 100644 --- a/sys/fs/nfs/nfs_commonsubs.c +++ b/sys/fs/nfs/nfs_commonsubs.c @@ -296,7 +296,7 @@ static struct { { NFSV4OP_OPEN, 8, "CreateLayGet", 12, }, { NFSV4OP_IOADVISE, 1, "Advise", 6, }, { NFSV4OP_ALLOCATE, 2, "Allocate", 8, }, - { NFSV4OP_SAVEFH, 6, "Copy", 4, }, + { NFSV4OP_SAVEFH, 5, "Copy", 4, }, { NFSV4OP_SEEK, 2, "Seek", 4, }, { NFSV4OP_SEEK, 1, "SeekDS", 6, }, { NFSV4OP_GETXATTR, 2, "Getxattr", 8, }, diff --git a/sys/fs/nfsclient/nfs_clrpcops.c b/sys/fs/nfsclient/nfs_clrpcops.c index e9acedfb647..09660730d48 100644 --- a/sys/fs/nfsclient/nfs_clrpcops.c +++ b/sys/fs/nfsclient/nfs_clrpcops.c @@ -8728,7 +8728,7 @@ nfsrpc_copyrpc(vnode_t invp, off_t inoff, vnode_t outvp, off_t outoff, int *outattrflagp, bool consecutive, int *commitp, struct ucred *cred, NFSPROC_T *p) { - uint32_t *tl; + uint32_t *tl, *opcntp; int error; struct nfsrv_descript nfsd; struct nfsrv_descript *nd = &nfsd; @@ -8737,14 +8737,15 @@ nfsrpc_copyrpc(vnode_t invp, off_t inoff, vnode_t outvp, off_t outoff, struct vattr va; uint64_t len; - nmp = VFSTONFS(outvp->v_mount); + nmp = VFSTONFS(invp->v_mount); *inattrflagp = *outattrflagp = 0; *commitp = NFSWRITE_UNSTABLE; len = *lenp; *lenp = 0; if (len > nfs_maxcopyrange) len = nfs_maxcopyrange; - NFSCL_REQSTART(nd, NFSPROC_COPY, invp, cred); + nfscl_reqstart(nd, NFSPROC_COPY, nmp, VTONFS(invp)->n_fhp->nfh_fh, + VTONFS(invp)->n_fhp->nfh_len, &opcntp, NULL, 0, 0, cred); /* * First do a Setattr of atime to the server's clock * time. The FreeBSD "collective" was of the opinion @@ -8753,13 +8754,17 @@ nfsrpc_copyrpc(vnode_t invp, off_t inoff, vnode_t outvp, off_t outoff, * handled well if the server replies NFSERR_DELAY to * the Setattr operation. */ - NFSM_BUILD(tl, uint32_t *, NFSX_UNSIGNED); - *tl = txdr_unsigned(NFSV4OP_SETATTR); - nfsm_stateidtom(nd, instateidp, NFSSTATEID_PUTSTATEID); - VATTR_NULL(&va); - va.va_atime.tv_sec = va.va_atime.tv_nsec = 0; - va.va_vaflags = VA_UTIMES_NULL; - nfscl_fillsattr(nd, &va, invp, 0, 0); + if ((nmp->nm_mountp->mnt_flag & MNT_NOATIME) == 0) { + NFSM_BUILD(tl, uint32_t *, NFSX_UNSIGNED); + *tl = txdr_unsigned(NFSV4OP_SETATTR); + nfsm_stateidtom(nd, instateidp, NFSSTATEID_PUTSTATEID); + VATTR_NULL(&va); + va.va_atime.tv_sec = va.va_atime.tv_nsec = 0; + va.va_vaflags = VA_UTIMES_NULL; + nfscl_fillsattr(nd, &va, invp, 0, 0); + /* Bump opcnt from 7 to 8. */ + *opcntp = txdr_unsigned(8); + } /* Now Getattr the invp attributes. */ NFSM_BUILD(tl, uint32_t *, NFSX_UNSIGNED); @@ -8798,7 +8803,8 @@ nfsrpc_copyrpc(vnode_t invp, off_t inoff, vnode_t outvp, off_t outoff, if (error != 0) return (error); /* Skip over the Setattr reply. */ - if ((nd->nd_flag & ND_NOMOREDATA) == 0) { + if ((nd->nd_flag & ND_NOMOREDATA) == 0 && + (nmp->nm_mountp->mnt_flag & MNT_NOATIME) == 0) { NFSM_DISSECT(tl, uint32_t *, 2 * NFSX_UNSIGNED); if (*(tl + 1) == 0) { error = nfsrv_getattrbits(nd, &attrbits, NULL, NULL); diff --git a/sys/fs/nfsclient/nfs_clvnops.c b/sys/fs/nfsclient/nfs_clvnops.c index 0014f8a26d2..0b8c587a542 100644 --- a/sys/fs/nfsclient/nfs_clvnops.c +++ b/sys/fs/nfsclient/nfs_clvnops.c @@ -3934,18 +3934,22 @@ relock: */ if (inoff >= vap->va_size) { *ap->a_lenp = len = 0; - VATTR_NULL(&va); - va.va_atime.tv_sec = va.va_atime.tv_nsec = 0; - va.va_vaflags = VA_UTIMES_NULL; - inattrflag = 0; - error = nfsrpc_setattr(invp, &va, NULL, - ap->a_incred, curthread, &innfsva, - &inattrflag); - if (inattrflag != 0) - ret = nfscl_loadattrcache(&invp, - &innfsva, NULL, 0, 1); - if (error == 0 && ret != 0) - error = ret; + if ((nmp->nm_mountp->mnt_flag & MNT_NOATIME) == + 0) { + VATTR_NULL(&va); + va.va_atime.tv_sec = 0; + va.va_atime.tv_nsec = 0; + va.va_vaflags = VA_UTIMES_NULL; + inattrflag = 0; + error = nfsrpc_setattr(invp, &va, NULL, + ap->a_incred, curthread, &innfsva, + &inattrflag); + if (inattrflag != 0) + ret = nfscl_loadattrcache(&invp, + &innfsva, NULL, 0, 1); + if (error == 0 && ret != 0) + error = ret; + } } else if (inoff + len > vap->va_size) *ap->a_lenp = len = vap->va_size - inoff; } else