summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorjkh <jkh@FreeBSD.org>1994-10-27 20:45:13 +0000
committerjkh <jkh@FreeBSD.org>1994-10-27 20:45:13 +0000
commit1ca2f392e18c355a8108c5c84aa5e4705aedc786 (patch)
tree0f822c63937b648594897abc7f741b0a112e7844 /sys
parent6cc6dda103dfdc45f437f7bccf591034663fd883 (diff)
downloadFreeBSD-src-1ca2f392e18c355a8108c5c84aa5e4705aedc786.zip
FreeBSD-src-1ca2f392e18c355a8108c5c84aa5e4705aedc786.tar.gz
Julian Elischer's disklabel fixes.
Diffstat (limited to 'sys')
-rw-r--r--sys/amd64/amd64/machdep.c3
-rw-r--r--sys/conf/files.i3863
-rw-r--r--sys/dev/fdc/fdc.c8
-rw-r--r--sys/dev/mcd/mcd.c3
-rw-r--r--sys/i386/conf/files.i3863
-rw-r--r--sys/i386/i386/machdep.c3
-rw-r--r--sys/i386/isa/fd.c8
-rw-r--r--sys/i386/isa/mcd.c3
-rw-r--r--sys/i386/isa/readMBR.c232
-rw-r--r--sys/i386/isa/wd.c27
-rw-r--r--sys/isa/fd.c8
-rw-r--r--sys/kern/subr_disklabel.c232
-rw-r--r--sys/scsi/cd.c6
-rw-r--r--sys/scsi/sd.c9
-rw-r--r--sys/sys/disklabel.h42
-rw-r--r--sys/sys/diskmbr.h42
-rw-r--r--sys/sys/diskpc98.h42
-rw-r--r--sys/ufs/ufs/ufs_disksubr.c232
-rw-r--r--sys/ufs/ufs/ufs_extern.h10
19 files changed, 687 insertions, 229 deletions
diff --git a/sys/amd64/amd64/machdep.c b/sys/amd64/amd64/machdep.c
index cfedceb..49dbd47 100644
--- a/sys/amd64/amd64/machdep.c
+++ b/sys/amd64/amd64/machdep.c
@@ -35,7 +35,7 @@
* SUCH DAMAGE.
*
* from: @(#)machdep.c 7.4 (Berkeley) 6/3/91
- * $Id: machdep.c,v 1.80 1994/10/25 08:58:33 davidg Exp $
+ * $Id: machdep.c,v 1.81 1994/10/26 18:35:02 jkh Exp $
*/
#include "npx.h"
@@ -1563,7 +1563,6 @@ Debugger(const char *msg)
#include <sys/disklabel.h>
#define b_cylin b_resid
-#define dkpart(dev) (minor(dev) & 7)
/*
* Determine the size of the transfer, and make sure it is
* within the boundaries of the partition. Adjust transfer
diff --git a/sys/conf/files.i386 b/sys/conf/files.i386
index 2e76e02..c0cdb8a 100644
--- a/sys/conf/files.i386
+++ b/sys/conf/files.i386
@@ -1,7 +1,7 @@
# This file tells config what files go into building a kernel,
# files marked standard are always included.
#
-# $Id: files.i386,v 1.54 1994/10/13 20:19:11 sos Exp $
+# $Id: files.i386,v 1.55 1994/10/26 19:19:12 jkh Exp $
#
i386/apm/apm.c optional apm device-driver
i386/apm/apm_setup.s optional apm
@@ -112,6 +112,7 @@ i386/isa/sound/uart6850.c optional snd device-driver
i386/isa/spkr.c optional speaker
i386/isa/tw.c optional tw device-driver
i386/isa/ultra14f.c optional uha device-driver
+i386/isa/readMBR.c standard
i386/isa/wd.c optional wd device-driver
i386/isa/wt.c optional wt device-driver
i386/isa/pcvt/pcvt_drv.c optional vt device-driver
diff --git a/sys/dev/fdc/fdc.c b/sys/dev/fdc/fdc.c
index a000acf..e06ac4a 100644
--- a/sys/dev/fdc/fdc.c
+++ b/sys/dev/fdc/fdc.c
@@ -40,7 +40,7 @@
* SUCH DAMAGE.
*
* from: @(#)fd.c 7.4 (Berkeley) 5/25/91
- * $Id: fd.c,v 1.36 1994/10/21 16:58:50 joerg Exp $
+ * $Id: fd.c,v 1.37 1994/10/23 21:27:12 wollman Exp $
*
*/
@@ -1522,7 +1522,7 @@ fdioctl(dev, cmd, addr, flag, p)
dl->d_secpercyl = fdt->size / fdt->tracks;
dl->d_type = DTYPE_FLOPPY;
- if (readdisklabel(dev, fdstrategy, dl, NULL, 0, 0) == NULL)
+ if (readdisklabel(dev, fdstrategy, dl, NULL, 0) == NULL)
error = 0;
else
error = EINVAL;
@@ -1550,11 +1550,11 @@ fdioctl(dev, cmd, addr, flag, p)
dl = (struct disklabel *)addr;
if ((error =
- setdisklabel ((struct disklabel *)buffer, dl, 0, NULL)))
+ setdisklabel ((struct disklabel *)buffer, dl, 0)))
break;
error = writedisklabel(dev, fdstrategy,
- (struct disklabel *)buffer, NULL);
+ (struct disklabel *)buffer);
break;
case FD_FORM:
diff --git a/sys/dev/mcd/mcd.c b/sys/dev/mcd/mcd.c
index e27f600..a6d4bbb 100644
--- a/sys/dev/mcd/mcd.c
+++ b/sys/dev/mcd/mcd.c
@@ -39,7 +39,7 @@
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: mcd.c,v 1.25 1994/09/14 20:28:25 ache Exp $
+ * $Id: mcd.c,v 1.26 1994/10/23 21:27:29 wollman Exp $
*/
static char COPYRIGHT[] = "mcd-driver (C)1993 by H.Veit & B.Moore";
@@ -483,7 +483,6 @@ MCD_TRACE("ioctl called 0x%x\n",cmd,0,0,0);
else {
return setdisklabel(&cd->dlabel,
(struct disklabel *) addr,
- 0,
0);
}
case DIOCWLABEL:
diff --git a/sys/i386/conf/files.i386 b/sys/i386/conf/files.i386
index 2e76e02..c0cdb8a 100644
--- a/sys/i386/conf/files.i386
+++ b/sys/i386/conf/files.i386
@@ -1,7 +1,7 @@
# This file tells config what files go into building a kernel,
# files marked standard are always included.
#
-# $Id: files.i386,v 1.54 1994/10/13 20:19:11 sos Exp $
+# $Id: files.i386,v 1.55 1994/10/26 19:19:12 jkh Exp $
#
i386/apm/apm.c optional apm device-driver
i386/apm/apm_setup.s optional apm
@@ -112,6 +112,7 @@ i386/isa/sound/uart6850.c optional snd device-driver
i386/isa/spkr.c optional speaker
i386/isa/tw.c optional tw device-driver
i386/isa/ultra14f.c optional uha device-driver
+i386/isa/readMBR.c standard
i386/isa/wd.c optional wd device-driver
i386/isa/wt.c optional wt device-driver
i386/isa/pcvt/pcvt_drv.c optional vt device-driver
diff --git a/sys/i386/i386/machdep.c b/sys/i386/i386/machdep.c
index cfedceb..49dbd47 100644
--- a/sys/i386/i386/machdep.c
+++ b/sys/i386/i386/machdep.c
@@ -35,7 +35,7 @@
* SUCH DAMAGE.
*
* from: @(#)machdep.c 7.4 (Berkeley) 6/3/91
- * $Id: machdep.c,v 1.80 1994/10/25 08:58:33 davidg Exp $
+ * $Id: machdep.c,v 1.81 1994/10/26 18:35:02 jkh Exp $
*/
#include "npx.h"
@@ -1563,7 +1563,6 @@ Debugger(const char *msg)
#include <sys/disklabel.h>
#define b_cylin b_resid
-#define dkpart(dev) (minor(dev) & 7)
/*
* Determine the size of the transfer, and make sure it is
* within the boundaries of the partition. Adjust transfer
diff --git a/sys/i386/isa/fd.c b/sys/i386/isa/fd.c
index a000acf..e06ac4a 100644
--- a/sys/i386/isa/fd.c
+++ b/sys/i386/isa/fd.c
@@ -40,7 +40,7 @@
* SUCH DAMAGE.
*
* from: @(#)fd.c 7.4 (Berkeley) 5/25/91
- * $Id: fd.c,v 1.36 1994/10/21 16:58:50 joerg Exp $
+ * $Id: fd.c,v 1.37 1994/10/23 21:27:12 wollman Exp $
*
*/
@@ -1522,7 +1522,7 @@ fdioctl(dev, cmd, addr, flag, p)
dl->d_secpercyl = fdt->size / fdt->tracks;
dl->d_type = DTYPE_FLOPPY;
- if (readdisklabel(dev, fdstrategy, dl, NULL, 0, 0) == NULL)
+ if (readdisklabel(dev, fdstrategy, dl, NULL, 0) == NULL)
error = 0;
else
error = EINVAL;
@@ -1550,11 +1550,11 @@ fdioctl(dev, cmd, addr, flag, p)
dl = (struct disklabel *)addr;
if ((error =
- setdisklabel ((struct disklabel *)buffer, dl, 0, NULL)))
+ setdisklabel ((struct disklabel *)buffer, dl, 0)))
break;
error = writedisklabel(dev, fdstrategy,
- (struct disklabel *)buffer, NULL);
+ (struct disklabel *)buffer);
break;
case FD_FORM:
diff --git a/sys/i386/isa/mcd.c b/sys/i386/isa/mcd.c
index e27f600..a6d4bbb 100644
--- a/sys/i386/isa/mcd.c
+++ b/sys/i386/isa/mcd.c
@@ -39,7 +39,7 @@
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: mcd.c,v 1.25 1994/09/14 20:28:25 ache Exp $
+ * $Id: mcd.c,v 1.26 1994/10/23 21:27:29 wollman Exp $
*/
static char COPYRIGHT[] = "mcd-driver (C)1993 by H.Veit & B.Moore";
@@ -483,7 +483,6 @@ MCD_TRACE("ioctl called 0x%x\n",cmd,0,0,0);
else {
return setdisklabel(&cd->dlabel,
(struct disklabel *) addr,
- 0,
0);
}
case DIOCWLABEL:
diff --git a/sys/i386/isa/readMBR.c b/sys/i386/isa/readMBR.c
new file mode 100644
index 0000000..4165d21
--- /dev/null
+++ b/sys/i386/isa/readMBR.c
@@ -0,0 +1,232 @@
+/*
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE WRITERS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE WRITERS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * written by julian elischer (julian@tfs.com)
+ *
+ * @(#)readMBR.c 8.5 (tfs) 1/21/94
+ * $Id: readMBR.c,v 1.5 1994/10/17 02:31:33 phk Exp $
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/buf.h>
+#include <sys/disklabel.h>
+
+#define b_cylinder b_resid
+
+/*
+ * Attempt to read a machine-type dependent Device partitioning table
+ * In this case a PC BIOS MBR.
+ * Destroys the original disklabel if it finds an MBR, so you'd better
+ * know what you're doing. It assumes that the label you've given it
+ * Is the one that controls the device, so that it can fiddle with it
+ * to make sure it's reading absolute sectors.
+ * On exit:
+ * Leaves the disklabel set up with the various partitions
+ * in the last 4 entries,
+ * the A partition pointing to the BSD part
+ * the C partition set as the BSD partition, (read the disklabel from there) and
+ * the D partition set as the whole disk for beating up
+ * will also give you a copy of the machine dependent table if you ask..
+ * returns 0 for success,
+ * On failure, restores the disklabel and returns a messages pointer.
+ */
+char *
+readMBRtolabel(dev, strat, lp, dp, cyl)
+ dev_t dev;
+ void (*strat)();
+ register struct disklabel *lp;
+ struct dos_partition *dp;
+ int *cyl;
+{
+ register struct buf *bp;
+ struct disklabel *dlp;
+ struct disklabel labelsave;
+ char *msg = NULL;
+ int i;
+ int pseudopart = 4; /* we fill in pseudoparts from e through h*/
+ int seenBSD = 0;
+
+ /*
+ * Save a copy of the disklabel in case we return with an error
+ */
+ bcopy(lp,&labelsave,sizeof(labelsave));
+
+ /*
+ * Set the disklabel to some useable partitions in case it's rubbish
+ */
+ if (lp->d_secperunit == 0)
+ lp->d_secperunit = 0x1fffffff;
+ lp->d_npartitions = 4;
+ for (i=0; i<MAXPARTITIONS; i++) {
+ lp->d_partitions[i].p_offset = 0;
+ lp->d_partitions[i].p_size = 0;
+ }
+ lp->d_partitions[RAWPART].p_size = DOSBBSECTOR + 1; /* start low */
+ strcpy(lp->d_packname,"MBR based label"); /* Watch the length ! */
+
+ /*
+ * Get a buffer and get ready to read the MBR
+ */
+ bp = geteblk((int)lp->d_secsize);
+ /* read master boot record */
+ bp->b_dev = makedev(major(dev), dkminor(dkunit(dev), RAWPART));
+ bp->b_blkno = DOSBBSECTOR;
+ bp->b_bcount = lp->d_secsize;
+ bp->b_flags = B_BUSY | B_READ;
+ bp->b_cylinder = DOSBBSECTOR / lp->d_secpercyl;
+ (*strat)(bp);
+
+ /* if successful, wander through dos partition table */
+ if ( biowait(bp)) {
+ msg = "dos partition I/O error";
+ goto bad;
+ } else {
+ /*
+ * If there seems to be BIOS bootblock and partition table
+ * in that block, then try interpret it, otherwise
+ * give up and use whatever we have synthesised so far
+ */
+ if ((*(bp->b_un.b_addr + 510) != (char) 0x55)
+ ||(*(bp->b_un.b_addr + 511) != (char) 0xaa)) {
+ msg = "Disk has no Fdisk partitions";
+ goto bad;
+ }
+
+ if(dp) { /* if they asked for a copy, give it to them */
+ bcopy(bp->b_un.b_addr + DOSPARTOFF, dp,
+ NDOSPART * sizeof(*dp));
+ }
+ dp = (struct dos_partition *)(bp->b_un.b_addr + DOSPARTOFF);
+ /*
+ * We have a DOS MBR..
+ * We set up the last 4 partitions in the
+ * disklabel to reflect the DOS partitions
+ * In case we never find a disklabel, in which
+ * case this information will be all we have
+ * but it might be all we need to access a DOS
+ * partition.
+ */
+ for (i = 0; i < NDOSPART; i++, dp++,pseudopart++) {
+
+ if (!dp->dp_size)
+ continue;
+ /*
+ * Set this DOS part into the disklabel
+ */
+ lp->d_partitions[pseudopart].p_size =
+ dp->dp_size;
+ lp->d_partitions[pseudopart].p_offset =
+ dp->dp_start;
+
+ /*
+ * make sure the D part can hold it all
+ */
+ if((dp->dp_start + dp->dp_size)
+ > lp->d_partitions[3].p_size) {
+ lp->d_partitions[3].p_size
+ = (dp->dp_start + dp->dp_size);
+ }
+
+ /*
+ * If we haven't seen a *BSD partition then
+ * check if this is a valid part..
+ * if it is it may be the best we are going to
+ * to see, so take note of it to deduce a
+ * geometry in case we never find a disklabel.
+ */
+ switch(dp->dp_typ) {
+ case DOSPTYP_386BSD:
+ /*
+ * at a pinch we could throw
+ * a FFS on here
+ */
+ lp->d_partitions[pseudopart].p_fstype
+ = FS_BSDFFS;
+ /*
+ * Only get a disklabel from the
+ * first one we see..
+ */
+ if (seenBSD == 0) {
+ /*
+ * If it IS our part, then we
+ * need sector address for
+ * SCSI/IDE, cylinder for
+ * ESDI/ST506/RLL
+ */
+ seenBSD = 1;
+ *cyl = DPCYL(dp->dp_scyl,
+ dp->dp_ssect);
+
+ /*
+ * Note which part we are in (?)
+ */
+ lp->d_subtype &= ~3;
+ lp->d_subtype |= i & 3;
+ lp->d_subtype
+ |= DSTYPE_INDOSPART;
+
+ /*
+ * update disklabel with
+ * details for reading the REAL
+ * disklabel it it exists
+ */
+ lp->d_partitions[OURPART].p_size =
+ dp->dp_size;
+ lp->d_partitions[OURPART].p_offset =
+ dp->dp_start;
+ }
+ break;
+ case 0xB7: /* BSDI (?)*//* doubtful */
+ lp->d_partitions[pseudopart].p_fstype
+ = FS_BSDFFS;
+ break;
+ case 1:
+ case 4:
+ case 6:
+ case 0xF2:
+ lp->d_partitions[pseudopart].p_fstype
+ = FS_MSDOS;
+ break;
+ }
+
+ /*
+ * Try deduce the geometry, working
+ * on the principle that this
+ * partition PROBABLY ends on a
+ * cylinder boundary.
+ * This is really a kludge, but we are
+ * forced into it by the PC's design.
+ * If we've seen a 386bsd part,
+ * believe it and check no further.
+ */
+ if (seenBSD) continue;
+ lp->d_ntracks = dp->dp_ehd + 1;
+ lp->d_nsectors = DPSECT(dp->dp_esect);
+ lp->d_secpercyl = lp->d_ntracks *
+ lp->d_nsectors;
+ }
+ lp->d_npartitions = 8;
+ }
+ bp->b_flags = B_INVAL | B_AGE;
+ brelse(bp);
+ return 0;
+bad:
+ bcopy(&labelsave,lp,sizeof(labelsave));
+ bp->b_flags = B_INVAL | B_AGE;
+ brelse(bp);
+ return msg;
+}
+
+
diff --git a/sys/i386/isa/wd.c b/sys/i386/isa/wd.c
index 8cc7460..30c990d 100644
--- a/sys/i386/isa/wd.c
+++ b/sys/i386/isa/wd.c
@@ -37,7 +37,7 @@ static int wdtest = 0;
* SUCH DAMAGE.
*
* from: @(#)wd.c 7.2 (Berkeley) 5/9/91
- * $Id: wd.c,v 1.56 1994/10/23 21:27:40 wollman Exp $
+ * $Id: wd.c,v 1.57 1994/10/27 05:39:12 phk Exp $
*/
/* TODO:
@@ -271,8 +271,6 @@ struct isa_driver wdcdriver = {
wdprobe, wdattach, "wdc",
};
-extern char *readdisklabel();
-
/*
* Probe for controller.
*/
@@ -993,14 +991,9 @@ wdopen(dev_t dev, int flags, int fmt, struct proc *p)
save_label = du->dk_dd;
du->dk_dd.d_partitions[WDRAW].p_offset = 0;
du->dk_dd.d_partitions[WDRAW].p_size = 0x7fffffff;/* XXX */
-#define WDSTRATEGY ((int (*)(struct buf *)) wdstrategy) /* XXX */
msg = readdisklabel(makewddev(major(dev), lunit, WDRAW),
- WDSTRATEGY, &du->dk_dd,
+ wdstrategy, &du->dk_dd,
du->dk_dospartitions, &du->dk_bad);
-/*
- msg = readdisklabel(makewddev(major(dev), lunit, WDRAW),
- WDSTRATEGY, &du->dk_dd);
-*/
du->dk_flags &= ~DKFL_LABELLING;
if (msg != NULL) {
du->dk_dd = save_label;
@@ -1437,8 +1430,7 @@ wdioctl(dev_t dev, int cmd, caddr_t addr, int flag)
du->dk_flags & DKFL_BSDLABEL
? du->dk_openpart :
#endif
- 0,
- du->dk_dospartitions);
+ 0);
if (error == 0) {
du->dk_flags |= DKFL_BSDLABEL;
wdwsetctlr(du); /* XXX - check */
@@ -1463,8 +1455,7 @@ wdioctl(dev_t dev, int cmd, caddr_t addr, int flag)
du->dk_flags & DKFL_BSDLABEL
? du->dk_openpart :
#endif
- 0,
- du->dk_dospartitions)) == 0) {
+ 0)) == 0) {
int wlab;
du->dk_flags |= DKFL_BSDLABEL;
@@ -1474,8 +1465,7 @@ wdioctl(dev_t dev, int cmd, caddr_t addr, int flag)
du->dk_openpart |= (1 << 0); /* XXX */
wlab = du->dk_wlabel;
du->dk_wlabel = 1;
- error = writedisklabel(dev, WDSTRATEGY,
- &du->dk_dd, du->dk_dospartitions);
+ error = writedisklabel(dev, wdstrategy, &du->dk_dd);
du->dk_openpart = du->dk_copenpart | du->dk_bopenpart;
du->dk_wlabel = wlab;
}
@@ -1524,7 +1514,12 @@ wdformat(struct buf *bp)
{
bp->b_flags |= B_FORMAT;
- return (wdstrategy(bp));
+ wdstrategy(bp);
+ /*
+ * phk put this here, better that return(wdstrategy(bp));
+ * XXX
+ */
+ return -1;
}
#endif
diff --git a/sys/isa/fd.c b/sys/isa/fd.c
index a000acf..e06ac4a 100644
--- a/sys/isa/fd.c
+++ b/sys/isa/fd.c
@@ -40,7 +40,7 @@
* SUCH DAMAGE.
*
* from: @(#)fd.c 7.4 (Berkeley) 5/25/91
- * $Id: fd.c,v 1.36 1994/10/21 16:58:50 joerg Exp $
+ * $Id: fd.c,v 1.37 1994/10/23 21:27:12 wollman Exp $
*
*/
@@ -1522,7 +1522,7 @@ fdioctl(dev, cmd, addr, flag, p)
dl->d_secpercyl = fdt->size / fdt->tracks;
dl->d_type = DTYPE_FLOPPY;
- if (readdisklabel(dev, fdstrategy, dl, NULL, 0, 0) == NULL)
+ if (readdisklabel(dev, fdstrategy, dl, NULL, 0) == NULL)
error = 0;
else
error = EINVAL;
@@ -1550,11 +1550,11 @@ fdioctl(dev, cmd, addr, flag, p)
dl = (struct disklabel *)addr;
if ((error =
- setdisklabel ((struct disklabel *)buffer, dl, 0, NULL)))
+ setdisklabel ((struct disklabel *)buffer, dl, 0)))
break;
error = writedisklabel(dev, fdstrategy,
- (struct disklabel *)buffer, NULL);
+ (struct disklabel *)buffer);
break;
case FD_FORM:
diff --git a/sys/kern/subr_disklabel.c b/sys/kern/subr_disklabel.c
index f116269..4849146 100644
--- a/sys/kern/subr_disklabel.c
+++ b/sys/kern/subr_disklabel.c
@@ -36,17 +36,17 @@
* SUCH DAMAGE.
*
* @(#)ufs_disksubr.c 8.5 (Berkeley) 1/21/94
- * $Id: ufs_disksubr.c,v 1.4 1994/10/08 06:57:23 phk Exp $
+ * $Id: ufs_disksubr.c,v 1.5 1994/10/17 02:31:33 phk Exp $
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/buf.h>
+#include <sys/dkbad.h>
#include <sys/disklabel.h>
#include <sys/syslog.h>
#include <sys/dkbad.h>
-int dkcksum __P((struct disklabel *));
/*
* Seek sort for disks. We depend on the driver which calls us using b_resid
* as the current cylinder number.
@@ -154,86 +154,53 @@ insert: bp->b_actf = bq->b_actf;
* anything required in the strategy routine (e.g., sector size) must be
* filled in before calling us. Returns NULL on success and an error
* string on failure.
+ * If Machine Specific Partitions (MSP) are not found, then it will proceed
+ * as if the BSD partition starts at 0
+ * The MBR on an IBM PC is an example of an MSP.
*/
char *
readdisklabel(dev, strat, lp, dp, bdp)
dev_t dev;
- int (*strat)();
+ void (*strat)();
register struct disklabel *lp;
struct dos_partition *dp;
struct dkbad *bdp;
{
register struct buf *bp;
struct disklabel *dlp;
+ char *msgMSP = NULL;
char *msg = NULL;
- int dospartoff;
int i;
- int cyl;
+ int cyl = 0;
+ /*
+ * Set up the disklabel as in case there is no MSP.
+ * We set the BSD part, but don't need to set the
+ * RAW part, because readMSPtolabel() will reset that
+ * itself. On return however, if there was no MSP,
+ * then we will be looking into OUR part to find the label
+ * and we will want that to start at 0, and have at least SOME length.
+ */
if (lp->d_secperunit == 0)
lp->d_secperunit = 0x1fffffff;
- lp->d_npartitions = 1;
- if (lp->d_partitions[0].p_size == 0)
- lp->d_partitions[0].p_size = 0x1fffffff;
- lp->d_partitions[0].p_offset = 0;
-
- bp = geteblk((int)lp->d_secsize);
- /* do dos partitions in the process of getting disklabel? */
- dospartoff = 0;
- cyl = LABELSECTOR / lp->d_secpercyl;
- if (dp) {
- /* read master boot record */
- bp->b_dev = dev;
- bp->b_blkno = DOSBBSECTOR;
- bp->b_bcount = lp->d_secsize;
- bp->b_flags = B_BUSY | B_READ;
- bp->b_cylinder = DOSBBSECTOR / lp->d_secpercyl;
- (*strat)(bp);
-
- /* if successful, wander through dos partition table */
- if (biowait(bp)) {
- msg = "dos partition I/O error";
- goto done;
- } else {
- /* XXX how do we check veracity/bounds of this? */
- bcopy(bp->b_un.b_addr + DOSPARTOFF, dp,
- NDOSPART * sizeof(*dp));
- for (i = 0; i < NDOSPART; i++, dp++)
- /* is this ours? */
- if (dp->dp_size &&
- dp->dp_typ == DOSPTYP_386BSD
- && dospartoff == 0) {
+ lp->d_npartitions = OURPART + 1;
+ if (lp->d_partitions[OURPART].p_size == 0)
+ lp->d_partitions[OURPART].p_size = 0x100; /*enough for a label*/
+ lp->d_partitions[OURPART].p_offset = 0;
- /* need sector address for SCSI/IDE,
- cylinder for ESDI/ST506/RLL */
- dospartoff = dp->dp_start;
- cyl = DPCYL(dp->dp_scyl, dp->dp_ssect);
-
- /* update disklabel with details */
- lp->d_partitions[0].p_size =
- dp->dp_size;
- lp->d_partitions[0].p_offset =
- dp->dp_start;
- lp->d_ntracks = dp->dp_ehd + 1;
- lp->d_nsectors = DPSECT(dp->dp_esect);
-#ifdef CC_WALL
-/* The next statement looks bogus... i runs int 0..3 ??? */
- lp->d_subtype |= ((lp->d_subtype & 3)
- + i) | DSTYPE_INDOSPART;
-#else /* CC_WALL */
- lp->d_subtype |= (lp->d_subtype & 3)
- + i | DSTYPE_INDOSPART;
-#endif /* CC_WALL */
- lp->d_secpercyl = lp->d_ntracks *
- lp->d_nsectors;
- }
- }
-
- }
+ /*
+ * Dig out the Dos MSP.. If we get it, all remaining transfers
+ * will be relative to the base of the BSD part.
+ */
+ msgMSP = readMSPtolabel(dev, strat, lp, dp, &cyl );
- /* next, dig out disk label */
- bp->b_blkno = dospartoff + LABELSECTOR;
- bp->b_dev = dev;
+ /*
+ * next, dig out disk label, relative to either the base of the
+ * BSD part, or block 0, depending on if an MSP was found.
+ */
+ bp = geteblk((int)lp->d_secsize);
+ bp->b_blkno = LABELSECTOR;
+ bp->b_dev = makedev(major(dev), dkminor(dkunit(dev), OURPART));
bp->b_bcount = lp->d_secsize;
bp->b_flags = B_BUSY | B_READ;
bp->b_cylinder = cyl;
@@ -256,8 +223,19 @@ readdisklabel(dev, strat, lp, dp, bdp)
break;
}
}
- if (msg)
+
+ if (msg && msgMSP) {
+ msg = msgMSP;
goto done;
+ }
+
+ /*
+ * Since we had one of the two labels, either one made up from the
+ * MSP, one found in the FreeBSD-MSP-partitions sector 2, or even
+ * one in sector 2 absolute on the disk, there is not really an error.
+ */
+
+ msg = NULL;
/* obtain bad sector table if requested and present */
if (bdp && (lp->d_flags & D_BADSECT)) {
@@ -312,11 +290,20 @@ setdisklabel(olp, nlp, openmask)
register i;
register struct partition *opp, *npp;
+ /*
+ * Check it is actually a disklabel we are looking at.
+ */
if (nlp->d_magic != DISKMAGIC || nlp->d_magic2 != DISKMAGIC ||
dkcksum(nlp) != 0)
return (EINVAL);
+ /*
+ * For each partition that we think is open,
+ */
while ((i = ffs((long)openmask)) != 0) {
i--;
+ /*
+ * Check it is not changing....
+ */
openmask &= ~(1 << i);
if (nlp->d_npartitions <= i)
return (EBUSY);
@@ -327,6 +314,8 @@ setdisklabel(olp, nlp, openmask)
/*
* Copy internally-set partition information
* if new label doesn't include it. XXX
+ * (If we are using it then we had better stay the same type)
+ * This is possibly dubious, as someone else noted (XXX)
*/
if (npp->p_fstype == FS_UNUSED && opp->p_fstype != FS_UNUSED) {
npp->p_fstype = opp->p_fstype;
@@ -341,38 +330,100 @@ setdisklabel(olp, nlp, openmask)
return (0);
}
-/* encoding of disk minor numbers, should be elsewhere... */
-#define dkunit(dev) (minor(dev) >> 3)
-#define dkpart(dev) (minor(dev) & 07)
-#define dkminor(unit, part) (((unit) << 3) | (part))
-
/*
* Write disk label back to device after modification.
+ * For FreeBSD 2.0(x86) this routine will refuse to install a label if
+ * there is no DOS MSP. (this can be changed)
+ *
+ * Assumptions for THIS VERSION:
+ * The given disklabel pointer is actually that which is controlling this
+ * Device, so that by fiddling it, readMSPtolabel() can ensure that
+ * it can read from the MSP if it exists,
+ * This assumption will cease as soon as ther is a better way of ensuring
+ * that a read is done to the whole raw device.
+ * MSP defines a BSD part, label is in block 1 (2nd block) of this
*/
int
writedisklabel(dev, strat, lp)
dev_t dev;
- int (*strat)();
+ void (*strat)();
register struct disklabel *lp;
{
- struct buf *bp;
+ struct buf *bp = NULL;
struct disklabel *dlp;
- int labelpart;
int error = 0;
+ struct disklabel label;
+ char *msg;
+ int BSDstart,BSDlen;
+ int cyl; /* dummy arg for readMSPtolabel() */
- labelpart = dkpart(dev);
- /* XXX this is wrong. But leaving it in is worse. */
-#ifndef __FREEBSD__
- if (lp->d_partitions[labelpart].p_offset != 0) {
- if (lp->d_partitions[0].p_offset != 0)
- return (EXDEV); /* not quite right */
- labelpart = 0;
+ /*
+ * Save the label (better be the real one)
+ * because we are going to play funny games with the disklabel
+ * controlling this device..
+ */
+ bcopy(lp,&label,sizeof(label));
+ /*
+ * Unlike the read, we will trust the parameters given to us
+ * about the disk, in the new disklabel but will simply
+ * force OURPART to start at block 0 as a default in case there is NO
+ * MSP.
+ * readMSPtolabel() will reset it to start at the start of the BSD
+ * part if it exists
+ * At this time this is an error contition but I've left support for it
+ */
+ lp->d_npartitions = OURPART + 1;
+ if (lp->d_partitions[OURPART].p_size == 0)
+ lp->d_partitions[OURPART].p_size = 0x1fffffff;
+ lp->d_partitions[OURPART].p_offset = 0;
+
+ msg = readMSPtolabel(dev, strat, lp, 0, &cyl );
+ /*
+ * If we want to be able to install without an Machine Specific
+ * Partitioning , then
+ * the failure of readMSPtolabel() should be made non fatal.
+ */
+ if(msg) {
+ printf("writedisklabel:%s\n",msg);
+ error = ENXIO;
+ goto done;
}
-#endif
+ /*
+ * If we had MSP (no message) but there
+ * was no BSD part in it
+ * then balk.. they should use fdisk to make one first or smash it..
+ * This may just be me being paranoid, but it's my choice for now..
+ * note we test for !msg, because the test above might be changed
+ * as a valid option..
+ */
+ if((!msg) && (!(lp->d_subtype & DSTYPE_INDOSPART))) {
+ printf("writedisklabel: MSP with no BSD part\n");
+ }
+
+ /*
+ * get all the other bits back from the good new disklabel
+ * (the user wouldn't try confuse us would he?)
+ * With the exception of the OURPART which now points to the
+ * BSD partition.
+ */
+ BSDstart = lp->d_partitions[OURPART].p_offset;
+ BSDlen = lp->d_partitions[OURPART].p_size;
+ bcopy(&label,lp,sizeof(label));
+ lp->d_partitions[OURPART].p_offset = BSDstart;
+ lp->d_partitions[OURPART].p_size = BSDlen;
+
bp = geteblk((int)lp->d_secsize);
- bp->b_dev = makedev(major(dev), dkminor(dkunit(dev), labelpart));
+ bp->b_dev = makedev(major(dev), dkminor(dkunit(dev), OURPART));
bp->b_blkno = LABELSECTOR;
bp->b_bcount = lp->d_secsize;
+#ifdef STUPID
+ /*
+ * We read the label first to see if it's there,
+ * in which case we will put ours at the same offset into the block..
+ * (I think this is stupid [Julian])
+ * Note that you can't write a label out over a corrupted label!
+ * (also stupid.. how do you write the first one? by raw writes?)
+ */
bp->b_flags = B_READ;
(*strat)(bp);
error = biowait(bp);
@@ -384,7 +435,7 @@ writedisklabel(dev, strat, lp)
dlp = (struct disklabel *)((char *)dlp + sizeof(long))) {
if (dlp->d_magic == DISKMAGIC && dlp->d_magic2 == DISKMAGIC &&
dkcksum(dlp) == 0) {
- *dlp = *lp;
+ bcopy(&label,dlp,sizeof(label));
bp->b_flags = B_WRITE;
(*strat)(bp);
error = biowait(bp);
@@ -392,15 +443,24 @@ writedisklabel(dev, strat, lp)
}
}
error = ESRCH;
+#else /* Stupid */
+ dlp = (struct disklabel *)bp->b_data;
+ bcopy(&label,dlp,sizeof(label));
+ bp->b_flags = B_WRITE;
+ (*strat)(bp);
+ error = biowait(bp);
+#endif /* Stupid */
done:
- brelse(bp);
+ bcopy(&label,lp,sizeof(label)); /* start using the new label again */
+ if(bp)
+ brelse(bp);
return (error);
}
/*
* Compute checksum for disk label.
*/
-int
+u_int
dkcksum(lp)
register struct disklabel *lp;
{
diff --git a/sys/scsi/cd.c b/sys/scsi/cd.c
index 9c94bb3..438d047 100644
--- a/sys/scsi/cd.c
+++ b/sys/scsi/cd.c
@@ -14,7 +14,7 @@
*
* Ported to run under 386BSD by Julian Elischer (julian@tfs.com) Sept 1992
*
- * $Id: cd.c,v 1.26 1994/10/19 00:09:42 wollman Exp $
+ * $Id: cd.c,v 1.27 1994/10/23 21:27:52 wollman Exp $
*/
#define SPLCD splbio
@@ -677,9 +677,7 @@ cdioctl(dev_t dev, int cmd, caddr_t addr, int flag)
error = EBADF;
else
error = setdisklabel(&cd->disklabel,
- (struct disklabel *) addr,
- 0,
- 0);
+ (struct disklabel *) addr, 0);
if (error == 0)
break;
diff --git a/sys/scsi/sd.c b/sys/scsi/sd.c
index 6bfb807..2223b97 100644
--- a/sys/scsi/sd.c
+++ b/sys/scsi/sd.c
@@ -14,7 +14,7 @@
*
* Ported to run under 386BSD by Julian Elischer (julian@dialix.oz.au) Sept 1992
*
- * $Id: sd.c,v 1.36 1994/10/20 00:08:31 phk Exp $
+ * $Id: sd.c,v 1.37 1994/10/23 21:27:57 wollman Exp $
*/
#define SPLSD splbio
@@ -67,7 +67,6 @@ int Debugger(const char *);
#define WHOLE_DISK(unit) ( (unit << UNITSHIFT) + RAW_PART )
-extern char *readdisklabel();
errval sdgetdisklabel __P((unsigned char unit));
errval sd_get_parms __P((int unit, int flags));
void sdstrategy __P((struct buf *));
@@ -782,6 +781,10 @@ sdgetdisklabel(unsigned char unit)
/*
* Call the generic disklabel extraction routine
*/
+ sd->flags |= SDHAVELABEL; /* chicken and egg problem */
+ /* we need to pretend this disklabel */
+ /* is real before we can read */
+ /* real disklabel */
errstring = readdisklabel(makedev(0, (unit << UNITSHIFT) + RAW_PART),
sdstrategy,
&sd->disklabel
@@ -792,10 +795,10 @@ sdgetdisklabel(unsigned char unit)
#endif
);
if (errstring) {
+ sd->flags &= ~SDHAVELABEL; /* not now we don't */
printf("sd%d: %s\n", unit, errstring);
return ENXIO;
}
- sd->flags |= SDHAVELABEL; /* WE HAVE IT ALL NOW */
return ESUCCESS;
}
diff --git a/sys/sys/disklabel.h b/sys/sys/disklabel.h
index 38738ca..229d52b 100644
--- a/sys/sys/disklabel.h
+++ b/sys/sys/disklabel.h
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)disklabel.h 8.1 (Berkeley) 6/2/93
- * $Id: disklabel.h,v 1.4 1994/08/21 04:41:39 paul Exp $
+ * $Id: disklabel.h,v 1.5 1994/10/20 23:41:57 paul Exp $
*/
#ifndef _SYS_DISKLABEL_H_
@@ -54,6 +54,25 @@
#ifdef i386
#define LABELSECTOR 1 /* sector containing label */
#define LABELOFFSET 0 /* offset of label in sector */
+#define OURPART 2 /* partition is 'all BSD' */
+#define RAWPART 3 /* partition is 'all device' */
+#define readMSPtolabel readMBRtolabel
+#endif
+
+#ifndef readMSPtolabel
+#define readMSPtolabel(a,b,c,d,e,) /* zap calls if irrelevant */
+#endif
+
+#ifdef tahoe
+#define RAWPART 0
+#endif
+
+#ifndef RAWPART
+#define RAWPART 2
+#endif
+
+#ifndef OURPART
+#define OURPART RAWPART /* by default it's all ours */
#endif
#ifndef LABELSECTOR
@@ -358,6 +377,18 @@ extern struct dos_partition dos_partitions[NDOSPART];
#endif /* LOCORE */
+#ifdef KERNEL
+u_int dkcksum __P((struct disklabel *));
+int writedisklabel __P((dev_t dev, void (*strat)(), struct disklabel *lp));
+char * readdisklabel __P((dev_t dev, void (*strat)(), struct disklabel *lp, struct dos_partition *dp, struct dkbad *bdp));
+int setdisklabel __P((struct disklabel *olp, struct disklabel *nlp, u_long openmask));
+void disksort __P((struct buf *ap, struct buf *bp));
+void diskerr __P((struct buf *, char *, char *, int, int, struct disklabel *));
+#ifdef __i386
+char * readMBRtolabel __P(( dev_t dev , void (*strat)(), register struct disklabel *lp, struct dos_partition *dp, int *cyl));
+#endif
+#endif
+
#if !defined(KERNEL) && !defined(LOCORE)
#include <sys/cdefs.h>
@@ -368,4 +399,13 @@ __END_DECLS
#endif
+#ifdef __i386
+/* encoding of disk minor numbers, should be elsewhere... */
+#define dkunit(dev) (minor(dev) >> 3)
+#define dkpart(dev) (minor(dev) & 07)
+#define dkminor(unit, part) (((unit) << 3) | (part))
#endif
+
+#endif
+
+
diff --git a/sys/sys/diskmbr.h b/sys/sys/diskmbr.h
index 38738ca..229d52b 100644
--- a/sys/sys/diskmbr.h
+++ b/sys/sys/diskmbr.h
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)disklabel.h 8.1 (Berkeley) 6/2/93
- * $Id: disklabel.h,v 1.4 1994/08/21 04:41:39 paul Exp $
+ * $Id: disklabel.h,v 1.5 1994/10/20 23:41:57 paul Exp $
*/
#ifndef _SYS_DISKLABEL_H_
@@ -54,6 +54,25 @@
#ifdef i386
#define LABELSECTOR 1 /* sector containing label */
#define LABELOFFSET 0 /* offset of label in sector */
+#define OURPART 2 /* partition is 'all BSD' */
+#define RAWPART 3 /* partition is 'all device' */
+#define readMSPtolabel readMBRtolabel
+#endif
+
+#ifndef readMSPtolabel
+#define readMSPtolabel(a,b,c,d,e,) /* zap calls if irrelevant */
+#endif
+
+#ifdef tahoe
+#define RAWPART 0
+#endif
+
+#ifndef RAWPART
+#define RAWPART 2
+#endif
+
+#ifndef OURPART
+#define OURPART RAWPART /* by default it's all ours */
#endif
#ifndef LABELSECTOR
@@ -358,6 +377,18 @@ extern struct dos_partition dos_partitions[NDOSPART];
#endif /* LOCORE */
+#ifdef KERNEL
+u_int dkcksum __P((struct disklabel *));
+int writedisklabel __P((dev_t dev, void (*strat)(), struct disklabel *lp));
+char * readdisklabel __P((dev_t dev, void (*strat)(), struct disklabel *lp, struct dos_partition *dp, struct dkbad *bdp));
+int setdisklabel __P((struct disklabel *olp, struct disklabel *nlp, u_long openmask));
+void disksort __P((struct buf *ap, struct buf *bp));
+void diskerr __P((struct buf *, char *, char *, int, int, struct disklabel *));
+#ifdef __i386
+char * readMBRtolabel __P(( dev_t dev , void (*strat)(), register struct disklabel *lp, struct dos_partition *dp, int *cyl));
+#endif
+#endif
+
#if !defined(KERNEL) && !defined(LOCORE)
#include <sys/cdefs.h>
@@ -368,4 +399,13 @@ __END_DECLS
#endif
+#ifdef __i386
+/* encoding of disk minor numbers, should be elsewhere... */
+#define dkunit(dev) (minor(dev) >> 3)
+#define dkpart(dev) (minor(dev) & 07)
+#define dkminor(unit, part) (((unit) << 3) | (part))
#endif
+
+#endif
+
+
diff --git a/sys/sys/diskpc98.h b/sys/sys/diskpc98.h
index 38738ca..229d52b 100644
--- a/sys/sys/diskpc98.h
+++ b/sys/sys/diskpc98.h
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)disklabel.h 8.1 (Berkeley) 6/2/93
- * $Id: disklabel.h,v 1.4 1994/08/21 04:41:39 paul Exp $
+ * $Id: disklabel.h,v 1.5 1994/10/20 23:41:57 paul Exp $
*/
#ifndef _SYS_DISKLABEL_H_
@@ -54,6 +54,25 @@
#ifdef i386
#define LABELSECTOR 1 /* sector containing label */
#define LABELOFFSET 0 /* offset of label in sector */
+#define OURPART 2 /* partition is 'all BSD' */
+#define RAWPART 3 /* partition is 'all device' */
+#define readMSPtolabel readMBRtolabel
+#endif
+
+#ifndef readMSPtolabel
+#define readMSPtolabel(a,b,c,d,e,) /* zap calls if irrelevant */
+#endif
+
+#ifdef tahoe
+#define RAWPART 0
+#endif
+
+#ifndef RAWPART
+#define RAWPART 2
+#endif
+
+#ifndef OURPART
+#define OURPART RAWPART /* by default it's all ours */
#endif
#ifndef LABELSECTOR
@@ -358,6 +377,18 @@ extern struct dos_partition dos_partitions[NDOSPART];
#endif /* LOCORE */
+#ifdef KERNEL
+u_int dkcksum __P((struct disklabel *));
+int writedisklabel __P((dev_t dev, void (*strat)(), struct disklabel *lp));
+char * readdisklabel __P((dev_t dev, void (*strat)(), struct disklabel *lp, struct dos_partition *dp, struct dkbad *bdp));
+int setdisklabel __P((struct disklabel *olp, struct disklabel *nlp, u_long openmask));
+void disksort __P((struct buf *ap, struct buf *bp));
+void diskerr __P((struct buf *, char *, char *, int, int, struct disklabel *));
+#ifdef __i386
+char * readMBRtolabel __P(( dev_t dev , void (*strat)(), register struct disklabel *lp, struct dos_partition *dp, int *cyl));
+#endif
+#endif
+
#if !defined(KERNEL) && !defined(LOCORE)
#include <sys/cdefs.h>
@@ -368,4 +399,13 @@ __END_DECLS
#endif
+#ifdef __i386
+/* encoding of disk minor numbers, should be elsewhere... */
+#define dkunit(dev) (minor(dev) >> 3)
+#define dkpart(dev) (minor(dev) & 07)
+#define dkminor(unit, part) (((unit) << 3) | (part))
#endif
+
+#endif
+
+
diff --git a/sys/ufs/ufs/ufs_disksubr.c b/sys/ufs/ufs/ufs_disksubr.c
index f116269..4849146 100644
--- a/sys/ufs/ufs/ufs_disksubr.c
+++ b/sys/ufs/ufs/ufs_disksubr.c
@@ -36,17 +36,17 @@
* SUCH DAMAGE.
*
* @(#)ufs_disksubr.c 8.5 (Berkeley) 1/21/94
- * $Id: ufs_disksubr.c,v 1.4 1994/10/08 06:57:23 phk Exp $
+ * $Id: ufs_disksubr.c,v 1.5 1994/10/17 02:31:33 phk Exp $
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/buf.h>
+#include <sys/dkbad.h>
#include <sys/disklabel.h>
#include <sys/syslog.h>
#include <sys/dkbad.h>
-int dkcksum __P((struct disklabel *));
/*
* Seek sort for disks. We depend on the driver which calls us using b_resid
* as the current cylinder number.
@@ -154,86 +154,53 @@ insert: bp->b_actf = bq->b_actf;
* anything required in the strategy routine (e.g., sector size) must be
* filled in before calling us. Returns NULL on success and an error
* string on failure.
+ * If Machine Specific Partitions (MSP) are not found, then it will proceed
+ * as if the BSD partition starts at 0
+ * The MBR on an IBM PC is an example of an MSP.
*/
char *
readdisklabel(dev, strat, lp, dp, bdp)
dev_t dev;
- int (*strat)();
+ void (*strat)();
register struct disklabel *lp;
struct dos_partition *dp;
struct dkbad *bdp;
{
register struct buf *bp;
struct disklabel *dlp;
+ char *msgMSP = NULL;
char *msg = NULL;
- int dospartoff;
int i;
- int cyl;
+ int cyl = 0;
+ /*
+ * Set up the disklabel as in case there is no MSP.
+ * We set the BSD part, but don't need to set the
+ * RAW part, because readMSPtolabel() will reset that
+ * itself. On return however, if there was no MSP,
+ * then we will be looking into OUR part to find the label
+ * and we will want that to start at 0, and have at least SOME length.
+ */
if (lp->d_secperunit == 0)
lp->d_secperunit = 0x1fffffff;
- lp->d_npartitions = 1;
- if (lp->d_partitions[0].p_size == 0)
- lp->d_partitions[0].p_size = 0x1fffffff;
- lp->d_partitions[0].p_offset = 0;
-
- bp = geteblk((int)lp->d_secsize);
- /* do dos partitions in the process of getting disklabel? */
- dospartoff = 0;
- cyl = LABELSECTOR / lp->d_secpercyl;
- if (dp) {
- /* read master boot record */
- bp->b_dev = dev;
- bp->b_blkno = DOSBBSECTOR;
- bp->b_bcount = lp->d_secsize;
- bp->b_flags = B_BUSY | B_READ;
- bp->b_cylinder = DOSBBSECTOR / lp->d_secpercyl;
- (*strat)(bp);
-
- /* if successful, wander through dos partition table */
- if (biowait(bp)) {
- msg = "dos partition I/O error";
- goto done;
- } else {
- /* XXX how do we check veracity/bounds of this? */
- bcopy(bp->b_un.b_addr + DOSPARTOFF, dp,
- NDOSPART * sizeof(*dp));
- for (i = 0; i < NDOSPART; i++, dp++)
- /* is this ours? */
- if (dp->dp_size &&
- dp->dp_typ == DOSPTYP_386BSD
- && dospartoff == 0) {
+ lp->d_npartitions = OURPART + 1;
+ if (lp->d_partitions[OURPART].p_size == 0)
+ lp->d_partitions[OURPART].p_size = 0x100; /*enough for a label*/
+ lp->d_partitions[OURPART].p_offset = 0;
- /* need sector address for SCSI/IDE,
- cylinder for ESDI/ST506/RLL */
- dospartoff = dp->dp_start;
- cyl = DPCYL(dp->dp_scyl, dp->dp_ssect);
-
- /* update disklabel with details */
- lp->d_partitions[0].p_size =
- dp->dp_size;
- lp->d_partitions[0].p_offset =
- dp->dp_start;
- lp->d_ntracks = dp->dp_ehd + 1;
- lp->d_nsectors = DPSECT(dp->dp_esect);
-#ifdef CC_WALL
-/* The next statement looks bogus... i runs int 0..3 ??? */
- lp->d_subtype |= ((lp->d_subtype & 3)
- + i) | DSTYPE_INDOSPART;
-#else /* CC_WALL */
- lp->d_subtype |= (lp->d_subtype & 3)
- + i | DSTYPE_INDOSPART;
-#endif /* CC_WALL */
- lp->d_secpercyl = lp->d_ntracks *
- lp->d_nsectors;
- }
- }
-
- }
+ /*
+ * Dig out the Dos MSP.. If we get it, all remaining transfers
+ * will be relative to the base of the BSD part.
+ */
+ msgMSP = readMSPtolabel(dev, strat, lp, dp, &cyl );
- /* next, dig out disk label */
- bp->b_blkno = dospartoff + LABELSECTOR;
- bp->b_dev = dev;
+ /*
+ * next, dig out disk label, relative to either the base of the
+ * BSD part, or block 0, depending on if an MSP was found.
+ */
+ bp = geteblk((int)lp->d_secsize);
+ bp->b_blkno = LABELSECTOR;
+ bp->b_dev = makedev(major(dev), dkminor(dkunit(dev), OURPART));
bp->b_bcount = lp->d_secsize;
bp->b_flags = B_BUSY | B_READ;
bp->b_cylinder = cyl;
@@ -256,8 +223,19 @@ readdisklabel(dev, strat, lp, dp, bdp)
break;
}
}
- if (msg)
+
+ if (msg && msgMSP) {
+ msg = msgMSP;
goto done;
+ }
+
+ /*
+ * Since we had one of the two labels, either one made up from the
+ * MSP, one found in the FreeBSD-MSP-partitions sector 2, or even
+ * one in sector 2 absolute on the disk, there is not really an error.
+ */
+
+ msg = NULL;
/* obtain bad sector table if requested and present */
if (bdp && (lp->d_flags & D_BADSECT)) {
@@ -312,11 +290,20 @@ setdisklabel(olp, nlp, openmask)
register i;
register struct partition *opp, *npp;
+ /*
+ * Check it is actually a disklabel we are looking at.
+ */
if (nlp->d_magic != DISKMAGIC || nlp->d_magic2 != DISKMAGIC ||
dkcksum(nlp) != 0)
return (EINVAL);
+ /*
+ * For each partition that we think is open,
+ */
while ((i = ffs((long)openmask)) != 0) {
i--;
+ /*
+ * Check it is not changing....
+ */
openmask &= ~(1 << i);
if (nlp->d_npartitions <= i)
return (EBUSY);
@@ -327,6 +314,8 @@ setdisklabel(olp, nlp, openmask)
/*
* Copy internally-set partition information
* if new label doesn't include it. XXX
+ * (If we are using it then we had better stay the same type)
+ * This is possibly dubious, as someone else noted (XXX)
*/
if (npp->p_fstype == FS_UNUSED && opp->p_fstype != FS_UNUSED) {
npp->p_fstype = opp->p_fstype;
@@ -341,38 +330,100 @@ setdisklabel(olp, nlp, openmask)
return (0);
}
-/* encoding of disk minor numbers, should be elsewhere... */
-#define dkunit(dev) (minor(dev) >> 3)
-#define dkpart(dev) (minor(dev) & 07)
-#define dkminor(unit, part) (((unit) << 3) | (part))
-
/*
* Write disk label back to device after modification.
+ * For FreeBSD 2.0(x86) this routine will refuse to install a label if
+ * there is no DOS MSP. (this can be changed)
+ *
+ * Assumptions for THIS VERSION:
+ * The given disklabel pointer is actually that which is controlling this
+ * Device, so that by fiddling it, readMSPtolabel() can ensure that
+ * it can read from the MSP if it exists,
+ * This assumption will cease as soon as ther is a better way of ensuring
+ * that a read is done to the whole raw device.
+ * MSP defines a BSD part, label is in block 1 (2nd block) of this
*/
int
writedisklabel(dev, strat, lp)
dev_t dev;
- int (*strat)();
+ void (*strat)();
register struct disklabel *lp;
{
- struct buf *bp;
+ struct buf *bp = NULL;
struct disklabel *dlp;
- int labelpart;
int error = 0;
+ struct disklabel label;
+ char *msg;
+ int BSDstart,BSDlen;
+ int cyl; /* dummy arg for readMSPtolabel() */
- labelpart = dkpart(dev);
- /* XXX this is wrong. But leaving it in is worse. */
-#ifndef __FREEBSD__
- if (lp->d_partitions[labelpart].p_offset != 0) {
- if (lp->d_partitions[0].p_offset != 0)
- return (EXDEV); /* not quite right */
- labelpart = 0;
+ /*
+ * Save the label (better be the real one)
+ * because we are going to play funny games with the disklabel
+ * controlling this device..
+ */
+ bcopy(lp,&label,sizeof(label));
+ /*
+ * Unlike the read, we will trust the parameters given to us
+ * about the disk, in the new disklabel but will simply
+ * force OURPART to start at block 0 as a default in case there is NO
+ * MSP.
+ * readMSPtolabel() will reset it to start at the start of the BSD
+ * part if it exists
+ * At this time this is an error contition but I've left support for it
+ */
+ lp->d_npartitions = OURPART + 1;
+ if (lp->d_partitions[OURPART].p_size == 0)
+ lp->d_partitions[OURPART].p_size = 0x1fffffff;
+ lp->d_partitions[OURPART].p_offset = 0;
+
+ msg = readMSPtolabel(dev, strat, lp, 0, &cyl );
+ /*
+ * If we want to be able to install without an Machine Specific
+ * Partitioning , then
+ * the failure of readMSPtolabel() should be made non fatal.
+ */
+ if(msg) {
+ printf("writedisklabel:%s\n",msg);
+ error = ENXIO;
+ goto done;
}
-#endif
+ /*
+ * If we had MSP (no message) but there
+ * was no BSD part in it
+ * then balk.. they should use fdisk to make one first or smash it..
+ * This may just be me being paranoid, but it's my choice for now..
+ * note we test for !msg, because the test above might be changed
+ * as a valid option..
+ */
+ if((!msg) && (!(lp->d_subtype & DSTYPE_INDOSPART))) {
+ printf("writedisklabel: MSP with no BSD part\n");
+ }
+
+ /*
+ * get all the other bits back from the good new disklabel
+ * (the user wouldn't try confuse us would he?)
+ * With the exception of the OURPART which now points to the
+ * BSD partition.
+ */
+ BSDstart = lp->d_partitions[OURPART].p_offset;
+ BSDlen = lp->d_partitions[OURPART].p_size;
+ bcopy(&label,lp,sizeof(label));
+ lp->d_partitions[OURPART].p_offset = BSDstart;
+ lp->d_partitions[OURPART].p_size = BSDlen;
+
bp = geteblk((int)lp->d_secsize);
- bp->b_dev = makedev(major(dev), dkminor(dkunit(dev), labelpart));
+ bp->b_dev = makedev(major(dev), dkminor(dkunit(dev), OURPART));
bp->b_blkno = LABELSECTOR;
bp->b_bcount = lp->d_secsize;
+#ifdef STUPID
+ /*
+ * We read the label first to see if it's there,
+ * in which case we will put ours at the same offset into the block..
+ * (I think this is stupid [Julian])
+ * Note that you can't write a label out over a corrupted label!
+ * (also stupid.. how do you write the first one? by raw writes?)
+ */
bp->b_flags = B_READ;
(*strat)(bp);
error = biowait(bp);
@@ -384,7 +435,7 @@ writedisklabel(dev, strat, lp)
dlp = (struct disklabel *)((char *)dlp + sizeof(long))) {
if (dlp->d_magic == DISKMAGIC && dlp->d_magic2 == DISKMAGIC &&
dkcksum(dlp) == 0) {
- *dlp = *lp;
+ bcopy(&label,dlp,sizeof(label));
bp->b_flags = B_WRITE;
(*strat)(bp);
error = biowait(bp);
@@ -392,15 +443,24 @@ writedisklabel(dev, strat, lp)
}
}
error = ESRCH;
+#else /* Stupid */
+ dlp = (struct disklabel *)bp->b_data;
+ bcopy(&label,dlp,sizeof(label));
+ bp->b_flags = B_WRITE;
+ (*strat)(bp);
+ error = biowait(bp);
+#endif /* Stupid */
done:
- brelse(bp);
+ bcopy(&label,lp,sizeof(label)); /* start using the new label again */
+ if(bp)
+ brelse(bp);
return (error);
}
/*
* Compute checksum for disk label.
*/
-int
+u_int
dkcksum(lp)
register struct disklabel *lp;
{
diff --git a/sys/ufs/ufs/ufs_extern.h b/sys/ufs/ufs/ufs_extern.h
index 8370ecf..7e62140 100644
--- a/sys/ufs/ufs/ufs_extern.h
+++ b/sys/ufs/ufs/ufs_extern.h
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)ufs_extern.h 8.3 (Berkeley) 4/16/94
- * $Id: ufs_extern.h,v 1.3 1994/08/21 07:16:17 paul Exp $
+ * $Id: ufs_extern.h,v 1.4 1994/09/22 19:38:40 wollman Exp $
*/
#ifndef _UFS_UFS_UFS_EXTERN_H_
@@ -54,14 +54,6 @@ struct vnode;
struct ufs_args;
__BEGIN_DECLS
-void diskerr
- __P((struct buf *, char *, char *, int, int, struct disklabel *));
-void disksort __P((struct buf *, struct buf *));
-u_int dkcksum __P((struct disklabel *));
-char *readdisklabel __P((dev_t, int (*)(), struct disklabel *));
-int setdisklabel __P((struct disklabel *, struct disklabel *, u_long));
-int writedisklabel __P((dev_t, int (*)(), struct disklabel *));
-
int ufs_abortop __P((struct vop_abortop_args *));
int ufs_access __P((struct vop_access_args *));
int ufs_advlock __P((struct vop_advlock_args *));
OpenPOWER on IntegriCloud