[Oops, forgot to commit this together with things that depend on it.]
First attempt at creating devfs entries for sliced devices. Doesn't quite work yet, so the heart of it is disabled. Added bdev and cdev args to dsopen(). Create devfs entries in dsopen() and (unsuccessfully) attempt to make them go away at the right times. DEVFS is #undefed at the start so that this shouldn't cause problems.
This commit is contained in:
parent
5be35af9cd
commit
f5b11add34
@ -43,11 +43,15 @@
|
||||
* from: wd.c,v 1.55 1994/10/22 01:57:12 phk Exp $
|
||||
* from: @(#)ufs_disksubr.c 7.16 (Berkeley) 5/4/91
|
||||
* from: ufs_disksubr.c,v 1.8 1994/06/07 01:21:39 phk Exp $
|
||||
* $Id: subr_diskslice.c,v 1.16 1996/01/07 22:39:06 phk Exp $
|
||||
* $Id: subr_diskslice.c,v 1.17 1996/01/16 18:11:24 phk Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/buf.h>
|
||||
#undef DEVFS /* XXX */
|
||||
#ifdef DEVFS
|
||||
#include <sys/devfsext.h>
|
||||
#endif
|
||||
#include <sys/disklabel.h>
|
||||
#include <sys/diskslice.h>
|
||||
#include <sys/dkbad.h>
|
||||
@ -70,12 +74,17 @@ static volatile bool_t ds_debug;
|
||||
static void dsiodone __P((struct buf *bp));
|
||||
static char *fixlabel __P((char *sname, struct diskslice *sp,
|
||||
struct disklabel *lp, int writeflag));
|
||||
static void free_label __P((struct diskslices *ssp, int slice));
|
||||
static void partition_info __P((char *sname, int part, struct partition *pp));
|
||||
static void slice_info __P((char *sname, struct diskslice *sp));
|
||||
static void set_ds_bad __P((struct diskslices *ssp, int slice,
|
||||
struct dkbad_intern *btp));
|
||||
static void set_ds_label __P((struct diskslices *ssp, int slice,
|
||||
struct disklabel *lp));
|
||||
#ifdef DEVFS
|
||||
static void set_ds_labeldevs __P((char *dname, dev_t dev,
|
||||
struct diskslices *ssp));
|
||||
#endif
|
||||
static void set_ds_wlabel __P((struct diskslices *ssp, int slice,
|
||||
int wlabel));
|
||||
|
||||
@ -253,6 +262,9 @@ void
|
||||
dsgone(sspp)
|
||||
struct diskslices **sspp;
|
||||
{
|
||||
#ifdef DEVFS
|
||||
int part;
|
||||
#endif
|
||||
int slice;
|
||||
struct diskslice *sp;
|
||||
struct diskslices *ssp;
|
||||
@ -263,10 +275,13 @@ dsgone(sspp)
|
||||
free(sp->ds_bad, M_DEVBUF);
|
||||
set_ds_bad(ssp, slice, (struct dkbad_intern *)NULL);
|
||||
}
|
||||
if (sp->ds_label != NULL) {
|
||||
free(sp->ds_label, M_DEVBUF);
|
||||
set_ds_label(ssp, slice, (struct disklabel *)NULL);
|
||||
}
|
||||
#ifdef DEVFS
|
||||
if (sp->ds_bdev != NULL)
|
||||
devfs_remove_dev(sp->ds_bdev);
|
||||
if (sp->ds_cdev != NULL)
|
||||
devfs_remove_dev(sp->ds_cdev);
|
||||
#endif
|
||||
free_label(ssp, slice);
|
||||
}
|
||||
free(ssp, M_DEVBUF);
|
||||
*sspp = NULL;
|
||||
@ -362,9 +377,11 @@ dsioctl(dname, dev, cmd, data, flags, sspp, strat, setgeom)
|
||||
free(lp, M_DEVBUF);
|
||||
return (error);
|
||||
}
|
||||
if (sp->ds_label != NULL)
|
||||
free(sp->ds_label, M_DEVBUF);
|
||||
free_label(ssp, slice);
|
||||
set_ds_label(ssp, slice, lp);
|
||||
#ifdef DEVFS
|
||||
set_ds_labeldevs(dname, dev, ssp);
|
||||
#endif
|
||||
return (0);
|
||||
|
||||
case DIOCSYNCSLICEINFO:
|
||||
@ -393,7 +410,8 @@ dsioctl(dname, dev, cmd, data, flags, sspp, strat, setgeom)
|
||||
error = dsopen(dname, dev,
|
||||
ssp->dss_slices[WHOLE_DISK_SLICE].ds_copenmask
|
||||
& (1 << RAW_PART) ? S_IFCHR : S_IFBLK,
|
||||
sspp, lp, strat, setgeom);
|
||||
sspp, lp, strat, setgeom, ssp->dss_bdevsw,
|
||||
ssp->dss_cdevsw);
|
||||
if (error != 0) {
|
||||
free(lp, M_DEVBUF);
|
||||
*sspp = ssp;
|
||||
@ -417,9 +435,12 @@ dsioctl(dname, dev, cmd, data, flags, sspp, strat, setgeom)
|
||||
dkmodslice(dkmodpart(dev, part),
|
||||
slice),
|
||||
S_IFBLK, sspp, lp, strat,
|
||||
setgeom);
|
||||
setgeom, ssp->dss_bdevsw,
|
||||
ssp->dss_cdevsw);
|
||||
if (error != 0) {
|
||||
/* XXX should free devfs toks. */
|
||||
free(lp, M_DEVBUF);
|
||||
/* XXX should restore devfs toks. */
|
||||
*sspp = ssp;
|
||||
return (EBUSY);
|
||||
}
|
||||
@ -432,15 +453,19 @@ dsioctl(dname, dev, cmd, data, flags, sspp, strat, setgeom)
|
||||
dkmodslice(dkmodpart(dev, part),
|
||||
slice),
|
||||
S_IFCHR, sspp, lp, strat,
|
||||
setgeom);
|
||||
setgeom, ssp->dss_bdevsw,
|
||||
ssp->dss_cdevsw);
|
||||
if (error != 0) {
|
||||
/* XXX should free devfs toks. */
|
||||
free(lp, M_DEVBUF);
|
||||
/* XXX should restore devfs toks. */
|
||||
*sspp = ssp;
|
||||
return (EBUSY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* XXX devfs tokens? */
|
||||
free(lp, M_DEVBUF);
|
||||
dsgone(&ssp);
|
||||
return (0);
|
||||
@ -542,7 +567,7 @@ dsname(dname, unit, slice, part, partname)
|
||||
* strategy routine must be special to allow activity.
|
||||
*/
|
||||
int
|
||||
dsopen(dname, dev, mode, sspp, lp, strat, setgeom)
|
||||
dsopen(dname, dev, mode, sspp, lp, strat, setgeom, bdevsw, cdevsw)
|
||||
char *dname;
|
||||
dev_t dev;
|
||||
int mode;
|
||||
@ -550,11 +575,19 @@ dsopen(dname, dev, mode, sspp, lp, strat, setgeom)
|
||||
struct disklabel *lp;
|
||||
d_strategy_t *strat;
|
||||
ds_setgeom_t *setgeom;
|
||||
struct bdevsw *bdevsw;
|
||||
struct cdevsw *cdevsw;
|
||||
{
|
||||
#ifdef DEVFS
|
||||
char devname[64];
|
||||
#endif
|
||||
int error;
|
||||
struct disklabel *lp1;
|
||||
char *msg;
|
||||
u_char mask;
|
||||
#ifdef DEVFS
|
||||
int mynor;
|
||||
#endif
|
||||
bool_t need_init;
|
||||
int part;
|
||||
char partname[2];
|
||||
@ -582,6 +615,10 @@ dsopen(dname, dev, mode, sspp, lp, strat, setgeom)
|
||||
lp->d_npartitions = RAW_PART + 1;
|
||||
lp->d_partitions[RAW_PART].p_size = lp->d_secperunit;
|
||||
ssp = *sspp;
|
||||
#ifdef DEVFS
|
||||
ssp->dss_bdevsw = bdevsw;
|
||||
ssp->dss_cdevsw = cdevsw;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* If there are no real slices, then make the compatiblity
|
||||
@ -624,6 +661,17 @@ dsopen(dname, dev, mode, sspp, lp, strat, setgeom)
|
||||
sp = &ssp->dss_slices[slice];
|
||||
part = dkpart(dev);
|
||||
unit = dkunit(dev);
|
||||
#ifdef DEVFS
|
||||
if (slice >= BASE_SLICE && sp->ds_bdev == NULL && sp->ds_size != 0) {
|
||||
mynor = minor(dkmodpart(dev, RAW_PART));
|
||||
sprintf(devname, "r%s",
|
||||
dsname(dname, unit, slice, RAW_PART, partname));
|
||||
sp->ds_bdev = devfs_add_devsw("/", devname + 1, bdevsw,
|
||||
mynor, DV_BLK, 0, 0, 0640);
|
||||
sp->ds_cdev = devfs_add_devsw("/", devname, cdevsw,
|
||||
mynor, DV_CHR, 0, 0, 0640);
|
||||
}
|
||||
#endif
|
||||
if (sp->ds_label == NULL) {
|
||||
set_ds_wlabel(ssp, slice, TRUE); /* XXX invert */
|
||||
lp1 = malloc(sizeof *lp1, M_DEVBUF, M_WAITOK);
|
||||
@ -673,6 +721,9 @@ dsopen(dname, dev, mode, sspp, lp, strat, setgeom)
|
||||
}
|
||||
}
|
||||
set_ds_label(ssp, slice, lp);
|
||||
#ifdef DEVFS
|
||||
set_ds_labeldevs(dname, dev, ssp);
|
||||
#endif
|
||||
set_ds_wlabel(ssp, slice, FALSE);
|
||||
}
|
||||
if (part != RAW_PART
|
||||
@ -720,6 +771,31 @@ dssize(dev, sspp, dopen, dclose)
|
||||
return ((int)lp->d_partitions[part].p_size);
|
||||
}
|
||||
|
||||
static void
|
||||
free_label(ssp, slice)
|
||||
struct diskslices *ssp;
|
||||
int slice;
|
||||
{
|
||||
struct disklabel *lp;
|
||||
int part;
|
||||
struct diskslice *sp;
|
||||
|
||||
sp = &ssp->dss_slices[slice];
|
||||
if (sp->ds_label == NULL)
|
||||
return;
|
||||
lp = sp->ds_label;
|
||||
#ifdef DEVFS
|
||||
for (part = 0; part < lp->d_npartitions; part++) {
|
||||
if (sp->ds_bdevs[part] != NULL)
|
||||
devfs_remove_dev(sp->ds_bdevs[part]);
|
||||
if (sp->ds_cdevs[part] != NULL)
|
||||
devfs_remove_dev(sp->ds_cdevs[part]);
|
||||
}
|
||||
#endif
|
||||
free(lp, M_DEVBUF);
|
||||
set_ds_label(ssp, slice, (struct disklabel *)NULL);
|
||||
}
|
||||
|
||||
static char *
|
||||
fixlabel(sname, sp, lp, writeflag)
|
||||
char *sname;
|
||||
@ -858,6 +934,52 @@ set_ds_label(ssp, slice, lp)
|
||||
ssp->dss_slices[COMPATIBILITY_SLICE].ds_label = lp;
|
||||
}
|
||||
|
||||
#ifdef DEVFS
|
||||
static void
|
||||
set_ds_labeldevs(dname, dev, ssp)
|
||||
char *dname;
|
||||
dev_t dev;
|
||||
struct diskslices *ssp;
|
||||
{
|
||||
char devname[64];
|
||||
struct disklabel *lp;
|
||||
int mynor;
|
||||
int part;
|
||||
char partname[2];
|
||||
struct partition *pp;
|
||||
int slice;
|
||||
struct diskslice *sp;
|
||||
|
||||
slice = dkslice(dev);
|
||||
sp = &ssp->dss_slices[slice];
|
||||
if (sp->ds_size == 0)
|
||||
return;
|
||||
lp = sp->ds_label;
|
||||
for (part = 0; part < lp->d_npartitions; part++) {
|
||||
pp = &lp->d_partitions[part];
|
||||
if (pp->p_size == 0)
|
||||
continue;
|
||||
sprintf(devname, "r%s%s",
|
||||
dsname(dname, dkunit(dev), slice, part, partname),
|
||||
partname);
|
||||
if (part == RAW_PART && sp->ds_bdev != NULL) {
|
||||
sp->ds_bdevs[part] =
|
||||
dev_link("/", devname + 1, sp->ds_bdev);
|
||||
sp->ds_cdevs[part] =
|
||||
dev_link("/", devname, sp->ds_cdev);
|
||||
} else {
|
||||
mynor = minor(dkmodpart(dev, part));
|
||||
sp->ds_bdevs[part] =
|
||||
devfs_add_devsw("/", devname+1, ssp->dss_bdevsw,
|
||||
mynor, DV_BLK, 0, 0, 0640);
|
||||
sp->ds_cdevs[part] =
|
||||
devfs_add_devsw("/", devname, ssp->dss_cdevsw,
|
||||
mynor, DV_CHR, 0, 0, 0640);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* DEVFS */
|
||||
|
||||
static void
|
||||
set_ds_wlabel(ssp, slice, wlabel)
|
||||
struct diskslices *ssp;
|
||||
|
Loading…
Reference in New Issue
Block a user