Date: Wed, 12 Apr 2017 21:37:12 +0000 (UTC) From: Rick Macklem <rmacklem@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r316745 - head/sys/fs/nfsclient Message-ID: <201704122137.v3CLbCoA052529@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: rmacklem Date: Wed Apr 12 21:37:12 2017 New Revision: 316745 URL: https://svnweb.freebsd.org/changeset/base/316745 Log: Fix the NFS client for "text file modified, process killed" mmap'd case. When an mmap'd text file is written and then executed immediately afterwards, it was possible that the modify time would change after the text file was executing, resulting in the process executing the file being killed. This was usually only observed when the file system's times were set to higher resolution, but could have occurred for any time resolution. This was reported on a recent email list discussion. This patch adds a VOP_SET_TEXT() to the NFS client which flushed all dirty pages to the NFS server and then makes sure that n_mtime is up to date to avoid this from occurring. Thanks go to kib@ and pho@ for their help with developing this patch. Tested by: pho Reviewed by: kib MFC after: 2 weeks Modified: head/sys/fs/nfsclient/nfs_clvnops.c Modified: head/sys/fs/nfsclient/nfs_clvnops.c ============================================================================== --- head/sys/fs/nfsclient/nfs_clvnops.c Wed Apr 12 21:15:55 2017 (r316744) +++ head/sys/fs/nfsclient/nfs_clvnops.c Wed Apr 12 21:37:12 2017 (r316745) @@ -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 = { @@ -3381,6 +3383,39 @@ 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, flush any dirty pages to the + * buffer cache and then... + * Make sure all writes are pushed to the NFS server. If this is not + * done, the modify time of the file can change while the text + * file is being executed. This will cause the process that is + * executing the text file to be terminated. + */ + if (vp->v_object != NULL) { + VM_OBJECT_WLOCK(vp->v_object); + vm_object_page_clean(vp->v_object, 0, 0, OBJPC_SYNC); + VM_OBJECT_WUNLOCK(vp->v_object); + } + + /* Now, flush the buffer cache. */ + ncl_flush(vp, MNT_WAIT, NULL, curthread, 0, 0); + + /* And, finally, make sure that n_mtime is up to date. */ + np = VTONFS(vp); + 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. */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201704122137.v3CLbCoA052529>