aboutsummaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorKonstantin Belousov <kib@FreeBSD.org>2019-05-06 08:49:43 +0000
committerKonstantin Belousov <kib@FreeBSD.org>2019-05-06 08:49:43 +0000
commit391918a3c179789fb4fbc2e33f3af9327e2a7ded (patch)
tree08dd1796ec2f63e2a8a838711aefb6095caa97eb /sys
parent12487941f4b1c12e3ea2606a1cd5511a80d77f76 (diff)
downloadsrc-391918a3c179789fb4fbc2e33f3af9327e2a7ded.tar.gz
src-391918a3c179789fb4fbc2e33f3af9327e2a7ded.zip
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
Notes
Notes: svn path=/head/; revision=347181
Diffstat (limited to 'sys')
-rw-r--r--sys/fs/nfsclient/nfs_clvnops.c61
1 files changed, 27 insertions, 34 deletions
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.
*/