Module Name:    src
Committed By:   hannken
Date:           Thu Feb 27 16:51:39 UTC 2014

Modified Files:
        src/share/man/man9: vnodeops.9 vnsubr.9
        src/sys/coda: coda_vnops.c
        src/sys/fs/adosfs: adutil.c
        src/sys/fs/cd9660: cd9660_node.c
        src/sys/fs/efs: efs_ihash.c
        src/sys/fs/filecorefs: filecore_node.c
        src/sys/fs/hfs: hfs_nhash.c
        src/sys/fs/ptyfs: ptyfs_subr.c
        src/sys/fs/tmpfs: tmpfs_vnops.c
        src/sys/fs/union: union_vnops.c
        src/sys/kern: vfs_vnode.c vfs_vnops.c
        src/sys/miscfs/deadfs: dead_vnops.c
        src/sys/miscfs/fdesc: fdesc_vnops.c
        src/sys/miscfs/genfs: genfs.h genfs_vnops.c layer_extern.h
            layer_vnops.c
        src/sys/miscfs/kernfs: kernfs_subr.c
        src/sys/miscfs/nullfs: null_vnops.c
        src/sys/miscfs/overlay: overlay_vnops.c
        src/sys/miscfs/umapfs: umap_vnops.c
        src/sys/nfs: nfs_node.c
        src/sys/sys: param.h
        src/sys/ufs/chfs: chfs_ihash.c
        src/sys/ufs/lfs: ulfs_ihash.c
        src/sys/ufs/ufs: ufs_ihash.c

Log Message:
The current implementation of vn_lock() is racy.  Modification of
the vnode operations vector for active vnodes is unsafe because it
is not known whether deadfs or the original file system will be
called.

- Pass down LK_RETRY to the lock operation (hint for deadfs only).

- Change deadfs lock operation to return ENOENT if LK_RETRY is unset.

- Change all other lock operations to check for dead vnode once
  the vnode is locked and unlock and return ENOENT in this case.

With these changes in place vnode lock operations will never succeed
after vclean() has marked the vnode as VI_XLOCK and before vclean()
has changed the operations vector.

Adresses PR kern/37706 (Forced unmount of file systems is unsafe)

Discussed on tech-kern.

Welcome to 6.99.33


To generate a diff of this commit:
cvs rdiff -u -r1.92 -r1.93 src/share/man/man9/vnodeops.9
cvs rdiff -u -r1.41 -r1.42 src/share/man/man9/vnsubr.9
cvs rdiff -u -r1.94 -r1.95 src/sys/coda/coda_vnops.c
cvs rdiff -u -r1.15 -r1.16 src/sys/fs/adosfs/adutil.c
cvs rdiff -u -r1.29 -r1.30 src/sys/fs/cd9660/cd9660_node.c
cvs rdiff -u -r1.9 -r1.10 src/sys/fs/efs/efs_ihash.c
cvs rdiff -u -r1.25 -r1.26 src/sys/fs/filecorefs/filecore_node.c
cvs rdiff -u -r1.12 -r1.13 src/sys/fs/hfs/hfs_nhash.c
cvs rdiff -u -r1.25 -r1.26 src/sys/fs/ptyfs/ptyfs_subr.c
cvs rdiff -u -r1.117 -r1.118 src/sys/fs/tmpfs/tmpfs_vnops.c
cvs rdiff -u -r1.56 -r1.57 src/sys/fs/union/union_vnops.c
cvs rdiff -u -r1.31 -r1.32 src/sys/kern/vfs_vnode.c
cvs rdiff -u -r1.188 -r1.189 src/sys/kern/vfs_vnops.c
cvs rdiff -u -r1.55 -r1.56 src/sys/miscfs/deadfs/dead_vnops.c
cvs rdiff -u -r1.117 -r1.118 src/sys/miscfs/fdesc/fdesc_vnops.c
cvs rdiff -u -r1.31 -r1.32 src/sys/miscfs/genfs/genfs.h
cvs rdiff -u -r1.189 -r1.190 src/sys/miscfs/genfs/genfs_vnops.c
cvs rdiff -u -r1.34 -r1.35 src/sys/miscfs/genfs/layer_extern.h
cvs rdiff -u -r1.54 -r1.55 src/sys/miscfs/genfs/layer_vnops.c
cvs rdiff -u -r1.25 -r1.26 src/sys/miscfs/kernfs/kernfs_subr.c
cvs rdiff -u -r1.38 -r1.39 src/sys/miscfs/nullfs/null_vnops.c
cvs rdiff -u -r1.19 -r1.20 src/sys/miscfs/overlay/overlay_vnops.c
cvs rdiff -u -r1.55 -r1.56 src/sys/miscfs/umapfs/umap_vnops.c
cvs rdiff -u -r1.116 -r1.117 src/sys/nfs/nfs_node.c
cvs rdiff -u -r1.441 -r1.442 src/sys/sys/param.h
cvs rdiff -u -r1.2 -r1.3 src/sys/ufs/chfs/chfs_ihash.c
cvs rdiff -u -r1.3 -r1.4 src/sys/ufs/lfs/ulfs_ihash.c
cvs rdiff -u -r1.31 -r1.32 src/sys/ufs/ufs/ufs_ihash.c

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

Modified files:

Index: src/share/man/man9/vnodeops.9
diff -u src/share/man/man9/vnodeops.9:1.92 src/share/man/man9/vnodeops.9:1.93
--- src/share/man/man9/vnodeops.9:1.92	Fri Feb  7 15:29:21 2014
+++ src/share/man/man9/vnodeops.9	Thu Feb 27 16:51:37 2014
@@ -1,4 +1,4 @@
-.\"     $NetBSD: vnodeops.9,v 1.92 2014/02/07 15:29:21 hannken Exp $
+.\"     $NetBSD: vnodeops.9,v 1.93 2014/02/27 16:51:37 hannken Exp $
 .\"
 .\" Copyright (c) 2001, 2005, 2006 The NetBSD Foundation, Inc.
 .\" All rights reserved.
@@ -27,7 +27,7 @@
 .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 .\" POSSIBILITY OF SUCH DAMAGE.
 .\"
-.Dd February 7, 2014
+.Dd February 27, 2014
 .Dt VNODEOPS 9
 .Os
 .Sh NAME
@@ -1071,6 +1071,11 @@ If
 contains
 .Dv LK_NOWAIT
 and the lock is busy, the operation will return immediately with an error code.
+If
+.Fa flags
+contains
+.Dv LK_RETRY
+this is a hint the caller wants the lock on dead vnodes too.
 If the operation is successful zero is returned, otherwise an
 appropriate error code is returned.
 .Fn VOP_LOCK

Index: src/share/man/man9/vnsubr.9
diff -u src/share/man/man9/vnsubr.9:1.41 src/share/man/man9/vnsubr.9:1.42
--- src/share/man/man9/vnsubr.9:1.41	Sun Jan 30 07:04:48 2011
+++ src/share/man/man9/vnsubr.9	Thu Feb 27 16:51:37 2014
@@ -1,4 +1,4 @@
-.\"     $NetBSD: vnsubr.9,v 1.41 2011/01/30 07:04:48 rmind Exp $
+.\"     $NetBSD: vnsubr.9,v 1.42 2014/02/27 16:51:37 hannken Exp $
 .\"
 .\" Copyright (c) 2001, 2005, 2006 The NetBSD Foundation, Inc.
 .\" All rights reserved.
