Module Name:    src
Committed By:   hannken
Date:           Mon Feb 10 11:23:14 UTC 2014

Modified Files:
        src/sys/miscfs/genfs: layer_subr.c layer_vfsops.c
        src/sys/miscfs/nullfs: null_vfsops.c
        src/sys/miscfs/overlay: overlay_vfsops.c
        src/sys/miscfs/umapfs: umap_vfsops.c

Log Message:
Change layerfs_vget(), layerfs_fhtovp() and the various layer xxx_mount()
functions to unlock/relock the node for the call to layer_node_create().

Finally remove dirty hacks (LK_NOWAIT, kpause) from layer_node_find().


To generate a diff of this commit:
cvs rdiff -u -r1.34 -r1.35 src/sys/miscfs/genfs/layer_subr.c
cvs rdiff -u -r1.41 -r1.42 src/sys/miscfs/genfs/layer_vfsops.c
cvs rdiff -u -r1.84 -r1.85 src/sys/miscfs/nullfs/null_vfsops.c
cvs rdiff -u -r1.57 -r1.58 src/sys/miscfs/overlay/overlay_vfsops.c
cvs rdiff -u -r1.88 -r1.89 src/sys/miscfs/umapfs/umap_vfsops.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/miscfs/genfs/layer_subr.c
diff -u src/sys/miscfs/genfs/layer_subr.c:1.34 src/sys/miscfs/genfs/layer_subr.c:1.35
--- src/sys/miscfs/genfs/layer_subr.c:1.34	Sun Feb  9 17:15:51 2014
+++ src/sys/miscfs/genfs/layer_subr.c	Mon Feb 10 11:23:14 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: layer_subr.c,v 1.34 2014/02/09 17:15:51 hannken Exp $	*/
+/*	$NetBSD: layer_subr.c,v 1.35 2014/02/10 11:23:14 hannken Exp $	*/
 
 /*
  * Copyright (c) 1999 National Aeronautics & Space Administration
@@ -69,7 +69,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: layer_subr.c,v 1.34 2014/02/09 17:15:51 hannken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: layer_subr.c,v 1.35 2014/02/10 11:23:14 hannken Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -112,7 +112,7 @@ layerfs_done(void)
 /*
  * layer_node_find: find and return alias for lower vnode or NULL.
  *
- * => Return alias vnode locked and referenced. if already exists.
+ * => Return alias vnode referenced. if already exists.
  * => The layermp's hashlock must be held on entry, we will unlock on success.
  */
 struct vnode *
@@ -128,7 +128,7 @@ layer_node_find(struct mount *mp, struct
 	 * Find hash bucket and search the (two-way) linked list looking
 	 * for a layerfs node structure which is referencing the lower vnode.
 	 * If found, the increment the layer_node reference count, but NOT
-	 * the lower vnode's reference counter.  Return vnode locked.
+	 * the lower vnode's reference counter.
 	 */
 	KASSERT(mutex_owned(&lmp->layerm_hashlock));
 	hd = LAYER_NHASH(lmp, lowervp);
@@ -142,29 +142,9 @@ loop:
 			continue;
 		}
 		mutex_enter(vp->v_interlock);
-		/*
-		 * If we find a node being cleaned out, then ignore it and
-		 * continue.  A thread trying to clean out the extant layer
-		 * vnode needs to acquire the shared lock (i.e. the lower
-		 * vnode's lock), which our caller already holds.  To allow
-		 * the cleaning to succeed the current thread must make
-		 * progress.  So, for a brief time more than one vnode in a
-		 * layered file system may refer to a single vnode in the
-		 * lower file system.
-		 */
-		if ((vp->v_iflag & VI_XLOCK) != 0) {
-			mutex_exit(vp->v_interlock);
-			continue;
-		}
 		mutex_exit(&lmp->layerm_hashlock);
-		/*
-		 * We must not let vget() try to lock the layer vp, since
-		 * the lower vp is already locked and locking the layer vp
-		 * will involve locking the lower vp.
-		 */
-		error = vget(vp, LK_NOWAIT);
+		error = vget(vp, 0);
 		if (error) {
-			kpause("layerfs", false, 1, NULL);
 			mutex_enter(&lmp->layerm_hashlock);
 			goto loop;
 		}

