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