Module Name:    src
Committed By:   hannken
Date:           Wed Feb 13 14:03:49 UTC 2013

Modified Files:
        src/sys/dev: fss.c
        src/sys/kern: vfs_mount.c vfs_subr.c vfs_vnode.c
        src/sys/miscfs/specfs: spec_vnops.c specdev.h
        src/sys/sys: param.h

Log Message:
Make the spec_node table implementation private to spec_vnops.c.

To retrieve a spec_node, two new lookup functions (by device or by mount)
are implemented.  Both return a referenced vnode, for an opened block device
the opened vnode is returned so further diagnostic checks "vp == ... sd_bdevvp"
will not fire.  Otherwise any vnode matching the criteria gets returned.

No objections on tech-kern.

Welcome to 6.99.17


To generate a diff of this commit:
cvs rdiff -u -r1.85 -r1.86 src/sys/dev/fss.c
cvs rdiff -u -r1.16 -r1.17 src/sys/kern/vfs_mount.c
cvs rdiff -u -r1.435 -r1.436 src/sys/kern/vfs_subr.c
cvs rdiff -u -r1.18 -r1.19 src/sys/kern/vfs_vnode.c
cvs rdiff -u -r1.136 -r1.137 src/sys/miscfs/specfs/spec_vnops.c
cvs rdiff -u -r1.39 -r1.40 src/sys/miscfs/specfs/specdev.h
cvs rdiff -u -r1.424 -r1.425 src/sys/sys/param.h

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

Modified files:

Index: src/sys/dev/fss.c
diff -u src/sys/dev/fss.c:1.85 src/sys/dev/fss.c:1.86
--- src/sys/dev/fss.c:1.85	Wed Feb  6 09:33:16 2013
+++ src/sys/dev/fss.c	Wed Feb 13 14:03:48 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: fss.c,v 1.85 2013/02/06 09:33:16 hannken Exp $	*/
+/*	$NetBSD: fss.c,v 1.86 2013/02/13 14:03:48 hannken Exp $	*/
 
 /*-
  * Copyright (c) 2003 The NetBSD Foundation, Inc.
@@ -36,7 +36,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: fss.c,v 1.85 2013/02/06 09:33:16 hannken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: fss.c,v 1.86 2013/02/13 14:03:48 hannken Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -620,7 +620,7 @@ static int
 fss_create_files(struct fss_softc *sc, struct fss_set *fss,
     off_t *bsize, struct lwp *l)
 {
-	int i, error, bits, fsbsize;
+	int error, bits, fsbsize;
 	uint64_t numsec;
 	unsigned int secsize;
 	struct timespec ts;
@@ -694,24 +694,7 @@ fss_create_files(struct fss_softc *sc, s
 	 * Get the block device it is mounted on and its size.
 	 */
 
-	mutex_enter(&device_lock);
-	for (i = 0; i < SPECHSZ; i++) {
-		for (vp = specfs_hash[i]; vp; vp = vp->v_specnext) {
-			if (vp->v_type == VBLK &&
-			    vp == vp->v_specnode->sn_dev->sd_bdevvp &&
-			    vp->v_specmountpoint == sc->sc_mount)
-				break;
-		}
-		if (vp != NULL)
-			break;
-	}
-	if (vp == NULL) {
-		mutex_exit(&device_lock);
-		return EINVAL;
-	}
-	mutex_enter(vp->v_interlock);
-	mutex_exit(&device_lock);
-	error = vget(vp, 0);
+	error = spec_node_lookup_by_mount(sc->sc_mount, &vp);
 	if (error)
 		return error;
 	sc->sc_bdev = vp->v_rdev;