@@ -27,7 +27,7 @@
 .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 .\" POSSIBILITY OF SUCH DAMAGE.
 .\"
-.Dd January 30, 2010
+.Dd February 27, 2014
 .Dt VNSUBR 9
 .Os
 .Sh NAME
@@ -138,14 +138,11 @@ exclusive lock
 .It LK_NOWAIT
 do not sleep to await lock
 .It LK_RETRY
-retry lock operation until locked
+allow lock operation on dead vnode
 .El
 .Pp
 If the operation is successful zero is returned, otherwise an
 appropriate error code is returned.
-The vnode interlock
-.Em v_interlock
-is released on return.
 .Pp
 .Fn vn_lock
 must not be called when the vnode's reference count is zero.

Index: src/sys/coda/coda_vnops.c
diff -u src/sys/coda/coda_vnops.c:1.94 src/sys/coda/coda_vnops.c:1.95
--- src/sys/coda/coda_vnops.c:1.94	Fri Feb  7 15:29:21 2014
+++ src/sys/coda/coda_vnops.c	Thu Feb 27 16:51:37 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: coda_vnops.c,v 1.94 2014/02/07 15:29:21 hannken Exp $	*/
+/*	$NetBSD: coda_vnops.c,v 1.95 2014/02/27 16:51:37 hannken Exp $	*/
 
 /*
  *
@@ -46,7 +46,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: coda_vnops.c,v 1.94 2014/02/07 15:29:21 hannken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: coda_vnops.c,v 1.95 2014/02/27 16:51:37 hannken Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -229,8 +229,7 @@ coda_open(void *v)
 
     MARK_ENTRY(CODA_OPEN_STATS);
 
-    if (!VOP_ISLOCKED(vp))
-	VOP_LOCK(vp, LK_EXCLUSIVE);
+    KASSERT(VOP_ISLOCKED(vp));
     /* Check for open of control file. */
     if (IS_CTL_VP(vp)) {
 	/* if (WRITABLE(flag)) */
@@ -1745,8 +1744,6 @@ coda_grab_vnode(vnode_t *uvp, dev_t dev,
 
     /*
      * Obtain vnode from mount point and inode.
-     * XXX VFS_VGET does not clearly define locked/referenced state of
-     * returned vnode.
      */
     error = VFS_VGET(mp, ino, vpp);
     if (error) {
@@ -1757,8 +1754,7 @@ coda_grab_vnode(vnode_t *uvp, dev_t dev,
     /* share the underlying vnode lock with the coda vnode */
     mutex_obj_hold((*vpp)->v_interlock);
     uvm_obj_setlock(&uvp->v_uobj, (*vpp)->v_interlock);
-    if (!VOP_ISLOCKED(*vpp))
-	VOP_LOCK(*vpp, LK_EXCLUSIVE);
+    KASSERT(VOP_ISLOCKED(*vpp));
     return(0);
 }
 

Index: src/sys/fs/adosfs/adutil.c
diff -u src/sys/fs/adosfs/adutil.c:1.15 src/sys/fs/adosfs/adutil.c:1.16
--- src/sys/fs/adosfs/adutil.c:1.15	Sun Jun 12 03:35:52 2011
+++ src/sys/fs/adosfs/adutil.c	Thu Feb 27 16:51:37 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: adutil.c,v 1.15 2011/06/12 03:35:52 rmind Exp $	*/
+/*	$NetBSD: adutil.c,v 1.16 2014/02/27 16:51:37 hannken Exp $	*/
 
 /*
  * Copyright (c) 1994 Christian E. Hopps
@@ -32,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: adutil.c,v 1.15 2011/06/12 03:35:52 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: adutil.c,v 1.16 2014/02/27 16:51:37 hannken Exp $");
 
 #include <sys/param.h>
 #include <sys/vnode.h>
@@ -85,7 +85,10 @@ start_over:
 void
 adosfs_ainshash(struct adosfsmount *amp, struct anode *ap)
 {
-	VOP_LOCK(ATOV(ap), LK_EXCLUSIVE);
+	int error __diagused;
+
+	error = VOP_LOCK(ATOV(ap), LK_EXCLUSIVE);
+	KASSERT(error == 0);
 
 	mutex_enter(&adosfs_hashlock);
 	LIST_INSERT_HEAD(&amp->anodetab[AHASH(ap->block)], ap, link);

Index: src/sys/fs/cd9660/cd9660_node.c
diff -u src/sys/fs/cd9660/cd9660_node.c:1.29 src/sys/fs/cd9660/cd9660_node.c:1.30
--- src/sys/fs/cd9660/cd9660_node.c:1.29	Sun Jun 12 03:35:52 2011
+++ src/sys/fs/cd9660/cd9660_node.c	Thu Feb 27 16:51:38 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: cd9660_node.c,v 1.29 2011/06/12 03:35:52 rmind Exp $	*/
+/*	$NetBSD: cd9660_node.c,v 1.30 2014/02/27 16:51:38 hannken Exp $	*/
 
 /*-
  * Copyright (c) 1982, 1986, 1989, 1994
@@ -37,7 +37,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: cd9660_node.c,v 1.29 2011/06/12 03:35:52 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cd9660_node.c,v 1.30 2014/02/27 16:51:38 hannken Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -170,6 +170,7 @@ void
 cd9660_ihashins(struct iso_node *ip)
 {
 	struct ihashhead *ipp;
+	int error __diagused;
 
 	KASSERT(mutex_owned(&cd9660_hashlock));
 
@@ -178,7 +179,8 @@ cd9660_ihashins(struct iso_node *ip)
 	LIST_INSERT_HEAD(ipp, ip, i_hash);
 	mutex_exit(&cd9660_ihash_lock);
 
-	VOP_LOCK(ITOV(ip), LK_EXCLUSIVE);
+	error = VOP_LOCK(ITOV(ip), LK_EXCLUSIVE);
+	KASSERT(error == 0);
 }
 
 /*

Index: src/sys/fs/efs/efs_ihash.c
diff -u src/sys/fs/efs/efs_ihash.c:1.9 src/sys/fs/efs/efs_ihash.c:1.10
--- src/sys/fs/efs/efs_ihash.c:1.9	Sun Apr 29 20:27:31 2012
+++ src/sys/fs/efs/efs_ihash.c	Thu Feb 27 16:51:38 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: efs_ihash.c,v 1.9 2012/04/29 20:27:31 dsl Exp $	*/
+/*	$NetBSD: efs_ihash.c,v 1.10 2014/02/27 16:51:38 hannken Exp $	*/
 
 /*
  * Copyright (c) 1982, 1986, 1989, 1991, 1993
@@ -36,7 +36,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: efs_ihash.c,v 1.9 2012/04/29 20:27:31 dsl Exp $");
+__KERNEL_RCSID(0, "$NetBSD: efs_ihash.c,v 1.10 2014/02/27 16:51:38 hannken Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -162,11 +162,13 @@ void
 efs_ihashins(struct efs_inode *eip)
 {
 	struct ihashhead *ipp;
+	int error __diagused;
 
 	KASSERT(mutex_owned(&efs_hashlock));
 
 	/* lock the inode, then put it on the appropriate hash list */
-	VOP_LOCK(EFS_ITOV(eip), LK_EXCLUSIVE);
+	error = VOP_LOCK(EFS_ITOV(eip), LK_EXCLUSIVE);
+	KASSERT(error == 0);
 
 	mutex_enter(&efs_ihash_lock);
 	ipp = &ihashtbl[INOHASH(eip->ei_dev, eip->ei_number)];

Index: src/sys/fs/filecorefs/filecore_node.c
diff -u src/sys/fs/filecorefs/filecore_node.c:1.25 src/sys/fs/filecorefs/filecore_node.c:1.26
--- src/sys/fs/filecorefs/filecore_node.c:1.25	Sun Jun 12 03:35:52 2011
+++ src/sys/fs/filecorefs/filecore_node.c	Thu Feb 27 16:51:38 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: filecore_node.c,v 1.25 2011/06/12 03:35:52 rmind Exp $	*/
+/*	$NetBSD: filecore_node.c,v 1.26 2014/02/27 16:51:38 hannken Exp $	*/
 
 /*-
  * Copyright (c) 1982, 1986, 1989, 1994
@@ -67,7 +67,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: filecore_node.c,v 1.25 2011/06/12 03:35:52 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: filecore_node.c,v 1.26 2014/02/27 16:51:38 hannken Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -188,13 +188,15 @@ void
 filecore_ihashins(struct filecore_node *ip)
 {
 	struct ihashhead *ipp;
+	int error __diagused;
 
 	mutex_enter(&filecore_ihash_lock);
 	ipp = &filecorehashtbl[INOHASH(ip->i_dev, ip->i_number)];
 	LIST_INSERT_HEAD(ipp, ip, i_hash);
 	mutex_exit(&filecore_ihash_lock);
 
-	VOP_LOCK(ITOV(ip), LK_EXCLUSIVE);
+	error = VOP_LOCK(ITOV(ip), LK_EXCLUSIVE);
+	KASSERT(error == 0);
 }
 
 /*

Index: src/sys/fs/hfs/hfs_nhash.c
diff -u src/sys/fs/hfs/hfs_nhash.c:1.12 src/sys/fs/hfs/hfs_nhash.c:1.13
--- src/sys/fs/hfs/hfs_nhash.c:1.12	Sun Jun 12 03:35:53 2011
+++ src/sys/fs/hfs/hfs_nhash.c	Thu Feb 27 16:51:38 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: hfs_nhash.c,v 1.12 2011/06/12 03:35:53 rmind Exp $	*/
+/*	$NetBSD: hfs_nhash.c,v 1.13 2014/02/27 16:51:38 hannken Exp $	*/
 
 /*-
  * Copyright (c) 2005, 2007 The NetBSD Foundation, Inc.
@@ -59,7 +59,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: hfs_nhash.c,v 1.12 2011/06/12 03:35:53 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: hfs_nhash.c,v 1.13 2014/02/27 16:51:38 hannken Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -148,9 +148,11 @@ void
 hfs_nhashinsert(struct hfsnode *hp)
 {
 	struct nhashhead *hpp;
+	int error __diagused;
 
 	/* lock the inode, then put it on the appropriate hash list */
-	VOP_LOCK(HTOV(hp), LK_EXCLUSIVE);
+	error = VOP_LOCK(HTOV(hp), LK_EXCLUSIVE);
+	KASSERT(error == 0);
 
 	mutex_enter(&hfs_nhash_lock);
 	hpp = &nhashtbl[HNOHASH(hp->h_dev, hp->h_rec.u.cnid, hp->h_fork)];

Index: src/sys/fs/ptyfs/ptyfs_subr.c
diff -u src/sys/fs/ptyfs/ptyfs_subr.c:1.25 src/sys/fs/ptyfs/ptyfs_subr.c:1.26
--- src/sys/fs/ptyfs/ptyfs_subr.c:1.25	Wed Oct 24 23:36:15 2012
+++ src/sys/fs/ptyfs/ptyfs_subr.c	Thu Feb 27 16:51:38 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: ptyfs_subr.c,v 1.25 2012/10/24 23:36:15 christos Exp $	*/
+/*	$NetBSD: ptyfs_subr.c,v 1.26 2014/02/27 16:51:38 hannken Exp $	*/
 
 /*
  * Copyright (c) 1993
@@ -73,7 +73,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ptyfs_subr.c,v 1.25 2012/10/24 23:36:15 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ptyfs_subr.c,v 1.26 2014/02/27 16:51:38 hannken Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -397,9 +397,11 @@ static void
 ptyfs_hashins(struct ptyfsnode *pp)
 {
 	struct ptyfs_hashhead *ppp;
+	int error __diagused;
 
 	/* lock the ptyfsnode, then put it on the appropriate hash list */
-	VOP_LOCK(PTYFSTOV(pp), LK_EXCLUSIVE);
+	error = VOP_LOCK(PTYFSTOV(pp), LK_EXCLUSIVE);
+	KASSERT(error == 0);
 
 	mutex_enter(&ptyfs_used_slock);
 	ppp = &ptyfs_used_tbl[PTYHASH(pp->ptyfs_type, pp->ptyfs_pty,

Index: src/sys/fs/tmpfs/tmpfs_vnops.c
diff -u src/sys/fs/tmpfs/tmpfs_vnops.c:1.117 src/sys/fs/tmpfs/tmpfs_vnops.c:1.118
--- src/sys/fs/tmpfs/tmpfs_vnops.c:1.117	Mon Feb 17 20:16:52 2014
+++ src/sys/fs/tmpfs/tmpfs_vnops.c	Thu Feb 27 16:51:38 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: tmpfs_vnops.c,v 1.117 2014/02/17 20:16:52 maxv Exp $	*/
+/*	$NetBSD: tmpfs_vnops.c,v 1.118 2014/02/27 16:51:38 hannken Exp $	*/
 
 /*
  * Copyright (c) 2005, 2006, 2007 The NetBSD Foundation, Inc.
@@ -35,7 +35,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tmpfs_vnops.c,v 1.117 2014/02/17 20:16:52 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tmpfs_vnops.c,v 1.118 2014/02/27 16:51:38 hannken Exp $");
 
 #include <sys/param.h>
 #include <sys/dirent.h>
@@ -1082,7 +1082,6 @@ tmpfs_reclaim(void *v)
 	bool recycle;
 
 	mutex_enter(&node->tn_vlock);
-	VOP_LOCK(vp, LK_EXCLUSIVE);
 
 	/* Disassociate inode from vnode. */
 	node->tn_vnode = NULL;
@@ -1091,7 +1090,6 @@ tmpfs_reclaim(void *v)
 	/* If inode is not referenced, i.e. no links, then destroy it. */
 	recycle = node->tn_links == 0 && TMPFS_NODE_RECLAIMING(node) == 0;
 
-	VOP_UNLOCK(vp);
 	mutex_exit(&node->tn_vlock);
 
 	if (recycle) {

Index: src/sys/fs/union/union_vnops.c
diff -u src/sys/fs/union/union_vnops.c:1.56 src/sys/fs/union/union_vnops.c:1.57
--- src/sys/fs/union/union_vnops.c:1.56	Sun Feb 16 09:50:25 2014
+++ src/sys/fs/union/union_vnops.c	Thu Feb 27 16:51:38 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: union_vnops.c,v 1.56 2014/02/16 09:50:25 hannken Exp $	*/
+/*	$NetBSD: union_vnops.c,v 1.57 2014/02/27 16:51:38 hannken Exp $	*/
 
 /*
  * Copyright (c) 1992, 1993, 1994, 1995
@@ -72,7 +72,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: union_vnops.c,v 1.56 2014/02/16 09:50:25 hannken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: union_vnops.c,v 1.57 2014/02/27 16:51:38 hannken Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -1598,10 +1598,32 @@ union_lock(void *v)
 		int a_flags;
 	} */ *ap = v;
 	struct vnode *vp;
-	struct union_node *un;
+	struct union_node *un = VTOUNION(ap->a_vp);
+	int flags = ap->a_flags;
 	int error;
 
-	un = VTOUNION(ap->a_vp);
+	if ((flags & LK_NOWAIT) != 0) {
+		if (!mutex_tryenter(&un->un_lock))
+			return EBUSY;
+		vp = LOCKVP(ap->a_vp);
+		if (!mutex_tryenter(vp->v_interlock)) {
+			mutex_exit(&un->un_lock);
+			return EBUSY;
+		}
+		if ((vp->v_iflag & (VI_XLOCK | VI_CLEAN)) != 0) {
+			mutex_exit(vp->v_interlock);
+			mutex_exit(&un->un_lock);
+			return EBUSY;
+		}
+		mutex_exit(vp->v_interlock);
+		if (vp == ap->a_vp)
+			error = genfs_lock(ap);
+		else
+			error = VOP_LOCK(vp, flags);
+		mutex_exit(&un->un_lock);
+		return error;
+	}
+
 	mutex_enter(&un->un_lock);
 	for (;;) {
 		vp = LOCKVP(ap->a_vp);
@@ -1620,9 +1642,22 @@ union_lock(void *v)
 		else
 			VOP_UNLOCK(vp);
 	}
+	mutex_enter(vp->v_interlock);
+	if ((vp->v_iflag & (VI_XLOCK | VI_CLEAN)) != 0) {
+		if (vp == ap->a_vp)
+			genfs_unlock(ap);
+		else
+			VOP_UNLOCK(vp);
+		if ((vp->v_iflag & VI_XLOCK))
+			vwait(vp, VI_XLOCK);
+		mutex_exit(vp->v_interlock);
+		mutex_exit(&un->un_lock);
+		return ENOENT;
+	}
+	mutex_exit(vp->v_interlock);
 	mutex_exit(&un->un_lock);
 
-	return error;
+	return 0;
 }
 
 int

Index: src/sys/kern/vfs_vnode.c
diff -u src/sys/kern/vfs_vnode.c:1.31 src/sys/kern/vfs_vnode.c:1.32
--- src/sys/kern/vfs_vnode.c:1.31	Thu Feb 27 13:00:06 2014
+++ src/sys/kern/vfs_vnode.c	Thu Feb 27 16:51:38 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: vfs_vnode.c,v 1.31 2014/02/27 13:00:06 hannken Exp $	*/
+/*	$NetBSD: vfs_vnode.c,v 1.32 2014/02/27 16:51:38 hannken Exp $	*/
 
 /*-
  * Copyright (c) 1997-2011 The NetBSD Foundation, Inc.
@@ -116,7 +116,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: vfs_vnode.c,v 1.31 2014/02/27 13:00:06 hannken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vfs_vnode.c,v 1.32 2014/02/27 16:51:38 hannken Exp $");
 
 #define _VFS_VNODE_PRIVATE
 
@@ -642,28 +642,17 @@ vrelel(vnode_t *vp, int flags)
 			 * We have to try harder.
 			 */
 			mutex_exit(vp->v_interlock);
-			error = VOP_LOCK(vp, LK_EXCLUSIVE);
+			error = vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
 			KASSERT(error == 0);
 			mutex_enter(vp->v_interlock);
-			/*
-			 * If the node got another reference while sleeping,
-			 * don't try to inactivate it yet.
-			 */
-			if (__predict_false(vtryrele(vp))) {
-				VOP_UNLOCK(vp);
-				if ((flags & VRELEL_CHANGING_SET) != 0) {
-					KASSERT((vp->v_iflag & VI_CHANGING) != 0);
-					vp->v_iflag &= ~VI_CHANGING;
-					cv_broadcast(&vp->v_cv);
-				}
-				mutex_exit(vp->v_interlock);
-				return;
-			}
 			defer = false;
 		} else {
 			/* If we can't acquire the lock, then defer. */
-			error = VOP_LOCK(vp, LK_EXCLUSIVE | LK_NOWAIT);
+			mutex_exit(vp->v_interlock);
+			error = vn_lock(vp,
+			    LK_EXCLUSIVE | LK_RETRY | LK_NOWAIT);
 			defer = (error != 0);
+			mutex_enter(vp->v_interlock);
 		}
 
 		KASSERT(mutex_owned(vp->v_interlock));
@@ -688,6 +677,21 @@ vrelel(vnode_t *vp, int flags)
 			return;
 		}
 
+		/*
+		 * If the node got another reference while we
+		 * released the interlock, don't try to inactivate it yet.
+		 */
+		if (__predict_false(vtryrele(vp))) {
+			VOP_UNLOCK(vp);
+			if ((flags & VRELEL_CHANGING_SET) != 0) {
+				KASSERT((vp->v_iflag & VI_CHANGING) != 0);
+				vp->v_iflag &= ~VI_CHANGING;
+				cv_broadcast(&vp->v_cv);
+			}
+			mutex_exit(vp->v_interlock);
+			return;
+		}
+
 		if ((flags & VRELEL_CHANGING_SET) == 0) {
 			KASSERT((vp->v_iflag & VI_CHANGING) == 0);
 			vp->v_iflag |= VI_CHANGING;
@@ -930,35 +934,31 @@ vclean(vnode_t *vp)
 	KASSERT((vp->v_iflag & VI_MARKER) == 0);
 	KASSERT(vp->v_usecount != 0);
 
-	/* If cleaning is already in progress wait until done and return. */
-	if (vp->v_iflag & VI_XLOCK) {
-		vwait(vp, VI_XLOCK);
-		return;
-	}
-
 	/* If already clean, nothing to do. */
 	if ((vp->v_iflag & VI_CLEAN) != 0) {
 		return;
 	}
 
+	active = (vp->v_usecount > 1);
+	doclose = ! (active && vp->v_type == VBLK &&
+	    spec_node_getmountedfs(vp) != NULL);
+	mutex_exit(vp->v_interlock);
+
+	vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
+
 	/*
 	 * Prevent the vnode from being recycled or brought into use
 	 * while we clean it out.
 	 */
+	mutex_enter(vp->v_interlock);
+	KASSERT((vp->v_iflag & (VI_XLOCK | VI_CLEAN)) == 0);
 	vp->v_iflag |= VI_XLOCK;
 	if (vp->v_iflag & VI_EXECMAP) {
 		atomic_add_int(&uvmexp.execpages, -vp->v_uobj.uo_npages);
 		atomic_add_int(&uvmexp.filepages, vp->v_uobj.uo_npages);
 	}
 	vp->v_iflag &= ~(VI_TEXT|VI_EXECMAP);
-	active = (vp->v_usecount > 1);
-
-	/* XXXAD should not lock vnode under layer */
 	mutex_exit(vp->v_interlock);
-	VOP_LOCK(vp, LK_EXCLUSIVE);
-
-	doclose = ! (active && vp->v_type == VBLK &&
-	    spec_node_getmountedfs(vp) != NULL);
 
 	/*
 	 * Clean out any cached data associated with the vnode.

Index: src/sys/kern/vfs_vnops.c
diff -u src/sys/kern/vfs_vnops.c:1.188 src/sys/kern/vfs_vnops.c:1.189
--- src/sys/kern/vfs_vnops.c:1.188	Thu Jan 23 10:13:57 2014
+++ src/sys/kern/vfs_vnops.c	Thu Feb 27 16:51:38 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: vfs_vnops.c,v 1.188 2014/01/23 10:13:57 hannken Exp $	*/
+/*	$NetBSD: vfs_vnops.c,v 1.189 2014/02/27 16:51:38 hannken Exp $	*/
 
 /*-
  * Copyright (c) 2009 The NetBSD Foundation, Inc.
@@ -66,7 +66,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: vfs_vnops.c,v 1.188 2014/01/23 10:13:57 hannken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vfs_vnops.c,v 1.189 2014/02/27 16:51:38 hannken Exp $");
 
 #include "veriexec.h"
 
@@ -792,28 +792,14 @@ vn_lock(struct vnode *vp, int flags)
 		WAPBL_JUNLOCK_ASSERT(wapbl_vptomp(vp));
 #endif
 
-	do {
-		/*
-		 * XXX PR 37706 forced unmount of file systems is unsafe.
-		 * Race between vclean() and this the remaining problem.
-		 */
-		mutex_enter(vp->v_interlock);
-		if (vp->v_iflag & VI_XLOCK) {
-			if (flags & LK_NOWAIT) {
-				mutex_exit(vp->v_interlock);
-				return EBUSY;
-			}
-			vwait(vp, VI_XLOCK);
-			mutex_exit(vp->v_interlock);
-			error = ENOENT;
-		} else {
-			mutex_exit(vp->v_interlock);
-			error = VOP_LOCK(vp, (flags & ~LK_RETRY));
-			if (error == 0 || error == EDEADLK || error == EBUSY)
-				return (error);
-		}
-	} while (flags & LK_RETRY);
-	return (error);
+	error = VOP_LOCK(vp, flags);
+	if ((flags & LK_RETRY) != 0 && error == ENOENT)
+		error = VOP_LOCK(vp, flags);
+
+	KASSERT((flags & LK_RETRY) == 0 || (flags & LK_NOWAIT) != 0 ||
+	    error == 0);
+
+	return error;
 }
 
 /*

Index: src/sys/miscfs/deadfs/dead_vnops.c
diff -u src/sys/miscfs/deadfs/dead_vnops.c:1.55 src/sys/miscfs/deadfs/dead_vnops.c:1.56
--- src/sys/miscfs/deadfs/dead_vnops.c:1.55	Thu Feb 27 13:00:06 2014
+++ src/sys/miscfs/deadfs/dead_vnops.c	Thu Feb 27 16:51:38 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: dead_vnops.c,v 1.55 2014/02/27 13:00:06 hannken Exp $	*/
+/*	$NetBSD: dead_vnops.c,v 1.56 2014/02/27 16:51:38 hannken Exp $	*/
 
 /*
  * Copyright (c) 1989, 1993
@@ -32,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: dead_vnops.c,v 1.55 2014/02/27 13:00:06 hannken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: dead_vnops.c,v 1.56 2014/02/27 16:51:38 hannken Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -65,12 +65,12 @@ int	dead_rmdir(void *);
 #define dead_seek	genfs_nullop
 int	dead_inactive(void *);
 #define dead_reclaim	genfs_nullop
-#define dead_lock	genfs_lock
-#define dead_unlock	genfs_unlock
+#define dead_lock	genfs_deadlock
+#define dead_unlock	genfs_deadunlock
 int	dead_bmap(void *);
 int	dead_strategy(void *);
 int	dead_print(void *);
-#define dead_islocked	genfs_islocked
+#define dead_islocked	genfs_deadislocked
 #define dead_revoke	genfs_nullop
 int	dead_getpages(void *);
 int	dead_putpages(void *);

Index: src/sys/miscfs/fdesc/fdesc_vnops.c
diff -u src/sys/miscfs/fdesc/fdesc_vnops.c:1.117 src/sys/miscfs/fdesc/fdesc_vnops.c:1.118
--- src/sys/miscfs/fdesc/fdesc_vnops.c:1.117	Fri Feb  7 15:29:22 2014
+++ src/sys/miscfs/fdesc/fdesc_vnops.c	Thu Feb 27 16:51:38 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: fdesc_vnops.c,v 1.117 2014/02/07 15:29:22 hannken Exp $	*/
+/*	$NetBSD: fdesc_vnops.c,v 1.118 2014/02/27 16:51:38 hannken Exp $	*/
 
 /*
  * Copyright (c) 1992, 1993
@@ -41,7 +41,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: fdesc_vnops.c,v 1.117 2014/02/07 15:29:22 hannken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: fdesc_vnops.c,v 1.118 2014/02/27 16:51:38 hannken Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -249,7 +249,8 @@ loop:
 	fd->fd_link = 0;
 	fd->fd_ix = ix;
 	uvm_vnp_setsize(*vpp, 0);
-	VOP_LOCK(*vpp, LK_EXCLUSIVE);
+	error = VOP_LOCK(*vpp, LK_EXCLUSIVE);
+	KASSERT(error == 0);
 	LIST_INSERT_HEAD(fc, fd, fd_hash);
 	mutex_exit(&fdcache_lock);
 

Index: src/sys/miscfs/genfs/genfs.h
diff -u src/sys/miscfs/genfs/genfs.h:1.31 src/sys/miscfs/genfs/genfs.h:1.32
--- src/sys/miscfs/genfs/genfs.h:1.31	Thu May  2 14:49:51 2013
+++ src/sys/miscfs/genfs/genfs.h	Thu Feb 27 16:51:38 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: genfs.h,v 1.31 2013/05/02 14:49:51 riastradh Exp $	*/
+/*	$NetBSD: genfs.h,v 1.32 2014/02/27 16:51:38 hannken Exp $	*/
 
 #ifndef	_MISCFS_GENFS_GENFS_H_
 #define	_MISCFS_GENFS_GENFS_H_
@@ -20,6 +20,10 @@ int	genfs_nolock(void *);
 int	genfs_noislocked(void *);
 int	genfs_nounlock(void *);
 
+int	genfs_deadlock(void *);
+#define	genfs_deadislocked genfs_islocked
+int	genfs_deadunlock(void *);
+
 int	genfs_poll(void *);
 int	genfs_kqfilter(void *);
 int	genfs_fcntl(void *);

Index: src/sys/miscfs/genfs/genfs_vnops.c
diff -u src/sys/miscfs/genfs/genfs_vnops.c:1.189 src/sys/miscfs/genfs/genfs_vnops.c:1.190
--- src/sys/miscfs/genfs/genfs_vnops.c:1.189	Fri Mar 30 18:24:08 2012
+++ src/sys/miscfs/genfs/genfs_vnops.c	Thu Feb 27 16:51:38 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: genfs_vnops.c,v 1.189 2012/03/30 18:24:08 njoly Exp $	*/
+/*	$NetBSD: genfs_vnops.c,v 1.190 2014/02/27 16:51:38 hannken Exp $	*/
 
 /*-
  * Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -57,7 +57,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: genfs_vnops.c,v 1.189 2012/03/30 18:24:08 njoly Exp $");
+__KERNEL_RCSID(0, "$NetBSD: genfs_vnops.c,v 1.190 2014/02/27 16:51:38 hannken Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -278,6 +278,65 @@ genfs_revoke(void *v)
 }
 
 /*
+ * Lock the node (for deadfs).
+ */
+int
+genfs_deadlock(void *v)
+{
+	struct vop_lock_args /* {
+		struct vnode *a_vp;
+		int a_flags;
+	} */ *ap = v;
+	struct vnode *vp = ap->a_vp;
+	int flags = ap->a_flags;
+	krw_t op;
+
+	if ((flags & LK_NOWAIT) != 0) {
+		if (!mutex_tryenter(vp->v_interlock))
+			return EBUSY;
+		if ((vp->v_iflag & VI_XLOCK)) {
+			mutex_exit(vp->v_interlock);
+			return EBUSY;
+		}
+	}
+
+	mutex_enter(vp->v_interlock);
+	if ((vp->v_iflag & VI_XLOCK))
+		vwait(vp, VI_XLOCK);
+	mutex_exit(vp->v_interlock);
+
+	if ((flags & LK_RETRY) == 0)
+		return ENOENT;
+
+	op = ((flags & LK_EXCLUSIVE) != 0 ? RW_WRITER : RW_READER);
+	if ((flags & LK_NOWAIT) != 0) {
+		if (! rw_tryenter(&vp->v_lock, op))
+			return EBUSY;
+		return 0;
+	}
+
+	rw_enter(&vp->v_lock, op);
+
+	return 0;
+}
+
+/*
+ * Unlock the node (for deadfs).
+ */
+int
+genfs_deadunlock(void *v)
+{
+	struct vop_unlock_args /* {
+		struct vnode *a_vp;
+	} */ *ap = v;
+	struct vnode *vp = ap->a_vp;
+
+	rw_exit(&vp->v_lock);
+
+	return 0;
+}
+
+/*
  * Lock the node.
  */
 int
@@ -288,25 +347,42 @@ genfs_lock(void *v)
 		int a_flags;
 	} */ *ap = v;
 	struct vnode *vp = ap->a_vp;
+	struct mount *mp = vp->v_mount;
 	int flags = ap->a_flags;
 	krw_t op;
 
-	KASSERT((flags & ~(LK_EXCLUSIVE | LK_SHARED | LK_NOWAIT)) == 0);
-
 	op = ((flags & LK_EXCLUSIVE) != 0 ? RW_WRITER : RW_READER);
 	if ((flags & LK_NOWAIT) != 0) {
-		if (fstrans_start_nowait(vp->v_mount, FSTRANS_SHARED))
+		if (!mutex_tryenter(vp->v_interlock))
+			return EBUSY;
+		if ((vp->v_iflag & (VI_XLOCK | VI_CLEAN)) != 0) {
+			mutex_exit(vp->v_interlock);
+			return EBUSY;
+		}
+		mutex_exit(vp->v_interlock);
+		if (fstrans_start_nowait(mp, FSTRANS_SHARED))
 			return EBUSY;
 		if (! rw_tryenter(&vp->v_lock, op)) {
-			fstrans_done(vp->v_mount);
+			fstrans_done(mp);
 			return EBUSY;
 		}
 		return 0;
 	}
 
-	fstrans_start(vp->v_mount, FSTRANS_SHARED);
+	fstrans_start(mp, FSTRANS_SHARED);
 	rw_enter(&vp->v_lock, op);
 
+	mutex_enter(vp->v_interlock);
+	if ((vp->v_iflag & (VI_XLOCK | VI_CLEAN)) != 0) {
+		rw_exit(&vp->v_lock);
+		fstrans_done(mp);
+		if ((vp->v_iflag & VI_XLOCK))
+			vwait(vp, VI_XLOCK);
+		mutex_exit(vp->v_interlock);
+		return ENOENT;
+	}
+	mutex_exit(vp->v_interlock);
+
 	return 0;
 }
 

