summaryrefslogtreecommitdiffstats
path: root/sys/kern/subr_diskmbr.c
diff options
context:
space:
mode:
authorbde <bde@FreeBSD.org>1995-02-16 15:19:19 +0000
committerbde <bde@FreeBSD.org>1995-02-16 15:19:19 +0000
commit4e75b5962cb8132048272b1b7c4f3f11b158f40c (patch)
treebec48c07ddb7f0865796e61ebc793545078c01a5 /sys/kern/subr_diskmbr.c
parent83aff90f5e42f9f2a8cd80d917f144fa72f1d937 (diff)
downloadFreeBSD-src-4e75b5962cb8132048272b1b7c4f3f11b158f40c.zip
FreeBSD-src-4e75b5962cb8132048272b1b7c4f3f11b158f40c.tar.gz
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.
Diffstat (limited to 'sys/kern/subr_diskmbr.c')
-rw-r--r--sys/kern/subr_diskmbr.c84
1 files changed, 54 insertions, 30 deletions
diff --git a/sys/kern/subr_diskmbr.c b/sys/kern/subr_diskmbr.c
index 2d43fb3..3c35445 100644
--- a/sys/kern/subr_diskmbr.c
+++ b/sys/kern/subr_diskmbr.c
@@ -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).
+ */
+ 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)
- + (1 + NDOSPART) * sizeof(*sp), M_DEVBUF, M_WAITOK);
+ + (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, (1 + NDOSPART) * sizeof *sp);
- sp->ds_size = lp->d_secperunit;
- sp++;
+ 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;
- }
- ssp->dss_nslices = 1 + NDOSPART;
- if (max_nsectors != 0) {
- lp->d_nsectors = max_nsectors;
- lp->d_ntracks = max_ntracks;
- lp->d_secpercyl = secpercyl;
- }
#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;
OpenPOWER on IntegriCloud