Index: src/sys/kern/vfs_mount.c
diff -u src/sys/kern/vfs_mount.c:1.16 src/sys/kern/vfs_mount.c:1.17
--- src/sys/kern/vfs_mount.c:1.16	Fri Dec 14 18:39:48 2012
+++ src/sys/kern/vfs_mount.c	Wed Feb 13 14:03:48 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: vfs_mount.c,v 1.16 2012/12/14 18:39:48 pooka Exp $	*/
+/*	$NetBSD: vfs_mount.c,v 1.17 2013/02/13 14:03:48 hannken Exp $	*/
 
 /*-
  * Copyright (c) 1997-2011 The NetBSD Foundation, Inc.
@@ -67,7 +67,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: vfs_mount.c,v 1.16 2012/12/14 18:39:48 pooka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vfs_mount.c,v 1.17 2013/02/13 14:03:48 hannken Exp $");
 
 #include <sys/param.h>
 #include <sys/kernel.h>
@@ -1252,19 +1252,14 @@ vfs_mountedon(vnode_t *vp)
 	if (vp->v_type != VBLK)
 		return ENOTBLK;
 	if (vp->v_specmountpoint != NULL)
-		return (EBUSY);
-	mutex_enter(&device_lock);
-	for (vq = specfs_hash[SPECHASH(vp->v_rdev)]; vq != NULL;
-	    vq = vq->v_specnext) {
-		if (vq->v_type != vp->v_type || vq->v_rdev != vp->v_rdev)
-			continue;
-		if (vq->v_specmountpoint != NULL) {
+		return EBUSY;
+	if (spec_node_lookup_by_dev(vp->v_type, vp->v_rdev, &vq) == 0) {
+		if (vq->v_specmountpoint != NULL)
 			error = EBUSY;
-			break;
-		}
+		vrele(vq);
 	}
-	mutex_exit(&device_lock);
-	return (error);
+
+	return error;
 }
 
 /*

Index: src/sys/kern/vfs_subr.c
diff -u src/sys/kern/vfs_subr.c:1.435 src/sys/kern/vfs_subr.c:1.436
--- src/sys/kern/vfs_subr.c:1.435	Sat May 12 18:42:08 2012
+++ src/sys/kern/vfs_subr.c	Wed Feb 13 14:03:48 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: vfs_subr.c,v 1.435 2012/05/12 18:42:08 chs Exp $	*/
+/*	$NetBSD: vfs_subr.c,v 1.436 2013/02/13 14:03:48 hannken Exp $	*/
 
 /*-
  * Copyright (c) 1997, 1998, 2004, 2005, 2007, 2008 The NetBSD Foundation, Inc.
@@ -67,7 +67,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: vfs_subr.c,v 1.435 2012/05/12 18:42:08 chs Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vfs_subr.c,v 1.436 2013/02/13 14:03:48 hannken Exp $");
 
 #include "opt_ddb.h"
 #include "opt_compat_netbsd.h"
@@ -513,23 +513,8 @@ getdevvp(dev_t dev, vnode_t **vpp, enum 
 int
 vfinddev(dev_t dev, enum vtype type, vnode_t **vpp)
 {
-	vnode_t *vp;
 
-	mutex_enter(&device_lock);
-	for (vp = specfs_hash[SPECHASH(dev)]; vp; vp = vp->v_specnext) {
-		if (type == vp->v_type && dev == vp->v_rdev)
-			break;
-	}
-	if (vp == NULL) {
-		mutex_exit(&device_lock);
-		return 0;
-	}
-	mutex_enter(vp->v_interlock);
-	mutex_exit(&device_lock);
-	if (vget(vp, 0) != 0)
-		return 0;
-	*vpp = vp;
-	return 1;
+	return (spec_node_lookup_by_dev(type, dev, vpp) == 0);
 }
 
 /*
@@ -539,34 +524,17 @@ vfinddev(dev_t dev, enum vtype type, vno
 void
 vdevgone(int maj, int minl, int minh, enum vtype type)
 {
-	vnode_t *vp, **vpp;
+	vnode_t *vp;
 	dev_t dev;
 	int mn;
 
-	vp = NULL;	/* XXX gcc */
-
-	mutex_enter(&device_lock);
 	for (mn = minl; mn <= minh; mn++) {
 		dev = makedev(maj, mn);
-		vpp = &specfs_hash[SPECHASH(dev)];
-		for (vp = *vpp; vp != NULL;) {
-			mutex_enter(vp->v_interlock);
-			if ((vp->v_iflag & VI_CLEAN) != 0 ||
-			    type != vp->v_type || dev != vp->v_rdev) {
-				mutex_exit(vp->v_interlock);
-				vp = vp->v_specnext;
-				continue;
-			}
-			mutex_exit(&device_lock);
-			if (vget(vp, 0) == 0) {
-				VOP_REVOKE(vp, REVOKEALL);
-				vrele(vp);
-			}
-			mutex_enter(&device_lock);
-			vp = *vpp;
+		while (spec_node_lookup_by_dev(type, dev, &vp) == 0) {
+			VOP_REVOKE(vp, REVOKEALL);
+			vrele(vp);
 		}
 	}
-	mutex_exit(&device_lock);
 }
 
 /*

Index: src/sys/kern/vfs_vnode.c
diff -u src/sys/kern/vfs_vnode.c:1.18 src/sys/kern/vfs_vnode.c:1.19
--- src/sys/kern/vfs_vnode.c:1.18	Sat Feb  9 00:31:21 2013
+++ src/sys/kern/vfs_vnode.c	Wed Feb 13 14:03:48 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: vfs_vnode.c,v 1.18 2013/02/09 00:31:21 christos Exp $	*/
+/*	$NetBSD: vfs_vnode.c,v 1.19 2013/02/13 14:03:48 hannken Exp $	*/
 
 /*-
  * Copyright (c) 1997-2011 The NetBSD Foundation, Inc.
@@ -124,7 +124,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: vfs_vnode.c,v 1.18 2013/02/09 00:31:21 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vfs_vnode.c,v 1.19 2013/02/13 14:03:48 hannken Exp $");
 
 #include <sys/param.h>
 #include <sys/kernel.h>
@@ -1110,7 +1110,7 @@ vrecycle(vnode_t *vp, kmutex_t *inter_lk
 void
 vrevoke(vnode_t *vp)
 {
-	vnode_t *vq, **vpp;
+	vnode_t *vq;
 	enum vtype type;
 	dev_t dev;
 
@@ -1131,30 +1131,11 @@ vrevoke(vnode_t *vp)
 		mutex_exit(vp->v_interlock);
 	}
 
-	vpp = &specfs_hash[SPECHASH(dev)];
-	mutex_enter(&device_lock);
-	for (vq = *vpp; vq != NULL;) {
-		/* If clean or being cleaned, then ignore it. */
+	while (spec_node_lookup_by_dev(type, dev, &vq) == 0) {
 		mutex_enter(vq->v_interlock);
-		if ((vq->v_iflag & (VI_CLEAN | VI_XLOCK)) != 0 ||
-		    vq->v_type != type || vq->v_rdev != dev) {
-			mutex_exit(vq->v_interlock);
-			vq = vq->v_specnext;
-			continue;
-		}
-		mutex_exit(&device_lock);
-		if (vq->v_usecount == 0) {
-			vremfree(vq);
-			vq->v_usecount = 1;
-		} else {
-			atomic_inc_uint(&vq->v_usecount);
-		}
 		vclean(vq, DOCLOSE);
 		vrelel(vq, 0);
-		mutex_enter(&device_lock);
-		vq = *vpp;
 	}