Index: src/sys/miscfs/genfs/layer_extern.h
diff -u src/sys/miscfs/genfs/layer_extern.h:1.34 src/sys/miscfs/genfs/layer_extern.h:1.35
--- src/sys/miscfs/genfs/layer_extern.h:1.34	Wed Feb  1 05:34:42 2012
+++ src/sys/miscfs/genfs/layer_extern.h	Thu Feb 27 16:51:38 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: layer_extern.h,v 1.34 2012/02/01 05:34:42 dholland Exp $	*/
+/*	$NetBSD: layer_extern.h,v 1.35 2014/02/27 16:51:38 hannken Exp $	*/
 
 /*
  * Copyright (c) 1999 National Aeronautics & Space Administration
@@ -103,6 +103,7 @@ int	layer_bypass(void *);
 int	layer_getattr(void *);
 int	layer_inactive(void *);
 int	layer_reclaim(void *);
+int	layer_lock(void *);
 int	layer_print(void *);
 int	layer_bmap(void *);
 int	layer_fsync(void *);

Index: src/sys/miscfs/genfs/layer_vnops.c
diff -u src/sys/miscfs/genfs/layer_vnops.c:1.54 src/sys/miscfs/genfs/layer_vnops.c:1.55
--- src/sys/miscfs/genfs/layer_vnops.c:1.54	Fri Feb  7 15:29:22 2014
+++ src/sys/miscfs/genfs/layer_vnops.c	Thu Feb 27 16:51:38 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: layer_vnops.c,v 1.54 2014/02/07 15:29:22 hannken Exp $	*/
+/*	$NetBSD: layer_vnops.c,v 1.55 2014/02/27 16:51:38 hannken Exp $	*/
 
 /*
  * Copyright (c) 1999 National Aeronautics & Space Administration
@@ -170,7 +170,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: layer_vnops.c,v 1.54 2014/02/07 15:29:22 hannken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: layer_vnops.c,v 1.55 2014/02/27 16:51:38 hannken Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -706,6 +706,46 @@ layer_reclaim(void *v)
 	return 0;
 }
 
+int
+layer_lock(void *v)
+{
+	struct vop_lock_args /* {
+		struct vnode *a_vp;
+		int a_flags;
+	} */ *ap = v;
+	struct vnode *vp = ap->a_vp;
+	struct vnode *lowervp = LAYERVPTOLOWERVP(vp);
+	int flags = ap->a_flags;
+	int error;
+
+	if ((flags & LK_NOWAIT) != 0) {
+		if (!mutex_tryenter(vp->v_interlock))
+			return EBUSY;
+		if ((vp->v_iflag & (VI_XLOCK | VI_CLEAN)) != 0) {
+			mutex_exit(vp->v_interlock);
+			return EBUSY;
+		}
+		mutex_exit(vp->v_interlock);
+		return VOP_LOCK(lowervp, flags);
+	}
+
+	error = VOP_LOCK(lowervp, flags);
+	if (error)
+		return error;
+
+	mutex_enter(vp->v_interlock);
+	if ((vp->v_iflag & (VI_XLOCK | VI_CLEAN)) != 0) {
+		VOP_UNLOCK(lowervp);
+		if ((vp->v_iflag & VI_XLOCK))
+			vwait(vp, VI_XLOCK);
+		mutex_exit(vp->v_interlock);
+		return ENOENT;
+	}
+	mutex_exit(vp->v_interlock);
+
+	return 0;
+}
+
 /*
  * We just feed the returned vnode up to the caller - there's no need
  * to build a layer node on top of the node on which we're going to do

Index: src/sys/miscfs/kernfs/kernfs_subr.c
diff -u src/sys/miscfs/kernfs/kernfs_subr.c:1.25 src/sys/miscfs/kernfs/kernfs_subr.c:1.26
--- src/sys/miscfs/kernfs/kernfs_subr.c:1.25	Thu Mar 22 20:34:38 2012
+++ src/sys/miscfs/kernfs/kernfs_subr.c	Thu Feb 27 16:51:38 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: kernfs_subr.c,v 1.25 2012/03/22 20:34:38 drochner Exp $	*/
+/*	$NetBSD: kernfs_subr.c,v 1.26 2014/02/27 16:51:38 hannken Exp $	*/
 
 /*
  * Copyright (c) 1993
@@ -73,7 +73,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kernfs_subr.c,v 1.25 2012/03/22 20:34:38 drochner Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kernfs_subr.c,v 1.26 2014/02/27 16:51:38 hannken Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -322,9 +322,11 @@ void
 kernfs_hashins(struct kernfs_node *pp)
 {
 	struct kfs_hashhead *ppp;
+	int error __diagused;
 
 	/* lock the kfsnode, then put it on the appropriate hash list */
