--- fs/nfsclient/nfs_clvnops.c.text 2017-03-16 21:55:16.263393000 -0400 +++ fs/nfsclient/nfs_clvnops.c 2017-03-17 09:31:23.632814000 -0400 @@ -140,6 +140,7 @@ static vop_advlock_t nfs_advlock; static vop_advlockasync_t nfs_advlockasync; static vop_getacl_t nfs_getacl; static vop_setacl_t nfs_setacl; +static vop_set_text_t nfs_set_text; /* * Global vfs data structures for nfs @@ -176,6 +177,7 @@ struct vop_vector newnfs_vnodeops = { .vop_write = ncl_write, .vop_getacl = nfs_getacl, .vop_setacl = nfs_setacl, + .vop_set_text = nfs_set_text, }; struct vop_vector newnfs_fifoops = { @@ -3373,6 +3375,29 @@ nfs_setacl(struct vop_setacl_args *ap) return (error); } +static int +nfs_set_text(struct vop_set_text_args *ap) +{ + struct vnode *vp = ap->a_vp; + struct nfsnode *np; + + /* + * If the text file has been mmap'd, the dirty pages must be flushed + * so that the modify time of the file will be up to date. + */ + if (vp->v_object != NULL) { + np = VTONFS(vp); + VM_OBJECT_WLOCK(vp->v_object); + vm_object_page_clean(vp->v_object, 0, 0, OBJPC_SYNC); + VM_OBJECT_WUNLOCK(vp->v_object); + mtx_lock(&np->n_mtx); + np->n_mtime = np->n_vattr.na_mtime; + mtx_unlock(&np->n_mtx); + } + vp->v_vflag |= VV_TEXT; + return (0); +} + /* * Return POSIX pathconf information applicable to nfs filesystems. */