mirror of
https://git.FreeBSD.org/src.git
synced 2025-01-17 15:27:36 +00:00
Add compatibility cruft.
Slice 0 is now for the first BSD slice. The first BSD slice is the first DOSpartition with id 0xa5 or the whole disk if their are no DOSpartitions (except the latter is not yet implemented). Existing partitions on it work the same as in 2.0 except the 'd' partition is no longer special and partitions are relative to the skice. Slice 1 is now for the whole disk and gets a read-only label describing the disk. Previously, slice 0 was for the whole disk and there was no label on it. Slices 2-31 are for DOSpartitions. Slice 0 is an alias for one of these if there is a BSD slice. Previously, slices 1-31 were for DOSpartitions. diskslice_machdep.c: Expand whole disk slice to include all DOSpartitions. More work is required for >1024 cylinders and to rewrite the label iff the driver is unsure about the geometry. subr_diskslice.c: New function dsisopen() to help handle media changes.
This commit is contained in:
parent
2987d72f4a
commit
7a867ed547
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=6507
@ -35,7 +35,7 @@
|
||||
*
|
||||
* 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$
|
||||
* $Id: diskslice_machdep.c,v 1.3 1995/01/23 02:31:53 phk Exp $
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
@ -59,6 +59,7 @@ dsinit(dname, dev, strat, lp, sspp)
|
||||
struct dos_partition *dp;
|
||||
struct dos_partition *dp0;
|
||||
int error;
|
||||
int max_ncyls;
|
||||
int max_nsectors;
|
||||
int max_ntracks;
|
||||
u_long secpercyl;
|
||||
@ -67,22 +68,19 @@ dsinit(dname, dev, strat, lp, sspp)
|
||||
struct diskslices *ssp;
|
||||
|
||||
/*
|
||||
* Free old slices "struct", if any, and allocate a dummy new one.
|
||||
* Allocate a dummy slices "struct" and initialize it to contain
|
||||
* only an empty compatibility slice (pointing to itself) and a
|
||||
* whole disk slice (which may be a dummy if the label is a dummy).
|
||||
* If there is an error, then these slices become the only slices.
|
||||
*/
|
||||
if (*sspp != NULL)
|
||||
free(*sspp, M_DEVBUF);
|
||||
ssp = malloc(offsetof(struct diskslices, dss_slices) + sizeof(*sp),
|
||||
M_DEVBUF, M_WAITOK);
|
||||
ssp = malloc(offsetof(struct diskslices, dss_slices)
|
||||
+ BASE_SLICE * sizeof *sp, M_DEVBUF, M_WAITOK);
|
||||
*sspp = ssp;
|
||||
|
||||
/*
|
||||
* Initialize dummy slice. If there is an error, this becomes the
|
||||
* only slice, and no more restrictive than the (dummy) label.
|
||||
*/
|
||||
ssp->dss_first_bsd_slice = COMPATIBILITY_SLICE;
|
||||
ssp->dss_nslices = BASE_SLICE;
|
||||
sp = &ssp->dss_slices[0];
|
||||
bzero(sp, sizeof *sp);
|
||||
sp->ds_size = lp->d_secperunit;
|
||||
ssp->dss_nslices = 1;
|
||||
bzero(sp, BASE_SLICE * sizeof *sp);
|
||||
sp[WHOLE_DISK_SLICE].ds_size = lp->d_secperunit;
|
||||
|
||||
/* Read master boot record. */
|
||||
bp = geteblk((int)lp->d_secsize);
|
||||
@ -109,6 +107,7 @@ dsinit(dname, dev, strat, lp, sspp)
|
||||
* Perhaps skip entries with 0 size.
|
||||
* Perhaps only look at entries of type DOSPTYP_386BSD.
|
||||
*/
|
||||
max_ncyls = 0;
|
||||
max_nsectors = 0;
|
||||
max_ntracks = 0;
|
||||
dp0 = (struct dos_partition *)(cp + DOSPARTOFF);
|
||||
@ -116,6 +115,9 @@ dsinit(dname, dev, strat, lp, sspp)
|
||||
int nsectors;
|
||||
int ntracks;
|
||||
|
||||
max_ncyls = DPCYL(dp->dp_ecyl, dp->dp_esect);
|
||||
if (max_ncyls < max_ncyls)
|
||||
max_ncyls = max_ncyls;
|
||||
nsectors = DPSECT(dp->dp_esect);
|
||||
if (max_nsectors < nsectors)
|
||||
max_nsectors = nsectors;
|
||||
@ -129,7 +131,7 @@ dsinit(dname, dev, strat, lp, sspp)
|
||||
* TODO:
|
||||
* As above.
|
||||
* Check for overlaps.
|
||||
* Check or adjust against d_ncylinders and d_secperunit.
|
||||
* Check against d_secperunit if the latter is reliable.
|
||||
*/
|
||||
error = 0;
|
||||
secpercyl = max_nsectors * max_ntracks;
|
||||
@ -169,39 +171,61 @@ dsinit(dname, dev, strat, lp, sspp)
|
||||
|
||||
/*
|
||||
* We're not handling extended partitions yet, so there are always
|
||||
* 1 + NDOSPART slices.
|
||||
* BASE_SLICE + NDOSPART slices.
|
||||
*/
|
||||
if (dkslice(dev) >= 1 + NDOSPART) {
|
||||
if (dkslice(dev) >= BASE_SLICE + NDOSPART) {
|
||||
error = ENXIO;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/*
|
||||
* Accept the DOS partition table.
|
||||
* Free dummy slices "struct" and allocate a real new one.
|
||||
* First adjust the label (we have been careful not to change it
|
||||
* before we can guarantee success).
|
||||
*/
|
||||
free(ssp, M_DEVBUF);
|
||||
ssp = malloc(offsetof(struct diskslices, dss_slices)
|
||||
+ (1 + NDOSPART) * sizeof(*sp), M_DEVBUF, M_WAITOK);
|
||||
*sspp = ssp;
|
||||
sp = &ssp->dss_slices[0];
|
||||
bzero(sp, (1 + NDOSPART) * sizeof *sp);
|
||||
sp->ds_size = lp->d_secperunit;
|
||||
sp++;
|
||||
for (dp = dp0, slice = 1; slice <= NDOSPART; dp++, slice++, sp++) {
|
||||
sp->ds_offset = dp->dp_start;
|
||||
sp->ds_size = dp->dp_size;
|
||||
}
|
||||
ssp->dss_nslices = 1 + NDOSPART;
|
||||
if (max_nsectors != 0) {
|
||||
if (secpercyl != 0) {
|
||||
u_long secperunit;
|
||||
|
||||
lp->d_nsectors = max_nsectors;
|
||||
lp->d_ntracks = max_ntracks;
|
||||
lp->d_secpercyl = secpercyl;
|
||||
secperunit = secpercyl * max_ncyls;
|
||||
if (lp->d_secperunit < secperunit)
|
||||
lp->d_secperunit = secperunit;
|
||||
}
|
||||
|
||||
/*
|
||||
* Free the dummy slices "struct" and allocate a real new one.
|
||||
* Initialize special slices as above.
|
||||
*/
|
||||
free(ssp, M_DEVBUF);
|
||||
ssp = malloc(offsetof(struct diskslices, dss_slices)
|
||||
+ (BASE_SLICE + NDOSPART) * sizeof *sp,
|
||||
M_DEVBUF, M_WAITOK);
|
||||
*sspp = ssp;
|
||||
ssp->dss_first_bsd_slice = COMPATIBILITY_SLICE;
|
||||
ssp->dss_nslices = BASE_SLICE + NDOSPART;
|
||||
sp = &ssp->dss_slices[0];
|
||||
bzero(sp, (BASE_SLICE + NDOSPART) * sizeof *sp);
|
||||
sp[WHOLE_DISK_SLICE].ds_size = lp->d_secperunit;
|
||||
|
||||
/* Initialize normal slices. */
|
||||
sp += BASE_SLICE;
|
||||
for (dp = dp0, slice = 1; slice <= NDOSPART; dp++, slice++, sp++) {
|
||||
if (dp->dp_typ == DOSPTYP_386BSD
|
||||
&& ssp->dss_first_bsd_slice == COMPATIBILITY_SLICE) {
|
||||
ssp->dss_first_bsd_slice = BASE_SLICE + slice - 1;
|
||||
ssp->dss_slices[COMPATIBILITY_SLICE].ds_offset
|
||||
= dp->dp_start;
|
||||
ssp->dss_slices[COMPATIBILITY_SLICE].ds_size
|
||||
= dp->dp_size;
|
||||
}
|
||||
sp->ds_offset = dp->dp_start;
|
||||
sp->ds_size = dp->dp_size;
|
||||
#if 0
|
||||
lp->d_secperunit = what?;
|
||||
lp->d_subtype |= (lp->d_subtype & 3) + (slice - 1) | DSTYPE_INDOSPART;
|
||||
#endif
|
||||
}
|
||||
|
||||
done:
|
||||
bp->b_flags = B_INVAL | B_AGE;
|
||||
|
@ -35,7 +35,7 @@
|
||||
*
|
||||
* 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$
|
||||
* $Id: diskslice_machdep.c,v 1.3 1995/01/23 02:31:53 phk Exp $
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
@ -59,6 +59,7 @@ dsinit(dname, dev, strat, lp, sspp)
|
||||
struct dos_partition *dp;
|
||||
struct dos_partition *dp0;
|
||||
int error;
|
||||
int max_ncyls;
|
||||
int max_nsectors;
|
||||
int max_ntracks;
|
||||
u_long secpercyl;
|
||||
@ -67,22 +68,19 @@ dsinit(dname, dev, strat, lp, sspp)
|
||||
struct diskslices *ssp;
|
||||
|
||||
/*
|
||||
* Free old slices "struct", if any, and allocate a dummy new one.
|
||||
* Allocate a dummy slices "struct" and initialize it to contain
|
||||
* only an empty compatibility slice (pointing to itself) and a
|
||||
* whole disk slice (which may be a dummy if the label is a dummy).
|
||||
* If there is an error, then these slices become the only slices.
|
||||
*/
|
||||
if (*sspp != NULL)
|
||||
free(*sspp, M_DEVBUF);
|
||||
ssp = malloc(offsetof(struct diskslices, dss_slices) + sizeof(*sp),
|
||||
M_DEVBUF, M_WAITOK);
|
||||
ssp = malloc(offsetof(struct diskslices, dss_slices)
|
||||
+ BASE_SLICE * sizeof *sp, M_DEVBUF, M_WAITOK);
|
||||
*sspp = ssp;
|
||||
|
||||
/*
|
||||
* Initialize dummy slice. If there is an error, this becomes the
|
||||
* only slice, and no more restrictive than the (dummy) label.
|
||||
*/
|
||||
ssp->dss_first_bsd_slice = COMPATIBILITY_SLICE;
|
||||
ssp->dss_nslices = BASE_SLICE;
|
||||
sp = &ssp->dss_slices[0];
|
||||
bzero(sp, sizeof *sp);
|
||||
sp->ds_size = lp->d_secperunit;
|
||||
ssp->dss_nslices = 1;
|
||||
bzero(sp, BASE_SLICE * sizeof *sp);
|
||||
sp[WHOLE_DISK_SLICE].ds_size = lp->d_secperunit;
|
||||
|
||||
/* Read master boot record. */
|
||||
bp = geteblk((int)lp->d_secsize);
|
||||
@ -109,6 +107,7 @@ dsinit(dname, dev, strat, lp, sspp)
|
||||
* Perhaps skip entries with 0 size.
|
||||
* Perhaps only look at entries of type DOSPTYP_386BSD.
|
||||
*/
|
||||
max_ncyls = 0;
|
||||
max_nsectors = 0;
|
||||
max_ntracks = 0;
|
||||
dp0 = (struct dos_partition *)(cp + DOSPARTOFF);
|
||||
@ -116,6 +115,9 @@ dsinit(dname, dev, strat, lp, sspp)
|
||||
int nsectors;
|
||||
int ntracks;
|
||||
|
||||
max_ncyls = DPCYL(dp->dp_ecyl, dp->dp_esect);
|
||||
if (max_ncyls < max_ncyls)
|
||||
max_ncyls = max_ncyls;
|
||||
nsectors = DPSECT(dp->dp_esect);
|
||||
if (max_nsectors < nsectors)
|
||||
max_nsectors = nsectors;
|
||||
@ -129,7 +131,7 @@ dsinit(dname, dev, strat, lp, sspp)
|
||||
* TODO:
|
||||
* As above.
|
||||
* Check for overlaps.
|
||||
* Check or adjust against d_ncylinders and d_secperunit.
|
||||
* Check against d_secperunit if the latter is reliable.
|
||||
*/
|
||||
error = 0;
|
||||
secpercyl = max_nsectors * max_ntracks;
|
||||
@ -169,39 +171,61 @@ dsinit(dname, dev, strat, lp, sspp)
|
||||
|
||||
/*
|
||||
* We're not handling extended partitions yet, so there are always
|
||||
* 1 + NDOSPART slices.
|
||||
* BASE_SLICE + NDOSPART slices.
|
||||
*/
|
||||
if (dkslice(dev) >= 1 + NDOSPART) {
|
||||
if (dkslice(dev) >= BASE_SLICE + NDOSPART) {
|
||||
error = ENXIO;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/*
|
||||
* Accept the DOS partition table.
|
||||
* Free dummy slices "struct" and allocate a real new one.
|
||||
* First adjust the label (we have been careful not to change it
|
||||
* before we can guarantee success).
|
||||
*/
|
||||
free(ssp, M_DEVBUF);
|
||||
ssp = malloc(offsetof(struct diskslices, dss_slices)
|
||||
+ (1 + NDOSPART) * sizeof(*sp), M_DEVBUF, M_WAITOK);
|
||||
*sspp = ssp;
|
||||
sp = &ssp->dss_slices[0];
|
||||
bzero(sp, (1 + NDOSPART) * sizeof *sp);
|
||||
sp->ds_size = lp->d_secperunit;
|
||||
sp++;
|
||||
for (dp = dp0, slice = 1; slice <= NDOSPART; dp++, slice++, sp++) {
|
||||
sp->ds_offset = dp->dp_start;
|
||||
sp->ds_size = dp->dp_size;
|
||||
}
|
||||
ssp->dss_nslices = 1 + NDOSPART;
|
||||
if (max_nsectors != 0) {
|
||||
if (secpercyl != 0) {
|
||||
u_long secperunit;
|
||||
|
||||
lp->d_nsectors = max_nsectors;
|
||||
lp->d_ntracks = max_ntracks;
|
||||
lp->d_secpercyl = secpercyl;
|
||||
secperunit = secpercyl * max_ncyls;
|
||||
if (lp->d_secperunit < secperunit)
|
||||
lp->d_secperunit = secperunit;
|
||||
}
|
||||
|
||||
/*
|
||||
* Free the dummy slices "struct" and allocate a real new one.
|
||||
* Initialize special slices as above.
|
||||
*/
|
||||
free(ssp, M_DEVBUF);
|
||||
ssp = malloc(offsetof(struct diskslices, dss_slices)
|
||||
+ (BASE_SLICE + NDOSPART) * sizeof *sp,
|
||||
M_DEVBUF, M_WAITOK);
|
||||
*sspp = ssp;
|
||||
ssp->dss_first_bsd_slice = COMPATIBILITY_SLICE;
|
||||
ssp->dss_nslices = BASE_SLICE + NDOSPART;
|
||||
sp = &ssp->dss_slices[0];
|
||||
bzero(sp, (BASE_SLICE + NDOSPART) * sizeof *sp);
|
||||
sp[WHOLE_DISK_SLICE].ds_size = lp->d_secperunit;
|
||||
|
||||
/* Initialize normal slices. */
|
||||
sp += BASE_SLICE;
|
||||
for (dp = dp0, slice = 1; slice <= NDOSPART; dp++, slice++, sp++) {
|
||||
if (dp->dp_typ == DOSPTYP_386BSD
|
||||
&& ssp->dss_first_bsd_slice == COMPATIBILITY_SLICE) {
|
||||
ssp->dss_first_bsd_slice = BASE_SLICE + slice - 1;
|
||||
ssp->dss_slices[COMPATIBILITY_SLICE].ds_offset
|
||||
= dp->dp_start;
|
||||
ssp->dss_slices[COMPATIBILITY_SLICE].ds_size
|
||||
= dp->dp_size;
|
||||
}
|
||||
sp->ds_offset = dp->dp_start;
|
||||
sp->ds_size = dp->dp_size;
|
||||
#if 0
|
||||
lp->d_secperunit = what?;
|
||||
lp->d_subtype |= (lp->d_subtype & 3) + (slice - 1) | DSTYPE_INDOSPART;
|
||||
#endif
|
||||
}
|
||||
|
||||
done:
|
||||
bp->b_flags = B_INVAL | B_AGE;
|
||||
|
@ -43,7 +43,7 @@
|
||||
* 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$
|
||||
* $Id: subr_diskslice.c,v 1.3 1995/01/31 04:33:41 phk Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
@ -70,6 +70,12 @@ static void partition_info __P((char *dname, int unit, int slice,
|
||||
int part, struct partition *pp));
|
||||
static void slice_info __P((char *dname, int unit, int slice,
|
||||
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));
|
||||
static void set_ds_wlabel __P((struct diskslices *ssp, int slice,
|
||||
int wlabel));
|
||||
|
||||
/*
|
||||
* Determine the size of the transfer, and make sure it is
|
||||
@ -104,7 +110,7 @@ dscheck(bp, ssp)
|
||||
maxsz = sp->ds_size;
|
||||
} else {
|
||||
labelsect = lp->d_partitions[LABEL_PART].p_offset;
|
||||
if (labelsect != 0) Debugger("");
|
||||
if (labelsect != 0) Debugger("labelsect != 0 in dscheck()");
|
||||
pp = &lp->d_partitions[dkpart(bp->b_dev)];
|
||||
blkno = pp->p_offset + bp->b_blkno;
|
||||
maxsz = pp->p_size;
|
||||
@ -113,7 +119,7 @@ if (labelsect != 0) Debugger("");
|
||||
|
||||
newblkno = transbad144(sp->ds_bad, blkno);
|
||||
if (newblkno != blkno)
|
||||
printf("bad block %lu -> %lu\n",
|
||||
printf("should map bad block %lu -> %lu\n",
|
||||
blkno, newblkno);
|
||||
}
|
||||
}
|
||||
@ -202,13 +208,14 @@ dsgone(sspp)
|
||||
sp = &ssp->dss_slices[slice];
|
||||
if (sp->ds_bad != NULL) {
|
||||
free(sp->ds_bad, M_DEVBUF);
|
||||
sp->ds_bad = NULL;
|
||||
set_ds_bad(ssp, slice, (struct dkbad_intern *)NULL);
|
||||
}
|
||||
if (sp->ds_label != NULL) {
|
||||
free(sp->ds_label, M_DEVBUF);
|
||||
sp->ds_label = NULL;
|
||||
set_ds_label(ssp, slice, (struct disklabel *)NULL);
|
||||
}
|
||||
}
|
||||
free(ssp, M_DEVBUF);
|
||||
*sspp = NULL;
|
||||
}
|
||||
|
||||
@ -229,9 +236,11 @@ dsioctl(dev, cmd, data, flags, ssp, strat, setgeom)
|
||||
int error;
|
||||
struct disklabel *lp;
|
||||
int old_wlabel;
|
||||
int slice;
|
||||
struct diskslice *sp;
|
||||
|
||||
sp = &ssp->dss_slices[dkslice(dev)];
|
||||
slice = dkslice(dev);
|
||||
sp = &ssp->dss_slices[slice];
|
||||
lp = sp->ds_label;
|
||||
switch (cmd) {
|
||||
|
||||
@ -258,16 +267,20 @@ dsioctl(dev, cmd, data, flags, ssp, strat, setgeom)
|
||||
return (0);
|
||||
|
||||
case DIOCSBAD:
|
||||
if (slice == WHOLE_DISK_SLICE)
|
||||
return (ENODEV);
|
||||
if (!(flags & FWRITE))
|
||||
return (EBADF);
|
||||
if (lp == NULL)
|
||||
return (EINVAL);
|
||||
if (sp->ds_bad != NULL)
|
||||
free(sp->ds_bad, M_DEVBUF);
|
||||
sp->ds_bad = internbad144((struct dkbad *)data, lp);
|
||||
set_ds_bad(ssp, slice, internbad144((struct dkbad *)data, lp));
|
||||
return (0);
|
||||
|
||||
case DIOCSDINFO:
|
||||
if (slice == WHOLE_DISK_SLICE)
|
||||
return (ENODEV);
|
||||
if (!(flags & FWRITE))
|
||||
return (EBADF);
|
||||
lp = malloc(sizeof *lp, M_DEVBUF, M_WAITOK);
|
||||
@ -284,7 +297,7 @@ dsioctl(dev, cmd, data, flags, ssp, strat, setgeom)
|
||||
}
|
||||
if (sp->ds_label != NULL)
|
||||
free(sp->ds_label, M_DEVBUF);
|
||||
sp->ds_label = lp;
|
||||
set_ds_label(ssp, slice, lp);
|
||||
return (0);
|
||||
|
||||
case DIOCWDINFO:
|
||||
@ -297,15 +310,17 @@ dsioctl(dev, cmd, data, flags, ssp, strat, setgeom)
|
||||
* partition 0 in case that is used instead of dkpart(dev).
|
||||
*/
|
||||
old_wlabel = sp->ds_wlabel;
|
||||
sp->ds_wlabel = TRUE;
|
||||
set_ds_wlabel(ssp, slice, TRUE);
|
||||
error = correct_writedisklabel(dev, strat, sp->ds_label);
|
||||
sp->ds_wlabel = old_wlabel;
|
||||
set_ds_wlabel(ssp, slice, old_wlabel);
|
||||
return (error);
|
||||
|
||||
case DIOCWLABEL:
|
||||
if (slice == WHOLE_DISK_SLICE)
|
||||
return (ENODEV);
|
||||
if (!(flags & FWRITE))
|
||||
return (EBADF);
|
||||
sp->ds_wlabel = (*(int *)data != 0);
|
||||
set_ds_wlabel(ssp, slice, *(int *)data != 0);
|
||||
return (0);
|
||||
|
||||
default:
|
||||
@ -313,6 +328,21 @@ dsioctl(dev, cmd, data, flags, ssp, strat, setgeom)
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
dsisopen(ssp)
|
||||
struct diskslices *ssp;
|
||||
{
|
||||
int slice;
|
||||
struct diskslice *sp;
|
||||
|
||||
if (ssp == NULL)
|
||||
return (0);
|
||||
for (slice = 0; slice < ssp->dss_nslices; slice++)
|
||||
if (ssp->dss_slices[slice].ds_openmask)
|
||||
return (1);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* This should only be called when the unit is inactive and the strategy
|
||||
* routine should not allow it to become active unless we call it. Our
|
||||
@ -338,26 +368,20 @@ dsopen(dname, dev, mode, sspp, lp, strat, setgeom)
|
||||
struct diskslices *ssp;
|
||||
int unit;
|
||||
|
||||
need_init = TRUE;
|
||||
if (*sspp != NULL) {
|
||||
/*
|
||||
* XXX reinitialize the slice table unless there is an open
|
||||
* device on the unit. This should only be done if the media
|
||||
* has changed.
|
||||
*/
|
||||
for (slice = 0, ssp = *sspp; slice < ssp->dss_nslices; slice++)
|
||||
if (ssp->dss_slices[slice].ds_openmask) {
|
||||
need_init = FALSE;
|
||||
break;
|
||||
}
|
||||
if (need_init)
|
||||
dsgone(sspp);
|
||||
}
|
||||
/*
|
||||
* XXX reinitialize the slice table unless there is an open device
|
||||
* on the unit. This should only be done if the media has changed.
|
||||
*/
|
||||
need_init = !dsisopen(*sspp);
|
||||
if (*sspp != NULL && need_init)
|
||||
dsgone(sspp);
|
||||
if (need_init) {
|
||||
printf("dsinit\n");
|
||||
error = dsinit(dname, dev, strat, lp, sspp);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
lp->d_npartitions = RAW_PART + 1;
|
||||
lp->d_partitions[RAW_PART].p_size = lp->d_secperunit;
|
||||
if (setgeom != NULL) {
|
||||
error = setgeom(lp);
|
||||
if (error != 0)
|
||||
@ -365,6 +389,7 @@ dsopen(dname, dev, mode, sspp, lp, strat, setgeom)
|
||||
return (error);
|
||||
}
|
||||
}
|
||||
|
||||
ssp = *sspp;
|
||||
slice = dkslice(dev);
|
||||
if (slice >= ssp->dss_nslices)
|
||||
@ -372,12 +397,14 @@ dsopen(dname, dev, mode, sspp, lp, strat, setgeom)
|
||||
sp = &ssp->dss_slices[slice];
|
||||
part = dkpart(dev);
|
||||
unit = dkunit(dev);
|
||||
if (slice != WHOLE_DISK_SLICE && sp->ds_label == NULL) {
|
||||
if (sp->ds_label == NULL) {
|
||||
struct disklabel *lp1;
|
||||
|
||||
lp1 = malloc(sizeof *lp1, M_DEVBUF, M_WAITOK);
|
||||
*lp1 = *lp;
|
||||
lp = lp1;
|
||||
if (slice == WHOLE_DISK_SLICE)
|
||||
goto set;
|
||||
printf("readdisklabel\n");
|
||||
msg = correct_readdisklabel(dkmodpart(dev, RAW_PART), strat, lp);
|
||||
#if 0 /* XXX */
|
||||
@ -410,7 +437,7 @@ dsopen(dname, dev, mode, sspp, lp, strat, setgeom)
|
||||
goto out;
|
||||
return (EINVAL); /* XXX needs translation */
|
||||
}
|
||||
sp->ds_bad = internbad144(btp, lp);
|
||||
set_ds_bad(ssp, slice, internbad144(btp, lp));
|
||||
free(btp, M_DEVBUF);
|
||||
if (sp->ds_bad == NULL) {
|
||||
free(lp, M_DEVBUF);
|
||||
@ -419,8 +446,9 @@ dsopen(dname, dev, mode, sspp, lp, strat, setgeom)
|
||||
return (EINVAL); /* XXX needs translation */
|
||||
}
|
||||
}
|
||||
sp->ds_label = lp;
|
||||
sp->ds_wlabel = TRUE;
|
||||
set:
|
||||
set_ds_label(ssp, slice, lp);
|
||||
set_ds_wlabel(ssp, slice, FALSE);
|
||||
}
|
||||
if (part != RAW_PART
|
||||
&& (sp->ds_label == NULL || part >= sp->ds_label->d_npartitions))
|
||||
@ -520,6 +548,13 @@ partition_info(dname, unit, slice, part, pp)
|
||||
pp->p_offset, pp->p_offset + pp->p_size - 1, pp->p_size);
|
||||
}
|
||||
|
||||
/*
|
||||
* Most changes to ds_bad, ds_label and ds_wlabel are made using the
|
||||
* following functions to ensure coherency of the compatibility slice
|
||||
* with the first BSD slice. The openmask fields are _not_ shared and
|
||||
* the other fields (ds_offset and ds_size) aren't changed after they
|
||||
* are initialized.
|
||||
*/
|
||||
static void
|
||||
slice_info(dname, unit, slice, sp)
|
||||
char *dname;
|
||||
@ -531,3 +566,42 @@ slice_info(dname, unit, slice, sp)
|
||||
dname, unit, slice,
|
||||
sp->ds_offset, sp->ds_offset + sp->ds_size - 1, sp->ds_size);
|
||||
}
|
||||
|
||||
static void
|
||||
set_ds_bad(ssp, slice, btp)
|
||||
struct diskslices *ssp;
|
||||
int slice;
|
||||
struct dkbad_intern *btp;
|
||||
{
|
||||
ssp->dss_slices[slice].ds_bad = btp;
|
||||
if (slice == COMPATIBILITY_SLICE)
|
||||
ssp->dss_slices[ssp->dss_first_bsd_slice].ds_bad = btp;
|
||||
else if (slice == ssp->dss_first_bsd_slice)
|
||||
ssp->dss_slices[COMPATIBILITY_SLICE].ds_bad = btp;
|
||||
}
|
||||
|
||||
static void
|
||||
set_ds_label(ssp, slice, lp)
|
||||
struct diskslices *ssp;
|
||||
int slice;
|
||||
struct disklabel *lp;
|
||||
{
|
||||
ssp->dss_slices[slice].ds_label = lp;
|
||||
if (slice == COMPATIBILITY_SLICE)
|
||||
ssp->dss_slices[ssp->dss_first_bsd_slice].ds_label = lp;
|
||||
else if (slice == ssp->dss_first_bsd_slice)
|
||||
ssp->dss_slices[COMPATIBILITY_SLICE].ds_label = lp;
|
||||
}
|
||||
|
||||
static void
|
||||
set_ds_wlabel(ssp, slice, wlabel)
|
||||
struct diskslices *ssp;
|
||||
int slice;
|
||||
int wlabel;
|
||||
{
|
||||
ssp->dss_slices[slice].ds_wlabel = wlabel;
|
||||
if (slice == COMPATIBILITY_SLICE)
|
||||
ssp->dss_slices[ssp->dss_first_bsd_slice].ds_wlabel = wlabel;
|
||||
else if (slice == ssp->dss_first_bsd_slice)
|
||||
ssp->dss_slices[COMPATIBILITY_SLICE].ds_wlabel = wlabel;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user