-	VOP_LOCK(KERNFSTOV(pp), LK_EXCLUSIVE);
+	error = VOP_LOCK(KERNFSTOV(pp), LK_EXCLUSIVE);
+	KASSERT(error == 0);
 
 	mutex_enter(&kfs_ihash_lock);
 	ppp = &kfs_hashtbl[KFSVALUEHASH(pp->kfs_value)];

Index: src/sys/miscfs/nullfs/null_vnops.c
diff -u src/sys/miscfs/nullfs/null_vnops.c:1.38 src/sys/miscfs/nullfs/null_vnops.c:1.39
--- src/sys/miscfs/nullfs/null_vnops.c:1.38	Mon Jul 11 08:27:38 2011
+++ src/sys/miscfs/nullfs/null_vnops.c	Thu Feb 27 16:51:38 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: null_vnops.c,v 1.38 2011/07/11 08:27:38 hannken Exp $	*/
+/*	$NetBSD: null_vnops.c,v 1.39 2014/02/27 16:51:38 hannken Exp $	*/
 
 /*
  * Copyright (c) 1999 National Aeronautics & Space Administration
@@ -80,7 +80,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: null_vnops.c,v 1.38 2011/07/11 08:27:38 hannken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: null_vnops.c,v 1.39 2014/02/27 16:51:38 hannken Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -106,6 +106,7 @@ const struct vnodeopv_entry_desc null_vn
 	{ &vop_fsync_desc,	layer_fsync },
 	{ &vop_inactive_desc,	layer_inactive },
 	{ &vop_reclaim_desc,	layer_reclaim },
+	{ &vop_lock_desc,	layer_lock },
 	{ &vop_print_desc,	layer_print },
 	{ &vop_remove_desc,	layer_remove },
 	{ &vop_rename_desc,	layer_rename },

Index: src/sys/miscfs/overlay/overlay_vnops.c
diff -u src/sys/miscfs/overlay/overlay_vnops.c:1.19 src/sys/miscfs/overlay/overlay_vnops.c:1.20
--- src/sys/miscfs/overlay/overlay_vnops.c:1.19	Mon Jul 11 08:27:39 2011
+++ src/sys/miscfs/overlay/overlay_vnops.c	Thu Feb 27 16:51:38 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: overlay_vnops.c,v 1.19 2011/07/11 08:27:39 hannken Exp $	*/
+/*	$NetBSD: overlay_vnops.c,v 1.20 2014/02/27 16:51:38 hannken Exp $	*/
 
 /*
  * Copyright (c) 1999, 2000 National Aeronautics & Space Administration
@@ -67,7 +67,7 @@
  *
  * Ancestors:
  *	@(#)lofs_vnops.c	1.2 (Berkeley) 6/18/92
- *	$Id: overlay_vnops.c,v 1.19 2011/07/11 08:27:39 hannken Exp $
+ *	$Id: overlay_vnops.c,v 1.20 2014/02/27 16:51:38 hannken Exp $
  *	...and...
  *	@(#)null_vnodeops.c 1.20 92/07/07 UCLA Ficus project
  */
