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 | |
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()
-rw-r--r-- | sys/fs/devfs/devfs_devs.c | 2 | ||||
-rw-r--r-- | sys/kern/kern_conf.c | 31 | ||||
-rw-r--r-- | sys/kern/subr_disk.c | 21 | ||||
-rw-r--r-- | sys/kern/subr_disklabel.c | 2 | ||||
-rw-r--r-- | sys/kern/subr_diskmbr.c | 17 | ||||
-rw-r--r-- | sys/kern/subr_diskslice.c | 15 | ||||
-rw-r--r-- | sys/sys/conf.h | 6 | ||||
-rw-r--r-- | sys/sys/linedisc.h | 6 |
8 files changed, 56 insertions, 44 deletions
diff --git a/sys/fs/devfs/devfs_devs.c b/sys/fs/devfs/devfs_devs.c index 224ca07..9f19fca 100644 --- a/sys/fs/devfs/devfs_devs.c +++ b/sys/fs/devfs/devfs_devs.c @@ -339,7 +339,7 @@ devfs_populate(struct devfs_mount *dm) de->de_gid = 0; de->de_mode = 0666; de->de_dirent->d_type = DT_LNK; - pdev = dev->si_drv1; + pdev = dev->si_parent; j = strlen(pdev->si_name) + 1; MALLOC(de->de_symlink, char *, j, M_DEVFS, M_WAITOK); bcopy(pdev->si_name, de->de_symlink, j); 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; diff --git a/sys/kern/subr_disk.c b/sys/kern/subr_disk.c index c50c21a..3ac9525 100644 --- a/sys/kern/subr_disk.c +++ b/sys/kern/subr_disk.c @@ -86,6 +86,7 @@ disk_clone(void *arg, char *name, int namelen, dev_t *dev) *dev = make_dev(pdev->si_devsw, dkmakeminor(u, s, p), UID_ROOT, GID_OPERATOR, 0640, name); + dev_depends(pdev, *dev); return; } } @@ -105,7 +106,14 @@ dev_t disk_create(int unit, struct disk *dp, int flags, struct cdevsw *cdevsw, struct cdevsw *proto) { static int once; - dev_t dev; + dev_t dev, cdev; + int i; + char buf[20]; + + if (!once) { + EVENTHANDLER_REGISTER(dev_clone, disk_clone, 0, 1000); + once++; + } bzero(dp, sizeof(*dp)); @@ -128,9 +136,14 @@ disk_create(int unit, struct disk *dp, int flags, struct cdevsw *cdevsw, struct dp->d_dsflags = flags; dp->d_devsw = cdevsw; LIST_INSERT_HEAD(&disklist, dp, d_list); - if (!once) { - EVENTHANDLER_REGISTER(dev_clone, disk_clone, 0, 1000); - once++; + + sprintf(buf, "%sc", dev->si_name); + cdev = NODEV; + disk_clone(NULL, buf, strlen(buf), &cdev); + for (i = 1; i < 5; i++) { + sprintf(buf, "%ss%d", dev->si_name, i); + cdev = NODEV; + disk_clone(NULL, buf, strlen(buf), &cdev); } return (dev); } diff --git a/sys/kern/subr_disklabel.c b/sys/kern/subr_disklabel.c index 3a9ad24..5498bf2 100644 --- a/sys/kern/subr_disklabel.c +++ b/sys/kern/subr_disklabel.c @@ -352,8 +352,6 @@ diskerr(bp, what, blkdone, lp) int blkdone; register struct disklabel *lp; { - int unit = dkunit(bp->bio_dev); - int slice = dkslice(bp->bio_dev); int part = dkpart(bp->bio_dev); char partname[2]; char *sname; diff --git a/sys/kern/subr_diskmbr.c b/sys/kern/subr_diskmbr.c index 593d71b..92234d5 100644 --- a/sys/kern/subr_diskmbr.c +++ b/sys/kern/subr_diskmbr.c @@ -298,26 +298,9 @@ reread_mbr: */ secpercyl = (u_long)max_nsectors * max_ntracks; if (secpercyl != 0) { -#if 0 - u_long secperunit; -#endif - lp->d_nsectors = max_nsectors; lp->d_ntracks = max_ntracks; lp->d_secpercyl = secpercyl; - /* - * Temporarily, don't even consider adjusting the drive's - * size, since the adjusted size may exceed the hardware's - * addressing capabilities. The adjustment helped mainly - * for ancient MFM drives with > 1024 cylinders, but now - * breaks at least IDE drives with 63*16*65536 sectors if - * they are controlled by the wd driver in CHS mode. - */ -#if 0 - secperunit = secpercyl * max_ncyls; - if (lp->d_secperunit < secperunit) - lp->d_secperunit = secperunit; -#endif lp->d_ncylinders = lp->d_secperunit / secpercyl; } diff --git a/sys/kern/subr_diskslice.c b/sys/kern/subr_diskslice.c index 9d9c705..0e20032 100644 --- a/sys/kern/subr_diskslice.c +++ b/sys/kern/subr_diskslice.c @@ -648,7 +648,6 @@ dsopen(dev, mode, flags, sspp, lp) struct disklabel *lp1; char *msg; u_char mask; - bool_t need_init; int part; char partname[2]; int slice; @@ -671,10 +670,9 @@ dsopen(dev, mode, flags, sspp, lp) * on the unit. This should only be done if the media has changed. */ ssp = *sspp; - need_init = !dsisopen(ssp); - if (ssp != NULL && need_init) - dsgone(sspp); - if (need_init) { + if (!dsisopen(ssp)) { + if (ssp != NULL) + dsgone(sspp); /* * Allocate a minimal slices "struct". This will become * the final slices "struct" if we don't want real slices @@ -730,9 +728,12 @@ dsopen(dev, mode, flags, sspp, lp) ) continue; dev1 = dkmodslice(dkmodpart(dev, RAW_PART), slice); - if (dev1->si_devsw == NULL) - dev1->si_devsw = dev->si_devsw; +#if 0 sname = dsname(dev, unit, slice, RAW_PART, partname); +#else + *partname='\0'; + sname = dev1->si_name; +#endif /* * XXX this should probably only be done for the need_init * case, but there may be a problem with DIOCSYNCSLICEINFO. diff --git a/sys/sys/conf.h b/sys/sys/conf.h index 3d156a4..689fb0d 100644 --- a/sys/sys/conf.h +++ b/sys/sys/conf.h @@ -59,13 +59,16 @@ struct specinfo { #define SI_ALIAS 0x0002 /* carrier of alias name */ #define SI_NAMED 0x0004 /* make_dev{_alias} has been called */ #define SI_CHEAPCLONE 0x0008 /* can be removed_dev'ed when vnode reclaims */ +#define SI_CHILD 0x0010 /* child of another dev_t */ struct timespec si_atime; struct timespec si_ctime; struct timespec si_mtime; udev_t si_udev; LIST_ENTRY(specinfo) si_hash; SLIST_HEAD(, vnode) si_hlist; - LIST_HEAD(, specinfo) si_names; + LIST_HEAD(, specinfo) si_children; + LIST_ENTRY(specinfo) si_siblings; + dev_t si_parent; struct snaphead si_snapshots; int (*si_copyonwrite)(struct vnode *, struct buf *); u_int si_inode; @@ -294,6 +297,7 @@ int count_dev __P((dev_t dev)); void destroy_dev __P((dev_t dev)); struct cdevsw *devsw __P((dev_t dev)); const char *devtoname __P((dev_t dev)); +void dev_depends __P((dev_t pdev, dev_t cdev)); void freedev __P((dev_t dev)); int iszerodev __P((dev_t dev)); dev_t makebdev __P((int maj, int min)); diff --git a/sys/sys/linedisc.h b/sys/sys/linedisc.h index 3d156a4..689fb0d 100644 --- a/sys/sys/linedisc.h +++ b/sys/sys/linedisc.h @@ -59,13 +59,16 @@ struct specinfo { #define SI_ALIAS 0x0002 /* carrier of alias name */ #define SI_NAMED 0x0004 /* make_dev{_alias} has been called */ #define SI_CHEAPCLONE 0x0008 /* can be removed_dev'ed when vnode reclaims */ +#define SI_CHILD 0x0010 /* child of another dev_t */ struct timespec si_atime; struct timespec si_ctime; struct timespec si_mtime; udev_t si_udev; LIST_ENTRY(specinfo) si_hash; SLIST_HEAD(, vnode) si_hlist; - LIST_HEAD(, specinfo) si_names; + LIST_HEAD(, specinfo) si_children; + LIST_ENTRY(specinfo) si_siblings; + dev_t si_parent; struct snaphead si_snapshots; int (*si_copyonwrite)(struct vnode *, struct buf *); u_int si_inode; @@ -294,6 +297,7 @@ int count_dev __P((dev_t dev)); void destroy_dev __P((dev_t dev)); struct cdevsw *devsw __P((dev_t dev)); const char *devtoname __P((dev_t dev)); +void dev_depends __P((dev_t pdev, dev_t cdev)); void freedev __P((dev_t dev)); int iszerodev __P((dev_t dev)); dev_t makebdev __P((int maj, int min)); |