diff options
author | phk <phk@FreeBSD.org> | 2001-05-26 08:27:58 +0000 |
---|---|---|
committer | phk <phk@FreeBSD.org> | 2001-05-26 08:27:58 +0000 |
commit | 2072a71f0e5186928f3cb8cfac61fe8199029442 (patch) | |
tree | b40e6ace9e559eda88dc8e88344909bffdde59e4 /sys/kern/kern_conf.c | |
parent | 32df247d021a07cb6a2425587a871d41f24660e6 (diff) | |
download | FreeBSD-src-2072a71f0e5186928f3cb8cfac61fe8199029442.zip FreeBSD-src-2072a71f0e5186928f3cb8cfac61fe8199029442.tar.gz |
Create a general facility for making dev_t's depend on another
dev_t. The dev_depends(dev_t, dev_t) function is for tying them
to each other.
When destroy_dev() is called on a dev_t, all dev_t's depending
on it will also be destroyed (depth first order).
Rewrite the make_dev_alias() to use this dependency facility.
kern/subr_disk.c:
Make the disk mini-layer use dependencies to make sure all
relevant dev_t's are removed when the disk disappears.
Make the disk mini-layer precreate some magic sub devices
which the disk/slice/label code expects to be there.
kern/subr_disklabel.c:
Remove some now unneeded variables.
kern/subr_diskmbr.c:
Remove some ancient, commented out code.
kern/subr_diskslice.c:
Minor cleanup. Use name from dev_t instead of dsname()
Diffstat (limited to 'sys/kern/kern_conf.c')
-rw-r--r-- | sys/kern/kern_conf.c | 31 |
1 files changed, 20 insertions, 11 deletions
diff --git a/sys/kern/kern_conf.c b/sys/kern/kern_conf.c index bfb3ce5..f5c4c1a 100644 --- a/sys/kern/kern_conf.c +++ b/sys/kern/kern_conf.c @@ -177,9 +177,10 @@ allocdev(void) LIST_REMOVE(si, si_hash); } else { si = devt_stash + stashed++; - si->si_flags |= SI_STASHED; + bzero(si, sizeof *si); + si->si_flags |= SI_STASHED; } - LIST_INIT(&si->si_names); + LIST_INIT(&si->si_children); TAILQ_INIT(&si->si_snapshots); return (si); } @@ -208,7 +209,6 @@ makedev(int x, int y) void freedev(dev_t dev) { - dev_t adev; if (!free_devt) return; @@ -216,14 +216,10 @@ freedev(dev_t dev) return; if (dev->si_devsw || dev->si_drv1 || dev->si_drv2) return; - while (!LIST_EMPTY(&dev->si_names)) { - adev = LIST_FIRST(&dev->si_names); - adev->si_drv1 = NULL; - freedev(adev); - } LIST_REMOVE(dev, si_hash); if (dev->si_flags & SI_STASHED) { bzero(dev, sizeof(*dev)); + dev->si_flags |= SI_STASHED; LIST_INSERT_HEAD(&dev_free, dev, si_hash); } else { FREE(dev, M_DEVT); @@ -304,6 +300,15 @@ make_dev(struct cdevsw *devsw, int minor, uid_t uid, gid_t gid, int perms, char return (dev); } +void +dev_depends(dev_t pdev, dev_t cdev) +{ + + cdev->si_parent = pdev; + cdev->si_flags |= SI_CHILD; + LIST_INSERT_HEAD(&pdev->si_children, cdev, si_siblings); +} + dev_t make_dev_alias(dev_t pdev, char *fmt, ...) { @@ -314,9 +319,7 @@ make_dev_alias(dev_t pdev, char *fmt, ...) dev = allocdev(); dev->si_flags |= SI_ALIAS; dev->si_flags |= SI_NAMED; - dev->si_drv1 = pdev; - LIST_INSERT_HEAD(&pdev->si_names, dev, si_hash); - + dev_depends(pdev, dev); va_start(ap, fmt); i = kvprintf(fmt, NULL, dev->si_name, 32, ap); dev->si_name[i] = '\0'; @@ -339,6 +342,12 @@ destroy_dev(dev_t dev) if (devfs_destroy_hook) devfs_destroy_hook(dev); + if (dev->si_flags & SI_CHILD) { + LIST_REMOVE(dev, si_siblings); + dev->si_flags &= ~SI_CHILD; + } + while (!LIST_EMPTY(&dev->si_children)) + destroy_dev(LIST_FIRST(&dev->si_children)); dev->si_drv1 = 0; dev->si_drv2 = 0; dev->si_devsw = 0; |