@@ -126,7 +126,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: overlay_vnops.c,v 1.19 2011/07/11 08:27:39 hannken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: overlay_vnops.c,v 1.20 2014/02/27 16:51:38 hannken Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -155,6 +155,7 @@ const struct vnodeopv_entry_desc overlay
 	{ &vop_fsync_desc,    layer_fsync },
 	{ &vop_inactive_desc, layer_inactive },
 	{ &vop_reclaim_desc,  layer_reclaim },
+	{ &vop_lock_desc,     layer_lock },
 	{ &vop_print_desc,    layer_print },
 	{ &vop_remove_desc,   layer_remove },
 	{ &vop_rename_desc,   layer_rename },

Index: src/sys/miscfs/umapfs/umap_vnops.c
diff -u src/sys/miscfs/umapfs/umap_vnops.c:1.55 src/sys/miscfs/umapfs/umap_vnops.c:1.56
--- src/sys/miscfs/umapfs/umap_vnops.c:1.55	Sun Feb  9 17:18:38 2014
+++ src/sys/miscfs/umapfs/umap_vnops.c	Thu Feb 27 16:51:38 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: umap_vnops.c,v 1.55 2014/02/09 17:18:38 hannken Exp $	*/
+/*	$NetBSD: umap_vnops.c,v 1.56 2014/02/27 16:51:38 hannken Exp $	*/
 
 /*
  * Copyright (c) 1992, 1993
@@ -39,7 +39,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: umap_vnops.c,v 1.55 2014/02/09 17:18:38 hannken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: umap_vnops.c,v 1.56 2014/02/27 16:51:38 hannken Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -89,6 +89,7 @@ const struct vnodeopv_entry_desc umap_vn
 	{ &vop_fsync_desc,	layer_fsync },
 	{ &vop_inactive_desc,	layer_inactive },
 	{ &vop_reclaim_desc,	layer_reclaim },
+	{ &vop_lock_desc,	layer_lock },
 	{ &vop_open_desc,	layer_open },
 	{ &vop_setattr_desc,	layer_setattr },
 	{ &vop_access_desc,	layer_access },

Index: src/sys/nfs/nfs_node.c
diff -u src/sys/nfs/nfs_node.c:1.116 src/sys/nfs/nfs_node.c:1.117
--- src/sys/nfs/nfs_node.c:1.116	Sun Jun 12 03:35:59 2011
+++ src/sys/nfs/nfs_node.c	Thu Feb 27 16:51:38 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: nfs_node.c,v 1.116 2011/06/12 03:35:59 rmind Exp $	*/
+/*	$NetBSD: nfs_node.c,v 1.117 2014/02/27 16:51:38 hannken Exp $	*/
 
 /*
  * Copyright (c) 1989, 1993
@@ -35,7 +35,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: nfs_node.c,v 1.116 2011/06/12 03:35:59 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nfs_node.c,v 1.117 2014/02/27 16:51:38 hannken Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_nfs.h"
@@ -229,7 +229,8 @@ loop:
 	kauth_cred_hold(np->n_rcred);
 	np->n_wcred = curlwp->l_cred;
 	kauth_cred_hold(np->n_wcred);
-	VOP_LOCK(vp, LK_EXCLUSIVE);
+	error = VOP_LOCK(vp, LK_EXCLUSIVE);
+	KASSERT(error == 0);
 	NFS_INVALIDATE_ATTRCACHE(np);
 	uvm_vnp_setsize(vp, 0);
 	(void)rb_tree_insert_node(&nmp->nm_rbtree, np);

Index: src/sys/sys/param.h
diff -u src/sys/sys/param.h:1.441 src/sys/sys/param.h:1.442
--- src/sys/sys/param.h:1.441	Thu Feb 20 18:19:10 2014
+++ src/sys/sys/param.h	Thu Feb 27 16:51:39 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: param.h,v 1.441 2014/02/20 18:19:10 dsl Exp $	*/
+/*	$NetBSD: param.h,v 1.442 2014/02/27 16:51:39 hannken Exp $	*/
 
 /*-
  * Copyright (c) 1982, 1986, 1989, 1993
@@ -63,7 +63,7 @@
  *	2.99.9		(299000900)
  */
 