-	mutex_exit(&device_lock);
 }
 
 /*

Index: src/sys/miscfs/specfs/spec_vnops.c
diff -u src/sys/miscfs/specfs/spec_vnops.c:1.136 src/sys/miscfs/specfs/spec_vnops.c:1.137
--- src/sys/miscfs/specfs/spec_vnops.c:1.136	Thu Dec 20 08:03:43 2012
+++ src/sys/miscfs/specfs/spec_vnops.c	Wed Feb 13 14:03:48 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: spec_vnops.c,v 1.136 2012/12/20 08:03:43 hannken Exp $	*/
+/*	$NetBSD: spec_vnops.c,v 1.137 2013/02/13 14:03:48 hannken Exp $	*/
 
 /*-
  * Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -58,7 +58,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: spec_vnops.c,v 1.136 2012/12/20 08:03:43 hannken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: spec_vnops.c,v 1.137 2013/02/13 14:03:48 hannken Exp $");
 
 #include <sys/param.h>
 #include <sys/proc.h>
@@ -93,7 +93,14 @@ const char	devout[] = "devout";
 const char	devioc[] = "devioc";
 const char	devcls[] = "devcls";
 
-vnode_t		*specfs_hash[SPECHSZ];
+#define	SPECHSZ	64
+#if	((SPECHSZ&(SPECHSZ-1)) == 0)
+#define	SPECHASH(rdev)	(((rdev>>5)+(rdev))&(SPECHSZ-1))
+#else
+#define	SPECHASH(rdev)	(((unsigned)((rdev>>5)+(rdev)))%SPECHSZ)
+#endif
+
+static vnode_t	*specfs_hash[SPECHSZ];
 
 /*
  * This vnode operations vector is used for special device nodes
@@ -268,6 +275,82 @@ spec_node_init(vnode_t *vp, dev_t rdev)
 }
 
 /*
+ * Lookup a vnode by device number and return it referenced.
+ */
+int
+spec_node_lookup_by_dev(enum vtype type, dev_t dev, vnode_t **vpp)
+{
+	int error;
+	vnode_t *vp;
+
+	mutex_enter(&device_lock);
+	for (vp = specfs_hash[SPECHASH(dev)]; vp; vp = vp->v_specnext) {
+		if (type == vp->v_type && dev == vp->v_rdev) {
+			mutex_enter(vp->v_interlock);
+			/* If clean or being cleaned, then ignore it. */
+			if ((vp->v_iflag & (VI_CLEAN | VI_XLOCK)) == 0)
+				break;
+			mutex_exit(vp->v_interlock);
+		}
+	}
+	KASSERT(vp == NULL || mutex_owned(vp->v_interlock));
+	if (vp == NULL) {
+		mutex_exit(&device_lock);
+		return ENOENT;
+	}
+	/*
+	 * If it is an opened block device return the opened vnode.
+	 */
+	if (type == VBLK && vp->v_specnode->sn_dev->sd_bdevvp != NULL) {
+		mutex_exit(vp->v_interlock);
+		vp = vp->v_specnode->sn_dev->sd_bdevvp;
+		mutex_enter(vp->v_interlock);
+	}
+	mutex_exit(&device_lock);
+	error = vget(vp, 0);
+	if (error != 0)
+		return error;
+	*vpp = vp;
+
+	return 0;
+}
+
+/*
+ * Lookup a vnode by file system mounted on and return it referenced.
+ */
+int
+spec_node_lookup_by_mount(struct mount *mp, vnode_t **vpp)
+{
+	int i, error;
+	vnode_t *vp, *vq;
+
+	mutex_enter(&device_lock);
+	for (i = 0, vq = NULL; i < SPECHSZ && vq == NULL; i++) {
+		for (vp = specfs_hash[i]; vp; vp = vp->v_specnext) {
+			if (vp->v_type != VBLK)
+				continue;
+			vq = vp->v_specnode->sn_dev->sd_bdevvp;
+			if (vq != NULL && vq->v_specmountpoint == mp)
+				break;
+			vq = NULL;
+		}
+	}
+	if (vq == NULL) {
+		mutex_exit(&device_lock);
+		return ENOENT;
+	}
+	mutex_enter(vq->v_interlock);
+	mutex_exit(&device_lock);
+	error = vget(vq, 0);
+	if (error != 0)
+		return error;
+	*vpp = vq;
+
+	return 0;
+
+}
+
+/*
  * A vnode representing a special device is going away.  Close
  * the device if the vnode holds it open.
  */