Index: src/sys/miscfs/genfs/layer_vfsops.c
diff -u src/sys/miscfs/genfs/layer_vfsops.c:1.41 src/sys/miscfs/genfs/layer_vfsops.c:1.42
--- src/sys/miscfs/genfs/layer_vfsops.c:1.41	Thu May 31 16:08:14 2012
+++ src/sys/miscfs/genfs/layer_vfsops.c	Mon Feb 10 11:23:14 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: layer_vfsops.c,v 1.41 2012/05/31 16:08:14 pgoyette Exp $	*/
+/*	$NetBSD: layer_vfsops.c,v 1.42 2014/02/10 11:23:14 hannken Exp $	*/
 
 /*
  * Copyright (c) 1999 National Aeronautics & Space Administration
@@ -74,7 +74,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: layer_vfsops.c,v 1.41 2012/05/31 16:08:14 pgoyette Exp $");
+__KERNEL_RCSID(0, "$NetBSD: layer_vfsops.c,v 1.42 2014/02/10 11:23:14 hannken Exp $");
 
 #include <sys/param.h>
 #include <sys/sysctl.h>
@@ -214,9 +214,16 @@ layerfs_vget(struct mount *mp, ino_t ino
 		*vpp = NULL;
 		return error;
 	}
+	VOP_UNLOCK(vp);
 	error = layer_node_create(mp, vp, vpp);
 	if (error) {
-		vput(vp);
+		vrele(vp);
+		*vpp = NULL;
+		return error;
+	}
+	error = vn_lock(*vpp, LK_EXCLUSIVE);
+	if (error) {
+		vrele(*vpp);
 		*vpp = NULL;
 		return error;
 	}
@@ -231,14 +238,22 @@ layerfs_fhtovp(struct mount *mp, struct 
 
 	error = VFS_FHTOVP(MOUNTTOLAYERMOUNT(mp)->layerm_vfs, fidp, &vp);
 	if (error) {
+		*vpp = NULL;
 		return error;
 	}
+	VOP_UNLOCK(vp);
 	error = layer_node_create(mp, vp, vpp);
 	if (error) {
 		vput(vp);
 		*vpp = NULL;
 		return (error);
 	}
+	error = vn_lock(*vpp, LK_EXCLUSIVE);
+	if (error) {
+		vrele(*vpp);
+		*vpp = NULL;
+		return error;
+	}
 	return 0;
 }
 

Index: src/sys/miscfs/nullfs/null_vfsops.c
diff -u src/sys/miscfs/nullfs/null_vfsops.c:1.84 src/sys/miscfs/nullfs/null_vfsops.c:1.85
--- src/sys/miscfs/nullfs/null_vfsops.c:1.84	Mon Apr 30 22:51:27 2012
+++ src/sys/miscfs/nullfs/null_vfsops.c	Mon Feb 10 11:23:14 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: null_vfsops.c,v 1.84 2012/04/30 22:51:27 rmind Exp $	*/
+/*	$NetBSD: null_vfsops.c,v 1.85 2014/02/10 11:23:14 hannken Exp $	*/
 
 /*
  * Copyright (c) 1999 National Aeronautics & Space Administration
@@ -76,7 +76,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: null_vfsops.c,v 1.84 2012/04/30 22:51:27 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: null_vfsops.c,v 1.85 2014/02/10 11:23:14 hannken Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -159,9 +159,10 @@ nullfs_mount(struct mount *mp, const cha
 	    &nmp->nullm_node_hash);
 
 	/* Setup a null node for root vnode. */