-#define	__NetBSD_Version__	699003200	/* NetBSD 6.99.32 */
+#define	__NetBSD_Version__	699003300	/* NetBSD 6.99.33 */
 
 #define __NetBSD_Prereq__(M,m,p) (((((M) * 100000000) + \
     (m) * 1000000) + (p) * 100) <= __NetBSD_Version__)

Index: src/sys/ufs/chfs/chfs_ihash.c
diff -u src/sys/ufs/chfs/chfs_ihash.c:1.2 src/sys/ufs/chfs/chfs_ihash.c:1.3
--- src/sys/ufs/chfs/chfs_ihash.c:1.2	Fri Oct 19 12:44:39 2012
+++ src/sys/ufs/chfs/chfs_ihash.c	Thu Feb 27 16:51:39 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: chfs_ihash.c,v 1.2 2012/10/19 12:44:39 ttoth Exp $	*/
+/*	$NetBSD: chfs_ihash.c,v 1.3 2014/02/27 16:51:39 hannken Exp $	*/
 
 /*-
  * Copyright (c) 2010 Department of Software Engineering,
@@ -183,13 +183,15 @@ void
 chfs_ihashins(struct chfs_inode *ip)
 {
 	struct ihashhead *ipp;
+	int error __diagused;
 
 	dbg("ip: %p\n", ip);
 
 	KASSERT(mutex_owned(&chfs_hashlock));
 
 	/* lock the inode, then put it on the appropriate hash list */
