Module Name:    src
Committed By:   hannken
Date:           Wed May 17 12:46:14 UTC 2017

Modified Files:
        src/sys/kern: vfs_vnode.c

Log Message:
Suspend file system while revoking a vnode.  This way no operations run
on the mounted file system during revoke and all operations see
the state before or after the revoke.


To generate a diff of this commit:
cvs rdiff -u -r1.87 -r1.88 src/sys/kern/vfs_vnode.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/kern/vfs_vnode.c
diff -u src/sys/kern/vfs_vnode.c:1.87 src/sys/kern/vfs_vnode.c:1.88
--- src/sys/kern/vfs_vnode.c:1.87	Mon Apr 17 08:32:01 2017
+++ src/sys/kern/vfs_vnode.c	Wed May 17 12:46:14 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: vfs_vnode.c,v 1.87 2017/04/17 08:32:01 hannken Exp $	*/
+/*	$NetBSD: vfs_vnode.c,v 1.88 2017/05/17 12:46:14 hannken Exp $	*/
 
 /*-
  * Copyright (c) 1997-2011 The NetBSD Foundation, Inc.
@@ -156,7 +156,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: vfs_vnode.c,v 1.87 2017/04/17 08:32:01 hannken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vfs_vnode.c,v 1.88 2017/05/17 12:46:14 hannken Exp $");
 
 #include <sys/param.h>
 #include <sys/kernel.h>
@@ -950,31 +950,48 @@ vrecycle(vnode_t *vp)
 void
 vrevoke(vnode_t *vp)
 {
+	int error;
+	struct mount *mp;
 	vnode_t *vq;
 	enum vtype type;
 	dev_t dev;
 
 	KASSERT(vp->v_usecount > 0);
 
+	mp = vp->v_mount;
+	error = vfs_suspend(mp, 0);
+	KASSERT(error == 0 || error == EOPNOTSUPP);
+	if (error)
+		mp = NULL;
+
 	mutex_enter(vp->v_interlock);
 	VSTATE_WAIT_STABLE(vp);
 	if (VSTATE_GET(vp) == VS_RECLAIMED) {
 		mutex_exit(vp->v_interlock);
-		return;
 	} else if (vp->v_type != VBLK && vp->v_type != VCHR) {
 		atomic_inc_uint(&vp->v_usecount);
 		mutex_exit(vp->v_interlock);
 		vgone(vp);
-		return;
 	} else {
 		dev = vp->v_rdev;
 		type = vp->v_type;
 		mutex_exit(vp->v_interlock);
-	}
 
-	while (spec_node_lookup_by_dev(type, dev, &vq) == 0) {
-		vgone(vq);
+		while (spec_node_lookup_by_dev(type, dev, &vq) == 0) {
+			if (mp != vq->v_mount) {
+				if (mp)
+					vfs_resume(mp);
+				mp = vp->v_mount;
+				error = vfs_suspend(mp, 0);
+				KASSERT(error == 0 || error == EOPNOTSUPP);
+				if (error)
+					mp = NULL;
+			}
+			vgone(vq);
+		}
 	}
+	if (mp)
+		vfs_resume(mp);
 }
 
 /*

Reply via email to