diff --git a/sys/fs/nfsclient/nfs_clbio.c.write b/sys/fs/nfsclient/nfs_clbio.c --- a/sys/fs/nfsclient/nfs_clbio.c.write +++ b/sys/fs/nfsclient/nfs_clbio.c @@ -906,6 +906,7 @@ int bp_cached, n, on, error = 0, error1, save2, wouldcommit; size_t orig_resid, local_resid; off_t orig_size, tmp_off; + struct timespec ts; KASSERT(uio->uio_rw == UIO_WRITE, ("ncl_write mode")); KASSERT(uio->uio_segflg != UIO_USERSPACE || uio->uio_td == curthread, @@ -1283,7 +1284,12 @@ break; } while (uio->uio_resid > 0 && n > 0); - if (error != 0) { + if (error == 0) { + nanouptime(&ts); + NFSLOCKNODE(np); + np->n_localmodtime = ts; + NFSUNLOCKNODE(np); + } else { if (ioflag & IO_UNIT) { VATTR_NULL(&vattr); vattr.va_size = orig_size; @@ -1355,6 +1361,7 @@ struct nfsmount *nmp = VFSTONFS(vp->v_mount); int error = 0, slpflag, slptimeo; bool old_lock; + struct timespec ts; ASSERT_VOP_LOCKED(vp, "ncl_vinvalbuf"); @@ -1399,16 +1406,21 @@ } if (NFSHASPNFS(nmp)) { nfscl_layoutcommit(vp, td); + nanouptime(&ts); /* * Invalidate the attribute cache, since writes to a DS * won't update the size attribute. */ NFSLOCKNODE(np); np->n_attrstamp = 0; - } else + } else { + nanouptime(&ts); NFSLOCKNODE(np); - if (np->n_directio_asyncwr == 0) + } + if (np->n_directio_asyncwr == 0 && (np->n_flag & NMODIFIED) != 0) { + np->n_localmodtime = ts; np->n_flag &= ~NMODIFIED; + } NFSUNLOCKNODE(np); out: ncl_excl_finish(vp, old_lock); diff --git a/sys/fs/nfsclient/nfs_clvnops.c.write b/sys/fs/nfsclient/nfs_clvnops.c --- a/sys/fs/nfsclient/nfs_clvnops.c.write +++ b/sys/fs/nfsclient/nfs_clvnops.c @@ -2896,6 +2896,7 @@ #endif struct buf *bvec_on_stack[NFS_COMMITBVECSIZ]; u_int bvecsize = 0, bveccount; + struct timespec ts; if (called_from_renewthread != 0) slptimeo = hz; @@ -3215,6 +3216,12 @@ } vn_printf(vp, "ncl_flush failed"); error = called_from_renewthread != 0 ? EIO : EBUSY; + } + if (error == 0) { + nanouptime(&ts); + NFSLOCKNODE(np); + np->n_localmodtime = ts; + NFSUNLOCKNODE(np); } return (error); }