summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorphk <phk@FreeBSD.org>2001-05-26 08:27:58 +0000
committerphk <phk@FreeBSD.org>2001-05-26 08:27:58 +0000
commit2072a71f0e5186928f3cb8cfac61fe8199029442 (patch)
treeb40e6ace9e559eda88dc8e88344909bffdde59e4
parent32df247d021a07cb6a2425587a871d41f24660e6 (diff)
downloadFreeBSD-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.c2
-rw-r--r--sys/kern/kern_conf.c31
-rw-r--r--sys/kern/subr_disk.c21
-rw-r--r--sys/kern/subr_disklabel.c2
-rw-r--r--sys/kern/subr_diskmbr.c17
-rw-r--r--sys/kern/subr_diskslice.c15
-rw-r--r--sys/sys/conf.h6
-rw-r--r--sys/sys/linedisc.h6
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));
OpenPOWER on IntegriCloud