+	VOP_UNLOCK(lowerrootvp);
 	error = layer_node_create(mp, lowerrootvp, &vp);
 	if (error) {
-		vput(lowerrootvp);
+		vrele(lowerrootvp);
 		hashdone(nmp->nullm_node_hashtbl, HASH_LIST,
 		    nmp->nullm_node_hash);
 		kmem_free(nmp, sizeof(struct null_mount));
@@ -171,6 +172,7 @@ nullfs_mount(struct mount *mp, const cha
 	 * Keep a held reference to the root vnode.  It will be released on
 	 * umount.  Note: nullfs is MP-safe.
 	 */
+	vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
 	vp->v_vflag |= VV_ROOT;
 	nmp->nullm_rootvp = vp;
 	mp->mnt_iflag |= IMNT_MPSAFE;

Index: src/sys/miscfs/overlay/overlay_vfsops.c
diff -u src/sys/miscfs/overlay/overlay_vfsops.c:1.57 src/sys/miscfs/overlay/overlay_vfsops.c:1.58
--- src/sys/miscfs/overlay/overlay_vfsops.c:1.57	Mon Apr 30 22:51:27 2012
+++ src/sys/miscfs/overlay/overlay_vfsops.c	Mon Feb 10 11:23:14 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: overlay_vfsops.c,v 1.57 2012/04/30 22:51:27 rmind Exp $	*/
+/*	$NetBSD: overlay_vfsops.c,v 1.58 2014/02/10 11:23:14 hannken Exp $	*/
 
 /*
  * Copyright (c) 1999, 2000 National Aeronautics & Space Administration
@@ -74,7 +74,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: overlay_vfsops.c,v 1.57 2012/04/30 22:51:27 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: overlay_vfsops.c,v 1.58 2014/02/10 11:23:14 hannken Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -170,27 +170,26 @@ ov_mount(struct mount *mp, const char *p
 	/*
 	 * Fix up overlay node for root vnode
 	 */
+	VOP_UNLOCK(lowerrootvp);
 	error = layer_node_create(mp, lowerrootvp, &vp);
 	/*
 	 * Make sure the fixup worked
 	 */
 	if (error) {
-		vput(lowerrootvp);
+		vrele(lowerrootvp);
 		hashdone(nmp->ovm_node_hashtbl, HASH_LIST, nmp->ovm_node_hash);
 		kmem_free(nmp, sizeof(struct overlay_mount));
 		return error;
 	}
-	/*
-	 * Unlock the node
-	 */
-	VOP_UNLOCK(vp);
 
 	/*
 	 * Keep a held reference to the root vnode.
 	 * It is vrele'd in ov_unmount.
 	 */
+	vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
 	vp->v_vflag |= VV_ROOT;
 	nmp->ovm_rootvp = vp;
+	VOP_UNLOCK(vp);
 
 	error = set_statvfs_info(path, UIO_USERSPACE, args->la.target,
 	    UIO_USERSPACE, mp->mnt_op->vfs_name, mp, l);

Index: src/sys/miscfs/umapfs/umap_vfsops.c
diff -u src/sys/miscfs/umapfs/umap_vfsops.c:1.88 src/sys/miscfs/umapfs/umap_vfsops.c:1.89
--- src/sys/miscfs/umapfs/umap_vfsops.c:1.88	Mon Apr 30 22:51:28 2012
+++ src/sys/miscfs/umapfs/umap_vfsops.c	Mon Feb 10 11:23:14 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: umap_vfsops.c,v 1.88 2012/04/30 22:51:28 rmind Exp $	*/
+/*	$NetBSD: umap_vfsops.c,v 1.89 2014/02/10 11:23:14 hannken Exp $	*/
 
 /*
  * Copyright (c) 1992, 1993
@@ -41,7 +41,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: umap_vfsops.c,v 1.88 2012/04/30 22:51:28 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: umap_vfsops.c,v 1.89 2014/02/10 11:23:14 hannken Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -205,28 +205,27 @@ umapfs_mount(struct mount *mp, const cha
 	/*
 	 * fix up umap node for root vnode.
 	 */
+	VOP_UNLOCK(lowerrootvp);
 	error = layer_node_create(mp, lowerrootvp, &vp);
 	/*
 	 * Make sure the node alias worked
 	 */
 	if (error) {
-		vput(lowerrootvp);
+		vrele(lowerrootvp);
 		hashdone(amp->umapm_node_hashtbl, HASH_LIST,
 		    amp->umapm_node_hash);
 		kmem_free(amp, sizeof(struct umap_mount));
 		return error;
 	}
-	/*
-	 * Unlock the node (either the lower or the alias)
-	 */
-	vp->v_vflag |= VV_ROOT;
-	VOP_UNLOCK(vp);
 
 	/*
 	 * Keep a held reference to the root vnode.
 	 * It is vrele'd in umapfs_unmount.
 	 */
+	vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
+	vp->v_vflag |= VV_ROOT;
 	amp->umapm_rootvp = vp;
+	VOP_UNLOCK(vp);
 
 	error = set_statvfs_info(path, UIO_USERSPACE, args->umap_target,
 	    UIO_USERSPACE, mp->mnt_op->vfs_name, mp, l);

Reply via email to