From 391918a3c179789fb4fbc2e33f3af9327e2a7ded Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Mon, 6 May 2019 08:49:43 +0000 Subject: Do not flush NFS node from NFS VOP_SET_TEXT(). The more appropriate place to do the flushing is VOP_OPEN(). This was uncovered because VOP_SET_TEXT() is now called with the vnode' vm_object rlocked, which is incompatible with the flush operations. After the move, there is no need for NFS-specific VOP_SET_TEXT overload. Sponsored by: The FreeBSD Foundation MFC after: 30 days --- sys/fs/nfsclient/nfs_clvnops.c | 61 +++++++++++++++++++----------------------- 1 file changed, 27 insertions(+), 34 deletions(-) (limited to 'sys') diff --git a/sys/fs/nfsclient/nfs_clvnops.c b/sys/fs/nfsclient/nfs_clvnops.c index 41a7b2867c55..cc6294494401 100644 --- a/sys/fs/nfsclient/nfs_clvnops.c +++ b/sys/fs/nfsclient/nfs_clvnops.c @@ -142,7 +142,6 @@ 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 @@ -180,7 +179,6 @@ static struct vop_vector newnfs_vnodeops_nosig = { .vop_write = ncl_write, .vop_getacl = nfs_getacl, .vop_setacl = nfs_setacl, - .vop_set_text = nfs_set_text, }; static int @@ -523,6 +521,7 @@ nfs_open(struct vop_open_args *ap) int error; int fmode = ap->a_mode; struct ucred *cred; + vm_object_t obj; if (vp->v_type != VREG && vp->v_type != VDIR && vp->v_type != VLNK) return (EOPNOTSUPP); @@ -636,6 +635,32 @@ nfs_open(struct vop_open_args *ap) if (cred != NULL) crfree(cred); vnode_create_vobject(vp, vattr.va_size, ap->a_td); + + /* + * 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_writecount <= -1) { + if ((obj = vp->v_object) != NULL && + (obj->flags & OBJ_MIGHTBEDIRTY) != 0) { + VM_OBJECT_WLOCK(obj); + vm_object_page_clean(obj, 0, 0, OBJPC_SYNC); + VM_OBJECT_WUNLOCK(obj); + } + + /* Now, flush the buffer cache. */ + ncl_flush(vp, MNT_WAIT, 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); + } return (0); } @@ -3413,38 +3438,6 @@ 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, 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); - - return (vop_stdset_text(ap)); -} - /* * Return POSIX pathconf information applicable to nfs filesystems. */ -- cgit v1.2.3