Index: external/cddl/osnet/sys/sys/vnode.h
===================================================================
RCS file: /cvsroot/src/external/cddl/osnet/sys/sys/vnode.h,v
retrieving revision 1.11
diff -p -u -4 -r1.11 vnode.h
--- external/cddl/osnet/sys/sys/vnode.h	23 Sep 2013 20:44:24 -0000	1.11
+++ external/cddl/osnet/sys/sys/vnode.h	10 Oct 2013 09:08:13 -0000
@@ -685,9 +685,8 @@ vn_remove(char *fnamep, enum uio_seg seg
 }
 
 #define VN_RELE_ASYNC(vp, taskq) 	vrele_async((vp))
 #define vn_exists(a) 	do { } while(0)
-#define vn_reinit(a) 	vclean((a), 0)
 
 /*
  * Flags for VOP_LOOKUP
  *
Index: sys/kern/vfs_vnode.c
===================================================================
RCS file: /cvsroot/src/sys/kern/vfs_vnode.c,v
retrieving revision 1.21
diff -p -u -4 -r1.21 vfs_vnode.c
--- sys/kern/vfs_vnode.c	30 Sep 2013 15:24:14 -0000	1.21
+++ sys/kern/vfs_vnode.c	10 Oct 2013 09:08:23 -0000
@@ -127,8 +127,10 @@
 
 #include <sys/cdefs.h>
 __KERNEL_RCSID(0, "$NetBSD: vfs_vnode.c,v 1.21 2013/09/30 15:24:14 hannken Exp $");
 
+#define _VFS_VNODE_PRIVATE
+
 #include <sys/param.h>
 #include <sys/kernel.h>
 
 #include <sys/atomic.h>
@@ -149,8 +151,17 @@ __KERNEL_RCSID(0, "$NetBSD: vfs_vnode.c,
 
 #include <uvm/uvm.h>
 #include <uvm/uvm_readahead.h>
 
+/* v_usecount; see the comment near the top of vfs_vnode.c */
+#define	VC_XLOCK	0x80000000
+#define	VC_MASK		0x7fffffff
+
+#define	DOCLOSE		0x0008		/* vclean: close active files */
+
+/* Flags to vrelel. */
+#define	VRELEL_ASYNC_RELE	0x0001	/* Always defer to vrele thread. */
+
 u_int			numvnodes		__cacheline_aligned;
 
 static pool_cache_t	vnode_cache		__read_mostly;
 
@@ -171,8 +182,9 @@ static lwp_t *		vrele_lwp		__cacheline_a
 static int		vrele_pending		__cacheline_aligned;
 static int		vrele_gen		__cacheline_aligned;
 
 static int		cleanvnode(void);
+static void		vrelel(vnode_t *, int);
 static void		vdrain_thread(void *);
 static void		vrele_thread(void *);
 static void		vnpanic(vnode_t *, const char *, ...)
     __printflike(2, 3);
@@ -633,9 +645,9 @@ vtryrele(vnode_t *vp)
 /*
  * Vnode release.  If reference count drops to zero, call inactive
  * routine and either return to freelist or free to the pool.
  */
