diff options
author | phk <phk@FreeBSD.org> | 2001-10-27 17:44:21 +0000 |
---|---|---|
committer | phk <phk@FreeBSD.org> | 2001-10-27 17:44:21 +0000 |
commit | a298958ff19ad5e4d8416a9623b9d3e0601eefa3 (patch) | |
tree | 9c14f1616c72955669bdf28ab19ab8d89829a984 | |
parent | 4c52c72d92026ab3c4f2e80242e639274b443e09 (diff) | |
download | FreeBSD-src-a298958ff19ad5e4d8416a9623b9d3e0601eefa3.zip FreeBSD-src-a298958ff19ad5e4d8416a9623b9d3e0601eefa3.tar.gz |
Nudge the axe a bit closer to cdevsw[]:
Make it a panic to repeat make_dev() or destroy_dev(), this check
should maybe be neutered when -current goes -stable.
Whine if devsw() is called on anon dev_t's in a devfs system.
Make a hack to avoid our lazy-eval disk code triggering the above whine.
Fix the multiple make_dev() in disk code by making ${disk}${unit}s${slice}
an alias/symlink to ${disk}${unit}s${slice}c
-rw-r--r-- | sys/kern/kern_conf.c | 11 | ||||
-rw-r--r-- | sys/kern/subr_disk.c | 57 |
2 files changed, 66 insertions, 2 deletions
diff --git a/sys/kern/kern_conf.c b/sys/kern/kern_conf.c index ca42144..ef07c55 100644 --- a/sys/kern/kern_conf.c +++ b/sys/kern/kern_conf.c @@ -74,11 +74,20 @@ int devfs_present; static int free_devt; SYSCTL_INT(_debug, OID_AUTO, free_devt, CTLFLAG_RW, &free_devt, 0, ""); +/* XXX: This is a hack */ +void disk_dev_synth(dev_t dev); + struct cdevsw * devsw(dev_t dev) { if (dev->si_devsw) return (dev->si_devsw); + /* XXX: Hack around our backwards disk code */ + disk_dev_synth(dev); + if (dev->si_devsw) + return (dev->si_devsw); + if (devfs_present) + printf("WARNING: devsw() called on %s %u/%u\n", dev->si_name, major(dev), minor(dev)); return(cdevsw[major(dev)]); } @@ -283,6 +292,7 @@ make_dev(struct cdevsw *devsw, int minor, uid_t uid, gid_t gid, int perms, const if (dev->si_flags & SI_NAMED) { printf( "WARNING: Driver mistake: repeat make_dev(\"%s\")\n", dev->si_name); + panic("don't do that"); return (dev); } va_start(ap, fmt); @@ -350,6 +360,7 @@ destroy_dev(dev_t dev) if (!(dev->si_flags & SI_NAMED)) { printf( "WARNING: Driver mistake: destroy_dev on %d/%d\n", major(dev), minor(dev)); + panic("don't do that"); return; } diff --git a/sys/kern/subr_disk.c b/sys/kern/subr_disk.c index bb52bf0..8e637ff 100644 --- a/sys/kern/subr_disk.c +++ b/sys/kern/subr_disk.c @@ -32,6 +32,50 @@ static d_psize_t diskpsize; static LIST_HEAD(, disk) disklist = LIST_HEAD_INITIALIZER(&disklist); +void disk_dev_synth(dev_t dev); + +void +disk_dev_synth(dev_t dev) +{ + struct disk *dp; + int u, s, p; + dev_t pdev; + + LIST_FOREACH(dp, &disklist, d_list) { + if (major(dev) != dp->d_devsw->d_maj) + continue; + u = dkunit(dev); + p = RAW_PART; + s = WHOLE_DISK_SLICE; + pdev = makedev(dp->d_devsw->d_maj, dkmakeminor(u, s, p)); + s = dkslice(dev); + p = dkpart(dev); + if (s == WHOLE_DISK_SLICE && p == RAW_PART) { + /* XXX: actually should not happen */ + dev = make_dev(pdev->si_devsw, dkmakeminor(u, s, p), + UID_ROOT, GID_OPERATOR, 0640, "%s%d", + dp->d_devsw->d_name, u); + dev_depends(pdev, dev); + return; + } + if (s == COMPATIBILITY_SLICE) { + dev = make_dev(pdev->si_devsw, dkmakeminor(u, s, p), + UID_ROOT, GID_OPERATOR, 0640, "%s%d%c", + dp->d_devsw->d_name, u, 'a' + p); + dev_depends(pdev, dev); + return; + } + dev = make_dev(pdev->si_devsw, dkmakeminor(u, s, p), + UID_ROOT, GID_OPERATOR, 0640, "%s%ds%d%c", + dp->d_devsw->d_name, u, s - BASE_SLICE + 1, 'a' + p); + dev_depends(pdev, dev); + if (p == RAW_PART) + make_dev_alias(dev, "%s%ds%d", + dp->d_devsw->d_name, u, s - BASE_SLICE + 1); + return; + } +} + static void disk_clone(void *arg, char *name, int namelen, dev_t *dev) { @@ -86,9 +130,18 @@ disk_clone(void *arg, char *name, int namelen, dev_t *dev) p = name[i] - 'a'; } - *dev = make_dev(pdev->si_devsw, dkmakeminor(u, s, p), - UID_ROOT, GID_OPERATOR, 0640, name); + if (s >= BASE_SLICE) + *dev = make_dev(pdev->si_devsw, dkmakeminor(u, s, p), + UID_ROOT, GID_OPERATOR, 0640, "%s%ds%d%c", + pdev->si_devsw->d_name, u, s - BASE_SLICE + 1, p + 'a'); + else + *dev = make_dev(pdev->si_devsw, dkmakeminor(u, s, p), + UID_ROOT, GID_OPERATOR, 0640, name); dev_depends(pdev, *dev); + if (s >= BASE_SLICE && p == RAW_PART) { + make_dev_alias(*dev, "%s%ds%d", + pdev->si_devsw->d_name, u, s - BASE_SLICE + 1); + } return; } } |