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
This commit is contained in:
Poul-Henning Kamp 2001-10-27 17:44:21 +00:00
parent 6fdd5473af
commit 4e4a76633b
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=85603
2 changed files with 66 additions and 2 deletions

View File

@ -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;
}

View File

@ -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;
}
}