-void
+static void
 vrelel(vnode_t *vp, int flags)
 {
 	bool recycle, defer;
 	int error;
@@ -979,9 +991,9 @@ holdrelel(vnode_t *vp)
 void
 vclean(vnode_t *vp, int flags)
 {
 	lwp_t *l = curlwp;
-	bool recycle, active;
+	bool recycle, active, make_anon;
 	int error;
 
 	KASSERT(mutex_owned(vp->v_interlock));
 	KASSERT((vp->v_iflag & VI_MARKER) == 0);
@@ -1013,8 +1025,13 @@ vclean(vnode_t *vp, int flags)
 	/* XXXAD should not lock vnode under layer */
 	mutex_exit(vp->v_interlock);
 	VOP_LOCK(vp, LK_EXCLUSIVE);
 
+	make_anon = (active && vp->v_type == VBLK &&
+	    spec_node_getmountedfs(vp) != NULL);
+	if (make_anon)
+		flags &= ~DOCLOSE;
+
 	/*
 	 * Clean out any cached data associated with the vnode.
 	 * If purging an active vnode, it must be closed and
 	 * deactivated before being reclaimed. Note that the
@@ -1060,11 +1077,22 @@ vclean(vnode_t *vp, int flags)
 
 	/* Purge name cache. */
 	cache_purge(vp);
 
+	/*
+	 * The vnode isn't clean, but still resides on the mount list.  Remove
+	 * it. XXX This is a bit dodgy.
+	 */
+	if (make_anon)
+		vfs_insmntque(vp, NULL);
+
 	/* Done with purge, notify sleepers of the grim news. */
 	mutex_enter(vp->v_interlock);
-	vp->v_op = dead_vnodeop_p;
+	if (make_anon) {
+		vp->v_op = spec_vnodeop_p;
+	} else {
+		vp->v_op = dead_vnodeop_p;
+	}
 	vp->v_tag = VT_NON;
 	KNOTE(&vp->v_klist, NOTE_REVOKE);
 	vp->v_iflag &= ~VI_XLOCK;
 	vp->v_vflag &= ~VV_LOCKSWORK;
@@ -1080,9 +1108,9 @@ vclean(vnode_t *vp, int flags)
  * Recycle an unused vnode to the front of the free list.
  * Release the passed interlock if the vnode will be recycled.
  */
 int
-vrecycle(vnode_t *vp, kmutex_t *inter_lkp, struct lwp *l)
+vrecycle(vnode_t *vp, kmutex_t *inter_lkp)
 {
 
 	KASSERT((vp->v_iflag & VI_MARKER) == 0);
 
====

Index: sys/kern/uipc_usrreq.c
===================================================================
RCS file: /cvsroot/src/sys/kern/uipc_usrreq.c,v
retrieving revision 1.146
diff -p -u -4 -r1.146 uipc_usrreq.c
--- sys/kern/uipc_usrreq.c	8 Oct 2013 17:21:24 -0000	1.146
+++ sys/kern/uipc_usrreq.c	10 Oct 2013 09:08:23 -0000
@@ -852,9 +852,10 @@ unp_detach(struct unpcb *unp)
 		/* Acquire v_interlock to protect against unp_connect(). */
 		/* XXXAD racy */
 		mutex_enter(vp->v_interlock);
 		vp->v_socket = NULL;
-		vrelel(vp, 0);
+		mutex_exit(vp->v_interlock);
+		vrele(vp);
 		solock(so);
 		unp->unp_vnode = NULL;
 	}
 	if (unp->unp_conn)
Index: sys/kern/vfs_mount.c
===================================================================
RCS file: /cvsroot/src/sys/kern/vfs_mount.c,v
retrieving revision 1.21
diff -p -u -4 -r1.21 vfs_mount.c
--- sys/kern/vfs_mount.c	30 Sep 2013 18:58:00 -0000	1.21
+++ sys/kern/vfs_mount.c	10 Oct 2013 09:08:23 -0000
@@ -464,8 +464,15 @@ vflush(struct mount *mp, vnode_t *skipvp
 		 * Skip over a selected vnode.
 		 */
 		if (vp == skipvp)
 			continue;
+		/*
+		 * First try to recycle the vnode.
+		 */
+		if (vrecycle(vp, &mntvnode_lock)) {
+			mutex_enter(&mntvnode_lock);
+			continue;
+		}
 		mutex_enter(vp->v_interlock);
 		/*
 		 * Ignore clean but still referenced vnodes.
 		 */
@@ -489,44 +496,17 @@ vflush(struct mount *mp, vnode_t *skipvp
 			mutex_exit(vp->v_interlock);
 			continue;
 		}
 		/*
-		 * With v_usecount == 0, all we need to do is clear
-		 * out the vnode data structures and we are done.
-		 */
-		if (vp->v_usecount == 0) {
-			mutex_exit(&mntvnode_lock);
-			vremfree(vp);
-			vp->v_usecount = 1;
-			vclean(vp, DOCLOSE);
-			vrelel(vp, 0);
-			mutex_enter(&mntvnode_lock);
-			continue;
-		}
-		/*
 		 * If FORCECLOSE is set, forcibly close the vnode.
 		 * For block or character devices, revert to an
 		 * anonymous device.  For all other files, just
 		 * kill them.
 		 */
 		if (flags & FORCECLOSE) {
 			mutex_exit(&mntvnode_lock);
-			atomic_inc_uint(&vp->v_usecount);
-			if (vp->v_type != VBLK && vp->v_type != VCHR) {
-				vclean(vp, DOCLOSE);
-				vrelel(vp, 0);
-			} else {
-				vclean(vp, 0);
-				vp->v_op = spec_vnodeop_p; /* XXXSMP */
-				mutex_exit(vp->v_interlock);
-				/*
-				 * The vnode isn't clean, but still resides
-				 * on the mount list.  Remove it. XXX This
-				 * is a bit dodgy.
-				 */
-				vfs_insmntque(vp, NULL);
-				vrele(vp);
-			}
+			if (vget(vp, 0) == 0)
+				vgone(vp);
 			mutex_enter(&mntvnode_lock);
 			continue;
 		}
 #ifdef DEBUG
Index: sys/miscfs/procfs/procfs_subr.c
===================================================================
RCS file: /cvsroot/src/sys/miscfs/procfs/procfs_subr.c,v
retrieving revision 1.102
diff -p -u -4 -r1.102 procfs_subr.c
--- sys/miscfs/procfs/procfs_subr.c	25 Nov 2012 01:03:05 -0000	1.102
+++ sys/miscfs/procfs/procfs_subr.c	10 Oct 2013 09:08:23 -0000
@@ -670,20 +670,19 @@ procfs_revoke_vnodes(struct proc *p, voi
 	ppp = &pfs_hashtbl[PFSPIDHASH(p->p_pid)];
 	for (pfs = LIST_FIRST(ppp); pfs; pfs = pnext) {
 		vp = PFSTOV(pfs);
 		pnext = LIST_NEXT(pfs, pfs_hash);
+		if (pfs->pfs_pid != p->p_pid || vp->v_mount != mp)
+			continue;
 		mutex_enter(vp->v_interlock);
-		if (vp->v_usecount > 0 && pfs->pfs_pid == p->p_pid &&
-		    vp->v_mount == mp) {
-		    	vp->v_usecount++;
-		    	mutex_exit(vp->v_interlock);
-			mutex_exit(&pfs_ihash_lock);
-			VOP_REVOKE(vp, REVOKEALL);
-			vrele(vp);
+		mutex_exit(&pfs_ihash_lock);
+		if (vget(vp, 0) != 0) {
 			mutex_enter(&pfs_ihash_lock);
-		} else {
-			mutex_exit(vp->v_interlock);
+			continue;
 		}
+		VOP_REVOKE(vp, REVOKEALL);
+		vrele(vp);
+		mutex_enter(&pfs_ihash_lock);
 	}
 	mutex_exit(&pfs_ihash_lock);
 }
 
Index: sys/sys/vnode.h
===================================================================
RCS file: /cvsroot/src/sys/sys/vnode.h,v
retrieving revision 1.238
diff -p -u -4 -r1.238 vnode.h
--- sys/sys/vnode.h	30 Sep 2013 15:24:14 -0000	1.238
+++ sys/sys/vnode.h	10 Oct 2013 09:08:23 -0000
@@ -204,10 +204,12 @@ typedef struct vnode vnode_t;
 #define	VI_MARKER	0x00008000	/* Dummy marker vnode */
 #define	VI_LAYER	0x00020000	/* vnode is on a layer filesystem */
 #define	VI_LOCKSHARE	0x00040000	/* v_interlock is shared */
 #define	VI_CLEAN	0x00080000	/* has been reclaimed */
+#ifdef _VFS_VNODE_PRIVATE
 #define	VI_INACTREDO	0x00200000	/* need to redo VOP_INACTIVE() */
 #define	VI_INACTNOW	0x00800000	/* VOP_INACTIVE() in progress */
+#endif	/* _VFS_VNODE_PRIVATE */
 
 /*
  * The third set are locked by the underlying file system.
  */
@@ -221,14 +223,8 @@ typedef struct vnode vnode_t;
 
 #define	VSIZENOTSET	((voff_t)-1)
 
 /*
- * v_usecount; see the comment near the top of vfs_vnode.c
- */
-#define	VC_XLOCK	0x80000000
-#define	VC_MASK		0x7fffffff
-
-/*
  * vnode lock flags
  */
 #define	LK_SHARED	0x00000001	/* shared lock */
 #define	LK_EXCLUSIVE	0x00000002	/* exclusive lock */
@@ -317,9 +313,8 @@ extern const int	vttoif_tab[];
  */
 #define	SKIPSYSTEM	0x0001		/* vflush: skip vnodes marked VSYSTEM */
 #define	FORCECLOSE	0x0002		/* vflush: force file closeure */
 #define	WRITECLOSE	0x0004		/* vflush: only close writable files */
-#define	DOCLOSE		0x0008		/* vclean: close active files */
 #define	V_SAVE		0x0001		/* vinvalbuf: sync file first */
 
 /*
  * Flags to various vnode operations.
@@ -552,19 +547,17 @@ bool	vtryget(struct vnode *);
 void 	vgone(struct vnode *);
 int	vinvalbuf(struct vnode *, int, kauth_cred_t, struct lwp *, bool, int);
 void	vprint(const char *, struct vnode *);
 void 	vput(struct vnode *);
-int	vrecycle(struct vnode *, kmutex_t *, struct lwp *);
+int	vrecycle(struct vnode *, kmutex_t *);
 void 	vrele(struct vnode *);
 void 	vrele_async(struct vnode *);
 void	vrele_flush(void);
 int	vtruncbuf(struct vnode *, daddr_t, bool, int);
 void	vwakeup(struct buf *);
 void	vwait(struct vnode *, int);
 void	vclean(struct vnode *, int);
 void	vrevoke(struct vnode *);
-void	vrelel(struct vnode *, int);
-#define VRELEL_ASYNC_RELE	0x03
 struct vnode *
 	vnalloc(struct mount *);
 void	vnfree(struct vnode *);
 void	vmark(struct vnode *, struct vnode *);
Index: sys/ufs/ext2fs/ext2fs_vfsops.c
===================================================================
RCS file: /cvsroot/src/sys/ufs/ext2fs/ext2fs_vfsops.c,v
retrieving revision 1.173
diff -p -u -4 -r1.173 ext2fs_vfsops.c
--- sys/ufs/ext2fs/ext2fs_vfsops.c	30 Sep 2013 18:58:00 -0000	1.173
+++ sys/ufs/ext2fs/ext2fs_vfsops.c	10 Oct 2013 09:08:23 -0000
@@ -606,9 +606,9 @@ loop:
 			continue;
 		/*
 		 * Step 4: invalidate all inactive vnodes.
 		 */
-		if (vrecycle(vp, &mntvnode_lock, l)) {
+		if (vrecycle(vp, &mntvnode_lock)) {
 			mutex_enter(&mntvnode_lock);
 			(void)vunmark(mvp);
 			goto loop;
 		}
Index: sys/ufs/ffs/ffs_vfsops.c
===================================================================
RCS file: /cvsroot/src/sys/ufs/ffs/ffs_vfsops.c,v
retrieving revision 1.289
diff -p -u -4 -r1.289 ffs_vfsops.c
--- sys/ufs/ffs/ffs_vfsops.c	30 Sep 2013 18:58:00 -0000	1.289
+++ sys/ufs/ffs/ffs_vfsops.c	10 Oct 2013 09:08:23 -0000
@@ -826,9 +826,9 @@ ffs_reload(struct mount *mp, kauth_cred_
 			continue;
 		/*
 		 * Step 4: invalidate all inactive vnodes.
 		 */
-		if (vrecycle(vp, &mntvnode_lock, l)) {
+		if (vrecycle(vp, &mntvnode_lock)) {
 			mutex_enter(&mntvnode_lock);
 			(void)vunmark(mvp);
 			goto loop;
 		}
Index: sys/ufs/lfs/lfs_segment.c
===================================================================
RCS file: /cvsroot/src/sys/ufs/lfs/lfs_segment.c,v
retrieving revision 1.231
diff -p -u -4 -r1.231 lfs_segment.c
--- sys/ufs/lfs/lfs_segment.c	28 Jul 2013 01:05:52 -0000	1.231
+++ sys/ufs/lfs/lfs_segment.c	10 Oct 2013 09:08:23 -0000
@@ -2801,11 +2801,10 @@ lfs_vunref(struct vnode *vp)
 		--fs->lfs_flushvp_fakevref;
 		return;
 	}
 
-	/* does not call inactive */
-	mutex_enter(vp->v_interlock);
-	vrelel(vp, 0);
+	/* does not call inactive XXX sure it does XXX */
+	vrele(vp);
 }
 
 /*
  * We use this when we have vnodes that were loaded in solely for cleaning.
@@ -2820,11 +2819,11 @@ lfs_vunref_head(struct vnode *vp)
 {
 
 	ASSERT_SEGLOCK(VTOI(vp)->i_lfs);
 
-	/* does not call inactive, inserts non-held vnode at head of freelist */
-	mutex_enter(vp->v_interlock);
-	vrelel(vp, 0);
+	/* does not call inactive XXX sure it does XXX,
+	   inserts non-held vnode at head of freelist */
+	vrele(vp);
 }
 
 
 /*
Index: sys/ufs/lfs/lfs_syscalls.c
===================================================================
RCS file: /cvsroot/src/sys/ufs/lfs/lfs_syscalls.c,v
retrieving revision 1.149
diff -p -u -4 -r1.149 lfs_syscalls.c
--- sys/ufs/lfs/lfs_syscalls.c	7 Oct 2013 05:19:23 -0000	1.149
+++ sys/ufs/lfs/lfs_syscalls.c	10 Oct 2013 09:08:23 -0000
@@ -712,9 +712,9 @@ lfs_bmapv(struct proc *p, fsid_t *fsidp,
 			 */
 			if (v_daddr != LFS_UNUSED_DADDR) {
 				lfs_vunref(vp);
 				if (VTOI(vp)->i_lfs_iflags & LFSI_BMAP)
-					vrecycle(vp, NULL, NULL);
+					vrecycle(vp, NULL);
 				numrefed--;
 			}
 
 			/*
@@ -822,9 +822,9 @@ lfs_bmapv(struct proc *p, fsid_t *fsidp,
 	if (v_daddr != LFS_UNUSED_DADDR) {
 		lfs_vunref(vp);
 		/* Recycle as above. */
 		if (ip->i_lfs_iflags & LFSI_BMAP)
-			vrecycle(vp, NULL, NULL);
+			vrecycle(vp, NULL);
 		numrefed--;
 	}
 
 #ifdef DIAGNOSTIC
