summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorphk <phk@FreeBSD.org>1999-07-20 09:47:55 +0000
committerphk <phk@FreeBSD.org>1999-07-20 09:47:55 +0000
commitcacc73aa1890c8a258a383716e0c90da798acd4e (patch)
tree895deb1c3a5fdc3b63cee3173606b1811c3149f5
parentcf4a7fab742bfd88596615a4e608783600af67b5 (diff)
downloadFreeBSD-src-cacc73aa1890c8a258a383716e0c90da798acd4e.zip
FreeBSD-src-cacc73aa1890c8a258a383716e0c90da798acd4e.tar.gz
Now a dev_t is a pointer to struct specinfo which is shared by all specdev
vnodes referencing this device. Details: cdevsw->d_parms has been removed, the specinfo is available now (== dev_t) and the driver should modify it directly when applicable, and the only driver doing so, does so: vn.c. I am not sure the logic in checking for "<" was right before, and it looks even less so now. An intial pool of 50 struct specinfo are depleted during early boot, after that malloc had better work. It is likely that fewer than 50 would do. Hashing is done from udev_t to dev_t with a prime number remainder hash, experiments show no better hash available for decent cost (MD5 is only marginally better) The prime number used should not be close to a power of two, we use 83 for now. Add new checkalias2() to get around the loss of info from dev2udev() in bdevvp(); The aliased vnodes are hung on a list straight of the dev_t, and speclisth[SPECSZ] is unused. The sharing of struct specinfo means that the v_specnext moves into the vnode which grows by 4 bytes. Don't use a VBLK dev_t which doesn't make sense in MFS, now we hang a dummy cdevsw on B/Cmaj 253 so that things look sane. Storage overhead from all of this is O(50k). Bump __FreeBSD_version to 400009 The next step will add the stuff needed so device-drivers can start to hang things from struct specinfo
-rw-r--r--sys/dev/vn/vn.c47
-rw-r--r--sys/fs/specfs/spec_vnops.c3
-rw-r--r--sys/kern/kern_conf.c76
-rw-r--r--sys/kern/vfs_export.c89
-rw-r--r--sys/kern/vfs_subr.c89
-rw-r--r--sys/miscfs/specfs/spec_vnops.c3
-rw-r--r--sys/miscfs/specfs/specdev.h14
-rw-r--r--sys/sys/conf.h4
-rw-r--r--sys/sys/linedisc.h4
-rw-r--r--sys/sys/param.h4
-rw-r--r--sys/sys/types.h6
-rw-r--r--sys/sys/vnode.h11
-rw-r--r--sys/ufs/mfs/mfs_vfsops.c29
13 files changed, 185 insertions, 194 deletions
diff --git a/sys/dev/vn/vn.c b/sys/dev/vn/vn.c
index 3288038..06bf27f 100644
--- a/sys/dev/vn/vn.c
+++ b/sys/dev/vn/vn.c
@@ -38,7 +38,7 @@
* from: Utah Hdr: vn.c 1.13 94/04/02
*
* from: @(#)vn.c 8.6 (Berkeley) 4/1/94
- * $Id: vn.c,v 1.79 1999/05/11 19:54:02 phk Exp $
+ * $Id: vn.c,v 1.80 1999/05/30 16:51:55 phk Exp $
*/
/*
@@ -108,7 +108,6 @@ static d_close_t vnclose;
static d_dump_t vndump;
static d_psize_t vnsize;
static d_strategy_t vnstrategy;
-static d_parms_t vnparms;
#define CDEV_MAJOR 43
#define BDEV_MAJOR 15
@@ -133,7 +132,7 @@ static struct cdevsw vn_cdevsw = {
/* mmap */ nommap,
/* strategy */ vnstrategy,
/* name */ "vn",
- /* parms */ vnparms,
+ /* parms */ noparms,
/* maj */ CDEV_MAJOR,
/* dump */ vndump,
/* psize */ vnsize,
@@ -516,6 +515,10 @@ vniocattach_file(vn, vio, dev, flag, p)
(void) vn_close(nd.ni_vp, FREAD|FWRITE, p->p_ucred, p);
return(error);
}
+ if (dev->si_bsize_phys < vn->sc_secsize)
+ dev->si_bsize_phys = vn->sc_secsize;
+ if (dev->si_bsize_best < vn->sc_secsize)
+ dev->si_bsize_best = vn->sc_secsize;
vn->sc_flags |= VNF_INITED;
IFOPT(vn, VN_LABELS) {
/*
@@ -686,44 +689,6 @@ vnsize(dev_t dev)
return(vn->sc_size);
}
-/*
- * vnparms() - return requested device block info
- *
- * This is typically called by specfs with DBLK_MIN to get
- * the minimum read/write block size. If the device does not
- * exist or has not been configured, 0 is returned.
- */
-
-static int
-vnparms(dev_t dev, struct specinfo *sinfo, int ctl)
-{
- int unit = vnunit(dev);
- int r = -1;
- struct vn_softc *vn;
-
- if (unit < 0 || unit >= NVN)
- return(r);
- if ((vn = vn_softc[unit]) == NULL || (vn->sc_flags & VNF_INITED) == 0)
- return(r);
-
- switch(ctl) {
- case DPARM_GET:
- /*
- * Retrieve disk parameters. The system has already set
- * the defaults, we simply override them as necessary.
- */
- r = 0;
- if (sinfo->si_bsize_phys < vn->sc_secsize)
- sinfo->si_bsize_phys = vn->sc_secsize;
- if (sinfo->si_bsize_best < vn->sc_secsize)
- sinfo->si_bsize_best = vn->sc_secsize;
- break;
- default:
- break;
- }
- return(r);
-}
-
static int
vndump(dev_t dev)
{
diff --git a/sys/fs/specfs/spec_vnops.c b/sys/fs/specfs/spec_vnops.c
index 9a467fd..9dff63d 100644
--- a/sys/fs/specfs/spec_vnops.c
+++ b/sys/fs/specfs/spec_vnops.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)spec_vnops.c 8.14 (Berkeley) 5/21/95
- * $Id: spec_vnops.c,v 1.88 1999/06/01 20:29:58 dt Exp $
+ * $Id: spec_vnops.c,v 1.89 1999/06/26 02:46:21 mckusick Exp $
*/
#include <sys/param.h>
@@ -75,7 +75,6 @@ static int spec_read __P((struct vop_read_args *));
static int spec_strategy __P((struct vop_strategy_args *));
static int spec_write __P((struct vop_write_args *));
-struct vnode *speclisth[SPECHSZ];
vop_t **spec_vnodeop_p;
static struct vnodeopv_entry_desc spec_vnodeop_entries[] = {
{ &vop_default_desc, (vop_t *) vop_defaultop },
diff --git a/sys/kern/kern_conf.c b/sys/kern/kern_conf.c
index caedd0f..f14f1e6 100644
--- a/sys/kern/kern_conf.c
+++ b/sys/kern/kern_conf.c
@@ -30,20 +30,34 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: kern_conf.c,v 1.49 1999/07/17 19:57:25 phk Exp $
+ * $Id: kern_conf.c,v 1.50 1999/07/19 09:37:59 phk Exp $
*/
#include <sys/param.h>
+#include <sys/kernel.h>
#include <sys/systm.h>
#include <sys/module.h>
+#include <sys/malloc.h>
#include <sys/conf.h>
#include <sys/vnode.h>
+#include <sys/queue.h>
+
+#include <miscfs/specfs/specdev.h>
#define cdevsw_ALLOCSTART (NUMCDEVSW/2)
struct cdevsw *cdevsw[NUMCDEVSW];
-int bmaj2cmaj[NUMCDEVSW];
+static int bmaj2cmaj[NUMCDEVSW];
+
+MALLOC_DEFINE(M_DEVT, "dev_t", "dev_t storage");
+
+#define DEVT_HASH 83
+#define DEVT_STASH 50
+
+static struct specinfo devt_stash[DEVT_STASH];
+
+static SLIST_HEAD(devt_hash_head, specinfo) dev_hash[DEVT_HASH];
/*
* Routine to convert from character to block device number.
@@ -87,7 +101,7 @@ cdevsw_add(struct cdevsw *newentry)
if (!setup) {
for (i = 0; i < NUMCDEVSW; i++)
if (!bmaj2cmaj[i])
- bmaj2cmaj[i] = 256;
+ bmaj2cmaj[i] = 254;
setup++;
}
@@ -104,7 +118,7 @@ cdevsw_add(struct cdevsw *newentry)
cdevsw[newentry->d_maj] = newentry;
if (newentry->d_bmaj >= 0 && newentry->d_bmaj < NUMCDEVSW) {
- if (bmaj2cmaj[newentry->d_bmaj] != 256) {
+ if (bmaj2cmaj[newentry->d_bmaj] != 254) {
printf("WARNING: \"%s\" is usurping \"%s\"'s bmaj\n",
newentry->d_name,
cdevsw[bmaj2cmaj[newentry->d_bmaj]]->d_name);
@@ -169,51 +183,63 @@ devsw_module_handler(module_t mod, int what, void* arg)
* dev_t and u_dev_t primitives
*/
-#define DEVT_FASCIST 1
-
int
major(dev_t x)
{
- uintptr_t i = (uintptr_t)x;
-
-#ifdef DEVT_FASCIST
- return(255 - ((i >> 8) & 0xff));
-#else
- return((i >> 8) & 0xff);
-#endif
+ if (x == NODEV)
+ return NOUDEV;
+ return((x->si_udev >> 8) & 0xff);
}
int
minor(dev_t x)
{
- uintptr_t i = (uintptr_t)x;
-
- return(i & 0xffff00ff);
+ if (x == NODEV)
+ return NOUDEV;
+ return(x->si_udev & 0xffff00ff);
}
dev_t
makebdev(int x, int y)
{
- if (bmaj2cmaj[x] == 256) {
- return NODEV;
- }
return (makedev(bmaj2cmaj[x], y));
}
dev_t
makedev(int x, int y)
{
-#ifdef DEVT_FASCIST
- return ((dev_t)(uintptr_t) (((255 - x) << 8) | y));
-#else
- return ((dev_t)(uintptr_t) ((x << 8) | y));
-#endif
+ struct specinfo *si;
+ udev_t udev;
+ int hash;
+ static int stashed;
+
+ udev = (x << 8) | y;
+ hash = udev % DEVT_HASH;
+ SLIST_FOREACH(si, &dev_hash[hash], si_hash) {
+ if (si->si_udev == udev)
+ return (si);
+ }
+ if (stashed >= DEVT_STASH) {
+ MALLOC(si, struct specinfo *, sizeof(*si), M_DEVT,
+ M_USE_RESERVE);
+ } else {
+ si = devt_stash + stashed++;
+ }
+ bzero(si, sizeof(*si));
+ si->si_udev = udev;
+ si->si_bsize_phys = DEV_BSIZE;
+ si->si_bsize_best = BLKDEV_IOSIZE;
+ si->si_bsize_max = MAXBSIZE;
+ SLIST_INSERT_HEAD(&dev_hash[hash], si, si_hash);
+ return (si);
}
udev_t
dev2udev(dev_t x)
{
- return makeudev(major(x), minor(x));
+ if (x == NODEV)
+ return NOUDEV;
+ return (x->si_udev);
}
dev_t
diff --git a/sys/kern/vfs_export.c b/sys/kern/vfs_export.c
index 7dd2110..fddda87 100644
--- a/sys/kern/vfs_export.c
+++ b/sys/kern/vfs_export.c
@@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)vfs_subr.c 8.31 (Berkeley) 5/26/95
- * $Id: vfs_subr.c,v 1.211 1999/07/18 14:30:37 phk Exp $
+ * $Id: vfs_subr.c,v 1.212 1999/07/19 09:37:59 phk Exp $
*/
/*
@@ -80,6 +80,7 @@
static MALLOC_DEFINE(M_NETADDR, "Export Host", "Export host address structure");
+static struct vnode *checkalias2 __P((struct vnode *nvp, dev_t dev, struct mount *mp));
static void insmntque __P((struct vnode *vp, struct mount *mp));
static void vclean __P((struct vnode *vp, int flags, struct proc *p));
static void vfree __P((struct vnode *));
@@ -1245,12 +1246,11 @@ bdevvp(dev, vpp)
}
vp = nvp;
/* dev2udev() results in a CDEV, so we need to cheat here. */
- vp->v_type = VCHR;
- if ((nvp = checkalias(vp, dev2udev(dev), (struct mount *)0)) != NULL) {
+ vp->v_type = VBLK;
+ if ((nvp = checkalias2(vp, dev, (struct mount *)0)) != NULL) {
vput(vp);
vp = nvp;
}
- vp->v_type = VBLK;
*vpp = vp;
return (0);
}
@@ -1269,21 +1269,33 @@ checkalias(nvp, nvp_rdev, mp)
udev_t nvp_rdev;
struct mount *mp;
{
- struct proc *p = curproc; /* XXX */
- struct vnode *vp;
- struct vnode **vpp;
dev_t dev;
if (nvp->v_type != VBLK && nvp->v_type != VCHR)
return (NULLVP);
dev = udev2dev(nvp_rdev, nvp->v_type == VBLK ? 1 : 0);
+ return (checkalias2(nvp, dev, mp));
+}
- vpp = &speclisth[SPECHASH(dev)];
+static struct vnode *
+checkalias2(nvp, dev, mp)
+ register struct vnode *nvp;
+ dev_t dev;
+ struct mount *mp;
+{
+ struct proc *p = curproc; /* XXX */
+ struct vnode *vp;
+ struct vnode **vpp;
+
+ if (nvp->v_type != VBLK && nvp->v_type != VCHR)
+ return (NULLVP);
+
+ vpp = &dev->si_hlist;
loop:
simple_lock(&spechash_slock);
for (vp = *vpp; vp; vp = vp->v_specnext) {
- if (dev != vp->v_rdev || nvp->v_type != vp->v_type)
+ if (nvp->v_type != vp->v_type)
continue;
/*
* Alias, but not in use, so flush it out.
@@ -1319,32 +1331,11 @@ loop:
* Put the new vnode into the hash chain.
* and if there was an alias, connect them.
*/
- MALLOC(sinfo, struct specinfo *,
- sizeof(struct specinfo), M_VNODE, M_WAITOK);
- bzero(sinfo, sizeof(struct specinfo));
- nvp->v_specinfo = sinfo;
- sinfo->si_rdev = dev;
- sinfo->si_hashchain = vpp;
- sinfo->si_specnext = *vpp;
- sinfo->si_bsize_phys = DEV_BSIZE;
- sinfo->si_bsize_best = BLKDEV_IOSIZE;
- sinfo->si_bsize_max = MAXBSIZE;
-
- /*
- * Ask the device to fix up specinfo. Typically the
- * si_bsize_* parameters may need fixing up.
- */
-
- if (nvp->v_type == VBLK) {
- if (bdevsw(dev) && bdevsw(dev)->d_parms)
- (*bdevsw(dev)->d_parms)(dev, sinfo, DPARM_GET);
- } else if (nvp->v_type == VCHR) {
- if (devsw(dev) && devsw(dev)->d_parms)
- (*devsw(dev)->d_parms)(dev, sinfo, DPARM_GET);
- }
+ nvp->v_specnext = *vpp;
+ *vpp = nvp;
+ nvp->v_specinfo = sinfo = dev;
simple_unlock(&spechash_slock);
- *vpp = nvp;
if (vp != NULLVP) {
nvp->v_flag |= VALIASED;
vp->v_flag |= VALIASED;
@@ -1355,7 +1346,7 @@ loop:
/*
* if ( vp && (vp->v_tag == VT_NULL))
* We have a vnode alias, but it is a trashed.
- * Make it look like it's newley allocated. (by getnewvnode())
+ * Make it look like it's newly allocated. (by getnewvnode())
* The caller should use this instead.
*/
simple_unlock(&spechash_slock);
@@ -1797,9 +1788,8 @@ vop_revoke(ap)
simple_unlock(&vp->v_interlock);
while (vp->v_flag & VALIASED) {
simple_lock(&spechash_slock);
- for (vq = *vp->v_hashchain; vq; vq = vq->v_specnext) {
- if (vq->v_rdev != vp->v_rdev ||
- vq->v_type != vp->v_type || vp == vq)
+ for (vq = vp->v_hashchain; vq; vq = vq->v_specnext) {
+ if (vq->v_type != vp->v_type || vp == vq)
continue;
simple_unlock(&spechash_slock);
vgone(vq);
@@ -1902,10 +1892,10 @@ vgonel(vp, p)
*/
if ((vp->v_type == VBLK || vp->v_type == VCHR) && vp->v_specinfo != 0) {
simple_lock(&spechash_slock);
- if (*vp->v_hashchain == vp) {
- *vp->v_hashchain = vp->v_specnext;
+ if (vp->v_hashchain == vp) {
+ vp->v_hashchain = vp->v_specnext;
} else {
- for (vq = *vp->v_hashchain; vq; vq = vq->v_specnext) {
+ for (vq = vp->v_hashchain; vq; vq = vq->v_specnext) {
if (vq->v_specnext != vp)
continue;
vq->v_specnext = vp->v_specnext;
@@ -1916,9 +1906,8 @@ vgonel(vp, p)
}
if (vp->v_flag & VALIASED) {
vx = NULL;
- for (vq = *vp->v_hashchain; vq; vq = vq->v_specnext) {
- if (vq->v_rdev != vp->v_rdev ||
- vq->v_type != vp->v_type)
+ for (vq = vp->v_hashchain; vq; vq = vq->v_specnext) {
+ if (vq->v_type != vp->v_type)
continue;
if (vx)
break;
@@ -1931,7 +1920,6 @@ vgonel(vp, p)
vp->v_flag &= ~VALIASED;
}
simple_unlock(&spechash_slock);
- FREE(vp->v_specinfo, M_VNODE);
vp->v_specinfo = NULL;
}
@@ -1979,8 +1967,8 @@ vfinddev(dev, type, vpp)
int rc = 0;
simple_lock(&spechash_slock);
- for (vp = speclisth[SPECHASH(dev)]; vp; vp = vp->v_specnext) {
- if (dev != vp->v_rdev || type != vp->v_type)
+ for (vp = dev->si_hlist; vp; vp = vp->v_specnext) {
+ if (type != vp->v_type)
continue;
*vpp = vp;
rc = 1;
@@ -2004,9 +1992,9 @@ loop:
if ((vp->v_flag & VALIASED) == 0)
return (vp->v_usecount);
simple_lock(&spechash_slock);
- for (count = 0, vq = *vp->v_hashchain; vq; vq = vnext) {
+ for (count = 0, vq = vp->v_hashchain; vq; vq = vnext) {
vnext = vq->v_specnext;
- if (vq->v_rdev != vp->v_rdev || vq->v_type != vp->v_type)
+ if (vq->v_type != vp->v_type)
continue;
/*
* Alias, but not in use, so flush it out.
@@ -2267,9 +2255,8 @@ vfs_mountedon(vp)
return (EBUSY);
if (vp->v_flag & VALIASED) {
simple_lock(&spechash_slock);
- for (vq = *vp->v_hashchain; vq; vq = vq->v_specnext) {
- if (vq->v_rdev != vp->v_rdev ||
- vq->v_type != vp->v_type)
+ for (vq = vp->v_hashchain; vq; vq = vq->v_specnext) {
+ if (vq->v_type != vp->v_type)
continue;
if (vq->v_specmountpoint != NULL) {
error = EBUSY;
diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c
index 7dd2110..fddda87 100644
--- a/sys/kern/vfs_subr.c
+++ b/sys/kern/vfs_subr.c
@@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)vfs_subr.c 8.31 (Berkeley) 5/26/95
- * $Id: vfs_subr.c,v 1.211 1999/07/18 14:30:37 phk Exp $
+ * $Id: vfs_subr.c,v 1.212 1999/07/19 09:37:59 phk Exp $
*/
/*
@@ -80,6 +80,7 @@
static MALLOC_DEFINE(M_NETADDR, "Export Host", "Export host address structure");
+static struct vnode *checkalias2 __P((struct vnode *nvp, dev_t dev, struct mount *mp));
static void insmntque __P((struct vnode *vp, struct mount *mp));
static void vclean __P((struct vnode *vp, int flags, struct proc *p));
static void vfree __P((struct vnode *));
@@ -1245,12 +1246,11 @@ bdevvp(dev, vpp)
}
vp = nvp;
/* dev2udev() results in a CDEV, so we need to cheat here. */
- vp->v_type = VCHR;
- if ((nvp = checkalias(vp, dev2udev(dev), (struct mount *)0)) != NULL) {
+ vp->v_type = VBLK;
+ if ((nvp = checkalias2(vp, dev, (struct mount *)0)) != NULL) {
vput(vp);
vp = nvp;
}
- vp->v_type = VBLK;
*vpp = vp;
return (0);
}
@@ -1269,21 +1269,33 @@ checkalias(nvp, nvp_rdev, mp)
udev_t nvp_rdev;
struct mount *mp;
{
- struct proc *p = curproc; /* XXX */
- struct vnode *vp;
- struct vnode **vpp;
dev_t dev;
if (nvp->v_type != VBLK && nvp->v_type != VCHR)
return (NULLVP);
dev = udev2dev(nvp_rdev, nvp->v_type == VBLK ? 1 : 0);
+ return (checkalias2(nvp, dev, mp));
+}
- vpp = &speclisth[SPECHASH(dev)];
+static struct vnode *
+checkalias2(nvp, dev, mp)
+ register struct vnode *nvp;
+ dev_t dev;
+ struct mount *mp;
+{
+ struct proc *p = curproc; /* XXX */
+ struct vnode *vp;
+ struct vnode **vpp;
+
+ if (nvp->v_type != VBLK && nvp->v_type != VCHR)
+ return (NULLVP);
+
+ vpp = &dev->si_hlist;
loop:
simple_lock(&spechash_slock);
for (vp = *vpp; vp; vp = vp->v_specnext) {
- if (dev != vp->v_rdev || nvp->v_type != vp->v_type)
+ if (nvp->v_type != vp->v_type)
continue;
/*
* Alias, but not in use, so flush it out.
@@ -1319,32 +1331,11 @@ loop:
* Put the new vnode into the hash chain.
* and if there was an alias, connect them.
*/
- MALLOC(sinfo, struct specinfo *,
- sizeof(struct specinfo), M_VNODE, M_WAITOK);
- bzero(sinfo, sizeof(struct specinfo));
- nvp->v_specinfo = sinfo;
- sinfo->si_rdev = dev;
- sinfo->si_hashchain = vpp;
- sinfo->si_specnext = *vpp;
- sinfo->si_bsize_phys = DEV_BSIZE;
- sinfo->si_bsize_best = BLKDEV_IOSIZE;
- sinfo->si_bsize_max = MAXBSIZE;
-
- /*
- * Ask the device to fix up specinfo. Typically the
- * si_bsize_* parameters may need fixing up.
- */
-
- if (nvp->v_type == VBLK) {
- if (bdevsw(dev) && bdevsw(dev)->d_parms)
- (*bdevsw(dev)->d_parms)(dev, sinfo, DPARM_GET);
- } else if (nvp->v_type == VCHR) {
- if (devsw(dev) && devsw(dev)->d_parms)
- (*devsw(dev)->d_parms)(dev, sinfo, DPARM_GET);
- }
+ nvp->v_specnext = *vpp;
+ *vpp = nvp;
+ nvp->v_specinfo = sinfo = dev;
simple_unlock(&spechash_slock);
- *vpp = nvp;
if (vp != NULLVP) {
nvp->v_flag |= VALIASED;
vp->v_flag |= VALIASED;
@@ -1355,7 +1346,7 @@ loop:
/*
* if ( vp && (vp->v_tag == VT_NULL))
* We have a vnode alias, but it is a trashed.
- * Make it look like it's newley allocated. (by getnewvnode())
+ * Make it look like it's newly allocated. (by getnewvnode())
* The caller should use this instead.
*/
simple_unlock(&spechash_slock);
@@ -1797,9 +1788,8 @@ vop_revoke(ap)
simple_unlock(&vp->v_interlock);
while (vp->v_flag & VALIASED) {
simple_lock(&spechash_slock);
- for (vq = *vp->v_hashchain; vq; vq = vq->v_specnext) {
- if (vq->v_rdev != vp->v_rdev ||
- vq->v_type != vp->v_type || vp == vq)
+ for (vq = vp->v_hashchain; vq; vq = vq->v_specnext) {
+ if (vq->v_type != vp->v_type || vp == vq)
continue;
simple_unlock(&spechash_slock);
vgone(vq);
@@ -1902,10 +1892,10 @@ vgonel(vp, p)
*/
if ((vp->v_type == VBLK || vp->v_type == VCHR) && vp->v_specinfo != 0) {
simple_lock(&spechash_slock);
- if (*vp->v_hashchain == vp) {
- *vp->v_hashchain = vp->v_specnext;
+ if (vp->v_hashchain == vp) {
+ vp->v_hashchain = vp->v_specnext;
} else {
- for (vq = *vp->v_hashchain; vq; vq = vq->v_specnext) {
+ for (vq = vp->v_hashchain; vq; vq = vq->v_specnext) {
if (vq->v_specnext != vp)
continue;
vq->v_specnext = vp->v_specnext;
@@ -1916,9 +1906,8 @@ vgonel(vp, p)
}
if (vp->v_flag & VALIASED) {
vx = NULL;
- for (vq = *vp->v_hashchain; vq; vq = vq->v_specnext) {
- if (vq->v_rdev != vp->v_rdev ||
- vq->v_type != vp->v_type)
+ for (vq = vp->v_hashchain; vq; vq = vq->v_specnext) {
+ if (vq->v_type != vp->v_type)
continue;
if (vx)
break;
@@ -1931,7 +1920,6 @@ vgonel(vp, p)
vp->v_flag &= ~VALIASED;
}
simple_unlock(&spechash_slock);
- FREE(vp->v_specinfo, M_VNODE);
vp->v_specinfo = NULL;
}
@@ -1979,8 +1967,8 @@ vfinddev(dev, type, vpp)
int rc = 0;
simple_lock(&spechash_slock);
- for (vp = speclisth[SPECHASH(dev)]; vp; vp = vp->v_specnext) {
- if (dev != vp->v_rdev || type != vp->v_type)
+ for (vp = dev->si_hlist; vp; vp = vp->v_specnext) {
+ if (type != vp->v_type)
continue;
*vpp = vp;
rc = 1;
@@ -2004,9 +1992,9 @@ loop:
if ((vp->v_flag & VALIASED) == 0)
return (vp->v_usecount);
simple_lock(&spechash_slock);
- for (count = 0, vq = *vp->v_hashchain; vq; vq = vnext) {
+ for (count = 0, vq = vp->v_hashchain; vq; vq = vnext) {
vnext = vq->v_specnext;
- if (vq->v_rdev != vp->v_rdev || vq->v_type != vp->v_type)
+ if (vq->v_type != vp->v_type)
continue;
/*
* Alias, but not in use, so flush it out.
@@ -2267,9 +2255,8 @@ vfs_mountedon(vp)
return (EBUSY);
if (vp->v_flag & VALIASED) {
simple_lock(&spechash_slock);
- for (vq = *vp->v_hashchain; vq; vq = vq->v_specnext) {
- if (vq->v_rdev != vp->v_rdev ||
- vq->v_type != vp->v_type)
+ for (vq = vp->v_hashchain; vq; vq = vq->v_specnext) {
+ if (vq->v_type != vp->v_type)
continue;
if (vq->v_specmountpoint != NULL) {
error = EBUSY;
diff --git a/sys/miscfs/specfs/spec_vnops.c b/sys/miscfs/specfs/spec_vnops.c
index 9a467fd..9dff63d 100644
--- a/sys/miscfs/specfs/spec_vnops.c
+++ b/sys/miscfs/specfs/spec_vnops.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)spec_vnops.c 8.14 (Berkeley) 5/21/95
- * $Id: spec_vnops.c,v 1.88 1999/06/01 20:29:58 dt Exp $
+ * $Id: spec_vnops.c,v 1.89 1999/06/26 02:46:21 mckusick Exp $
*/
#include <sys/param.h>
@@ -75,7 +75,6 @@ static int spec_read __P((struct vop_read_args *));
static int spec_strategy __P((struct vop_strategy_args *));
static int spec_write __P((struct vop_write_args *));
-struct vnode *speclisth[SPECHSZ];
vop_t **spec_vnodeop_p;
static struct vnodeopv_entry_desc spec_vnodeop_entries[] = {
{ &vop_default_desc, (vop_t *) vop_defaultop },
diff --git a/sys/miscfs/specfs/specdev.h b/sys/miscfs/specfs/specdev.h
index d0cfd77..3150b49 100644
--- a/sys/miscfs/specfs/specdev.h
+++ b/sys/miscfs/specfs/specdev.h
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)specdev.h 8.6 (Berkeley) 5/21/95
- * $Id: specdev.h,v 1.16 1999/02/25 05:22:30 dillon Exp $
+ * $Id: specdev.h,v 1.17 1999/05/11 19:54:39 phk Exp $
*/
/*
@@ -40,20 +40,19 @@
* in vgone.
*/
struct specinfo {
- struct vnode **si_hashchain;
- struct vnode *si_specnext;
struct mount *si_mountpoint;
- dev_t si_rdev;
int si_bsize_phys; /* minimum physical block size */
int si_bsize_best; /* optimal block size / VBLK */
int si_bsize_max; /* maximum block size */
+
+ udev_t si_udev;
+ SLIST_ENTRY(specinfo) si_hash;
+ struct vnode *si_hlist;
};
/*
* Exported shorthand
*/
-#define v_rdev v_specinfo->si_rdev
-#define v_hashchain v_specinfo->si_hashchain
-#define v_specnext v_specinfo->si_specnext
+#define v_hashchain v_specinfo->si_hlist
#define v_specmountpoint v_specinfo->si_mountpoint
/*
@@ -62,7 +61,6 @@ struct specinfo {
#define SPECHSZ 64
#define SPECHASH(rdev) (((unsigned)(minor(rdev)))%SPECHSZ)
-extern struct vnode *speclisth[SPECHSZ];
/*
* Prototypes for special file operations on vnodes.
diff --git a/sys/sys/conf.h b/sys/sys/conf.h
index cfa4606..885350ea8 100644
--- a/sys/sys/conf.h
+++ b/sys/sys/conf.h
@@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)conf.h 8.5 (Berkeley) 1/9/95
- * $Id: conf.h,v 1.65 1999/07/07 04:06:56 msmith Exp $
+ * $Id: conf.h,v 1.66 1999/07/17 19:58:51 phk Exp $
*/
#ifndef _SYS_CONF_H_
@@ -118,7 +118,7 @@ struct cdevsw {
d_mmap_t *d_mmap;
d_strategy_t *d_strategy;
char *d_name; /* base device name, e.g. 'vn' */
- d_parms_t *d_parms; /* populate/override specinfo */
+ d_parms_t *d_bogoparms; /* XXX not used */
int d_maj;
d_dump_t *d_dump;
d_psize_t *d_psize;
diff --git a/sys/sys/linedisc.h b/sys/sys/linedisc.h
index cfa4606..885350ea8 100644
--- a/sys/sys/linedisc.h
+++ b/sys/sys/linedisc.h
@@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)conf.h 8.5 (Berkeley) 1/9/95
- * $Id: conf.h,v 1.65 1999/07/07 04:06:56 msmith Exp $
+ * $Id: conf.h,v 1.66 1999/07/17 19:58:51 phk Exp $
*/
#ifndef _SYS_CONF_H_
@@ -118,7 +118,7 @@ struct cdevsw {
d_mmap_t *d_mmap;
d_strategy_t *d_strategy;
char *d_name; /* base device name, e.g. 'vn' */
- d_parms_t *d_parms; /* populate/override specinfo */
+ d_parms_t *d_bogoparms; /* XXX not used */
int d_maj;
d_dump_t *d_dump;
d_psize_t *d_psize;
diff --git a/sys/sys/param.h b/sys/sys/param.h
index 29af0b6..ef89e20 100644
--- a/sys/sys/param.h
+++ b/sys/sys/param.h
@@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)param.h 8.3 (Berkeley) 4/4/95
- * $Id: param.h,v 1.49 1999/06/17 23:54:23 green Exp $
+ * $Id: param.h,v 1.50 1999/06/20 08:34:24 jb Exp $
*/
#ifndef _SYS_PARAM_H_
@@ -46,7 +46,7 @@
#define BSD4_3 1
#define BSD4_4 1
#undef __FreeBSD_version
-#define __FreeBSD_version 400008 /* Master, propagated to newvers */
+#define __FreeBSD_version 400009 /* Master, propagated to newvers */
#ifndef NULL
#define NULL 0
diff --git a/sys/sys/types.h b/sys/sys/types.h
index 9a240fd..cd42c19 100644
--- a/sys/sys/types.h
+++ b/sys/sys/types.h
@@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)types.h 8.6 (Berkeley) 2/19/95
- * $Id: types.h,v 1.33 1999/05/12 11:06:56 phk Exp $
+ * $Id: types.h,v 1.34 1999/07/18 02:26:02 jdp Exp $
*/
#ifndef _SYS_TYPES_H_
@@ -97,8 +97,10 @@ typedef struct vm_page *vm_page_t;
#ifdef KERNEL
+struct specinfo;
+
typedef u_int32_t udev_t; /* device number */
-typedef void *dev_t;
+typedef struct specinfo *dev_t;
#else /* !KERNEL */
diff --git a/sys/sys/vnode.h b/sys/sys/vnode.h
index 40ffd5a..ace76ac 100644
--- a/sys/sys/vnode.h
+++ b/sys/sys/vnode.h
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)vnode.h 8.7 (Berkeley) 2/4/94
- * $Id: vnode.h,v 1.89 1999/06/28 10:35:07 phk Exp $
+ * $Id: vnode.h,v 1.90 1999/07/18 14:30:30 phk Exp $
*/
#ifndef _SYS_VNODE_H_
@@ -101,7 +101,10 @@ struct vnode {
union {
struct mount *vu_mountedhere;/* ptr to mounted vfs (VDIR) */
struct socket *vu_socket; /* unix ipc (VSOCK) */
- struct specinfo *vu_specinfo; /* device (VCHR, VBLK) */
+ struct {
+ struct specinfo *vu_specinfo; /* device (VCHR, VBLK) */
+ struct vnode *vu_specnext;
+ } vu_spec;
struct fifoinfo *vu_fifoinfo; /* fifo (VFIFO) */
} v_un;
struct nqlease *v_lease; /* Soft reference to lease */
@@ -132,7 +135,9 @@ struct vnode {
};
#define v_mountedhere v_un.vu_mountedhere
#define v_socket v_un.vu_socket
-#define v_specinfo v_un.vu_specinfo
+#define v_specinfo v_un.vu_spec.vu_specinfo
+#define v_rdev v_un.vu_spec.vu_specinfo
+#define v_specnext v_un.vu_spec.vu_specnext
#define v_fifoinfo v_un.vu_fifoinfo
#define VN_POLLEVENT(vp, events) \
diff --git a/sys/ufs/mfs/mfs_vfsops.c b/sys/ufs/mfs/mfs_vfsops.c
index 47e4676..7569f74 100644
--- a/sys/ufs/mfs/mfs_vfsops.c
+++ b/sys/ufs/mfs/mfs_vfsops.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)mfs_vfsops.c 8.11 (Berkeley) 6/19/95
- * $Id: mfs_vfsops.c,v 1.64 1999/05/24 00:27:12 jb Exp $
+ * $Id: mfs_vfsops.c,v 1.65 1999/07/17 18:43:49 phk Exp $
*/
@@ -79,6 +79,28 @@ static int mfs_statfs __P((struct mount *mp, struct statfs *sbp,
struct proc *p));
static int mfs_init __P((struct vfsconf *));
+static struct cdevsw mfs_cdevsw = {
+ /* open */ noopen,
+ /* close */ noclose,
+ /* read */ physread,
+ /* write */ physwrite,
+ /* ioctl */ noioctl,
+ /* stop */ nostop,
+ /* reset */ noreset,
+ /* devtotty */ nodevtotty,
+ /* poll */ nopoll,
+ /* mmap */ nommap,
+ /* strategy */ nostrategy,
+ /* name */ "MFS",
+ /* parms */ noparms,
+ /* maj */ 253,
+ /* dump */ nodump,
+ /* psize */ nopsize,
+ /* flags */ D_DISK,
+ /* maxio */ 0,
+ /* bmaj */ 253,
+};
+
/*
* mfs vfs operations.
*/
@@ -308,7 +330,7 @@ mfs_mount(mp, path, data, ndp, p)
goto error_1;
}
devvp->v_type = VBLK;
- if (checkalias(devvp, makeudev(255, mfs_minor++), (struct mount *)0))
+ if (checkalias(devvp, makeudev(253, mfs_minor++), (struct mount *)0))
panic("mfs_mount: dup dev");
devvp->v_data = mfsp;
mfsp->mfs_baseoff = args.base;
@@ -459,12 +481,13 @@ static int
mfs_init(vfsp)
struct vfsconf *vfsp;
{
+ cdevsw_add(&mfs_cdevsw);
#ifdef MFS_ROOT
if (bootverbose)
printf("Considering MFS root f/s.\n");
if (mfs_getimage()) {
mountrootfsname = "mfs";
- rootdev = makedev(255, mfs_minor++);
+ rootdev = makedev(253, mfs_minor++);
} else if (bootverbose)
printf("No MFS image available as root f/s.\n");
#endif
OpenPOWER on IntegriCloud