-	VOP_LOCK(ITOV(ip), LK_EXCLUSIVE);
+	error = VOP_LOCK(ITOV(ip), LK_EXCLUSIVE);
+	KASSERT(error == 0);
 
 	mutex_enter(&chfs_ihash_lock);
 	ipp = &chfs_ihashtbl[INOHASH(ip->dev, ip->ino)];

Index: src/sys/ufs/lfs/ulfs_ihash.c
diff -u src/sys/ufs/lfs/ulfs_ihash.c:1.3 src/sys/ufs/lfs/ulfs_ihash.c:1.4
--- src/sys/ufs/lfs/ulfs_ihash.c:1.3	Thu Jun  6 00:48:04 2013
+++ src/sys/ufs/lfs/ulfs_ihash.c	Thu Feb 27 16:51:39 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: ulfs_ihash.c,v 1.3 2013/06/06 00:48:04 dholland Exp $	*/
+/*	$NetBSD: ulfs_ihash.c,v 1.4 2014/02/27 16:51:39 hannken Exp $	*/
 /*  from NetBSD: ufs_ihash.c,v 1.31 2011/06/12 03:36:02 rmind Exp  */
 
 /*
@@ -33,7 +33,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ulfs_ihash.c,v 1.3 2013/06/06 00:48:04 dholland Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ulfs_ihash.c,v 1.4 2014/02/27 16:51:39 hannken Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -168,11 +168,13 @@ void
 ulfs_ihashins(struct inode *ip)
 {
 	struct ihashhead *ipp;
+	int error __diagused;
 
 	KASSERT(mutex_owned(&ulfs_hashlock));
 
 	/* lock the inode, then put it on the appropriate hash list */