Index: src/sys/miscfs/specfs/specdev.h
diff -u src/sys/miscfs/specfs/specdev.h:1.39 src/sys/miscfs/specfs/specdev.h:1.40
--- src/sys/miscfs/specfs/specdev.h:1.39	Sat Nov 14 18:36:57 2009
+++ src/sys/miscfs/specfs/specdev.h	Wed Feb 13 14:03:49 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: specdev.h,v 1.39 2009/11/14 18:36:57 elad Exp $	*/
+/*	$NetBSD: specdev.h,v 1.40 2013/02/13 14:03:49 hannken Exp $	*/
 
 /*-
  * Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -91,17 +91,10 @@ typedef struct specdev {
 /*
  * Special device management
  */
-#define	SPECHSZ	64
-#if	((SPECHSZ&(SPECHSZ-1)) == 0)
-#define	SPECHASH(rdev)	(((rdev>>5)+(rdev))&(SPECHSZ-1))
-#else
-#define	SPECHASH(rdev)	(((unsigned)((rdev>>5)+(rdev)))%SPECHSZ)
-#endif
-
-extern vnode_t	*specfs_hash[SPECHSZ];
-
 void	spec_node_init(vnode_t *, dev_t);
 void	spec_node_destroy(vnode_t *);
+int	spec_node_lookup_by_dev(enum vtype, dev_t, vnode_t **);
+int	spec_node_lookup_by_mount(struct mount *, vnode_t **);
 void	spec_node_revoke(vnode_t *);
 
 /*

Index: src/sys/sys/param.h
diff -u src/sys/sys/param.h:1.424 src/sys/sys/param.h:1.425
--- src/sys/sys/param.h:1.424	Thu Dec 20 08:03:44 2012
+++ src/sys/sys/param.h	Wed Feb 13 14:03:49 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: param.h,v 1.424 2012/12/20 08:03:44 hannken Exp $	*/
+/*	$NetBSD: param.h,v 1.425 2013/02/13 14:03:49 hannken Exp $	*/
 
 /*-
  * Copyright (c) 1982, 1986, 1989, 1993
@@ -63,7 +63,7 @@
  *	2.99.9		(299000900)
  */
 
-#define	__NetBSD_Version__	699001600	/* NetBSD 6.99.16 */
+#define	__NetBSD_Version__	699001700	/* NetBSD 6.99.17 */
 
 #define __NetBSD_Prereq__(M,m,p) (((((M) * 100000000) + \
     (m) * 1000000) + (p) * 100) <= __NetBSD_Version__)

Reply via email to