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__)