-	VOP_LOCK(ITOV(ip), LK_EXCLUSIVE);
+	error = VOP_LOCK(ITOV(ip), LK_EXCLUSIVE);
+	KASSERT(error == 0);
 
 	mutex_enter(&ulfs_ihash_lock);
 	ipp = &ihashtbl[INOHASH(ip->i_dev, ip->i_number)];

Index: src/sys/ufs/ufs/ufs_ihash.c
diff -u src/sys/ufs/ufs/ufs_ihash.c:1.31 src/sys/ufs/ufs/ufs_ihash.c:1.32
--- src/sys/ufs/ufs/ufs_ihash.c:1.31	Sun Jun 12 03:36:02 2011
+++ src/sys/ufs/ufs/ufs_ihash.c	Thu Feb 27 16:51:39 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: ufs_ihash.c,v 1.31 2011/06/12 03:36:02 rmind Exp $	*/
+/*	$NetBSD: ufs_ihash.c,v 1.32 2014/02/27 16:51:39 hannken Exp $	*/
 
 /*
  * Copyright (c) 1982, 1986, 1989, 1991, 1993
@@ -32,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ufs_ihash.c,v 1.31 2011/06/12 03:36:02 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ufs_ihash.c,v 1.32 2014/02/27 16:51:39 hannken Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -167,11 +167,13 @@ void
 ufs_ihashins(struct inode *ip)
 {
 	struct ihashhead *ipp;
+	int error __diagused;
 
 	KASSERT(mutex_owned(&ufs_hashlock));
 
 	/* lock the inode, then put it on the appropriate hash list */
-	VOP_LOCK(ITOV(ip), LK_EXCLUSIVE);
+	error = VOP_LOCK(ITOV(ip), LK_EXCLUSIVE);
+	KASSERT(error == 0);
 
 	mutex_enter(&ufs_ihash_lock);
 	ipp = &ihashtbl[INOHASH(ip->i_dev, ip->i_number)];

Reply via email to