summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/arch/alpha/alpha/disksubr.c390
-rw-r--r--sys/arch/alpha/include/disklabel.h49
-rw-r--r--sys/arch/amd64/amd64/disksubr.c280
-rw-r--r--sys/arch/amd64/include/disklabel.h53
-rw-r--r--sys/arch/arm/arm/disksubr.c280
-rw-r--r--sys/arch/arm/include/disklabel.h64
-rw-r--r--sys/arch/armish/include/disklabel.h3
-rw-r--r--sys/arch/aviion/aviion/disksubr.c279
-rw-r--r--sys/arch/aviion/include/disklabel.h55
-rw-r--r--sys/arch/cats/include/disklabel.h3
-rw-r--r--sys/arch/hp300/hp300/disksubr.c99
-rw-r--r--sys/arch/hp300/include/disklabel.h7
-rw-r--r--sys/arch/hppa/hppa/disksubr.c614
-rw-r--r--sys/arch/hppa/include/disklabel.h46
-rw-r--r--sys/arch/hppa64/hppa64/disksubr.c614
-rw-r--r--sys/arch/hppa64/include/disklabel.h46
-rw-r--r--sys/arch/i386/i386/disksubr.c280
-rw-r--r--sys/arch/i386/include/disklabel.h53
-rw-r--r--sys/arch/landisk/include/disklabel.h2
-rw-r--r--sys/arch/landisk/landisk/disksubr.c280
-rw-r--r--sys/arch/luna88k/include/disklabel.h4
-rw-r--r--sys/arch/luna88k/luna88k/disksubr.c73
-rw-r--r--sys/arch/mac68k/include/disklabel.h15
-rw-r--r--sys/arch/mac68k/mac68k/disksubr.c175
-rw-r--r--sys/arch/macppc/include/disklabel.h47
-rw-r--r--sys/arch/macppc/macppc/disksubr.c337
-rw-r--r--sys/arch/mips64/include/disklabel.h46
-rw-r--r--sys/arch/mips64/mips64/disksubr.c489
-rw-r--r--sys/arch/mvme68k/include/disklabel.h7
-rw-r--r--sys/arch/mvme68k/mvme68k/disksubr.c117
-rw-r--r--sys/arch/mvme88k/include/disklabel.h8
-rw-r--r--sys/arch/mvme88k/mvme88k/disksubr.c118
-rw-r--r--sys/arch/mvmeppc/include/disklabel.h53
-rw-r--r--sys/arch/mvmeppc/mvmeppc/disksubr.c288
-rw-r--r--sys/arch/sh/include/disklabel.h63
-rw-r--r--sys/arch/solbourne/include/disklabel.h6
-rw-r--r--sys/arch/sparc/include/disklabel.h4
-rw-r--r--sys/arch/sparc/sparc/disksubr.c120
-rw-r--r--sys/arch/sparc64/include/disklabel.h5
-rw-r--r--sys/arch/sparc64/sparc64/disksubr.c123
-rw-r--r--sys/arch/vax/include/disklabel.h7
-rw-r--r--sys/arch/vax/vax/disksubr.c71
-rw-r--r--sys/arch/zaurus/include/disklabel.h3
-rw-r--r--sys/kern/subr_disk.c394
-rw-r--r--sys/sys/disklabel.h59
45 files changed, 1392 insertions, 4737 deletions
diff --git a/sys/arch/alpha/alpha/disksubr.c b/sys/arch/alpha/alpha/disksubr.c
index 6a7ef3615d3..0f0648ca81e 100644
--- a/sys/arch/alpha/alpha/disksubr.c
+++ b/sys/arch/alpha/alpha/disksubr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: disksubr.c,v 1.87 2007/06/14 03:37:23 deraadt Exp $ */
+/* $OpenBSD: disksubr.c,v 1.88 2007/06/17 00:27:28 deraadt Exp $ */
/* $NetBSD: disksubr.c,v 1.21 1996/05/03 19:42:03 christos Exp $ */
/*
@@ -30,80 +30,14 @@
* 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.
- *
- * @(#)ufs_disksubr.c 7.16 (Berkeley) 5/4/91
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/buf.h>
-#include <sys/device.h>
#include <sys/disklabel.h>
-#include <sys/syslog.h>
#include <sys/disk.h>
-char *readbsdlabel(struct buf *, void (*)(struct buf *), int, int,
- int, struct disklabel *, int);
-char *readdoslabel(struct buf *, void (*)(struct buf *),
- struct disklabel *, struct cpu_disklabel *, int *, int *, int);
-
-/*
- * Try to read a standard BSD disklabel at a certain sector.
- */
-char *
-readbsdlabel(struct buf *bp, void (*strat)(struct buf *),
- int cyl, int sec, int off, struct disklabel *lp, int spoofonly)
-{
- struct disklabel *dlp;
- char *msg = NULL;
- u_int16_t cksum;
-
- /* don't read the on-disk label if we are in spoofed-only mode */
- if (spoofonly)
- return (NULL);
-
- bp->b_blkno = sec;
- bp->b_cylinder = cyl;
- bp->b_bcount = lp->d_secsize;
- bp->b_flags = B_BUSY | B_READ;
- (*strat)(bp);
-
- /* if successful, locate disk label within block and validate */
- if (biowait(bp)) {
- /* XXX we return the faked label built so far */
- msg = "disk label I/O error";
- return (msg);
- }
-
- /*
- * If off is negative, search until the end of the sector for
- * the label, otherwise, just look at the specific location
- * we're given.
- */
- dlp = (struct disklabel *)(bp->b_data + (off >= 0 ? off : 0));
- do {
- if (dlp->d_magic != DISKMAGIC || dlp->d_magic2 != DISKMAGIC) {
- if (msg == NULL)
- msg = "no disk label";
- } else {
- cksum = dkcksum(dlp);
- if (dlp->d_npartitions > MAXPARTITIONS || cksum != 0) {
- msg = "disk label corrupted";
- } else {
- DL_SETDSIZE(dlp, DL_GETDSIZE(lp));
- *lp = *dlp;
- msg = NULL;
- break;
- }
- }
- if (off >= 0)
- break;
- dlp = (struct disklabel *)((char *)dlp + sizeof(int32_t));
- } while (dlp <= (struct disklabel *)(bp->b_data + lp->d_secsize -
- sizeof(*dlp)));
- return (msg);
-}
-
/*
* Attempt to read a disk label from a device
* using the indicated strategy routine.
@@ -119,264 +53,55 @@ readdisklabel(dev_t dev, void (*strat)(struct buf *),
struct disklabel *lp, struct cpu_disklabel *osdep, int spoofonly)
{
struct buf *bp = NULL;
- char *msg = "no disk label";
- int i;
- struct disklabel minilabel, fallbacklabel;
+ char *msg;
- /* minimal requirements for archetypal disk label */
- if (lp->d_secsize < DEV_BSIZE)
- lp->d_secsize = DEV_BSIZE;
- if (DL_GETDSIZE(lp) == 0)
- DL_SETDSIZE(lp, MAXDISKSIZE);
- if (lp->d_secpercyl == 0) {
- msg = "invalid geometry";
+ if ((msg = initdisklabel(lp)))
goto done;
- }
- lp->d_npartitions = RAW_PART + 1;
- for (i = 0; i < RAW_PART; i++) {
- DL_SETPSIZE(&lp->d_partitions[i], 0);
- DL_SETPOFFSET(&lp->d_partitions[i], 0);
- }
- if (DL_GETPSIZE(&lp->d_partitions[RAW_PART]) == 0)
- DL_SETPSIZE(&lp->d_partitions[RAW_PART], DL_GETDSIZE(lp));
- DL_SETPOFFSET(&lp->d_partitions[RAW_PART], 0);
- lp->d_version = 1;
- minilabel = fallbacklabel = *lp;
/* get a buffer and initialize it */
bp = geteblk((int)lp->d_secsize);
bp->b_dev = dev;
- msg = readbsdlabel(bp, strat, 0, LABELSECTOR, LABELOFFSET, lp,
- spoofonly);
- if (msg)
- *lp = minilabel;
- if (msg) {
- msg = readdoslabel(bp, strat, lp, osdep, 0, 0, spoofonly);
- if (msg) {
- /* Fallback alternative */
- fallbacklabel = *lp;
- *lp = minilabel;
- }
- }
- /* Record metainformation about the disklabel. */
- if (msg == NULL) {
- osdep->labelsector = bp->b_blkno;
+ if (spoofonly)
+ goto doslabel;
+
+ bp->b_blkno = LABELSECTOR;
+ bp->b_cylinder = 0;
+ bp->b_bcount = lp->d_secsize;
+ bp->b_flags = B_BUSY | B_READ;
+ (*strat)(bp);
+ if (biowait(bp)) {
+ msg = "disk label read error";
+ goto done;
}
+ msg = checkdisklabel(bp->b_data + LABELOFFSET, lp);
+ if (msg == NULL)
+ goto done;
+
+doslabel:
+ msg = readdoslabel(bp, strat, lp, osdep, NULL, NULL, spoofonly);
+ if (msg == NULL)
+ goto done;
+
#if defined(CD9660)
- if (msg && iso_disklabelspoof(dev, strat, lp) == 0)
+ if (iso_disklabelspoof(dev, strat, lp) == 0) {
msg = NULL;
+ goto done;
+ }
#endif
#if defined(UDF)
- if (msg && udf_disklabelspoof(dev, strat, lp) == 0)
+ if (udf_disklabelspoof(dev, strat, lp) == 0) {
msg = NULL;
+ goto done;
+ }
#endif
- /* If there was an error, still provide a decent fake one. */
- if (msg)
- *lp = fallbacklabel;
-
done:
if (bp) {
bp->b_flags |= B_INVAL;
brelse(bp);
}
- disklabeltokernlabel(lp);
- return (msg);
-}
-
-/*
- * If dos partition table requested, attempt to load it and
- * find disklabel inside a DOS partition. Return buffer
- * for use in signalling errors if requested.
- *
- * We would like to check if each MBR has a valid BOOT_MAGIC, but
- * we cannot because it doesn't always exist. So.. we assume the
- * MBR is valid.
- */
-char *
-readdoslabel(struct buf *bp, void (*strat)(struct buf *),
- struct disklabel *lp, struct cpu_disklabel *osdep,
- int *partoffp, int *cylp, int spoofonly)
-{
- struct dos_partition dp[NDOSPART], *dp2;
- struct partition *pp;
- unsigned long extoff = 0;
- unsigned int fattest;
- daddr64_t part_blkno = DOSBBSECTOR;
- char *msg = NULL;
- int dospartoff, cyl, i, ourpart = -1;
- int wander = 1, n = 0, loop = 0;
-
- if (lp->d_secpercyl == 0) {
- msg = "invalid label, d_secpercyl == 0";
- return (msg);
- }
- if (lp->d_secsize == 0) {
- msg = "invalid label, d_secsize == 0";
- return (msg);
- }
-
- /* do dos partitions in the process of getting disklabel? */
- dospartoff = 0;
- cyl = I386_LABELSECTOR / lp->d_secpercyl;
-
- /*
- * Read dos partition table, follow extended partitions.
- * Map the partitions to disklabel entries i-p
- */
- while (wander && n < 8 && loop < 8) {
- loop++;
- wander = 0;
- if (part_blkno < extoff)
- part_blkno = extoff;
-
- /* read boot record */
- bp->b_blkno = part_blkno;
- bp->b_bcount = lp->d_secsize;
- bp->b_flags = B_BUSY | B_READ;
- bp->b_cylinder = part_blkno / lp->d_secpercyl;
- (*strat)(bp);
-
- /* if successful, wander through dos partition table */
- if (biowait(bp)) {
- msg = "dos partition I/O error";
- if (partoffp)
- *partoffp = -1;
- return (msg);
- }
- bcopy(bp->b_data + DOSPARTOFF, dp, sizeof(dp));
-
- if (ourpart == -1 && part_blkno == DOSBBSECTOR) {
- /* Search for our MBR partition */
- for (dp2=dp, i=0; i < NDOSPART && ourpart == -1;
- i++, dp2++)
- if (letoh32(dp2->dp_size) &&
- dp2->dp_typ == DOSPTYP_OPENBSD)
- ourpart = i;
- if (ourpart == -1)
- goto donot;
- /*
- * This is our MBR partition. need sector
- * address for SCSI/IDE, cylinder for
- * ESDI/ST506/RLL
- */
- dp2 = &dp[ourpart];
- dospartoff = letoh32(dp2->dp_start) + part_blkno;
- cyl = DPCYL(dp2->dp_scyl, dp2->dp_ssect);
-
- /* XXX build a temporary disklabel */
- DL_SETPSIZE(&lp->d_partitions[0], letoh32(dp2->dp_size));
- DL_SETPOFFSET(&lp->d_partitions[0],
- letoh32(dp2->dp_start) + part_blkno);
- if (lp->d_ntracks == 0)
- lp->d_ntracks = dp2->dp_ehd + 1;
- if (lp->d_nsectors == 0)
- lp->d_nsectors = DPSECT(dp2->dp_esect);
- if (lp->d_secpercyl == 0)
- lp->d_secpercyl = lp->d_ntracks *
- lp->d_nsectors;
- }
-donot:
- /*
- * In case the disklabel read below fails, we want to
- * provide a fake label in i-p.
- */
- for (dp2=dp, i=0; i < NDOSPART && n < 8; i++, dp2++) {
- pp = &lp->d_partitions[8+n];
-
- if (dp2->dp_typ == DOSPTYP_OPENBSD)
- continue;
- if (letoh32(dp2->dp_size) > DL_GETDSIZE(lp))
- continue;
- if (letoh32(dp2->dp_start) > DL_GETDSIZE(lp))
- continue;
- if (letoh32(dp2->dp_size) == 0)
- continue;
- if (letoh32(dp2->dp_start))
- DL_SETPOFFSET(pp,
- letoh32(dp2->dp_start) + part_blkno);
-
- DL_SETPSIZE(pp, letoh32(dp2->dp_size));
-
- switch (dp2->dp_typ) {
- case DOSPTYP_UNUSED:
- pp->p_fstype = FS_UNUSED;
- n++;
- break;
-
- case DOSPTYP_LINUX:
- pp->p_fstype = FS_EXT2FS;
- n++;
- break;
-
- case DOSPTYP_FAT12:
- case DOSPTYP_FAT16S:
- case DOSPTYP_FAT16B:
- case DOSPTYP_FAT16L:
- case DOSPTYP_FAT32:
- case DOSPTYP_FAT32L:
- pp->p_fstype = FS_MSDOS;
- n++;
- break;
- case DOSPTYP_EXTEND:
- case DOSPTYP_EXTENDL:
- part_blkno = letoh32(dp2->dp_start) + extoff;
- if (!extoff) {
- extoff = letoh32(dp2->dp_start);
- part_blkno = 0;
- }
- wander = 1;
- break;
- default:
- pp->p_fstype = FS_OTHER;
- n++;
- break;
- }
- }
- }
- lp->d_bbsize = 8192;
- lp->d_sbsize = 64*1024; /* XXX ? */
- lp->d_npartitions = MAXPARTITIONS;
-
- if (n == 0 && part_blkno == DOSBBSECTOR) {
- /* Check for a short jump instruction. */
- fattest = ((bp->b_data[0] << 8) & 0xff00) | (bp->b_data[2] &
- 0xff);
- if (fattest != 0xeb90 && fattest != 0xe900)
- goto notfat;
-
- /* Check for a valid bytes per sector value. */
- fattest = ((bp->b_data[12] << 8) & 0xff00) | (bp->b_data[11] &
- 0xff);
- if (fattest < 512 || fattest > 4096 || (fattest % 512 != 0))
- goto notfat;
-
- /* Check the end of sector marker. */
- fattest = ((bp->b_data[510] << 8) & 0xff00) | (bp->b_data[511] &
- 0xff);
- if (fattest != 0x55aa)
- goto notfat;
-
- /* Looks like a FAT filesystem. Spoof 'i'. */
- DL_SETPSIZE(&lp->d_partitions['i' - 'a'],
- DL_GETPSIZE(&lp->d_partitions[RAW_PART]));
- DL_SETPOFFSET(&lp->d_partitions['i' - 'a'], 0);
- lp->d_partitions['i' - 'a'].p_fstype = FS_MSDOS;
- }
-notfat:
-
- /* record the OpenBSD partition's placement for the caller */
- if (partoffp)
- *partoffp = dospartoff;
- if (cylp)
- *cylp = cyl;
-
- /* next, dig out disk label */
- msg = readbsdlabel(bp, strat, cyl, dospartoff + I386_LABELSECTOR, -1,
- lp, spoofonly);
-
return (msg);
}
@@ -387,54 +112,31 @@ int
writedisklabel(dev_t dev, void (*strat)(struct buf *),
struct disklabel *lp, struct cpu_disklabel *osdep)
{
- char *msg = "no disk label";
+ u_int64_t csum = 0, *p;
+ struct disklabel *dlp;
struct buf *bp = NULL;
- struct disklabel dl;
- struct cpu_disklabel cdl;
- int labeloffset, error, i, partoff = 0, cyl = 0, needcsum = 0;
- u_int64_t csum, *p;
+ int error, i;
/* get a buffer and initialize it */
bp = geteblk((int)lp->d_secsize);
bp->b_dev = dev;
- /*
- * I once played with the thought of using osdep->label{tag,sector}
- * as a cache for knowing where (and what) to write. However, now I
- * think it might be useful to reprobe if someone has written
- * a newer disklabel of another type with disklabel(8) and -r.
- */
- dl = *lp;
- msg = readbsdlabel(bp, strat, 0, LABELSECTOR, LABELOFFSET, &dl, 0);
- labeloffset = LABELOFFSET;
- if (msg == NULL)
- needcsum = 1;
- if (msg) {
- dl = *lp;
- msg = readdoslabel(bp, strat, &dl, &cdl, &partoff, &cyl, 0);
- labeloffset = I386_LABELOFFSET;
- }
- if (msg) {
- if (partoff == -1) {
- error = EIO;
- goto done;
- }
-
- /* Write it in the regular place with native byte order. */
- labeloffset = LABELOFFSET;
- bp->b_blkno = partoff + LABELSECTOR;
- bp->b_cylinder = cyl;
- bp->b_bcount = lp->d_secsize;
- }
+ bp->b_blkno = LABELSECTOR;
+ bp->b_cylinder = 0;
+ bp->b_bcount = lp->d_secsize;
+ bp->b_flags = B_BUSY | B_READ;
+ (*strat)(bp);
+ if ((error = biowait(bp)) != 0)
+ goto done;
- *(struct disklabel *)(bp->b_data + labeloffset) = *lp;
+ /* Write it in the regular place. */
+ dlp = (struct disklabel *)(bp->b_data + LABELOFFSET);
+ *dlp = *lp;
- /* Alpha bootblocks are checksummed. */
- if (needcsum) {
- for (csum = i = 0, p = (u_int64_t *)bp->b_data; i < 63; i++)
- csum += *p++;
- *p = csum;
- }
+ /* Alpha bootblocks require a checksum over the sector */
+ for (i = 0, p = (u_int64_t *)bp->b_data; i < 63; i++)
+ csum += *p++;
+ *p = csum;
bp->b_flags = B_BUSY | B_WRITE;
(*strat)(bp);
diff --git a/sys/arch/alpha/include/disklabel.h b/sys/arch/alpha/include/disklabel.h
index 12523a08d15..f5c9c41f82e 100644
--- a/sys/arch/alpha/include/disklabel.h
+++ b/sys/arch/alpha/include/disklabel.h
@@ -1,5 +1,4 @@
-/* $OpenBSD: disklabel.h,v 1.20 2007/06/10 05:42:48 krw Exp $ */
-/* $NetBSD: disklabel.h,v 1.1 1995/02/13 23:07:34 cgd Exp $ */
+/* $OpenBSD: disklabel.h,v 1.21 2007/06/17 00:27:24 deraadt Exp $ */
/*
* Copyright (c) 1994 Christopher G. Demetriou
@@ -34,55 +33,9 @@
#ifndef _MACHINE_DISKLABEL_H_
#define _MACHINE_DISKLABEL_H_
-#define I386_LABELSECTOR 1 /* sector containing label */
-#define I386_LABELOFFSET 0 /* offset of label in sector */
-
#define LABELSECTOR 0
#define LABELOFFSET 64
-
#define MAXPARTITIONS 16 /* number of partitions */
-#define RAW_PART 2 /* raw partition: xx?c */
-
-/* DOS partition table -- located in boot block */
-#define DOSBBSECTOR 0 /* DOS boot block relative sector # */
-#define DOSPARTOFF 446
-#define DOSACTIVE 0x80
-#define NDOSPART 4
-#define DOSMBR_SIGNATURE 0xaa55
-#define DOSMBR_SIGNATURE_OFF 0x1fe
-
-struct dos_partition {
- u_int8_t dp_flag; /* bootstrap flags */
- u_int8_t dp_shd; /* starting head */
- u_int8_t dp_ssect; /* starting sector */
- u_int8_t dp_scyl; /* starting cylinder */
- u_int8_t dp_typ; /* partition type (see below) */
- u_int8_t dp_ehd; /* end head */
- u_int8_t dp_esect; /* end sector */
- u_int8_t dp_ecyl; /* end cylinder */
- u_int32_t dp_start; /* absolute starting sector number */
- u_int32_t dp_size; /* partition size in sectors */
-};
-
-/* Known DOS partition types. */
-#define DOSPTYP_UNUSED 0x00 /* Unused partition */
-#define DOSPTYP_FAT12 0x01 /* 12-bit FAT */
-#define DOSPTYP_FAT16S 0x04 /* 16-bit FAT, less than 32M */
-#define DOSPTYP_EXTEND 0x05 /* Extended; contains sub-partitions */
-#define DOSPTYP_FAT16B 0x06 /* 16-bit FAT, more than 32M */
-#define DOSPTYP_FAT32 0x0b /* 32-bit FAT */
-#define DOSPTYP_FAT32L 0x0c /* 32-bit FAT, LBA-mapped */
-#define DOSPTYP_FAT16L 0x0e /* 16-bit FAT, LBA-mapped */
-#define DOSPTYP_EXTENDL 0x0f /* Extended, LBA-mapped; contains sub-partitions */
-#define DOSPTYP_ONTRACK 0x54
-#define DOSPTYP_LINUX 0x83 /* That other thing */
-#define DOSPTYP_FREEBSD 0xa5 /* FreeBSD partition type */
-#define DOSPTYP_OPENBSD 0xa6 /* OpenBSD partition type */
-#define DOSPTYP_NETBSD 0xa9 /* NetBSD partition type */
-
-/* Isolate the relevant bits to get sector and cylinder. */
-#define DPSECT(s) ((s) & 0x3f)
-#define DPCYL(c, s) ((c) + (((s) & 0xc0) << 2))
struct cpu_disklabel {
int labelsector;
diff --git a/sys/arch/amd64/amd64/disksubr.c b/sys/arch/amd64/amd64/disksubr.c
index 437f3674c2e..3dc92c8504f 100644
--- a/sys/arch/amd64/amd64/disksubr.c
+++ b/sys/arch/amd64/amd64/disksubr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: disksubr.c,v 1.49 2007/06/14 03:37:23 deraadt Exp $ */
+/* $OpenBSD: disksubr.c,v 1.50 2007/06/17 00:27:28 deraadt Exp $ */
/* $NetBSD: disksubr.c,v 1.21 1996/05/03 19:42:03 christos Exp $ */
/*
@@ -29,16 +29,12 @@
* 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.
- *
- * @(#)ufs_disksubr.c 7.16 (Berkeley) 5/4/91
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/buf.h>
-#include <sys/device.h>
#include <sys/disklabel.h>
-#include <sys/syslog.h>
#include <sys/disk.h>
#include <sys/reboot.h>
#include <sys/conf.h>
@@ -69,37 +65,13 @@ char *
readdisklabel(dev_t dev, void (*strat)(struct buf *),
struct disklabel *lp, struct cpu_disklabel *osdep, int spoofonly)
{
- struct dos_partition dp[NDOSPART], *dp2;
- struct partition *pp;
- struct disklabel *dlp;
bios_diskinfo_t *pdi;
- unsigned long extoff = 0;
- unsigned int fattest;
struct buf *bp = NULL;
- daddr64_t part_blkno = DOSBBSECTOR;
dev_t devno;
- char *msg = NULL;
- int dospartoff, cyl, i, ourpart = -1;
- int wander = 1, n = 0, loop = 0;
+ char *msg;
- /* minimal requirements for archetypal disk label */
- if (lp->d_secsize < DEV_BSIZE)
- lp->d_secsize = DEV_BSIZE;
- if (DL_GETDSIZE(lp) == 0)
- DL_SETDSIZE(lp, MAXDISKSIZE);
- if (lp->d_secpercyl == 0) {
- msg = "invalid geometry";
+ if ((msg = initdisklabel(lp)))
goto done;
- }
- lp->d_npartitions = RAW_PART + 1;
- for (i = 0; i < RAW_PART; i++) {
- DL_SETPSIZE(&lp->d_partitions[i], 0);
- DL_SETPOFFSET(&lp->d_partitions[i], 0);
- }
- if (DL_GETPSIZE(&lp->d_partitions[RAW_PART]) == 0)
- DL_SETPSIZE(&lp->d_partitions[RAW_PART], DL_GETDSIZE(lp));
- DL_SETPOFFSET(&lp->d_partitions[RAW_PART], 0);
- lp->d_version = 1;
/* Look for any BIOS geometry information we should honour. */
devno = chrtoblk(dev);
@@ -124,193 +96,21 @@ readdisklabel(dev_t dev, void (*strat)(struct buf *),
bp = geteblk((int)lp->d_secsize);
bp->b_dev = dev;
- /* do dos partitions in the process of getting disklabel? */
- dospartoff = 0;
- cyl = LABELSECTOR / lp->d_secpercyl;
-
- /*
- * Read dos partition table, follow extended partitions.
- * Map the partitions to disklabel entries i-p
- */
- while (wander && n < 8 && loop < 8) {
- loop++;
- wander = 0;
- if (part_blkno < extoff)
- part_blkno = extoff;
-
- /* read boot record */
- bp->b_blkno = part_blkno;
- bp->b_bcount = lp->d_secsize;
- bp->b_flags = B_BUSY | B_READ;
- bp->b_cylinder = part_blkno / lp->d_secpercyl;
- (*strat)(bp);
-
- /* if successful, wander through dos partition table */
- if (biowait(bp)) {
- msg = "dos partition I/O error";
- goto done;
- }
- bcopy(bp->b_data + DOSPARTOFF, dp, sizeof(dp));
-
- if (ourpart == -1 && part_blkno == DOSBBSECTOR) {
- /* Search for our MBR partition */
- for (dp2=dp, i=0; i < NDOSPART && ourpart == -1;
- i++, dp2++)
- if (letoh32(dp2->dp_size) &&
- dp2->dp_typ == DOSPTYP_OPENBSD)
- ourpart = i;
- if (ourpart == -1)
- goto donot;
- /*
- * This is our MBR partition. need sector address
- * for SCSI/IDE, cylinder for ESDI/ST506/RLL
- */
- dp2 = &dp[ourpart];
- dospartoff = letoh32(dp2->dp_start) + part_blkno;
- cyl = DPCYL(dp2->dp_scyl, dp2->dp_ssect);
-
- /* XXX build a temporary disklabel */
- DL_SETPSIZE(&lp->d_partitions[0], letoh32(dp2->dp_size));
- DL_SETPOFFSET(&lp->d_partitions[0],
- letoh32(dp2->dp_start) + part_blkno);
- if (lp->d_ntracks == 0)
- lp->d_ntracks = dp2->dp_ehd + 1;
- if (lp->d_nsectors == 0)
- lp->d_nsectors = DPSECT(dp2->dp_esect);
- if (lp->d_secpercyl == 0)
- lp->d_secpercyl = lp->d_ntracks *
- lp->d_nsectors;
- }
-donot:
- /*
- * In case the disklabel read below fails, we want to
- * provide a fake label in i-p.
- */
- for (dp2=dp, i=0; i < NDOSPART && n < 8; i++, dp2++) {
- pp = &lp->d_partitions[8+n];
-
- if (dp2->dp_typ == DOSPTYP_OPENBSD)
- continue;
- if (letoh32(dp2->dp_size) > DL_GETDSIZE(lp))
- continue;
- if (letoh32(dp2->dp_start) > DL_GETDSIZE(lp))
- continue;
- if (letoh32(dp2->dp_size) == 0)
- continue;
- if (letoh32(dp2->dp_start))
- DL_SETPOFFSET(pp,
- letoh32(dp2->dp_start) + part_blkno);
-
- DL_SETPSIZE(pp, letoh32(dp2->dp_size));
-
- switch (dp2->dp_typ) {
- case DOSPTYP_UNUSED:
- pp->p_fstype = FS_UNUSED;
- n++;
- break;
-
- case DOSPTYP_LINUX:
- pp->p_fstype = FS_EXT2FS;
- n++;
- break;
-
- case DOSPTYP_FAT12:
- case DOSPTYP_FAT16S:
- case DOSPTYP_FAT16B:
- case DOSPTYP_FAT16L:
- case DOSPTYP_FAT32:
- case DOSPTYP_FAT32L:
- pp->p_fstype = FS_MSDOS;
- n++;
- break;
- case DOSPTYP_EXTEND:
- case DOSPTYP_EXTENDL:
- part_blkno = letoh32(dp2->dp_start) + extoff;
- if (!extoff) {
- extoff = letoh32(dp2->dp_start);
- part_blkno = 0;
- }
- wander = 1;
- break;
- default:
- pp->p_fstype = FS_OTHER;
- n++;
- break;
- }
- }
- }
- lp->d_bbsize = 8192;
- lp->d_sbsize = 64*1024; /* XXX ? */
- lp->d_npartitions = MAXPARTITIONS;
-
- if (n == 0 && part_blkno == DOSBBSECTOR) {
- /* Check for a short jump instruction. */
- fattest = ((bp->b_data[0] << 8) & 0xff00) | (bp->b_data[2] &
- 0xff);
- if (fattest != 0xeb90 && fattest != 0xe900)
- goto notfat;
-
- /* Check for a valid bytes per sector value. */
- fattest = ((bp->b_data[12] << 8) & 0xff00) | (bp->b_data[11] &
- 0xff);
- if (fattest < 512 || fattest > 4096 || (fattest % 512 != 0))
- goto notfat;
-
- /* Check the end of sector marker. */
- fattest = ((bp->b_data[510] << 8) & 0xff00) | (bp->b_data[511] &
- 0xff);
- if (fattest != 0x55aa)
- goto notfat;
-
- /* Looks like a FAT filesystem. Spoof 'i'. */
- DL_SETPSIZE(&lp->d_partitions['i' - 'a'],
- DL_GETPSIZE(&lp->d_partitions[RAW_PART]));
- DL_SETPOFFSET(&lp->d_partitions['i' - 'a'], 0);
- lp->d_partitions['i' - 'a'].p_fstype = FS_MSDOS;
- }
-notfat:
-
- /* don't read the on-disk label if we are in spoofed-only mode */
- if (spoofonly)
- goto done;
-
- /* next, dig out disk label */
- bp->b_blkno = dospartoff + LABELSECTOR;
- bp->b_cylinder = cyl;
- bp->b_bcount = lp->d_secsize;
- bp->b_flags = B_BUSY | B_READ;
- (*strat)(bp);
-
- /* if successful, locate disk label within block and validate */
- if (biowait(bp)) {
- /* XXX we return the faked label built so far */
- msg = "disk label I/O error";
+ msg = readdoslabel(bp, strat, lp, osdep, NULL, NULL, spoofonly);
+ if (msg == NULL)
goto done;
- }
- for (dlp = (struct disklabel *)bp->b_data;
- dlp <= (struct disklabel *)(bp->b_data + lp->d_secsize - sizeof(*dlp));
- dlp = (struct disklabel *)((char *)dlp + sizeof(long))) {
- if (dlp->d_magic != DISKMAGIC || dlp->d_magic2 != DISKMAGIC) {
- if (msg == NULL)
- msg = "no disk label";
- } else if (dlp->d_npartitions > MAXPARTITIONS ||
- dkcksum(dlp) != 0)
- msg = "disk label corrupted";
- else {
- DL_SETDSIZE(dlp, DL_GETDSIZE(lp));
- *lp = *dlp;
- msg = NULL;
- break;
- }
- }
#if defined(CD9660)
- if (msg && iso_disklabelspoof(dev, strat, lp) == 0)
+ if (iso_disklabelspoof(dev, strat, lp) == 0) {
msg = NULL;
+ goto done;
+ }
#endif
#if defined(UDF)
- if (msg && udf_disklabelspoof(dev, strat, lp) == 0)
+ if (udf_disklabelspoof(dev, strat, lp) == 0) {
msg = NULL;
+ goto done;
+ }
#endif
done:
@@ -318,7 +118,6 @@ done:
bp->b_flags |= B_INVAL;
brelse(bp);
}
- disklabeltokernlabel(lp);
return (msg);
}
@@ -330,73 +129,30 @@ int
writedisklabel(dev_t dev, void (*strat)(struct buf *),
struct disklabel *lp, struct cpu_disklabel *osdep)
{
- struct dos_partition dp[NDOSPART], *dp2;
+ int error, partoff = -1, cyl = 0;
struct disklabel *dlp;
struct buf *bp = NULL;
- int error, dospartoff, cyl, i;
- int ourpart = -1;
/* get a buffer and initialize it */
bp = geteblk((int)lp->d_secsize);
bp->b_dev = dev;
- /* do dos partitions in the process of getting disklabel? */
- dospartoff = 0;
- cyl = LABELSECTOR / lp->d_secpercyl;
-
- /* read master boot record */
- 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 ((error = biowait(bp)) != 0)
+ if (readdoslabel(bp, strat, lp, osdep, &partoff, &cyl, 1) != NULL) {
+ error = EIO;
goto done;
-
- /* XXX how do we check veracity/bounds of this? */
- bcopy(bp->b_data + DOSPARTOFF, dp, sizeof(dp));
-
- for (dp2=dp, i=0; i < NDOSPART && ourpart == -1; i++, dp2++)
- if (letoh32(dp2->dp_size) && dp2->dp_typ == DOSPTYP_OPENBSD)
- ourpart = i;
-
- if (ourpart != -1) {
- dp2 = &dp[ourpart];
-
- /*
- * need sector address for SCSI/IDE,
- * cylinder for ESDI/ST506/RLL
- */
- dospartoff = letoh32(dp2->dp_start);
- cyl = DPCYL(dp2->dp_scyl, dp2->dp_ssect);
}
- /* next, dig out disk label */
- bp->b_blkno = dospartoff + LABELSECTOR;
+ /* Read it in, slap the new label in, and write it back out */
+ bp->b_blkno = partoff + LABELSECTOR;
bp->b_cylinder = cyl;
bp->b_bcount = lp->d_secsize;
bp->b_flags = B_BUSY | B_READ;
(*strat)(bp);
-
- /* if successful, locate disk label within block and validate */
if ((error = biowait(bp)) != 0)
goto done;
- for (dlp = (struct disklabel *)bp->b_data;
- dlp <= (struct disklabel *)(bp->b_data + lp->d_secsize - sizeof(*dlp));
- dlp = (struct disklabel *)((char *)dlp + sizeof(long))) {
- if (dlp->d_magic == DISKMAGIC && dlp->d_magic2 == DISKMAGIC &&
- dkcksum(dlp) == 0) {
- *dlp = *lp;
- bp->b_flags = B_BUSY | B_WRITE;
- (*strat)(bp);
- error = biowait(bp);
- goto done;
- }
- }
- /* Write it in the regular place. */
- *(struct disklabel *)bp->b_data = *lp;
+ dlp = (struct disklabel *)(bp->b_data + LABELOFFSET);
+ *dlp = *lp;
bp->b_flags = B_BUSY | B_WRITE;
(*strat)(bp);
error = biowait(bp);
diff --git a/sys/arch/amd64/include/disklabel.h b/sys/arch/amd64/include/disklabel.h
index 0851f8a57b9..12c78faa294 100644
--- a/sys/arch/amd64/include/disklabel.h
+++ b/sys/arch/amd64/include/disklabel.h
@@ -1,5 +1,4 @@
-/* $OpenBSD: disklabel.h,v 1.8 2006/10/20 23:47:42 krw Exp $ */
-/* $NetBSD: disklabel.h,v 1.3 1996/03/09 20:52:54 ghudson Exp $ */
+/* $OpenBSD: disklabel.h,v 1.9 2007/06/17 00:27:26 deraadt Exp $ */
/*
* Copyright (c) 1994 Christopher G. Demetriou
@@ -37,58 +36,8 @@
#define LABELSECTOR 1 /* sector containing label */
#define LABELOFFSET 0 /* offset of label in sector */
#define MAXPARTITIONS 16 /* number of partitions */
-#define RAW_PART 2 /* raw partition: ie. rsd0c */
-
-/* DOS partition table -- located in boot block */
-#define DOSBBSECTOR 0 /* DOS boot block relative sector # */
-#define DOSPARTOFF 446
-#define DOSDISKOFF 444
-#define NDOSPART 4
-#define DOSACTIVE 0x80 /* active partition */
-
-struct dos_partition {
- u_int8_t dp_flag; /* bootstrap flags */
- u_int8_t dp_shd; /* starting head */
- u_int8_t dp_ssect; /* starting sector */
- u_int8_t dp_scyl; /* starting cylinder */
- u_int8_t dp_typ; /* partition type (see below) */
- u_int8_t dp_ehd; /* end head */
- u_int8_t dp_esect; /* end sector */
- u_int8_t dp_ecyl; /* end cylinder */
- u_int32_t dp_start; /* absolute starting sector number */
- u_int32_t dp_size; /* partition size in sectors */
-};
-
-/* Known DOS partition types. */
-#define DOSPTYP_UNUSED 0x00 /* Unused partition */
-#define DOSPTYP_FAT12 0x01 /* 12-bit FAT */
-#define DOSPTYP_FAT16S 0x04 /* 16-bit FAT, less than 32M */
-#define DOSPTYP_EXTEND 0x05 /* Extended; contains sub-partitions */
-#define DOSPTYP_FAT16B 0x06 /* 16-bit FAT, more than 32M */
-#define DOSPTYP_FAT32 0x0b /* 32-bit FAT */
-#define DOSPTYP_FAT32L 0x0c /* 32-bit FAT, LBA-mapped */
-#define DOSPTYP_FAT16L 0x0e /* 16-bit FAT, LBA-mapped */
-#define DOSPTYP_EXTENDL 0x0f /* Extended, LBA-mapped; contains sub-partitions */
-#define DOSPTYP_ONTRACK 0x54
-#define DOSPTYP_LINUX 0x83 /* That other thing */
-#define DOSPTYP_FREEBSD 0xa5 /* FreeBSD partition type */
-#define DOSPTYP_OPENBSD 0xa6 /* OpenBSD partition type */
-#define DOSPTYP_NETBSD 0xa9 /* NetBSD partition type */
-
-struct dos_mbr {
- u_int8_t dmbr_boot[DOSPARTOFF];
- struct dos_partition dmbr_parts[NDOSPART];
- u_int16_t dmbr_sign;
-} __packed;
-
-#define DOSMBR_SIGNATURE (0xaa55)
-#define DOSMBR_SIGNATURE_OFF (0x1fe)
struct cpu_disklabel {
};
-/* Isolate the relevant bits to get sector and cylinder. */
-#define DPSECT(s) ((s) & 0x3f)
-#define DPCYL(c, s) ((c) + (((s) & 0xc0) << 2))
-
#endif /* _MACHINE_DISKLABEL_H_ */
diff --git a/sys/arch/arm/arm/disksubr.c b/sys/arch/arm/arm/disksubr.c
index f8b9d9eaa97..fe58a178d2c 100644
--- a/sys/arch/arm/arm/disksubr.c
+++ b/sys/arch/arm/arm/disksubr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: disksubr.c,v 1.44 2007/06/14 03:37:23 deraadt Exp $ */
+/* $OpenBSD: disksubr.c,v 1.45 2007/06/17 00:27:28 deraadt Exp $ */
/* $NetBSD: disksubr.c,v 1.21 1996/05/03 19:42:03 christos Exp $ */
/*
@@ -29,16 +29,12 @@
* 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.
- *
- * @(#)ufs_disksubr.c 7.16 (Berkeley) 5/4/91
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/buf.h>
-#include <sys/device.h>
#include <sys/disklabel.h>
-#include <sys/syslog.h>
#include <sys/disk.h>
/*
@@ -63,227 +59,31 @@ char *
readdisklabel(dev_t dev, void (*strat)(struct buf *),
struct disklabel *lp, struct cpu_disklabel *osdep, int spoofonly)
{
- struct dos_partition dp[NDOSPART], *dp2;
- struct partition *pp;
- struct disklabel *dlp;
- unsigned long extoff = 0;
- unsigned int fattest;
struct buf *bp = NULL;
- daddr64_t part_blkno = DOSBBSECTOR;
- char *msg = NULL;
- int dospartoff, cyl, i, ourpart = -1;
- int wander = 1, n = 0, loop = 0;
+ char *msg;
- /* minimal requirements for archetypal disk label */
- if (lp->d_secsize < DEV_BSIZE)
- lp->d_secsize = DEV_BSIZE;
- if (DL_GETDSIZE(lp) == 0)
- DL_SETDSIZE(lp, MAXDISKSIZE);
- if (lp->d_secpercyl == 0) {
- msg = "invalid geometry";
+ if ((msg = initdisklabel(lp)))
goto done;
- }
- lp->d_npartitions = RAW_PART + 1;
- for (i = 0; i < RAW_PART; i++) {
- DL_SETPSIZE(&lp->d_partitions[i], 0);
- DL_SETPOFFSET(&lp->d_partitions[i], 0);
- }
- if (DL_GETPSIZE(&lp->d_partitions[RAW_PART]) == 0)
- DL_SETPSIZE(&lp->d_partitions[RAW_PART], DL_GETDSIZE(lp));
- DL_SETPOFFSET(&lp->d_partitions[RAW_PART], 0);
- lp->d_version = 1;
/* get a buffer and initialize it */
bp = geteblk((int)lp->d_secsize);
bp->b_dev = dev;
- /* do dos partitions in the process of getting disklabel? */
- dospartoff = 0;
- cyl = LABELSECTOR / lp->d_secpercyl;
-
- /*
- * Read dos partition table, follow extended partitions.
- * Map the partitions to disklabel entries i-p
- */
- while (wander && n < 8 && loop < 8) {
- loop++;
- wander = 0;
- if (part_blkno < extoff)
- part_blkno = extoff;
-
- /* read boot record */
- bp->b_blkno = part_blkno;
- bp->b_bcount = lp->d_secsize;
- bp->b_flags = B_BUSY | B_READ;
- bp->b_cylinder = part_blkno / lp->d_secpercyl;
- (*strat)(bp);
-
- /* if successful, wander through dos partition table */
- if (biowait(bp)) {
- msg = "dos partition I/O error";
- goto done;
- }
- bcopy(bp->b_data + DOSPARTOFF, dp, sizeof(dp));
-
- if (ourpart == -1 && part_blkno == DOSBBSECTOR) {
- /* Search for our MBR partition */
- for (dp2=dp, i=0; i < NDOSPART && ourpart == -1;
- i++, dp2++)
- if (letoh32(dp2->dp_size) &&
- dp2->dp_typ == DOSPTYP_OPENBSD)
- ourpart = i;
- if (ourpart == -1)
- goto donot;
- /*
- * This is our MBR partition. need sector address
- * for SCSI/IDE, cylinder for ESDI/ST506/RLL
- */
- dp2 = &dp[ourpart];
- dospartoff = letoh32(dp2->dp_start) + part_blkno;
- cyl = DPCYL(dp2->dp_scyl, dp2->dp_ssect);
-
- /* XXX build a temporary disklabel */
- DL_SETPSIZE(&lp->d_partitions[0], letoh32(dp2->dp_size));
- DL_SETPOFFSET(&lp->d_partitions[0],
- letoh32(dp2->dp_start) + part_blkno);
- if (lp->d_ntracks == 0)
- lp->d_ntracks = dp2->dp_ehd + 1;
- if (lp->d_nsectors == 0)
- lp->d_nsectors = DPSECT(dp2->dp_esect);
- if (lp->d_secpercyl == 0)
- lp->d_secpercyl = lp->d_ntracks *
- lp->d_nsectors;
- }
-donot:
- /*
- * In case the disklabel read below fails, we want to
- * provide a fake label in i-p.
- */
- for (dp2=dp, i=0; i < NDOSPART && n < 8; i++, dp2++) {
- pp = &lp->d_partitions[8+n];
-
- if (dp2->dp_typ == DOSPTYP_OPENBSD)
- continue;
- if (letoh32(dp2->dp_size) > DL_GETDSIZE(lp))
- continue;
- if (letoh32(dp2->dp_start) > DL_GETDSIZE(lp))
- continue;
- if (letoh32(dp2->dp_size) == 0)
- continue;
- if (letoh32(dp2->dp_start))
- DL_SETPOFFSET(pp,
- letoh32(dp2->dp_start) + part_blkno);
-
- DL_SETPSIZE(pp, letoh32(dp2->dp_size));
-
- switch (dp2->dp_typ) {
- case DOSPTYP_UNUSED:
- pp->p_fstype = FS_UNUSED;
- n++;
- break;
-
- case DOSPTYP_LINUX:
- pp->p_fstype = FS_EXT2FS;
- n++;
- break;
-
- case DOSPTYP_FAT12:
- case DOSPTYP_FAT16S:
- case DOSPTYP_FAT16B:
- case DOSPTYP_FAT16L:
- case DOSPTYP_FAT32:
- case DOSPTYP_FAT32L:
- pp->p_fstype = FS_MSDOS;
- n++;
- break;
- case DOSPTYP_EXTEND:
- case DOSPTYP_EXTENDL:
- part_blkno = letoh32(dp2->dp_start) + extoff;
- if (!extoff) {
- extoff = letoh32(dp2->dp_start);
- part_blkno = 0;
- }
- wander = 1;
- break;
- default:
- pp->p_fstype = FS_OTHER;
- n++;
- break;
- }
- }
- }
- lp->d_bbsize = 8192;
- lp->d_sbsize = 64*1024; /* XXX ? */
- lp->d_npartitions = MAXPARTITIONS;
-
- if (n == 0 && part_blkno == DOSBBSECTOR) {
- /* Check for a short jump instruction. */
- fattest = ((bp->b_data[0] << 8) & 0xff00) | (bp->b_data[2] &
- 0xff);
- if (fattest != 0xeb90 && fattest != 0xe900)
- goto notfat;
-
- /* Check for a valid bytes per sector value. */
- fattest = ((bp->b_data[12] << 8) & 0xff00) | (bp->b_data[11] &
- 0xff);
- if (fattest < 512 || fattest > 4096 || (fattest % 512 != 0))
- goto notfat;
-
- /* Check the end of sector marker. */
- fattest = ((bp->b_data[510] << 8) & 0xff00) | (bp->b_data[511] &
- 0xff);
- if (fattest != 0x55aa)
- goto notfat;
-
- /* Looks like a FAT filesystem. Spoof 'i'. */
- DL_SETPSIZE(&lp->d_partitions['i' - 'a'],
- DL_GETPSIZE(&lp->d_partitions[RAW_PART]));
- DL_SETPOFFSET(&lp->d_partitions['i' - 'a'], 0);
- lp->d_partitions['i' - 'a'].p_fstype = FS_MSDOS;
- }
-notfat:
-
- /* don't read the on-disk label if we are in spoofed-only mode */
- if (spoofonly)
- goto done;
-
- /* next, dig out disk label */
- bp->b_blkno = dospartoff + LABELSECTOR;
- bp->b_cylinder = cyl;
- bp->b_bcount = lp->d_secsize;
- bp->b_flags = B_BUSY | B_READ;
- (*strat)(bp);
-
- /* if successful, locate disk label within block and validate */
- if (biowait(bp)) {
- /* XXX we return the faked label built so far */
- msg = "disk label I/O error";
+ msg = readdoslabel(bp, strat, lp, osdep, NULL, NULL, spoofonly);
+ if (msg == NULL)
goto done;
- }
- for (dlp = (struct disklabel *)bp->b_data;
- dlp <= (struct disklabel *)(bp->b_data + lp->d_secsize - sizeof(*dlp));
- dlp = (struct disklabel *)((char *)dlp + sizeof(long))) {
- if (dlp->d_magic != DISKMAGIC || dlp->d_magic2 != DISKMAGIC) {
- if (msg == NULL)
- msg = "no disk label";
- } else if (dlp->d_npartitions > MAXPARTITIONS ||
- dkcksum(dlp) != 0)
- msg = "disk label corrupted";
- else {
- DL_SETDSIZE(dlp, DL_GETDSIZE(lp));
- *lp = *dlp;
- msg = NULL;
- break;
- }
- }
#if defined(CD9660)
- if (msg && iso_disklabelspoof(dev, strat, lp) == 0)
+ if (iso_disklabelspoof(dev, strat, lp) == 0) {
msg = NULL;
+ goto done;
+ }
#endif
#if defined(UDF)
- if (msg && udf_disklabelspoof(dev, strat, lp) == 0)
+ if (udf_disklabelspoof(dev, strat, lp) == 0) {
msg = NULL;
+ goto done;
+ }
#endif
done:
@@ -291,7 +91,6 @@ done:
bp->b_flags |= B_INVAL;
brelse(bp);
}
- disklabeltokernlabel(lp);
return (msg);
}
@@ -303,73 +102,30 @@ int
writedisklabel(dev_t dev, void (*strat)(struct buf *),
struct disklabel *lp, struct cpu_disklabel *osdep)
{
- struct dos_partition dp[NDOSPART], *dp2;
+ int error, partoff = -1, cyl = 0;
struct disklabel *dlp;
struct buf *bp = NULL;
- int error, dospartoff, cyl, i;
- int ourpart = -1;
/* get a buffer and initialize it */
bp = geteblk((int)lp->d_secsize);
bp->b_dev = dev;
- /* do dos partitions in the process of getting disklabel? */
- dospartoff = 0;
- cyl = LABELSECTOR / lp->d_secpercyl;
-
- /* read master boot record */
- 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 ((error = biowait(bp)) != 0)
+ if (readdoslabel(bp, strat, lp, osdep, &partoff, &cyl, 1) != NULL) {
+ error = EIO;
goto done;
-
- /* XXX how do we check veracity/bounds of this? */
- bcopy(bp->b_data + DOSPARTOFF, dp, sizeof(dp));
-
- for (dp2=dp, i=0; i < NDOSPART && ourpart == -1; i++, dp2++)
- if (letoh32(dp2->dp_size) && dp2->dp_typ == DOSPTYP_OPENBSD)
- ourpart = i;
-
- if (ourpart != -1) {
- dp2 = &dp[ourpart];
-
- /*
- * need sector address for SCSI/IDE,
- * cylinder for ESDI/ST506/RLL
- */
- dospartoff = letoh32(dp2->dp_start);
- cyl = DPCYL(dp2->dp_scyl, dp2->dp_ssect);
}
- /* next, dig out disk label */
- bp->b_blkno = dospartoff + LABELSECTOR;
+ /* Read it in, slap the new label in, and write it back out */
+ bp->b_blkno = partoff + LABELSECTOR;
bp->b_cylinder = cyl;
bp->b_bcount = lp->d_secsize;
bp->b_flags = B_BUSY | B_READ;
(*strat)(bp);
-
- /* if successful, locate disk label within block and validate */
if ((error = biowait(bp)) != 0)
goto done;
- for (dlp = (struct disklabel *)bp->b_data;
- dlp <= (struct disklabel *)(bp->b_data + lp->d_secsize - sizeof(*dlp));
- dlp = (struct disklabel *)((char *)dlp + sizeof(long))) {
- if (dlp->d_magic == DISKMAGIC && dlp->d_magic2 == DISKMAGIC &&
- dkcksum(dlp) == 0) {
- *dlp = *lp;
- bp->b_flags = B_BUSY | B_WRITE;
- (*strat)(bp);
- error = biowait(bp);
- goto done;
- }
- }
- /* Write it in the regular place. */
- *(struct disklabel *)bp->b_data = *lp;
+ dlp = (struct disklabel *)(bp->b_data + LABELOFFSET);
+ *dlp = *lp;
bp->b_flags = B_BUSY | B_WRITE;
(*strat)(bp);
error = biowait(bp);
diff --git a/sys/arch/arm/include/disklabel.h b/sys/arch/arm/include/disklabel.h
index d0ca438166d..621c3ae8de1 100644
--- a/sys/arch/arm/include/disklabel.h
+++ b/sys/arch/arm/include/disklabel.h
@@ -1,6 +1,4 @@
-/* $OpenBSD: disklabel.h,v 1.11 2006/10/20 23:47:42 krw Exp $ */
-/* $OpenBSD: disklabel.h,v 1.11 2006/10/20 23:47:42 krw Exp $ */
-/* $NetBSD: disklabel.h,v 1.2 2001/11/25 19:02:03 thorpej Exp $ */
+/* $OpenBSD: disklabel.h,v 1.12 2007/06/17 00:27:26 deraadt Exp $ */
/*
* Copyright (c) 1994 Mark Brinicombe.
@@ -35,14 +33,6 @@
* 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.
- *
- * RiscBSD kernel project
- *
- * disklabel.h
- *
- * machine specific disk label info
- *
- * Created : 04/10/94
*/
#ifndef _ARM_DISKLABEL_H_
@@ -51,58 +41,6 @@
#define LABELSECTOR 1 /* sector containing label */
#define LABELOFFSET 0 /* offset of label in sector */
#define MAXPARTITIONS 16 /* number of partitions */
-#define RAW_PART 2 /* raw partition: XX?c */
-
-#if 0
-#include <arm/disklabel_acorn.h>
-#include <sys/disklabel_mbr.h>
-#endif
-
-/* MBR partition table */
-#define DOSBBSECTOR 0 /* MBR sector number */
-#define DOSPARTOFF 446 /* Offset of MBR partition table */
-#define NDOSPART 4 /* # of partitions in MBR */
-#define DOSMAGICOFF 510 /* Offset of magic number */
-#define DOSMAGIC 0xaa55 /* Actual magic number */
-#define MBRMAGIC DOSMAGIC
-#define DOSMBR_SIGNATURE MBRMAGIC
-#define DOSMBR_SIGNATURE_OFF DOSMAGICOFF
-#define DOSACTIVE 0x80
-
-
-struct dos_partition {
- u_int8_t dp_flag; /* bootstrap flags */
- u_int8_t dp_shd; /* starting head */
- u_int8_t dp_ssect; /* starting sector */
- u_int8_t dp_scyl; /* starting cylinder */
- u_int8_t dp_typ; /* partition type (see below) */
- u_int8_t dp_ehd; /* end head */
- u_int8_t dp_esect; /* end sector */
- u_int8_t dp_ecyl; /* end cylinder */
- u_int32_t dp_start; /* absolute starting sector number */
- u_int32_t dp_size; /* partition size in sectors */
-};
-
-/* Known DOS partition types. */
-#define DOSPTYP_UNUSED 0x00 /* Unused partition */
-#define DOSPTYP_FAT12 0x01 /* 12-bit FAT */
-#define DOSPTYP_FAT16S 0x04 /* 16-bit FAT, less than 32M */
-#define DOSPTYP_EXTEND 0x05 /* Extended; contains sub-partitions */
-#define DOSPTYP_FAT16B 0x06 /* 16-bit FAT, more than 32M */
-#define DOSPTYP_FAT32 0x0b /* 32-bit FAT */
-#define DOSPTYP_FAT32L 0x0c /* 32-bit FAT, LBA-mapped */
-#define DOSPTYP_FAT16L 0x0e /* 16-bit FAT, LBA-mapped */
-#define DOSPTYP_EXTENDL 0x0f /* Extended, LBA-mapped; contains sub-partitions */
-#define DOSPTYP_ONTRACK 0x54
-#define DOSPTYP_LINUX 0x83 /* That other thing */
-#define DOSPTYP_FREEBSD 0xa5 /* FreeBSD partition type */
-#define DOSPTYP_OPENBSD 0xa6 /* OpenBSD partition type */
-#define DOSPTYP_NETBSD 0xa9 /* NetBSD partition type */
-
-/* Isolate the relevant bits to get sector and cylinder. */
-#define DPSECT(s) ((s) & 0x3f)
-#define DPCYL(c, s) ((c) + (((s) & 0xc0) << 2))
-
struct cpu_disklabel {
};
diff --git a/sys/arch/armish/include/disklabel.h b/sys/arch/armish/include/disklabel.h
index cef55a0c6c6..1c9c62e6cce 100644
--- a/sys/arch/armish/include/disklabel.h
+++ b/sys/arch/armish/include/disklabel.h
@@ -1,4 +1,3 @@
-/* $OpenBSD: disklabel.h,v 1.1 2006/05/29 17:13:19 drahn Exp $ */
-/* $NetBSD: disklabel.h,v 1.3 2001/11/25 15:55:55 thorpej Exp $ */
+/* $OpenBSD: disklabel.h,v 1.2 2007/06/17 00:27:26 deraadt Exp $ */
#include <arm/disklabel.h>
diff --git a/sys/arch/aviion/aviion/disksubr.c b/sys/arch/aviion/aviion/disksubr.c
index b3b1593aa14..db0f865e2c9 100644
--- a/sys/arch/aviion/aviion/disksubr.c
+++ b/sys/arch/aviion/aviion/disksubr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: disksubr.c,v 1.35 2007/06/14 03:37:23 deraadt Exp $ */
+/* $OpenBSD: disksubr.c,v 1.36 2007/06/17 00:27:28 deraadt Exp $ */
/* $NetBSD: disksubr.c,v 1.21 1996/05/03 19:42:03 christos Exp $ */
/*
@@ -29,16 +29,12 @@
* 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.
- *
- * @(#)ufs_disksubr.c 7.16 (Berkeley) 5/4/91
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/buf.h>
-#include <sys/device.h>
#include <sys/disklabel.h>
-#include <sys/syslog.h>
#include <sys/disk.h>
/*
@@ -63,227 +59,31 @@ char *
readdisklabel(dev_t dev, void (*strat)(struct buf *),
struct disklabel *lp, struct cpu_disklabel *osdep, int spoofonly)
{
- struct dos_partition dp[NDOSPART], *dp2;
- struct partition *pp;
- struct disklabel *dlp;
- unsigned long extoff = 0;
- unsigned int fattest;
struct buf *bp = NULL;
- daddr64_t part_blkno = DOSBBSECTOR;
- char *msg = NULL;
- int dospartoff, cyl, i, ourpart = -1;
- int wander = 1, n = 0, loop = 0;
+ char *msg;
- /* minimal requirements for archetypal disk label */
- if (lp->d_secsize < DEV_BSIZE)
- lp->d_secsize = DEV_BSIZE;
- if (DL_GETDSIZE(lp) == 0)
- DL_SETDSIZE(lp, MAXDISKSIZE);
- if (lp->d_secpercyl == 0) {
- msg = "invalid geometry";
+ if ((msg = initdisklabel(lp)))
goto done;
- }
- lp->d_npartitions = RAW_PART + 1;
- for (i = 0; i < RAW_PART; i++) {
- DL_SETPSIZE(&lp->d_partitions[i], 0);
- DL_SETPOFFSET(&lp->d_partitions[i], 0);
- }
- if (DL_GETPSIZE(&lp->d_partitions[RAW_PART]) == 0)
- DL_SETPSIZE(&lp->d_partitions[RAW_PART], DL_GETDSIZE(lp));
- DL_SETPOFFSET(&lp->d_partitions[RAW_PART], 0);
- lp->d_version = 1;
/* get a buffer and initialize it */
bp = geteblk((int)lp->d_secsize);
bp->b_dev = dev;
- /* do dos partitions in the process of getting disklabel? */
- dospartoff = 0;
- cyl = LABELSECTOR / lp->d_secpercyl;
-
- /*
- * Read dos partition table, follow extended partitions.
- * Map the partitions to disklabel entries i-p
- */
- while (wander && n < 8 && loop < 8) {
- loop++;
- wander = 0;
- if (part_blkno < extoff)
- part_blkno = extoff;
-
- /* read boot record */
- bp->b_blkno = part_blkno;
- bp->b_bcount = lp->d_secsize;
- bp->b_flags = B_BUSY | B_READ;
- bp->b_cylinder = part_blkno / lp->d_secpercyl;
- (*strat)(bp);
-
- /* if successful, wander through dos partition table */
- if (biowait(bp)) {
- msg = "dos partition I/O error";
- goto done;
- }
- bcopy(bp->b_data + DOSPARTOFF, dp, sizeof(dp));
-
- if (ourpart == -1 && part_blkno == DOSBBSECTOR) {
- /* Search for our MBR partition */
- for (dp2=dp, i=0; i < NDOSPART && ourpart == -1;
- i++, dp2++)
- if (letoh32(dp2->dp_size) &&
- dp2->dp_typ == DOSPTYP_OPENBSD)
- ourpart = i;
- if (ourpart == -1)
- goto donot;
- /*
- * This is our MBR partition. need sector address
- * for SCSI/IDE, cylinder for ESDI/ST506/RLL
- */
- dp2 = &dp[ourpart];
- dospartoff = letoh32(dp2->dp_start) + part_blkno;
- cyl = DPCYL(dp2->dp_scyl, dp2->dp_ssect);
-
- /* XXX build a temporary disklabel */
- DL_SETPSIZE(&lp->d_partitions[0], letoh32(dp2->dp_size));
- DL_SETPOFFSET(&lp->d_partitions[0],
- letoh32(dp2->dp_start) + part_blkno);
- if (lp->d_ntracks == 0)
- lp->d_ntracks = dp2->dp_ehd + 1;
- if (lp->d_nsectors == 0)
- lp->d_nsectors = DPSECT(dp2->dp_esect);
- if (lp->d_secpercyl == 0)
- lp->d_secpercyl = lp->d_ntracks *
- lp->d_nsectors;
- }
-donot:
- /*
- * In case the disklabel read below fails, we want to
- * provide a fake label in i-p.
- */
- for (dp2=dp, i=0; i < NDOSPART && n < 8; i++, dp2++) {
- pp = &lp->d_partitions[8+n];
-
- if (dp2->dp_typ == DOSPTYP_OPENBSD)
- continue;
- if (letoh32(dp2->dp_size) > DL_GETDSIZE(lp))
- continue;
- if (letoh32(dp2->dp_start) > DL_GETDSIZE(lp))
- continue;
- if (letoh32(dp2->dp_size) == 0)
- continue;
- if (letoh32(dp2->dp_start))
- DL_SETPOFFSET(pp,
- letoh32(dp2->dp_start) + part_blkno);
-
- DL_SETPSIZE(pp, letoh32(dp2->dp_size));
-
- switch (dp2->dp_typ) {
- case DOSPTYP_UNUSED:
- pp->p_fstype = FS_UNUSED;
- n++;
- break;
-
- case DOSPTYP_LINUX:
- pp->p_fstype = FS_EXT2FS;
- n++;
- break;
-
- case DOSPTYP_FAT12:
- case DOSPTYP_FAT16S:
- case DOSPTYP_FAT16B:
- case DOSPTYP_FAT16L:
- case DOSPTYP_FAT32:
- case DOSPTYP_FAT32L:
- pp->p_fstype = FS_MSDOS;
- n++;
- break;
- case DOSPTYP_EXTEND:
- case DOSPTYP_EXTENDL:
- part_blkno = letoh32(dp2->dp_start) + extoff;
- if (!extoff) {
- extoff = letoh32(dp2->dp_start);
- part_blkno = 0;
- }
- wander = 1;
- break;
- default:
- pp->p_fstype = FS_OTHER;
- n++;
- break;
- }
- }
- }
- lp->d_bbsize = 8192;
- lp->d_sbsize = 64*1024; /* XXX ? */
- lp->d_npartitions = MAXPARTITIONS;
-
- if (n == 0 && part_blkno == DOSBBSECTOR) {
- /* Check for a short jump instruction. */
- fattest = ((bp->b_data[0] << 8) & 0xff00) | (bp->b_data[2] &
- 0xff);
- if (fattest != 0xeb90 && fattest != 0xe900)
- goto notfat;
-
- /* Check for a valid bytes per sector value. */
- fattest = ((bp->b_data[12] << 8) & 0xff00) | (bp->b_data[11] &
- 0xff);
- if (fattest < 512 || fattest > 4096 || (fattest % 512 != 0))
- goto notfat;
-
- /* Check the end of sector marker. */
- fattest = ((bp->b_data[510] << 8) & 0xff00) | (bp->b_data[511] &
- 0xff);
- if (fattest != 0x55aa)
- goto notfat;
-
- /* Looks like a FAT filesystem. Spoof 'i'. */
- DL_SETPSIZE(&lp->d_partitions['i' - 'a'],
- DL_GETPSIZE(&lp->d_partitions[RAW_PART]));
- DL_GETPOFFSET(&lp->d_partitions['i' - 'a'], 0);
- lp->d_partitions['i' - 'a'].p_fstype = FS_MSDOS;
- }
-notfat:
-
- /* don't read the on-disk label if we are in spoofed-only mode */
- if (spoofonly)
+ msg = readdoslabel(bp, strat, lp, osdep, NULL, NULL, spoofonly);
+ if (msg == NULL)
goto done;
- /* next, dig out disk label */
- bp->b_blkno = dospartoff + LABELSECTOR;
- bp->b_cylinder = cyl;
- bp->b_bcount = lp->d_secsize;
- bp->b_flags = B_BUSY | B_READ;
- (*strat)(bp);
-
- /* if successful, locate disk label within block and validate */
- if (biowait(bp)) {
- /* XXX we return the faked label built so far */
- msg = "disk label I/O error";
- goto done;
- }
- for (dlp = (struct disklabel *)bp->b_data;
- dlp <= (struct disklabel *)(bp->b_data + lp->d_secsize - sizeof(*dlp));
- dlp = (struct disklabel *)((char *)dlp + sizeof(long))) {
- if (dlp->d_magic != DISKMAGIC || dlp->d_magic2 != DISKMAGIC) {
- if (msg == NULL)
- msg = "no disk label";
- } else if (dlp->d_npartitions > MAXPARTITIONS ||
- dkcksum(dlp) != 0)
- msg = "disk label corrupted";
- else {
- DL_SETDSIZE(dlp, DL_GETDSIZE(lp));
- *lp = *dlp;
- msg = NULL;
- break;
- }
- }
-
#if defined(CD9660)
- if (msg && iso_disklabelspoof(dev, strat, lp) == 0)
+ if (iso_disklabelspoof(dev, strat, lp) == 0) {
msg = NULL;
+ goto done;
+ }
#endif
#if defined(UDF)
- if (msg && udf_disklabelspoof(dev, strat, lp) == 0)
+ if (udf_disklabelspoof(dev, strat, lp) == 0) {
msg = NULL;
+ goto done;
+ }
#endif
done:
@@ -291,7 +91,6 @@ done:
bp->b_flags |= B_INVAL;
brelse(bp);
}
- disklabeltokernlabel(lp);
return (msg);
}
@@ -303,72 +102,30 @@ int
writedisklabel(dev_t dev, void (*strat)(struct buf *),
struct disklabel *lp, struct cpu_disklabel *osdep)
{
- struct dos_partition dp[NDOSPART], *dp2;
+ int error, partoff = -1, cyl = 0;
struct disklabel *dlp;
struct buf *bp = NULL;
- int error, dospartoff, cyl, i;
- int ourpart = -1;
/* get a buffer and initialize it */
bp = geteblk((int)lp->d_secsize);
bp->b_dev = dev;
- /* do dos partitions in the process of getting disklabel? */
- dospartoff = 0;
- cyl = LABELSECTOR / lp->d_secpercyl;
- /* read master boot record */
- 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 ((error = biowait(bp)) != 0)
+ if (readdoslabel(bp, strat, lp, osdep, &partoff, &cyl, 1) != NULL) {
+ error = EIO;
goto done;
-
- /* XXX how do we check veracity/bounds of this? */
- bcopy(bp->b_data + DOSPARTOFF, dp, sizeof(dp));
-
- for (dp2=dp, i=0; i < NDOSPART && ourpart == -1; i++, dp2++)
- if (letoh32(dp2->dp_size) && dp2->dp_typ == DOSPTYP_OPENBSD)
- ourpart = i;
-
- if (ourpart != -1) {
- dp2 = &dp[ourpart];
-
- /*
- * need sector address for SCSI/IDE,
- * cylinder for ESDI/ST506/RLL
- */
- dospartoff = letoh32(dp2->dp_start);
- cyl = DPCYL(dp2->dp_scyl, dp2->dp_ssect);
}
- /* next, dig out disk label */
- bp->b_blkno = dospartoff + LABELSECTOR;
+ /* Read it in, slap the new label in, and write it back out */
+ bp->b_blkno = partoff + LABELSECTOR;
bp->b_cylinder = cyl;
bp->b_bcount = lp->d_secsize;
bp->b_flags = B_BUSY | B_READ;
(*strat)(bp);
-
- /* if successful, locate disk label within block and validate */
if ((error = biowait(bp)) != 0)
goto done;
- for (dlp = (struct disklabel *)bp->b_data;
- dlp <= (struct disklabel *)(bp->b_data + lp->d_secsize - sizeof(*dlp));
- dlp = (struct disklabel *)((char *)dlp + sizeof(long))) {
- if (dlp->d_magic == DISKMAGIC && dlp->d_magic2 == DISKMAGIC &&
- dkcksum(dlp) == 0) {
- *dlp = *lp;
- bp->b_flags = B_BUSY | B_WRITE;
- (*strat)(bp);
- error = biowait(bp);
- goto done;
- }
- }
- /* Write it in the regular place. */
- *(struct disklabel *)bp->b_data = *lp;
+ dlp = (struct disklabel *)(bp->b_data + LABELOFFSET);
+ *dlp = *lp;
bp->b_flags = B_BUSY | B_WRITE;
(*strat)(bp);
error = biowait(bp);
diff --git a/sys/arch/aviion/include/disklabel.h b/sys/arch/aviion/include/disklabel.h
index 6ebfd898405..e97b301aea7 100644
--- a/sys/arch/aviion/include/disklabel.h
+++ b/sys/arch/aviion/include/disklabel.h
@@ -1,5 +1,4 @@
-/* $OpenBSD: disklabel.h,v 1.7 2006/10/20 23:47:42 krw Exp $ */
-/* $NetBSD: disklabel.h,v 1.2 2001/11/25 19:02:03 thorpej Exp $ */
+/* $OpenBSD: disklabel.h,v 1.8 2007/06/17 00:27:26 deraadt Exp $ */
/*
* Copyright (c) 1994 Mark Brinicombe.
@@ -34,14 +33,6 @@
* 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.
- *
- * RiscBSD kernel project
- *
- * disklabel.h
- *
- * machine specific disk label info
- *
- * Created : 04/10/94
*/
#ifndef _AVIION_DISKLABEL_H_
@@ -50,50 +41,6 @@
#define LABELSECTOR 1 /* sector containing label */
#define LABELOFFSET 0 /* offset of label in sector */
#define MAXPARTITIONS 16 /* number of partitions */
-#define RAW_PART 2 /* raw partition: XX?c */
-
-/* MBR partition table */
-#define DOSBBSECTOR 0 /* MBR sector number */
-#define DOSPARTOFF 446 /* Offset of MBR partition table */
-#define NDOSPART 4 /* # of partitions in MBR */
-#define DOSMAGICOFF 510 /* Offset of magic number */
-#define DOSMAGIC 0xaa55 /* Actual magic number */
-#define MBRMAGIC DOSMAGIC
-#define DOSMBR_SIGNATURE MBRMAGIC
-#define DOSMBR_SIGNATURE_OFF DOSMAGICOFF
-#define DOSACTIVE 0x80
-
-
-struct dos_partition {
- u_int8_t dp_flag; /* bootstrap flags */
- u_int8_t dp_shd; /* starting head */
- u_int8_t dp_ssect; /* starting sector */
- u_int8_t dp_scyl; /* starting cylinder */
- u_int8_t dp_typ; /* partition type (see below) */
- u_int8_t dp_ehd; /* end head */
- u_int8_t dp_esect; /* end sector */
- u_int8_t dp_ecyl; /* end cylinder */
- u_int32_t dp_start; /* absolute starting sector number */
- u_int32_t dp_size; /* partition size in sectors */
-};
-
-/* Known DOS partition types. */
-#define DOSPTYP_UNUSED 0x00 /* Unused partition */
-#define DOSPTYP_FAT12 0x01 /* 12-bit FAT */
-#define DOSPTYP_FAT16S 0x04 /* 16-bit FAT, less than 32M */
-#define DOSPTYP_EXTEND 0x05 /* Extended; contains sub-partitions */
-#define DOSPTYP_FAT16B 0x06 /* 16-bit FAT, more than 32M */
-#define DOSPTYP_FAT32 0x0b /* 32-bit FAT */
-#define DOSPTYP_FAT32L 0x0c /* 32-bit FAT, LBA-mapped */
-#define DOSPTYP_FAT16L 0x0e /* 16-bit FAT, LBA-mapped */
-#define DOSPTYP_EXTENDL 0x0f /* Extended, LBA-mapped; contains sub-partitions */
-#define DOSPTYP_ONTRACK 0x54
-#define DOSPTYP_LINUX 0x83 /* That other thing */
-#define DOSPTYP_OPENBSD 0xa6 /* OpenBSD partition type */
-
-/* Isolate the relevant bits to get sector and cylinder. */
-#define DPSECT(s) ((s) & 0x3f)
-#define DPCYL(c, s) ((c) + (((s) & 0xc0) << 2))
struct cpu_disklabel {
};
diff --git a/sys/arch/cats/include/disklabel.h b/sys/arch/cats/include/disklabel.h
index 4f02974008d..e7f8b010c8e 100644
--- a/sys/arch/cats/include/disklabel.h
+++ b/sys/arch/cats/include/disklabel.h
@@ -1,4 +1,3 @@
-/* $OpenBSD: disklabel.h,v 1.1 2004/02/01 05:12:54 drahn Exp $ */
-/* $NetBSD: disklabel.h,v 1.3 2001/11/25 15:55:55 thorpej Exp $ */
+/* $OpenBSD: disklabel.h,v 1.2 2007/06/17 00:27:27 deraadt Exp $ */
#include <arm/disklabel.h>
diff --git a/sys/arch/hp300/hp300/disksubr.c b/sys/arch/hp300/hp300/disksubr.c
index fbac9ede54e..a83996d1459 100644
--- a/sys/arch/hp300/hp300/disksubr.c
+++ b/sys/arch/hp300/hp300/disksubr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: disksubr.c,v 1.39 2007/06/14 03:35:29 deraadt Exp $ */
+/* $OpenBSD: disksubr.c,v 1.40 2007/06/17 00:27:28 deraadt Exp $ */
/* $NetBSD: disksubr.c,v 1.9 1997/04/01 03:12:13 scottr Exp $ */
/*
@@ -33,8 +33,6 @@
* 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.
- *
- * @(#)ufs_disksubr.c 8.5 (Berkeley) 1/21/94
*/
#include <sys/param.h>
@@ -56,74 +54,50 @@ readdisklabel(dev_t dev, void (*strat)(struct buf *),
struct disklabel *lp, struct cpu_disklabel *osdep, int spoofonly)
{
struct buf *bp = NULL;
- struct disklabel *dlp;
- int i;
- char *msg = NULL;
+ char *msg;
- /* minimal requirements for archetypal disk label */
- if (lp->d_secsize < DEV_BSIZE)
- lp->d_secsize = DEV_BSIZE;
- if (DL_GETDSIZE(lp) == 0)
- DL_SETDSIZE(lp, MAXDISKSIZE);
- if (lp->d_secpercyl == 0) {
- msg = "invalid geometry";
+ if ((msg = initdisklabel(lp)))
goto done;
- }
- lp->d_npartitions = RAW_PART + 1;
- for (i = 0; i < RAW_PART; i++) {
- DL_SETPSIZE(&lp->d_partitions[i], 0);
- DL_SETPOFFSET(&lp->d_partitions[i], 0);
- }
- if (DL_GETPSIZE(&lp->d_partitions[RAW_PART]) == 0)
- DL_SETPSIZE(&lp->d_partitions[RAW_PART], DL_GETDSIZE(lp));
- DL_SETPOFFSET(&lp->d_partitions[RAW_PART], 0);
- lp->d_version = 1;
+
+ bp = geteblk((int)lp->d_secsize);
+ bp->b_dev = dev;
/* don't read the on-disk label if we are in spoofed-only mode */
if (spoofonly)
goto done;
- bp = geteblk((int)lp->d_secsize);
- bp->b_dev = dev;
bp->b_blkno = LABELSECTOR;
bp->b_bcount = lp->d_secsize;
bp->b_flags = B_BUSY | B_READ;
bp->b_cylinder = LABELSECTOR / lp->d_secpercyl;
(*strat)(bp);
- if (biowait(bp))
+ if (biowait(bp)) {
msg = "disk label I/O error";
- else for (dlp = (struct disklabel *)bp->b_data;
- dlp <= (struct disklabel *)((char *)bp->b_data +
- DEV_BSIZE - sizeof(*dlp));
- dlp = (struct disklabel *)((char *)dlp + sizeof(long))) {
- if (dlp->d_magic != DISKMAGIC || dlp->d_magic2 != DISKMAGIC) {
- if (msg == NULL) {
+ goto done;
+ }
+
+ msg = checkdisklabel(bp->b_data + LABELOFFSET, lp);
+ if (msg == NULL)
+ goto done;
+
#if defined(CD9660)
- if (iso_disklabelspoof(dev, strat, lp) != 0)
+ if (iso_disklabelspoof(dev, strat, lp) == 0) {
+ msg = NULL;
+ goto done;
+ }
#endif
- msg = "no disk label";
#if defined(UDF)
- if (msg && udf_disklabelspoof(dev, strat, lp) == 0)
- msg = NULL;
-#endif
- }
- } else if (dlp->d_npartitions > MAXPARTITIONS ||
- dkcksum(dlp) != 0)
- msg = "disk label corrupted";
- else {
- DL_SETDSIZE(dlp, DL_GETDSIZE(lp));
- *lp = *dlp;
- msg = NULL;
- break;
- }
+ if (udf_disklabelspoof(dev, strat, lp) == 0) {
+ msg = NULL;
+ goto done;
}
+#endif
done:
if (bp) {
bp->b_flags |= B_INVAL;
brelse(bp);
}
- disklabeltokernlabel(lp);
return (msg);
}
@@ -136,38 +110,21 @@ writedisklabel(dev_t dev, void (*strat)(struct buf *),
{
struct buf *bp = NULL;
struct disklabel *dlp;
- int labelpart;
int error = 0;
- labelpart = DISKPART(dev);
- if (DL_GETPOFFSET(&lp->d_partitions[labelpart]) != 0) {
- if (DL_GETPOFFSET(&lp->d_partitions[0]) != 0)
- return (EXDEV); /* not quite right */
- labelpart = 0;
- }
+ /* get a buffer and initialize it */
bp = geteblk((int)lp->d_secsize);
- bp->b_dev = MAKEDISKDEV(major(dev), DISKUNIT(dev), labelpart);
+ bp->b_dev = dev;
bp->b_blkno = LABELSECTOR;
bp->b_bcount = lp->d_secsize;
bp->b_flags = B_BUSY | B_READ;
(*strat)(bp);
- if ((error = biowait(bp)))
+ if ((error = biowait(bp)) != 0)
goto done;
- for (dlp = (struct disklabel *)bp->b_data;
- dlp <= (struct disklabel *)
- ((char *)bp->b_data + lp->d_secsize - sizeof(*dlp));
- dlp = (struct disklabel *)((char *)dlp + sizeof(long))) {
- if (dlp->d_magic == DISKMAGIC && dlp->d_magic2 == DISKMAGIC &&
- dkcksum(dlp) == 0) {
- *dlp = *lp;
- bp->b_flags = B_BUSY | B_WRITE;
- (*strat)(bp);
- error = biowait(bp);
- goto done;
- }
- }
+
/* Write it in the regular place. */
- *(struct disklabel *)bp->b_data = *lp;
+ dlp = (struct disklabel *)(bp->b_data + LABELOFFSET);
+ *dlp = *lp;
bp->b_flags = B_BUSY | B_WRITE;
(*strat)(bp);
error = biowait(bp);
diff --git a/sys/arch/hp300/include/disklabel.h b/sys/arch/hp300/include/disklabel.h
index f94fbc6c623..9fb87357f80 100644
--- a/sys/arch/hp300/include/disklabel.h
+++ b/sys/arch/hp300/include/disklabel.h
@@ -1,5 +1,4 @@
-/* $OpenBSD: disklabel.h,v 1.5 2001/12/06 23:47:26 miod Exp $ */
-/* $NetBSD: disklabel.h,v 1.1 1994/10/14 18:26:39 cgd Exp $ */
+/* $OpenBSD: disklabel.h,v 1.6 2007/06/17 00:27:27 deraadt Exp $ */
/*
* Copyright (c) 1994 Christopher G. Demetriou
@@ -34,14 +33,12 @@
#ifndef _MACHINE_DISKLABEL_H_
#define _MACHINE_DISKLABEL_H_
-#define LABELSECTOR (1024 / DEV_BSIZE) /* sector containing label */
+#define LABELSECTOR 2 /* sector containing label */
#define LABELOFFSET 0 /* offset of label in sector */
#define MAXPARTITIONS 16 /* number of partitions */
-#define RAW_PART 2 /* raw partition: xx?c */
/* Just a dummy */
struct cpu_disklabel {
- /* EMPTY */
};
#endif /* _MACHINE_DISKLABEL_H_ */
diff --git a/sys/arch/hppa/hppa/disksubr.c b/sys/arch/hppa/hppa/disksubr.c
index 28c79688365..2a53a5d0bdf 100644
--- a/sys/arch/hppa/hppa/disksubr.c
+++ b/sys/arch/hppa/hppa/disksubr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: disksubr.c,v 1.65 2007/06/14 03:37:23 deraadt Exp $ */
+/* $OpenBSD: disksubr.c,v 1.66 2007/06/17 00:27:28 deraadt Exp $ */
/*
* Copyright (c) 1999 Michael Shalayeff
@@ -30,91 +30,18 @@
* 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.
- *
- * @(#)ufs_disksubr.c 7.16 (Berkeley) 5/4/91
- */
-
-/*
- * This disksubr.c module started to take its present form on OpenBSD/alpha
- * but it was always thought it should be made completely MI and not need to
- * be in that alpha-specific tree at all.
- *
- * XXX HPUX disklabel is not understood yet.
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/buf.h>
-#include <sys/device.h>
#include <sys/disklabel.h>
-#include <sys/syslog.h>
#include <sys/disk.h>
-char *readbsdlabel(struct buf *, void (*)(struct buf *), int, int,
- int, struct disklabel *, int);
-char *readdoslabel(struct buf *, void (*)(struct buf *),
- struct disklabel *, struct cpu_disklabel *, int *, int *, int);
char *readliflabel(struct buf *, void (*)(struct buf *),
struct disklabel *, struct cpu_disklabel *, int *, int *, int);
/*
- * Try to read a standard BSD disklabel at a certain sector.
- */
-char *
-readbsdlabel(struct buf *bp, void (*strat)(struct buf *),
- int cyl, int sec, int off, struct disklabel *lp, int spoofonly)
-{
- struct disklabel *dlp;
- char *msg = NULL;
- u_int16_t cksum;
-
- /* don't read the on-disk label if we are in spoofed-only mode */
- if (spoofonly)
- return (NULL);
-
- bp->b_blkno = sec;
- bp->b_cylinder = cyl;
- bp->b_bcount = lp->d_secsize;
- bp->b_flags = B_BUSY | B_READ;
- (*strat)(bp);
-
- /* if successful, locate disk label within block and validate */
- if (biowait(bp)) {
- /* XXX we return the faked label built so far */
- msg = "disk label I/O error";
- return (msg);
- }
-
- /*
- * If off is negative, search until the end of the sector for
- * the label, otherwise, just look at the specific location
- * we're given.
- */
- dlp = (struct disklabel *)(bp->b_data + (off >= 0 ? off : 0));
- do {
- if (dlp->d_magic != DISKMAGIC || dlp->d_magic2 != DISKMAGIC) {
- if (msg == NULL)
- msg = "no disk label";
- } else {
- cksum = dkcksum(dlp);
- if (dlp->d_npartitions > MAXPARTITIONS || cksum != 0) {
- msg = "disk label corrupted";
- } else {
- DL_SETDSIZE(dlp, DL_GETDSIZE(lp));
- *lp = *dlp;
- msg = NULL;
- break;
- }
- }
- if (off >= 0)
- break;
- dlp = (struct disklabel *)((char *)dlp + sizeof(int32_t));
- } while (dlp <= (struct disklabel *)(bp->b_data + lp->d_secsize -
- sizeof(*dlp)));
- return (msg);
-}
-
-/*
* Attempt to read a disk label from a device
* using the indicated strategy routine.
* The label must be partly set up before this:
@@ -129,259 +56,41 @@ readdisklabel(dev_t dev, void (*strat)(struct buf *),
struct disklabel *lp, struct cpu_disklabel *osdep, int spoofonly)
{
struct buf *bp = NULL;
- char *msg = "no disk label";
- int i;
- struct disklabel minilabel, fallbacklabel;
-
- /* minimal requirements for archetypal disk label */
- if (lp->d_secsize < DEV_BSIZE)
- lp->d_secsize = DEV_BSIZE;
- if (DL_GETDSIZE(lp) == 0)
- DL_SETDSIZE(lp, MAXDISKSIZE);
- if (lp->d_secpercyl == 0) {
- msg = "invalid geometry";
+ char *msg;
+
+ if ((msg = initdisklabel(lp)))
goto done;
- }
- lp->d_npartitions = RAW_PART + 1;
- for (i = 0; i < RAW_PART; i++) {
- DL_SETPSIZE(&lp->d_partitions[i], 0);
- DL_SETPOFFSET(&lp->d_partitions[i], 0);
- }
- if (DL_GETPSIZE(&lp->d_partitions[RAW_PART]) == 0)
- DL_SETPSIZE(&lp->d_partitions[RAW_PART], DL_GETDSIZE(lp));
- DL_SETPOFFSET(&lp->d_partitions[RAW_PART], 0);
- lp->d_version = 1;
- minilabel = fallbacklabel = *lp;
/* get a buffer and initialize it */
bp = geteblk((int)lp->d_secsize);
bp->b_dev = dev;
- msg = readliflabel(bp, strat, lp, osdep, 0, 0, spoofonly);
- if (msg)
- *lp = minilabel;
- if (msg) {
- msg = readdoslabel(bp, strat, lp, osdep, 0, 0, spoofonly);
- if (msg) {
- /* Fallback alternative XXX always valid? */
- fallbacklabel = *lp;
- *lp = minilabel;
- }
- }
+ msg = readliflabel(bp, strat, lp, osdep, NULL, NULL, spoofonly);
+ if (msg == NULL)
+ goto done;
+
+ msg = readdoslabel(bp, strat, lp, osdep, NULL, NULL, spoofonly);
+ if (msg == NULL)
+ goto done;
#if defined(CD9660)
- if (msg && iso_disklabelspoof(dev, strat, lp) == 0)
+ if (iso_disklabelspoof(dev, strat, lp) == 0) {
msg = NULL;
+ goto done;
+ }
#endif
#if defined(UDF)
- if (msg && udf_disklabelspoof(dev, strat, lp) == 0)
+ if (udf_disklabelspoof(dev, strat, lp) == 0) {
msg = NULL;
+ goto done;
+ }
#endif
- /* If there was an error, still provide a decent fake one. */
- if (msg)
- *lp = fallbacklabel;
-
done:
if (bp) {
bp->b_flags |= B_INVAL;
brelse(bp);
}
- disklabeltokernlabel(lp);
- return (msg);
-}
-
-/*
- * If dos partition table requested, attempt to load it and
- * find disklabel inside a DOS partition. Return buffer
- * for use in signalling errors if requested.
- *
- * We would like to check if each MBR has a valid BOOT_MAGIC, but
- * we cannot because it doesn't always exist. So.. we assume the
- * MBR is valid.
- */
-char *
-readdoslabel(struct buf *bp, void (*strat)(struct buf *),
- struct disklabel *lp, struct cpu_disklabel *osdep,
- int *partoffp, int *cylp, int spoofonly)
-{
- struct dos_partition dp[NDOSPART], *dp2;
- struct partition *pp;
- unsigned long extoff = 0;
- unsigned int fattest;
- daddr64_t part_blkno = DOSBBSECTOR;
- char *msg = NULL;
- int dospartoff, cyl, i, ourpart = -1;
- int wander = 1, n = 0, loop = 0;
-
- if (lp->d_secpercyl == 0) {
- msg = "invalid label, d_secpercyl == 0";
- return (msg);
- }
- if (lp->d_secsize == 0) {
- msg = "invalid label, d_secsize == 0";
- return (msg);
- }
-
- /* do dos partitions in the process of getting disklabel? */
- dospartoff = 0;
- cyl = LABELSECTOR / lp->d_secpercyl;
-
- /*
- * Read dos partition table, follow extended partitions.
- * Map the partitions to disklabel entries i-p
- */
- while (wander && n < 8 && loop < 8) {
- loop++;
- wander = 0;
- if (part_blkno < extoff)
- part_blkno = extoff;
-
- /* read boot record */
- bp->b_blkno = part_blkno;
- bp->b_bcount = lp->d_secsize;
- bp->b_flags = B_BUSY | B_READ;
- bp->b_cylinder = part_blkno / lp->d_secpercyl;
- (*strat)(bp);
-
- /* if successful, wander through dos partition table */
- if (biowait(bp)) {
- msg = "dos partition I/O error";
- if (partoffp)
- *partoffp = -1;
- return (msg);
- }
- bcopy(bp->b_data + DOSPARTOFF, dp, sizeof(dp));
-
- if (ourpart == -1 && part_blkno == DOSBBSECTOR) {
- /* Search for our MBR partition */
- for (dp2=dp, i=0; i < NDOSPART && ourpart == -1;
- i++, dp2++)
- if (letoh32(dp2->dp_size) &&
- dp2->dp_typ == DOSPTYP_OPENBSD)
- ourpart = i;
- if (ourpart == -1)
- goto donot;
- /*
- * This is our MBR partition. need sector
- * address for SCSI/IDE, cylinder for
- * ESDI/ST506/RLL
- */
- dp2 = &dp[ourpart];
- dospartoff = letoh32(dp2->dp_start) + part_blkno;
- cyl = DPCYL(dp2->dp_scyl, dp2->dp_ssect);
-
- /* XXX build a temporary disklabel */
- DL_SETPSIZE(&lp->d_partitions[0], letoh32(dp2->dp_size));
- DL_SETPOFFSET(&lp->d_partitions[0],
- letoh32(dp2->dp_start) + part_blkno);
- if (lp->d_ntracks == 0)
- lp->d_ntracks = dp2->dp_ehd + 1;
- if (lp->d_nsectors == 0)
- lp->d_nsectors = DPSECT(dp2->dp_esect);
- if (lp->d_secpercyl == 0)
- lp->d_secpercyl = lp->d_ntracks *
- lp->d_nsectors;
- }
-donot:
- /*
- * In case the disklabel read below fails, we want to
- * provide a fake label in i-p.
- */
- for (dp2=dp, i=0; i < NDOSPART && n < 8; i++, dp2++) {
- pp = &lp->d_partitions[8+n];
-
- if (dp2->dp_typ == DOSPTYP_OPENBSD)
- continue;
- if (letoh32(dp2->dp_size) > DL_GETDSIZE(lp))
- continue;
- if (letoh32(dp2->dp_start) > DL_GETDSIZE(lp))
- continue;
- if (letoh32(dp2->dp_size) == 0)
- continue;
- if (letoh32(dp2->dp_start))
- DL_SETPOFFSET(pp,
- letoh32(dp2->dp_start) + part_blkno);
-
- DL_SETPSIZE(pp, letoh32(dp2->dp_size));
-
- switch (dp2->dp_typ) {
- case DOSPTYP_UNUSED:
- pp->p_fstype = FS_UNUSED;
- n++;
- break;
-
- case DOSPTYP_LINUX:
- pp->p_fstype = FS_EXT2FS;
- n++;
- break;
-
- case DOSPTYP_FAT12:
- case DOSPTYP_FAT16S:
- case DOSPTYP_FAT16B:
- case DOSPTYP_FAT16L:
- case DOSPTYP_FAT32:
- case DOSPTYP_FAT32L:
- pp->p_fstype = FS_MSDOS;
- n++;
- break;
- case DOSPTYP_EXTEND:
- case DOSPTYP_EXTENDL:
- part_blkno = letoh32(dp2->dp_start) + extoff;
- if (!extoff) {
- extoff = letoh32(dp2->dp_start);
- part_blkno = 0;
- }
- wander = 1;
- break;
- default:
- pp->p_fstype = FS_OTHER;
- n++;
- break;
- }
- }
- }
- lp->d_bbsize = 8192;
- lp->d_sbsize = 64*1024; /* XXX ? */
- lp->d_npartitions = MAXPARTITIONS;
-
- if (n == 0 && part_blkno == DOSBBSECTOR) {
- /* Check for a short jump instruction. */
- fattest = ((bp->b_data[0] << 8) & 0xff00) | (bp->b_data[2] &
- 0xff);
- if (fattest != 0xeb90 && fattest != 0xe900)
- goto notfat;
-
- /* Check for a valid bytes per sector value. */
- fattest = ((bp->b_data[12] << 8) & 0xff00) | (bp->b_data[11] &
- 0xff);
- if (fattest < 512 || fattest > 4096 || (fattest % 512 != 0))
- goto notfat;
-
- /* Check the end of sector marker. */
- fattest = ((bp->b_data[510] << 8) & 0xff00) | (bp->b_data[511] &
- 0xff);
- if (fattest != 0x55aa)
- goto notfat;
-
- /* Looks like a FAT filesystem. Spoof 'i'. */
- DL_SETPSIZE(&lp->d_partitions['i' - 'a'],
- DL_GETPSIZE(&lp->d_partitions[RAW_PART]));
- DL_SETPOFFSET(&lp->d_partitions['i' - 'a'], 0);
- lp->d_partitions['i' - 'a'].p_fstype = FS_MSDOS;
- }
-notfat:
-
- /* record the OpenBSD partition's placement for the caller */
- if (partoffp)
- *partoffp = dospartoff;
- if (cylp)
- *cylp = cyl;
-
- /* next, dig out disk label */
- msg = readbsdlabel(bp, strat, cyl, dospartoff + LABELSECTOR, -1,
- lp, spoofonly);
-
return (msg);
}
@@ -390,7 +99,10 @@ readliflabel(struct buf *bp, void (*strat)(struct buf *),
struct disklabel *lp, struct cpu_disklabel *osdep,
int *partoffp, int *cylp, int spoofonly)
{
- int fsoff;
+ struct buf *dbp = NULL;
+ struct lifdir *p;
+ char *msg = NULL;
+ int fsoff = 0;
/* read LIF volume header */
bp->b_blkno = btodb(LIF_VOLSTART);
@@ -398,148 +110,147 @@ readliflabel(struct buf *bp, void (*strat)(struct buf *),
bp->b_flags = B_BUSY | B_READ;
bp->b_cylinder = btodb(LIF_VOLSTART) / lp->d_secpercyl;
(*strat)(bp);
-
- if (biowait(bp)) {
- if (partoffp)
- *partoffp = -1;
+ if (biowait(bp))
return "LIF volume header I/O error";
- }
- bcopy (bp->b_data, &osdep->u._hppa.lifvol, sizeof(struct lifvol));
+ bcopy(bp->b_data, &osdep->u._hppa.lifvol, sizeof(struct lifvol));
if (osdep->u._hppa.lifvol.vol_id != LIF_VOL_ID) {
fsoff = 0;
- } else {
- struct lifdir *p;
- struct buf *dbp;
- dev_t dev;
+ goto finished;
+ }
+
+ dbp = geteblk(LIF_DIRSIZE);
+ dbp->b_dev = bp->b_dev;
+
+ /* read LIF directory */
+ dbp->b_blkno = lifstodb(osdep->u._hppa.lifvol.vol_addr);
+ dbp->b_bcount = lp->d_secsize;
+ dbp->b_flags = B_BUSY | B_READ;
+ dbp->b_cylinder = dbp->b_blkno / lp->d_secpercyl;
+ (*strat)(dbp);
+
+ if (biowait(dbp)) {
+ msg = "LIF directory I/O error";
+ goto done;
+ }
- dev = bp->b_dev;
- dbp = geteblk(LIF_DIRSIZE);
- dbp->b_dev = dev;
+ bcopy(dbp->b_data, osdep->u._hppa.lifdir, LIF_DIRSIZE);
+
+ /* scan for LIF_DIR_FS dir entry */
+ for (fsoff = -1, p = &osdep->u._hppa.lifdir[0];
+ fsoff < 0 && p < &osdep->u._hppa.lifdir[LIF_NUMDIR]; p++) {
+ if (p->dir_type == LIF_DIR_FS ||
+ p->dir_type == LIF_DIR_HPLBL)
+ break;
+ }
+
+ if (p->dir_type == LIF_DIR_FS) {
+ fsoff = lifstodb(p->dir_addr);
+ goto finished;
+ }
+
+ /* Only came here to find the offset... */
+ if (partoffp && spoofonly)
+ goto finished;
+
+ if (p->dir_type == LIF_DIR_HPLBL) {
+ struct hpux_label *hl;
+ struct partition *pp;
+ u_int8_t fstype;
+ int i;
/* read LIF directory */
- dbp->b_blkno = lifstodb(osdep->u._hppa.lifvol.vol_addr);
+ dbp->b_blkno = lifstodb(p->dir_addr);
dbp->b_bcount = lp->d_secsize;
dbp->b_flags = B_BUSY | B_READ;
dbp->b_cylinder = dbp->b_blkno / lp->d_secpercyl;
(*strat)(dbp);
if (biowait(dbp)) {
- if (partoffp)
- *partoffp = -1;
-
- dbp->b_flags |= B_INVAL;
- brelse(dbp);
- return ("LIF directory I/O error");
+ msg = "HPUX label I/O error";
+ goto done;
}
- bcopy(dbp->b_data, osdep->u._hppa.lifdir, LIF_DIRSIZE);
- dbp->b_flags |= B_INVAL;
- brelse(dbp);
+ bcopy(dbp->b_data, &osdep->u._hppa.hplabel,
+ sizeof(osdep->u._hppa.hplabel));
- /* scan for LIF_DIR_FS dir entry */
- for (fsoff = -1, p = &osdep->u._hppa.lifdir[0];
- fsoff < 0 && p < &osdep->u._hppa.lifdir[LIF_NUMDIR]; p++) {
- if (p->dir_type == LIF_DIR_FS ||
- p->dir_type == LIF_DIR_HPLBL)
- break;
+ hl = &osdep->u._hppa.hplabel;
+ if (hl->hl_magic1 != hl->hl_magic2 ||
+ hl->hl_magic != HPUX_MAGIC || hl->hl_version != 1) {
+ msg = "HPUX label magic mismatch";
+ goto done;
}
- if (p->dir_type == LIF_DIR_FS)
- fsoff = lifstodb(p->dir_addr);
- else if (p->dir_type == LIF_DIR_HPLBL) {
- struct hpux_label *hl;
- struct partition *pp;
- u_int8_t fstype;
- int i;
-
- dev = bp->b_dev;
- dbp = geteblk(LIF_DIRSIZE);
- dbp->b_dev = dev;
-
- /* read LIF directory */
- dbp->b_blkno = lifstodb(p->dir_addr);
- dbp->b_bcount = lp->d_secsize;
- dbp->b_flags = B_BUSY | B_READ;
- dbp->b_cylinder = dbp->b_blkno / lp->d_secpercyl;
- (*strat)(dbp);
-
- if (biowait(dbp)) {
- if (partoffp)
- *partoffp = -1;
-
- dbp->b_flags |= B_INVAL;
- brelse(dbp);
- return ("HOUX label I/O error");
- }
-
- bcopy(dbp->b_data, &osdep->u._hppa.hplabel,
- sizeof(osdep->u._hppa.hplabel));
- dbp->b_flags |= B_INVAL;
- brelse(dbp);
-
- hl = &osdep->u._hppa.hplabel;
- if (hl->hl_magic1 != hl->hl_magic2 ||
- hl->hl_magic != HPUX_MAGIC ||
- hl->hl_version != 1) {
- if (partoffp)
- *partoffp = -1;
-
- return "HPUX label magic mismatch";
- }
-
- lp->d_bbsize = 8192;
- lp->d_sbsize = 8192;
- for (i = 0; i < MAXPARTITIONS; i++) {
- DL_SETPSIZE(&lp->d_partitions[i], 0);
- DL_SETPOFFSET(&lp->d_partitions[i], 0);
- lp->d_partitions[i].p_fstype = 0;
- }
-
- for (i = 0; i < HPUX_MAXPART; i++) {
- if (!hl->hl_flags[i])
- continue;
-
- if (hl->hl_flags[i] == HPUX_PART_ROOT) {
- pp = &lp->d_partitions[0];
- fstype = FS_BSDFFS;
- } else if (hl->hl_flags[i] == HPUX_PART_SWAP) {
- pp = &lp->d_partitions[1];
- fstype = FS_SWAP;
- } else if (hl->hl_flags[i] == HPUX_PART_BOOT) {
- pp = &lp->d_partitions[RAW_PART + 1];
- fstype = FS_BSDFFS;
- } else
- continue;
-
- DL_SETPSIZE(pp, hl->hl_parts[i].hlp_length * 2);
- DL_SETPOFFSET(pp, hl->hl_parts[i].hlp_start * 2);
- pp->p_fstype = fstype;
- }
-
- DL_SETPSIZE(&lp->d_partitions[RAW_PART], DL_GETDSIZE(lp));
- DL_SETPOFFSET(&lp->d_partitions[RAW_PART], 0);
- lp->d_partitions[RAW_PART].p_fstype = FS_UNUSED;
- lp->d_npartitions = MAXPARTITIONS;
- lp->d_magic = DISKMAGIC;
- lp->d_magic2 = DISKMAGIC;
- lp->d_checksum = 0;
- lp->d_checksum = dkcksum(lp);
-
- return (NULL);
+ lp->d_bbsize = 8192;
+ lp->d_sbsize = 8192;
+ for (i = 0; i < MAXPARTITIONS; i++) {
+ DL_SETPSIZE(&lp->d_partitions[i], 0);
+ DL_SETPOFFSET(&lp->d_partitions[i], 0);
+ lp->d_partitions[i].p_fstype = 0;
}
- /* if no suitable lifdir entry found assume zero */
- if (fsoff < 0) {
- fsoff = 0;
+ for (i = 0; i < HPUX_MAXPART; i++) {
+ if (!hl->hl_flags[i])
+ continue;
+ if (hl->hl_flags[i] == HPUX_PART_ROOT) {
+ pp = &lp->d_partitions[0];
+ fstype = FS_BSDFFS;
+ } else if (hl->hl_flags[i] == HPUX_PART_SWAP) {
+ pp = &lp->d_partitions[1];
+ fstype = FS_SWAP;
+ } else if (hl->hl_flags[i] == HPUX_PART_BOOT) {
+ pp = &lp->d_partitions[RAW_PART + 1];
+ fstype = FS_BSDFFS;
+ } else
+ continue;
+
+ DL_SETPSIZE(pp, hl->hl_parts[i].hlp_length * 2);
+ DL_SETPOFFSET(pp, hl->hl_parts[i].hlp_start * 2);
+ pp->p_fstype = fstype;
}
+
+ DL_SETPSIZE(&lp->d_partitions[RAW_PART], DL_GETDSIZE(lp));
+ DL_SETPOFFSET(&lp->d_partitions[RAW_PART], 0);
+ lp->d_partitions[RAW_PART].p_fstype = FS_UNUSED;
+ lp->d_npartitions = MAXPARTITIONS;
+ lp->d_magic = DISKMAGIC;
+ lp->d_magic2 = DISKMAGIC;
+ lp->d_version = 1;
+ lp->d_checksum = 0;
+ lp->d_checksum = dkcksum(lp);
+ /* drop through */
}
+finished:
+ /* if no suitable lifdir entry found assume zero */
+ if (fsoff < 0)
+ fsoff = 0;
if (partoffp)
*partoffp = fsoff;
- return readbsdlabel(bp, strat, 0, fsoff + LABELSECTOR,
- LABELOFFSET, lp, spoofonly);
+ if (spoofonly)
+ goto done;
+
+ bp->b_blkno = fsoff + LABELSECTOR;
+ bp->b_cylinder = 0;
+ bp->b_bcount = lp->d_secsize;
+ bp->b_flags = B_BUSY | B_READ;
+ (*strat)(bp);
+
+ /* if successful, locate disk label within block and validate */
+ if (biowait(bp)) {
+ msg = "disk label I/O error";
+ goto done;
+ }
+
+ return checkdisklabel(bp->b_data + LABELOFFSET, lp);
+
+done:
+ if (dbp) {
+ dbp->b_flags |= B_INVAL;
+ brelse(dbp);
+ }
+ return (msg);
}
/*
@@ -549,42 +260,43 @@ int
writedisklabel(dev_t dev, void (*strat)(struct buf *),
struct disklabel *lp, struct cpu_disklabel *osdep)
{
- char *msg = "no disk label";
- struct buf *bp;
- struct disklabel dl;
- struct cpu_disklabel cdl;
- int labeloffset, error, partoff = 0, cyl = 0;
+ int error, partoff = -1, cyl = 0;
+ struct disklabel *dlp;
+ struct buf *bp = NULL;
/* get a buffer and initialize it */
bp = geteblk((int)lp->d_secsize);
bp->b_dev = dev;
- dl = *lp;
- msg = readliflabel(bp, strat, &dl, &cdl, &partoff, &cyl, 0);
- labeloffset = LABELOFFSET;
- if (msg) {
- dl = *lp;
- msg = readdoslabel(bp, strat, &dl, &cdl, &partoff, &cyl, 0);
- labeloffset = LABELOFFSET;
- }
- if (msg) {
- if (partoff == -1)
- return EIO;
-
- /* Write it in the regular place with native byte order. */
- labeloffset = LABELOFFSET;
- bp->b_blkno = partoff + LABELSECTOR;
- bp->b_cylinder = cyl;
- bp->b_bcount = lp->d_secsize;
- }
+ if (readliflabel(bp, strat, lp, osdep, &partoff, &cyl, 1) == NULL)
+ goto writeit;
- *(struct disklabel *)(bp->b_data + labeloffset) = *lp;
+ if (readdoslabel(bp, strat, lp, osdep, &partoff, &cyl, 1) == NULL)
+ goto writeit;
+
+ error = EIO;
+ goto done;
+
+writeit:
+ /* Read it in, slap the new label in, and write it back out */
+ bp->b_blkno = partoff + LABELSECTOR;
+ bp->b_cylinder = cyl;
+ bp->b_bcount = lp->d_secsize;
+ bp->b_flags = B_BUSY | B_READ;
+ (*strat)(bp);
+ if ((error = biowait(bp)) != 0)
+ goto done;
+ dlp = (struct disklabel *)(bp->b_data + LABELOFFSET);
+ *dlp = *lp;
bp->b_flags = B_BUSY | B_WRITE;
(*strat)(bp);
error = biowait(bp);
- bp->b_flags |= B_INVAL;
- brelse(bp);
+done:
+ if (bp) {
+ bp->b_flags |= B_INVAL;
+ brelse(bp);
+ }
return (error);
}
diff --git a/sys/arch/hppa/include/disklabel.h b/sys/arch/hppa/include/disklabel.h
index a810e85eab3..c8fb499c60b 100644
--- a/sys/arch/hppa/include/disklabel.h
+++ b/sys/arch/hppa/include/disklabel.h
@@ -1,5 +1,4 @@
-/* $OpenBSD: disklabel.h,v 1.17 2007/06/07 02:55:12 krw Exp $ */
-/* $NetBSD: disklabel.h,v 1.1 1995/02/13 23:07:34 cgd Exp $ */
+/* $OpenBSD: disklabel.h,v 1.18 2007/06/17 00:27:27 deraadt Exp $ */
/*
* Copyright (c) 1994 Christopher G. Demetriou
@@ -36,50 +35,7 @@
#define LABELSECTOR 1
#define LABELOFFSET 0
-
#define MAXPARTITIONS 16 /* number of partitions */
-#define RAW_PART 2 /* raw partition: xx?c */
-
-/* DOS partition table -- located in boot block */
-#define DOSBBSECTOR 0 /* DOS boot block relative sector # */
-#define DOSPARTOFF 446
-#define DOSACTIVE 0x80
-#define NDOSPART 4
-#define DOSMBR_SIGNATURE 0xaa55
-#define DOSMBR_SIGNATURE_OFF 0x1fe
-
-struct dos_partition {
- u_int8_t dp_flag; /* bootstrap flags */
- u_int8_t dp_shd; /* starting head */
- u_int8_t dp_ssect; /* starting sector */
- u_int8_t dp_scyl; /* starting cylinder */
- u_int8_t dp_typ; /* partition type (see below) */
- u_int8_t dp_ehd; /* end head */
- u_int8_t dp_esect; /* end sector */
- u_int8_t dp_ecyl; /* end cylinder */
- u_int32_t dp_start; /* absolute starting sector number */
- u_int32_t dp_size; /* partition size in sectors */
-};
-
-/* Known DOS partition types. */
-#define DOSPTYP_UNUSED 0x00 /* Unused partition */
-#define DOSPTYP_FAT12 0x01 /* 12-bit FAT */
-#define DOSPTYP_FAT16S 0x04 /* 16-bit FAT, less than 32M */
-#define DOSPTYP_EXTEND 0x05 /* Extended; contains sub-partitions */
-#define DOSPTYP_FAT16B 0x06 /* 16-bit FAT, more than 32M */
-#define DOSPTYP_FAT32 0x0b /* 32-bit FAT */
-#define DOSPTYP_FAT32L 0x0c /* 32-bit FAT, LBA-mapped */
-#define DOSPTYP_FAT16L 0x0e /* 16-bit FAT, LBA-mapped */
-#define DOSPTYP_EXTENDL 0x0f /* Extended, LBA-mapped; contains sub-partitions */
-#define DOSPTYP_ONTRACK 0x54
-#define DOSPTYP_LINUX 0x83 /* That other thing */
-#define DOSPTYP_FREEBSD 0xa5 /* FreeBSD partition type */
-#define DOSPTYP_OPENBSD 0xa6 /* OpenBSD partition type */
-#define DOSPTYP_NETBSD 0xa9 /* NetBSD partition type */
-
-/* Isolate the relevant bits to get sector and cylinder. */
-#define DPSECT(s) ((s) & 0x3f)
-#define DPCYL(c, s) ((c) + (((s) & 0xc0) << 2))
/*
* volume header for "LIF" format volumes
diff --git a/sys/arch/hppa64/hppa64/disksubr.c b/sys/arch/hppa64/hppa64/disksubr.c
index 7e9125b7921..fb62b2850e0 100644
--- a/sys/arch/hppa64/hppa64/disksubr.c
+++ b/sys/arch/hppa64/hppa64/disksubr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: disksubr.c,v 1.48 2007/06/14 03:37:23 deraadt Exp $ */
+/* $OpenBSD: disksubr.c,v 1.49 2007/06/17 00:27:28 deraadt Exp $ */
/*
* Copyright (c) 1999 Michael Shalayeff
@@ -30,91 +30,18 @@
* 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.
- *
- * @(#)ufs_disksubr.c 7.16 (Berkeley) 5/4/91
- */
-
-/*
- * This disksubr.c module started to take its present form on OpenBSD/alpha
- * but it was always thought it should be made completely MI and not need to
- * be in that alpha-specific tree at all.
- *
- * XXX HPUX disklabel is not understood yet.
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/buf.h>
-#include <sys/device.h>
#include <sys/disklabel.h>
-#include <sys/syslog.h>
#include <sys/disk.h>
-char *readbsdlabel(struct buf *, void (*)(struct buf *), int, int,
- int, struct disklabel *, int);
-char *readdoslabel(struct buf *, void (*)(struct buf *),
- struct disklabel *, struct cpu_disklabel *, int *, int *, int);
char *readliflabel(struct buf *, void (*)(struct buf *),
struct disklabel *, struct cpu_disklabel *, int *, int *, int);
/*
- * Try to read a standard BSD disklabel at a certain sector.
- */
-char *
-readbsdlabel(struct buf *bp, void (*strat)(struct buf *),
- int cyl, int sec, int off, struct disklabel *lp, int spoofonly)
-{
- struct disklabel *dlp;
- char *msg = NULL;
- u_int16_t cksum;
-
- /* don't read the on-disk label if we are in spoofed-only mode */
- if (spoofonly)
- return (NULL);
-
- bp->b_blkno = sec;
- bp->b_cylinder = cyl;
- bp->b_bcount = lp->d_secsize;
- bp->b_flags = B_BUSY | B_READ;
- (*strat)(bp);
-
- /* if successful, locate disk label within block and validate */
- if (biowait(bp)) {
- /* XXX we return the faked label built so far */
- msg = "disk label I/O error";
- return (msg);
- }
-
- /*
- * If off is negative, search until the end of the sector for
- * the label, otherwise, just look at the specific location
- * we're given.
- */
- dlp = (struct disklabel *)(bp->b_data + (off >= 0 ? off : 0));
- do {
- if (dlp->d_magic != DISKMAGIC || dlp->d_magic2 != DISKMAGIC) {
- if (msg == NULL)
- msg = "no disk label";
- } else {
- cksum = dkcksum(dlp);
- if (dlp->d_npartitions > MAXPARTITIONS || cksum != 0) {
- msg = "disk label corrupted";
- } else {
- DL_SETDSIZE(dlp, DL_GETDSIZE(lp));
- *lp = *dlp;
- msg = NULL;
- break;
- }
- }
- if (off >= 0)
- break;
- dlp = (struct disklabel *)((char *)dlp + sizeof(int32_t));
- } while (dlp <= (struct disklabel *)(bp->b_data + lp->d_secsize -
- sizeof(*dlp)));
- return (msg);
-}
-
-/*
* Attempt to read a disk label from a device
* using the indicated strategy routine.
* The label must be partly set up before this:
@@ -129,259 +56,41 @@ readdisklabel(dev_t dev, void (*strat)(struct buf *),
struct disklabel *lp, struct cpu_disklabel *osdep, int spoofonly)
{
struct buf *bp = NULL;
- char *msg = "no disk label";
- int i;
- struct disklabel minilabel, fallbacklabel;
-
- /* minimal requirements for archetypal disk label */
- if (lp->d_secsize < DEV_BSIZE)
- lp->d_secsize = DEV_BSIZE;
- if (DL_GETDSIZE(lp) == 0)
- DL_SETDSIZE(lp, MAXDISKSIZE);
- if (lp->d_secpercyl == 0) {
- msg = "invalid geometry";
+ char *msg;
+
+ if ((msg = initdisklabel(lp)))
goto done;
- }
- lp->d_npartitions = RAW_PART + 1;
- for (i = 0; i < RAW_PART; i++) {
- DL_SETPSIZE(&lp->d_partitions[i], 0);
- DL_SETPOFFSET(&lp->d_partitions[i], 0);
- }
- if (DL_GETPSIZE(&lp->d_partitions[RAW_PART]) == 0)
- DL_SETPSIZE(&lp->d_partitions[RAW_PART], DL_GETDSIZE(lp));
- DL_SETPOFFSET(&lp->d_partitions[RAW_PART], 0);
- lp->d_version = 1;
- minilabel = fallbacklabel = *lp;
/* get a buffer and initialize it */
bp = geteblk((int)lp->d_secsize);
bp->b_dev = dev;
- msg = readliflabel(bp, strat, lp, osdep, 0, 0, spoofonly);
- if (msg)
- *lp = minilabel;
- if (msg) {
- msg = readdoslabel(bp, strat, lp, osdep, 0, 0, spoofonly);
- if (msg) {
- /* Fallback alternative XXX always valid? */
- fallbacklabel = *lp;
- *lp = minilabel;
- }
- }
+ msg = readliflabel(bp, strat, lp, osdep, NULL, NULL, spoofonly);
+ if (msg == NULL)
+ goto done;
+
+ msg = readdoslabel(bp, strat, lp, osdep, NULL, NULL, spoofonly);
+ if (msg == NULL)
+ goto done;
#if defined(CD9660)
- if (msg && iso_disklabelspoof(dev, strat, lp) == 0)
+ if (iso_disklabelspoof(dev, strat, lp) == 0) {
msg = NULL;
+ goto done;
+ }
#endif
#if defined(UDF)
- if (msg && udf_disklabelspoof(dev, strat, lp) == 0)
+ if (udf_disklabelspoof(dev, strat, lp) == 0) {
msg = NULL;
+ goto done;
+ }
#endif
- /* If there was an error, still provide a decent fake one. */
- if (msg)
- *lp = fallbacklabel;
-
done:
if (bp) {
bp->b_flags |= B_INVAL;
brelse(bp);
}
- disklabeltokernlabel(lp);
- return (msg);
-}
-
-/*
- * If dos partition table requested, attempt to load it and
- * find disklabel inside a DOS partition. Return buffer
- * for use in signalling errors if requested.
- *
- * We would like to check if each MBR has a valid BOOT_MAGIC, but
- * we cannot because it doesn't always exist. So.. we assume the
- * MBR is valid.
- */
-char *
-readdoslabel(struct buf *bp, void (*strat)(struct buf *),
- struct disklabel *lp, struct cpu_disklabel *osdep,
- int *partoffp, int *cylp, int spoofonly)
-{
- struct dos_partition dp[NDOSPART], *dp2;
- struct partition *pp;
- unsigned long extoff = 0;
- unsigned int fattest;
- daddr64_t part_blkno = DOSBBSECTOR;
- char *msg = NULL;
- int dospartoff, cyl, i, ourpart = -1;
- int wander = 1, n = 0, loop = 0;
-
- if (lp->d_secpercyl == 0) {
- msg = "invalid label, d_secpercyl == 0";
- return (msg);
- }
- if (lp->d_secsize == 0) {
- msg = "invalid label, d_secsize == 0";
- return (msg);
- }
-
- /* do dos partitions in the process of getting disklabel? */
- dospartoff = 0;
- cyl = LABELSECTOR / lp->d_secpercyl;
-
- /*
- * Read dos partition table, follow extended partitions.
- * Map the partitions to disklabel entries i-p
- */
- while (wander && n < 8 && loop < 8) {
- loop++;
- wander = 0;
- if (part_blkno < extoff)
- part_blkno = extoff;
-
- /* read boot record */
- bp->b_blkno = part_blkno;
- bp->b_bcount = lp->d_secsize;
- bp->b_flags = B_BUSY | B_READ;
- bp->b_cylinder = part_blkno / lp->d_secpercyl;
- (*strat)(bp);
-
- /* if successful, wander through dos partition table */
- if (biowait(bp)) {
- msg = "dos partition I/O error";
- if (partoffp)
- *partoffp = -1;
- return (msg);
- }
- bcopy(bp->b_data + DOSPARTOFF, dp, sizeof(dp));
-
- if (ourpart == -1 && part_blkno == DOSBBSECTOR) {
- /* Search for our MBR partition */
- for (dp2=dp, i=0; i < NDOSPART && ourpart == -1;
- i++, dp2++)
- if (letoh32(dp2->dp_size) &&
- dp2->dp_typ == DOSPTYP_OPENBSD)
- ourpart = i;
- if (ourpart == -1)
- goto donot;
- /*
- * This is our MBR partition. need sector
- * address for SCSI/IDE, cylinder for
- * ESDI/ST506/RLL
- */
- dp2 = &dp[ourpart];
- dospartoff = letoh32(dp2->dp_start) + part_blkno;
- cyl = DPCYL(dp2->dp_scyl, dp2->dp_ssect);
-
- /* XXX build a temporary disklabel */
- DL_SETPSIZE(&lp->d_partitions[0], letoh32(dp2->dp_size));
- DL_SETPOFFSET(&lp->d_partitions[0],
- letoh32(dp2->dp_start) + part_blkno);
- if (lp->d_ntracks == 0)
- lp->d_ntracks = dp2->dp_ehd + 1;
- if (lp->d_nsectors == 0)
- lp->d_nsectors = DPSECT(dp2->dp_esect);
- if (lp->d_secpercyl == 0)
- lp->d_secpercyl = lp->d_ntracks *
- lp->d_nsectors;
- }
-donot:
- /*
- * In case the disklabel read below fails, we want to
- * provide a fake label in i-p.
- */
- for (dp2=dp, i=0; i < NDOSPART && n < 8; i++, dp2++) {
- pp = &lp->d_partitions[8+n];
-
- if (dp2->dp_typ == DOSPTYP_OPENBSD)
- continue;
- if (letoh32(dp2->dp_size) > DL_GETDSIZE(lp))
- continue;
- if (letoh32(dp2->dp_start) > DL_GETDSIZE(lp))
- continue;
- if (letoh32(dp2->dp_size) == 0)
- continue;
- if (letoh32(dp2->dp_start))
- DL_SETPOFFSET(pp,
- letoh32(dp2->dp_start) + part_blkno);
-
- DL_SETPSIZE(pp, letoh32(dp2->dp_size));
-
- switch (dp2->dp_typ) {
- case DOSPTYP_UNUSED:
- pp->p_fstype = FS_UNUSED;
- n++;
- break;
-
- case DOSPTYP_LINUX:
- pp->p_fstype = FS_EXT2FS;
- n++;
- break;
-
- case DOSPTYP_FAT12:
- case DOSPTYP_FAT16S:
- case DOSPTYP_FAT16B:
- case DOSPTYP_FAT16L:
- case DOSPTYP_FAT32:
- case DOSPTYP_FAT32L:
- pp->p_fstype = FS_MSDOS;
- n++;
- break;
- case DOSPTYP_EXTEND:
- case DOSPTYP_EXTENDL:
- part_blkno = letoh32(dp2->dp_start) + extoff;
- if (!extoff) {
- extoff = letoh32(dp2->dp_start);
- part_blkno = 0;
- }
- wander = 1;
- break;
- default:
- pp->p_fstype = FS_OTHER;
- n++;
- break;
- }
- }
- }
- lp->d_bbsize = 8192;
- lp->d_sbsize = 64*1024; /* XXX ? */
- lp->d_npartitions = MAXPARTITIONS;
-
- if (n == 0 && part_blkno == DOSBBSECTOR) {
- /* Check for a short jump instruction. */
- fattest = ((bp->b_data[0] << 8) & 0xff00) | (bp->b_data[2] &
- 0xff);
- if (fattest != 0xeb90 && fattest != 0xe900)
- goto notfat;
-
- /* Check for a valid bytes per sector value. */
- fattest = ((bp->b_data[12] << 8) & 0xff00) | (bp->b_data[11] &
- 0xff);
- if (fattest < 512 || fattest > 4096 || (fattest % 512 != 0))
- goto notfat;
-
- /* Check the end of sector marker. */
- fattest = ((bp->b_data[510] << 8) & 0xff00) | (bp->b_data[511] &
- 0xff);
- if (fattest != 0x55aa)
- goto notfat;
-
- /* Looks like a FAT filesystem. Spoof 'i'. */
- DL_SETPSIZE(&lp->d_partitions['i' - 'a'],
- DL_GETPSIZE(&lp->d_partitions[RAW_PART]));
- DL_SETPOFFSET(&lp->d_partitions['i' - 'a'], 0);
- lp->d_partitions['i' - 'a'].p_fstype = FS_MSDOS;
- }
-notfat:
-
- /* record the OpenBSD partition's placement for the caller */
- if (partoffp)
- *partoffp = dospartoff;
- if (cylp)
- *cylp = cyl;
-
- /* next, dig out disk label */
- msg = readbsdlabel(bp, strat, cyl, dospartoff + LABELSECTOR, -1,
- lp, spoofonly);
-
return (msg);
}
@@ -390,7 +99,10 @@ readliflabel(struct buf *bp, void (*strat)(struct buf *),
struct disklabel *lp, struct cpu_disklabel *osdep,
int *partoffp, int *cylp, int spoofonly)
{
- int fsoff;
+ struct buf *dbp = NULL;
+ struct lifdir *p;
+ char *msg = NULL;
+ int fsoff = 0;
/* read LIF volume header */
bp->b_blkno = btodb(LIF_VOLSTART);
@@ -398,148 +110,147 @@ readliflabel(struct buf *bp, void (*strat)(struct buf *),
bp->b_flags = B_BUSY | B_READ;
bp->b_cylinder = btodb(LIF_VOLSTART) / lp->d_secpercyl;
(*strat)(bp);
-
- if (biowait(bp)) {
- if (partoffp)
- *partoffp = -1;
+ if (biowait(bp))
return "LIF volume header I/O error";
- }
- bcopy (bp->b_data, &osdep->u._hppa.lifvol, sizeof(struct lifvol));
+ bcopy(bp->b_data, &osdep->u._hppa.lifvol, sizeof(struct lifvol));
if (osdep->u._hppa.lifvol.vol_id != LIF_VOL_ID) {
fsoff = 0;
- } else {
- struct lifdir *p;
- struct buf *dbp;
- dev_t dev;
+ goto finished;
+ }
+
+ dbp = geteblk(LIF_DIRSIZE);
+ dbp->b_dev = bp->b_dev;
+
+ /* read LIF directory */
+ dbp->b_blkno = lifstodb(osdep->u._hppa.lifvol.vol_addr);
+ dbp->b_bcount = lp->d_secsize;
+ dbp->b_flags = B_BUSY | B_READ;
+ dbp->b_cylinder = dbp->b_blkno / lp->d_secpercyl;
+ (*strat)(dbp);
+
+ if (biowait(dbp)) {
+ msg = "LIF directory I/O error";
+ goto done;
+ }
- dev = bp->b_dev;
- dbp = geteblk(LIF_DIRSIZE);
- dbp->b_dev = dev;
+ bcopy(dbp->b_data, osdep->u._hppa.lifdir, LIF_DIRSIZE);
+
+ /* scan for LIF_DIR_FS dir entry */
+ for (fsoff = -1, p = &osdep->u._hppa.lifdir[0];
+ fsoff < 0 && p < &osdep->u._hppa.lifdir[LIF_NUMDIR]; p++) {
+ if (p->dir_type == LIF_DIR_FS ||
+ p->dir_type == LIF_DIR_HPLBL)
+ break;
+ }
+
+ if (p->dir_type == LIF_DIR_FS) {
+ fsoff = lifstodb(p->dir_addr);
+ goto finished;
+ }
+
+ /* Only came here to find the offset... */
+ if (partoffp && spoofonly)
+ goto finished;
+
+ if (p->dir_type == LIF_DIR_HPLBL) {
+ struct hpux_label *hl;
+ struct partition *pp;
+ u_int8_t fstype;
+ int i;
/* read LIF directory */
- dbp->b_blkno = lifstodb(osdep->u._hppa.lifvol.vol_addr);
+ dbp->b_blkno = lifstodb(p->dir_addr);
dbp->b_bcount = lp->d_secsize;
dbp->b_flags = B_BUSY | B_READ;
dbp->b_cylinder = dbp->b_blkno / lp->d_secpercyl;
(*strat)(dbp);
if (biowait(dbp)) {
- if (partoffp)
- *partoffp = -1;
-
- dbp->b_flags |= B_INVAL;
- brelse(dbp);
- return ("LIF directory I/O error");
+ msg = "HPUX label I/O error";
+ goto done;
}
- bcopy(dbp->b_data, osdep->u._hppa.lifdir, LIF_DIRSIZE);
- dbp->b_flags |= B_INVAL;
- brelse(dbp);
+ bcopy(dbp->b_data, &osdep->u._hppa.hplabel,
+ sizeof(osdep->u._hppa.hplabel));
- /* scan for LIF_DIR_FS dir entry */
- for (fsoff = -1, p = &osdep->u._hppa.lifdir[0];
- fsoff < 0 && p < &osdep->u._hppa.lifdir[LIF_NUMDIR]; p++) {
- if (p->dir_type == LIF_DIR_FS ||
- p->dir_type == LIF_DIR_HPLBL)
- break;
+ hl = &osdep->u._hppa.hplabel;
+ if (hl->hl_magic1 != hl->hl_magic2 ||
+ hl->hl_magic != HPUX_MAGIC || hl->hl_version != 1) {
+ msg = "HPUX label magic mismatch";
+ goto done;
}
- if (p->dir_type == LIF_DIR_FS)
- fsoff = lifstodb(p->dir_addr);
- else if (p->dir_type == LIF_DIR_HPLBL) {
- struct hpux_label *hl;
- struct partition *pp;
- u_int8_t fstype;
- int i;
-
- dev = bp->b_dev;
- dbp = geteblk(LIF_DIRSIZE);
- dbp->b_dev = dev;
-
- /* read LIF directory */
- dbp->b_blkno = lifstodb(p->dir_addr);
- dbp->b_bcount = lp->d_secsize;
- dbp->b_flags = B_BUSY | B_READ;
- dbp->b_cylinder = dbp->b_blkno / lp->d_secpercyl;
- (*strat)(dbp);
-
- if (biowait(dbp)) {
- if (partoffp)
- *partoffp = -1;
-
- dbp->b_flags |= B_INVAL;
- brelse(dbp);
- return ("HOUX label I/O error");
- }
-
- bcopy(dbp->b_data, &osdep->u._hppa.hplabel,
- sizeof(osdep->u._hppa.hplabel));
- dbp->b_flags |= B_INVAL;
- brelse(dbp);
-
- hl = &osdep->u._hppa.hplabel;
- if (hl->hl_magic1 != hl->hl_magic2 ||
- hl->hl_magic != HPUX_MAGIC ||
- hl->hl_version != 1) {
- if (partoffp)
- *partoffp = -1;
-
- return "HPUX label magic mismatch";
- }
-
- lp->d_bbsize = 8192;
- lp->d_sbsize = 8192;
- for (i = 0; i < MAXPARTITIONS; i++) {
- DL_SETPSIZE(&lp->d_partitions[i], 0);
- DL_SETPOFFSET(&lp->d_partitions[i], 0);
- lp->d_partitions[i].p_fstype = 0;
- }
-
- for (i = 0; i < HPUX_MAXPART; i++) {
- if (!hl->hl_flags[i])
- continue;
-
- if (hl->hl_flags[i] == HPUX_PART_ROOT) {
- pp = &lp->d_partitions[0];
- fstype = FS_BSDFFS;
- } else if (hl->hl_flags[i] == HPUX_PART_SWAP) {
- pp = &lp->d_partitions[1];
- fstype = FS_SWAP;
- } else if (hl->hl_flags[i] == HPUX_PART_BOOT) {
- pp = &lp->d_partitions[RAW_PART + 1];
- fstype = FS_BSDFFS;
- } else
- continue;
-
- DL_SETPSIZE(pp, hl->hl_parts[i].hlp_length * 2);
- DL_SETPOFFSET(pp, hl->hl_parts[i].hlp_start * 2);
- pp->p_fstype = fstype;
- }
-
- DL_SETPSIZE(&lp->d_partitions[RAW_PART], DL_GETDSIZE(lp));
- DL_SETPOFFSET(&lp->d_partitions[RAW_PART], 0);
- lp->d_partitions[RAW_PART].p_fstype = FS_UNUSED;
- lp->d_npartitions = MAXPARTITIONS;
- lp->d_magic = DISKMAGIC;
- lp->d_magic2 = DISKMAGIC;
- lp->d_checksum = 0;
- lp->d_checksum = dkcksum(lp);
-
- return (NULL);
+ lp->d_bbsize = 8192;
+ lp->d_sbsize = 8192;
+ for (i = 0; i < MAXPARTITIONS; i++) {
+ DL_SETPSIZE(&lp->d_partitions[i], 0);
+ DL_SETPOFFSET(&lp->d_partitions[i], 0);
+ lp->d_partitions[i].p_fstype = 0;
}
- /* if no suitable lifdir entry found assume zero */
- if (fsoff < 0) {
- fsoff = 0;
+ for (i = 0; i < HPUX_MAXPART; i++) {
+ if (!hl->hl_flags[i])
+ continue;
+ if (hl->hl_flags[i] == HPUX_PART_ROOT) {
+ pp = &lp->d_partitions[0];
+ fstype = FS_BSDFFS;
+ } else if (hl->hl_flags[i] == HPUX_PART_SWAP) {
+ pp = &lp->d_partitions[1];
+ fstype = FS_SWAP;
+ } else if (hl->hl_flags[i] == HPUX_PART_BOOT) {
+ pp = &lp->d_partitions[RAW_PART + 1];
+ fstype = FS_BSDFFS;
+ } else
+ continue;
+
+ DL_SETPSIZE(pp, hl->hl_parts[i].hlp_length * 2);
+ DL_SETPOFFSET(pp, hl->hl_parts[i].hlp_start * 2);
+ pp->p_fstype = fstype;
}
+
+ DL_SETPSIZE(&lp->d_partitions[RAW_PART], DL_GETDSIZE(lp));
+ DL_SETPOFFSET(&lp->d_partitions[RAW_PART], 0);
+ lp->d_partitions[RAW_PART].p_fstype = FS_UNUSED;
+ lp->d_npartitions = MAXPARTITIONS;
+ lp->d_magic = DISKMAGIC;
+ lp->d_magic2 = DISKMAGIC;
+ lp->d_version = 1;
+ lp->d_checksum = 0;
+ lp->d_checksum = dkcksum(lp);
+ /* drop through */
}
+finished:
+ /* if no suitable lifdir entry found assume zero */
+ if (fsoff < 0)
+ fsoff = 0;
if (partoffp)
*partoffp = fsoff;
- return readbsdlabel(bp, strat, 0, fsoff + LABELSECTOR,
- LABELOFFSET, lp, spoofonly);
+ if (spoofonly)
+ goto done;
+
+ bp->b_blkno = fsoff + LABELSECTOR;
+ bp->b_cylinder = 0;
+ bp->b_bcount = lp->d_secsize;
+ bp->b_flags = B_BUSY | B_READ;
+ (*strat)(bp);
+
+ /* if successful, locate disk label within block and validate */
+ if (biowait(bp)) {
+ msg = "disk label I/O error";
+ goto done;
+ }
+
+ return checkdisklabel(bp->b_data + LABELOFFSET, lp);
+
+done:
+ if (dbp) {
+ dbp->b_flags |= B_INVAL;
+ brelse(dbp);
+ }
+ return (msg);
}
/*
@@ -549,42 +260,43 @@ int
writedisklabel(dev_t dev, void (*strat)(struct buf *),
struct disklabel *lp, struct cpu_disklabel *osdep)
{
- char *msg = "no disk label";
- struct buf *bp;
- struct disklabel dl;
- struct cpu_disklabel cdl;
- int labeloffset, error, partoff = 0, cyl = 0;
+ int error, partoff = -1, cyl = 0;
+ struct disklabel *dlp;
+ struct buf *bp = NULL;
/* get a buffer and initialize it */
bp = geteblk((int)lp->d_secsize);
bp->b_dev = dev;
- dl = *lp;
- msg = readliflabel(bp, strat, &dl, &cdl, &partoff, &cyl, 0);
- labeloffset = LABELOFFSET;
- if (msg) {
- dl = *lp;
- msg = readdoslabel(bp, strat, &dl, &cdl, &partoff, &cyl, 0);
- labeloffset = LABELOFFSET;
- }
- if (msg) {
- if (partoff == -1)
- return EIO;
-
- /* Write it in the regular place with native byte order. */
- labeloffset = LABELOFFSET;
- bp->b_blkno = partoff + LABELSECTOR;
- bp->b_cylinder = cyl;
- bp->b_bcount = lp->d_secsize;
- }
+ if (readliflabel(bp, strat, lp, osdep, &partoff, &cyl, 1) == NULL)
+ goto writeit;
- *(struct disklabel *)(bp->b_data + labeloffset) = *lp;
+ if (readdoslabel(bp, strat, lp, osdep, &partoff, &cyl, 1) == NULL)
+ goto writeit;
+
+ error = EIO;
+ goto done;
+
+writeit:
+ /* Read it in, slap the new label in, and write it back out */
+ bp->b_blkno = partoff + LABELSECTOR;
+ bp->b_cylinder = cyl;
+ bp->b_bcount = lp->d_secsize;
+ bp->b_flags = B_BUSY | B_READ;
+ (*strat)(bp);
+ if ((error = biowait(bp)) != 0)
+ goto done;
+ dlp = (struct disklabel *)(bp->b_data + LABELOFFSET);
+ *dlp = *lp;
bp->b_flags = B_BUSY | B_WRITE;
(*strat)(bp);
error = biowait(bp);
- bp->b_flags |= B_INVAL;
- brelse(bp);
+done:
+ if (bp) {
+ bp->b_flags |= B_INVAL;
+ brelse(bp);
+ }
return (error);
}
diff --git a/sys/arch/hppa64/include/disklabel.h b/sys/arch/hppa64/include/disklabel.h
index 83ea80baf88..596696c2e64 100644
--- a/sys/arch/hppa64/include/disklabel.h
+++ b/sys/arch/hppa64/include/disklabel.h
@@ -1,5 +1,4 @@
-/* $OpenBSD: disklabel.h,v 1.11 2007/06/07 02:55:12 krw Exp $ */
-/* $NetBSD: disklabel.h,v 1.1 1995/02/13 23:07:34 cgd Exp $ */
+/* $OpenBSD: disklabel.h,v 1.12 2007/06/17 00:27:27 deraadt Exp $ */
/*
* Copyright (c) 1994 Christopher G. Demetriou
@@ -36,50 +35,7 @@
#define LABELSECTOR 1
#define LABELOFFSET 0
-
#define MAXPARTITIONS 16 /* number of partitions */
-#define RAW_PART 2 /* raw partition: xx?c */
-
-/* DOS partition table -- located in boot block */
-#define DOSBBSECTOR 0 /* DOS boot block relative sector # */
-#define DOSPARTOFF 446
-#define DOSACTIVE 0x80
-#define NDOSPART 4
-#define DOSMBR_SIGNATURE 0xaa55
-#define DOSMBR_SIGNATURE_OFF 0x1fe
-
-struct dos_partition {
- u_int8_t dp_flag; /* bootstrap flags */
- u_int8_t dp_shd; /* starting head */
- u_int8_t dp_ssect; /* starting sector */
- u_int8_t dp_scyl; /* starting cylinder */
- u_int8_t dp_typ; /* partition type (see below) */
- u_int8_t dp_ehd; /* end head */
- u_int8_t dp_esect; /* end sector */
- u_int8_t dp_ecyl; /* end cylinder */
- u_int32_t dp_start; /* absolute starting sector number */
- u_int32_t dp_size; /* partition size in sectors */
-};
-
-/* Known DOS partition types. */
-#define DOSPTYP_UNUSED 0x00 /* Unused partition */
-#define DOSPTYP_FAT12 0x01 /* 12-bit FAT */
-#define DOSPTYP_FAT16S 0x04 /* 16-bit FAT, less than 32M */
-#define DOSPTYP_EXTEND 0x05 /* Extended; contains sub-partitions */
-#define DOSPTYP_FAT16B 0x06 /* 16-bit FAT, more than 32M */
-#define DOSPTYP_FAT32 0x0b /* 32-bit FAT */
-#define DOSPTYP_FAT32L 0x0c /* 32-bit FAT, LBA-mapped */
-#define DOSPTYP_FAT16L 0x0e /* 16-bit FAT, LBA-mapped */
-#define DOSPTYP_EXTENDL 0x0f /* Extended, LBA-mapped; contains sub-partitions */
-#define DOSPTYP_ONTRACK 0x54
-#define DOSPTYP_LINUX 0x83 /* That other thing */
-#define DOSPTYP_FREEBSD 0xa5 /* FreeBSD partition type */
-#define DOSPTYP_OPENBSD 0xa6 /* OpenBSD partition type */
-#define DOSPTYP_NETBSD 0xa9 /* NetBSD partition type */
-
-/* Isolate the relevant bits to get sector and cylinder. */
-#define DPSECT(s) ((s) & 0x3f)
-#define DPCYL(c, s) ((c) + (((s) & 0xc0) << 2))
/*
* volume header for "LIF" format volumes
diff --git a/sys/arch/i386/i386/disksubr.c b/sys/arch/i386/i386/disksubr.c
index f44221b04fb..9e6bbb939be 100644
--- a/sys/arch/i386/i386/disksubr.c
+++ b/sys/arch/i386/i386/disksubr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: disksubr.c,v 1.90 2007/06/14 03:37:23 deraadt Exp $ */
+/* $OpenBSD: disksubr.c,v 1.91 2007/06/17 00:27:28 deraadt Exp $ */
/* $NetBSD: disksubr.c,v 1.21 1996/05/03 19:42:03 christos Exp $ */
/*
@@ -29,16 +29,12 @@
* 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.
- *
- * @(#)ufs_disksubr.c 7.16 (Berkeley) 5/4/91
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/buf.h>
-#include <sys/device.h>
#include <sys/disklabel.h>
-#include <sys/syslog.h>
#include <sys/disk.h>
#include <sys/reboot.h>
#include <sys/conf.h>
@@ -69,37 +65,13 @@ char *
readdisklabel(dev_t dev, void (*strat)(struct buf *),
struct disklabel *lp, struct cpu_disklabel *osdep, int spoofonly)
{
- struct dos_partition dp[NDOSPART], *dp2;
- struct partition *pp;
- struct disklabel *dlp;
bios_diskinfo_t *pdi;
- unsigned long extoff = 0;
- unsigned int fattest;
struct buf *bp = NULL;
- daddr64_t part_blkno = DOSBBSECTOR;
dev_t devno;
- char *msg = NULL;
- int dospartoff, cyl, i, ourpart = -1;
- int wander = 1, n = 0, loop = 0;
+ char *msg;
- /* minimal requirements for archetypal disk label */
- if (lp->d_secsize < DEV_BSIZE)
- lp->d_secsize = DEV_BSIZE;
- if (DL_GETDSIZE(lp) == 0)
- DL_SETDSIZE(lp, MAXDISKSIZE);
- if (lp->d_secpercyl == 0) {
- msg = "invalid geometry";
+ if ((msg = initdisklabel(lp)))
goto done;
- }
- lp->d_npartitions = RAW_PART + 1;
- for (i = 0; i < RAW_PART; i++) {
- DL_SETPSIZE(&lp->d_partitions[i], 0);
- DL_SETPOFFSET(&lp->d_partitions[i], 0);
- }
- if (DL_GETPSIZE(&lp->d_partitions[RAW_PART]) == 0)
- DL_SETPSIZE(&lp->d_partitions[RAW_PART], DL_GETDSIZE(lp));
- DL_SETPOFFSET(&lp->d_partitions[RAW_PART], 0);
- lp->d_version = 1;
/* Look for any BIOS geometry information we should honour. */
devno = chrtoblk(dev);
@@ -124,193 +96,21 @@ readdisklabel(dev_t dev, void (*strat)(struct buf *),
bp = geteblk((int)lp->d_secsize);
bp->b_dev = dev;
- /* do dos partitions in the process of getting disklabel? */
- dospartoff = 0;
- cyl = LABELSECTOR / lp->d_secpercyl;
-
- /*
- * Read dos partition table, follow extended partitions.
- * Map the partitions to disklabel entries i-p
- */
- while (wander && n < 8 && loop < 8) {
- loop++;
- wander = 0;
- if (part_blkno < extoff)
- part_blkno = extoff;
-
- /* read boot record */
- bp->b_blkno = part_blkno;
- bp->b_bcount = lp->d_secsize;
- bp->b_flags = B_BUSY | B_READ;
- bp->b_cylinder = part_blkno / lp->d_secpercyl;
- (*strat)(bp);
-
- /* if successful, wander through dos partition table */
- if (biowait(bp)) {
- msg = "dos partition I/O error";
- goto done;
- }
- bcopy(bp->b_data + DOSPARTOFF, dp, sizeof(dp));
-
- if (ourpart == -1 && part_blkno == DOSBBSECTOR) {
- /* Search for our MBR partition */
- for (dp2=dp, i=0; i < NDOSPART && ourpart == -1;
- i++, dp2++)
- if (letoh32(dp2->dp_size) &&
- dp2->dp_typ == DOSPTYP_OPENBSD)
- ourpart = i;
- if (ourpart == -1)
- goto donot;
- /*
- * This is our MBR partition. need sector address
- * for SCSI/IDE, cylinder for ESDI/ST506/RLL
- */
- dp2 = &dp[ourpart];
- dospartoff = letoh32(dp2->dp_start) + part_blkno;
- cyl = DPCYL(dp2->dp_scyl, dp2->dp_ssect);
-
- /* XXX build a temporary disklabel */
- DL_SETPSIZE(&lp->d_partitions[0], letoh32(dp2->dp_size));
- DL_SETPOFFSET(&lp->d_partitions[0],
- letoh32(dp2->dp_start) + part_blkno);
- if (lp->d_ntracks == 0)
- lp->d_ntracks = dp2->dp_ehd + 1;
- if (lp->d_nsectors == 0)
- lp->d_nsectors = DPSECT(dp2->dp_esect);
- if (lp->d_secpercyl == 0)
- lp->d_secpercyl = lp->d_ntracks *
- lp->d_nsectors;
- }
-donot:
- /*
- * In case the disklabel read below fails, we want to
- * provide a fake label in i-p.
- */
- for (dp2=dp, i=0; i < NDOSPART && n < 8; i++, dp2++) {
- pp = &lp->d_partitions[8+n];
-
- if (dp2->dp_typ == DOSPTYP_OPENBSD)
- continue;
- if (letoh32(dp2->dp_size) > DL_GETDSIZE(lp))
- continue;
- if (letoh32(dp2->dp_start) > DL_GETDSIZE(lp))
- continue;
- if (letoh32(dp2->dp_size) == 0)
- continue;
- if (letoh32(dp2->dp_start))
- DL_SETPOFFSET(pp,
- letoh32(dp2->dp_start) + part_blkno);
-
- DL_SETPSIZE(pp, letoh32(dp2->dp_size));
-
- switch (dp2->dp_typ) {
- case DOSPTYP_UNUSED:
- pp->p_fstype = FS_UNUSED;
- n++;
- break;
-
- case DOSPTYP_LINUX:
- pp->p_fstype = FS_EXT2FS;
- n++;
- break;
-
- case DOSPTYP_FAT12:
- case DOSPTYP_FAT16S:
- case DOSPTYP_FAT16B:
- case DOSPTYP_FAT16L:
- case DOSPTYP_FAT32:
- case DOSPTYP_FAT32L:
- pp->p_fstype = FS_MSDOS;
- n++;
- break;
- case DOSPTYP_EXTEND:
- case DOSPTYP_EXTENDL:
- part_blkno = letoh32(dp2->dp_start) + extoff;
- if (!extoff) {
- extoff = letoh32(dp2->dp_start);
- part_blkno = 0;
- }
- wander = 1;
- break;
- default:
- pp->p_fstype = FS_OTHER;
- n++;
- break;
- }
- }
- }
- lp->d_bbsize = 8192;
- lp->d_sbsize = 64*1024; /* XXX ? */
- lp->d_npartitions = MAXPARTITIONS;
-
- if (n == 0 && part_blkno == DOSBBSECTOR) {
- /* Check for a short jump instruction. */
- fattest = ((bp->b_data[0] << 8) & 0xff00) | (bp->b_data[2] &
- 0xff);
- if (fattest != 0xeb90 && fattest != 0xe900)
- goto notfat;
-
- /* Check for a valid bytes per sector value. */
- fattest = ((bp->b_data[12] << 8) & 0xff00) | (bp->b_data[11] &
- 0xff);
- if (fattest < 512 || fattest > 4096 || (fattest % 512 != 0))
- goto notfat;
-
- /* Check the end of sector marker. */
- fattest = ((bp->b_data[510] << 8) & 0xff00) | (bp->b_data[511] &
- 0xff);
- if (fattest != 0x55aa)
- goto notfat;
-
- /* Looks like a FAT filesystem. Spoof 'i'. */
- DL_SETPSIZE(&lp->d_partitions['i' - 'a'],
- DL_GETPSIZE(&lp->d_partitions[RAW_PART]));
- DL_SETPOFFSET(&lp->d_partitions['i' - 'a'], 0);
- lp->d_partitions['i' - 'a'].p_fstype = FS_MSDOS;
- }
-notfat:
-
- /* don't read the on-disk label if we are in spoofed-only mode */
- if (spoofonly)
- goto done;
-
- /* next, dig out disk label */
- bp->b_blkno = dospartoff + LABELSECTOR;
- bp->b_cylinder = cyl;
- bp->b_bcount = lp->d_secsize;
- bp->b_flags = B_BUSY | B_READ;
- (*strat)(bp);
-
- /* if successful, locate disk label within block and validate */
- if (biowait(bp)) {
- /* XXX we return the faked label built so far */
- msg = "disk label I/O error";
+ msg = readdoslabel(bp, strat, lp, osdep, NULL, NULL, spoofonly);
+ if (msg == NULL)
goto done;
- }
- for (dlp = (struct disklabel *)bp->b_data;
- dlp <= (struct disklabel *)(bp->b_data + lp->d_secsize - sizeof(*dlp));
- dlp = (struct disklabel *)((char *)dlp + sizeof(long))) {
- if (dlp->d_magic != DISKMAGIC || dlp->d_magic2 != DISKMAGIC) {
- if (msg == NULL)
- msg = "no disk label";
- } else if (dlp->d_npartitions > MAXPARTITIONS ||
- dkcksum(dlp) != 0)
- msg = "disk label corrupted";
- else {
- DL_SETDSIZE(dlp, DL_GETDSIZE(lp));
- *lp = *dlp;
- msg = NULL;
- break;
- }
- }
#if defined(CD9660)
- if (msg && iso_disklabelspoof(dev, strat, lp) == 0)
+ if (iso_disklabelspoof(dev, strat, lp) == 0) {
msg = NULL;
+ goto done;
+ }
#endif
#if defined(UDF)
- if (msg && udf_disklabelspoof(dev, strat, lp) == 0)
+ if (udf_disklabelspoof(dev, strat, lp) == 0) {
msg = NULL;
+ goto done;
+ }
#endif
done:
@@ -318,7 +118,6 @@ done:
bp->b_flags |= B_INVAL;
brelse(bp);
}
- disklabeltokernlabel(lp);
return (msg);
}
@@ -330,73 +129,30 @@ int
writedisklabel(dev_t dev, void (*strat)(struct buf *),
struct disklabel *lp, struct cpu_disklabel *osdep)
{
- struct dos_partition dp[NDOSPART], *dp2;
+ int error, partoff = -1, cyl = 0;
struct disklabel *dlp;
struct buf *bp = NULL;
- int error, dospartoff, cyl, i;
- int ourpart = -1;
/* get a buffer and initialize it */
bp = geteblk((int)lp->d_secsize);
bp->b_dev = dev;
- /* do dos partitions in the process of getting disklabel? */
- dospartoff = 0;
- cyl = LABELSECTOR / lp->d_secpercyl;
-
- /* read master boot record */
- 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 ((error = biowait(bp)) != 0)
+ if (readdoslabel(bp, strat, lp, osdep, &partoff, &cyl, 1) != NULL) {
+ error = EIO;
goto done;
-
- /* XXX how do we check veracity/bounds of this? */
- bcopy(bp->b_data + DOSPARTOFF, dp, sizeof(dp));
-
- for (dp2=dp, i=0; i < NDOSPART && ourpart == -1; i++, dp2++)
- if (letoh32(dp2->dp_size) && dp2->dp_typ == DOSPTYP_OPENBSD)
- ourpart = i;
-
- if (ourpart != -1) {
- dp2 = &dp[ourpart];
-
- /*
- * need sector address for SCSI/IDE,
- * cylinder for ESDI/ST506/RLL
- */
- dospartoff = letoh32(dp2->dp_start);
- cyl = DPCYL(dp2->dp_scyl, dp2->dp_ssect);
}
- /* next, dig out disk label */
- bp->b_blkno = dospartoff + LABELSECTOR;
+ /* Read it in, slap the new label in, and write it back out */
+ bp->b_blkno = partoff + LABELSECTOR;
bp->b_cylinder = cyl;
bp->b_bcount = lp->d_secsize;
bp->b_flags = B_BUSY | B_READ;
(*strat)(bp);
-
- /* if successful, locate disk label within block and validate */
if ((error = biowait(bp)) != 0)
goto done;
- for (dlp = (struct disklabel *)bp->b_data;
- dlp <= (struct disklabel *)(bp->b_data + lp->d_secsize - sizeof(*dlp));
- dlp = (struct disklabel *)((char *)dlp + sizeof(long))) {
- if (dlp->d_magic == DISKMAGIC && dlp->d_magic2 == DISKMAGIC &&
- dkcksum(dlp) == 0) {
- *dlp = *lp;
- bp->b_flags = B_BUSY | B_WRITE;
- (*strat)(bp);
- error = biowait(bp);
- goto done;
- }
- }
- /* Write it in the regular place. */
- *(struct disklabel *)bp->b_data = *lp;
+ dlp = (struct disklabel *)(bp->b_data + LABELOFFSET);
+ *dlp = *lp;
bp->b_flags = B_BUSY | B_WRITE;
(*strat)(bp);
error = biowait(bp);
diff --git a/sys/arch/i386/include/disklabel.h b/sys/arch/i386/include/disklabel.h
index 5a960c6dfb7..009a100a3a0 100644
--- a/sys/arch/i386/include/disklabel.h
+++ b/sys/arch/i386/include/disklabel.h
@@ -1,5 +1,4 @@
-/* $OpenBSD: disklabel.h,v 1.32 2006/10/20 23:47:42 krw Exp $ */
-/* $NetBSD: disklabel.h,v 1.3 1996/03/09 20:52:54 ghudson Exp $ */
+/* $OpenBSD: disklabel.h,v 1.33 2007/06/17 00:27:27 deraadt Exp $ */
/*
* Copyright (c) 1994 Christopher G. Demetriou
@@ -37,58 +36,8 @@
#define LABELSECTOR 1 /* sector containing label */
#define LABELOFFSET 0 /* offset of label in sector */
#define MAXPARTITIONS 16 /* number of partitions */
-#define RAW_PART 2 /* raw partition: ie. rsd0c */
-
-/* DOS partition table -- located in boot block */
-#define DOSBBSECTOR 0 /* DOS boot block relative sector # */
-#define DOSPARTOFF 446
-#define DOSDISKOFF 444
-#define NDOSPART 4
-#define DOSACTIVE 0x80 /* active partition */
-
-struct dos_partition {
- u_int8_t dp_flag; /* bootstrap flags */
- u_int8_t dp_shd; /* starting head */
- u_int8_t dp_ssect; /* starting sector */
- u_int8_t dp_scyl; /* starting cylinder */
- u_int8_t dp_typ; /* partition type (see below) */
- u_int8_t dp_ehd; /* end head */
- u_int8_t dp_esect; /* end sector */
- u_int8_t dp_ecyl; /* end cylinder */
- u_int32_t dp_start; /* absolute starting sector number */
- u_int32_t dp_size; /* partition size in sectors */
-};
-
-/* Known DOS partition types. */
-#define DOSPTYP_UNUSED 0x00 /* Unused partition */
-#define DOSPTYP_FAT12 0x01 /* 12-bit FAT */
-#define DOSPTYP_FAT16S 0x04 /* 16-bit FAT, less than 32M */
-#define DOSPTYP_EXTEND 0x05 /* Extended; contains sub-partitions */
-#define DOSPTYP_FAT16B 0x06 /* 16-bit FAT, more than 32M */
-#define DOSPTYP_FAT32 0x0b /* 32-bit FAT */
-#define DOSPTYP_FAT32L 0x0c /* 32-bit FAT, LBA-mapped */
-#define DOSPTYP_FAT16L 0x0e /* 16-bit FAT, LBA-mapped */
-#define DOSPTYP_EXTENDL 0x0f /* Extended, LBA-mapped; contains sub-partitions */
-#define DOSPTYP_ONTRACK 0x54
-#define DOSPTYP_LINUX 0x83 /* That other thing */
-#define DOSPTYP_FREEBSD 0xa5 /* FreeBSD partition type */
-#define DOSPTYP_OPENBSD 0xa6 /* OpenBSD partition type */
-#define DOSPTYP_NETBSD 0xa9 /* NetBSD partition type */
-
-struct dos_mbr {
- u_int8_t dmbr_boot[DOSPARTOFF];
- struct dos_partition dmbr_parts[NDOSPART];
- u_int16_t dmbr_sign;
-} __packed;
-
-#define DOSMBR_SIGNATURE (0xaa55)
-#define DOSMBR_SIGNATURE_OFF (0x1fe)
struct cpu_disklabel {
};
-/* Isolate the relevant bits to get sector and cylinder. */
-#define DPSECT(s) ((s) & 0x3f)
-#define DPCYL(c, s) ((c) + (((s) & 0xc0) << 2))
-
#endif /* _MACHINE_DISKLABEL_H_ */
diff --git a/sys/arch/landisk/include/disklabel.h b/sys/arch/landisk/include/disklabel.h
index 4d7cc146698..9da9360f5a0 100644
--- a/sys/arch/landisk/include/disklabel.h
+++ b/sys/arch/landisk/include/disklabel.h
@@ -1 +1,3 @@
+/* $OpenBSD: disklabel.h,v 1.2 2007/06/17 00:27:27 deraadt Exp $ */
+
#include <sh/disklabel.h>
diff --git a/sys/arch/landisk/landisk/disksubr.c b/sys/arch/landisk/landisk/disksubr.c
index fc73f3d3ab8..2f55984164f 100644
--- a/sys/arch/landisk/landisk/disksubr.c
+++ b/sys/arch/landisk/landisk/disksubr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: disksubr.c,v 1.32 2007/06/14 03:37:23 deraadt Exp $ */
+/* $OpenBSD: disksubr.c,v 1.33 2007/06/17 00:27:28 deraadt Exp $ */
/* $NetBSD: disksubr.c,v 1.21 1996/05/03 19:42:03 christos Exp $ */
/*
@@ -29,16 +29,12 @@
* 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.
- *
- * @(#)ufs_disksubr.c 7.16 (Berkeley) 5/4/91
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/buf.h>
-#include <sys/device.h>
#include <sys/disklabel.h>
-#include <sys/syslog.h>
#include <sys/disk.h>
/*
@@ -63,227 +59,31 @@ char *
readdisklabel(dev_t dev, void (*strat)(struct buf *),
struct disklabel *lp, struct cpu_disklabel *osdep, int spoofonly)
{
- struct dos_partition dp[NDOSPART], *dp2;
- struct partition *pp;
- struct disklabel *dlp;
- unsigned long extoff = 0;
- unsigned int fattest;
struct buf *bp = NULL;
- daddr64_t part_blkno = DOSBBSECTOR;
- char *msg = NULL;
- int dospartoff, cyl, i, ourpart = -1;
- int wander = 1, n = 0, loop = 0;
+ char *msg;
- /* minimal requirements for archetypal disk label */
- if (lp->d_secsize < DEV_BSIZE)
- lp->d_secsize = DEV_BSIZE;
- if (DL_GETDSIZE(lp) == 0)
- DL_SETDSIZE(lp, MAXDISKSIZE);
- if (lp->d_secpercyl == 0) {
- msg = "invalid geometry";
+ if ((msg = initdisklabel(lp)))
goto done;
- }
- lp->d_npartitions = RAW_PART + 1;
- for (i = 0; i < RAW_PART; i++) {
- DL_SETPSIZE(&lp->d_partitions[i], 0);
- DL_SETPOFFSET(&lp->d_partitions[i], 0);
- }
- if (DL_GETPSIZE(&lp->d_partitions[RAW_PART]) == 0)
- DL_SETPSIZE(&lp->d_partitions[RAW_PART], DL_GETDSIZE(lp));
- DL_SETPOFFSET(&lp->d_partitions[RAW_PART], 0);
- lp->d_version = 1;
/* get a buffer and initialize it */
bp = geteblk((int)lp->d_secsize);
bp->b_dev = dev;
- /* do dos partitions in the process of getting disklabel? */
- dospartoff = 0;
- cyl = LABELSECTOR / lp->d_secpercyl;
-
- /*
- * Read dos partition table, follow extended partitions.
- * Map the partitions to disklabel entries i-p
- */
- while (wander && n < 8 && loop < 8) {
- loop++;
- wander = 0;
- if (part_blkno < extoff)
- part_blkno = extoff;
-
- /* read boot record */
- bp->b_blkno = part_blkno;
- bp->b_bcount = lp->d_secsize;
- bp->b_flags = B_BUSY | B_READ;
- bp->b_cylinder = part_blkno / lp->d_secpercyl;
- (*strat)(bp);
-
- /* if successful, wander through dos partition table */
- if (biowait(bp)) {
- msg = "dos partition I/O error";
- goto done;
- }
- bcopy(bp->b_data + DOSPARTOFF, dp, sizeof(dp));
-
- if (ourpart == -1 && part_blkno == DOSBBSECTOR) {
- /* Search for our MBR partition */
- for (dp2=dp, i=0; i < NDOSPART && ourpart == -1;
- i++, dp2++)
- if (letoh32(dp2->dp_size) &&
- dp2->dp_typ == DOSPTYP_OPENBSD)
- ourpart = i;
- if (ourpart == -1)
- goto donot;
- /*
- * This is our MBR partition. need sector address
- * for SCSI/IDE, cylinder for ESDI/ST506/RLL
- */
- dp2 = &dp[ourpart];
- dospartoff = letoh32(dp2->dp_start) + part_blkno;
- cyl = DPCYL(dp2->dp_scyl, dp2->dp_ssect);
-
- /* XXX build a temporary disklabel */
- DL_SETPSIZE(&lp->d_partitions[0], letoh32(dp2->dp_size));
- DL_SETPOFFSET(&lp->d_partitions[0],
- letoh32(dp2->dp_start) + part_blkno);
- if (lp->d_ntracks == 0)
- lp->d_ntracks = dp2->dp_ehd + 1;
- if (lp->d_nsectors == 0)
- lp->d_nsectors = DPSECT(dp2->dp_esect);
- if (lp->d_secpercyl == 0)
- lp->d_secpercyl = lp->d_ntracks *
- lp->d_nsectors;
- }
-donot:
- /*
- * In case the disklabel read below fails, we want to
- * provide a fake label in i-p.
- */
- for (dp2=dp, i=0; i < NDOSPART && n < 8; i++, dp2++) {
- pp = &lp->d_partitions[8+n];
-
- if (dp2->dp_typ == DOSPTYP_OPENBSD)
- continue;
- if (letoh32(dp2->dp_size) > DL_GETDSIZE(lp))
- continue;
- if (letoh32(dp2->dp_start) > DL_GETDSIZE(lp))
- continue;
- if (letoh32(dp2->dp_size) == 0)
- continue;
- if (letoh32(dp2->dp_start))
- DL_SETPOFFSET(pp,
- letoh32(dp2->dp_start) + part_blkno);
-
- DL_SETPSIZE(pp, letoh32(dp2->dp_size));
-
- switch (dp2->dp_typ) {
- case DOSPTYP_UNUSED:
- pp->p_fstype = FS_UNUSED;
- n++;
- break;
-
- case DOSPTYP_LINUX:
- pp->p_fstype = FS_EXT2FS;
- n++;
- break;
-
- case DOSPTYP_FAT12:
- case DOSPTYP_FAT16S:
- case DOSPTYP_FAT16B:
- case DOSPTYP_FAT16L:
- case DOSPTYP_FAT32:
- case DOSPTYP_FAT32L:
- pp->p_fstype = FS_MSDOS;
- n++;
- break;
- case DOSPTYP_EXTEND:
- case DOSPTYP_EXTENDL:
- part_blkno = letoh32(dp2->dp_start) + extoff;
- if (!extoff) {
- extoff = letoh32(dp2->dp_start);
- part_blkno = 0;
- }
- wander = 1;
- break;
- default:
- pp->p_fstype = FS_OTHER;
- n++;
- break;
- }
- }
- }
- lp->d_bbsize = 8192;
- lp->d_sbsize = 64*1024; /* XXX ? */
- lp->d_npartitions = MAXPARTITIONS;
-
- if (n == 0 && part_blkno == DOSBBSECTOR) {
- /* Check for a short jump instruction. */
- fattest = ((bp->b_data[0] << 8) & 0xff00) | (bp->b_data[2] &
- 0xff);
- if (fattest != 0xeb90 && fattest != 0xe900)
- goto notfat;
-
- /* Check for a valid bytes per sector value. */
- fattest = ((bp->b_data[12] << 8) & 0xff00) | (bp->b_data[11] &
- 0xff);
- if (fattest < 512 || fattest > 4096 || (fattest % 512 != 0))
- goto notfat;
-
- /* Check the end of sector marker. */
- fattest = ((bp->b_data[510] << 8) & 0xff00) | (bp->b_data[511] &
- 0xff);
- if (fattest != 0x55aa)
- goto notfat;
-
- /* Looks like a FAT filesystem. Spoof 'i'. */
- DL_SETPSIZE(&lp->d_partitions['i' - 'a'],
- DL_GETPSIZE(&lp->d_partitions[RAW_PART]));
- DL_SETPOFFSET(&lp->d_partitions['i' - 'a'], 0);
- lp->d_partitions['i' - 'a'].p_fstype = FS_MSDOS;
- }
-notfat:
-
- /* don't read the on-disk label if we are in spoofed-only mode */
- if (spoofonly)
- goto done;
-
- /* next, dig out disk label */
- bp->b_blkno = dospartoff + LABELSECTOR;
- bp->b_cylinder = cyl;
- bp->b_bcount = lp->d_secsize;
- bp->b_flags = B_BUSY | B_READ;
- (*strat)(bp);
-
- /* if successful, locate disk label within block and validate */
- if (biowait(bp)) {
- /* XXX we return the faked label built so far */
- msg = "disk label I/O error";
+ msg = readdoslabel(bp, strat, lp, osdep, NULL, NULL, spoofonly);
+ if (msg == NULL)
goto done;
- }
- for (dlp = (struct disklabel *)bp->b_data;
- dlp <= (struct disklabel *)(bp->b_data + lp->d_secsize - sizeof(*dlp));
- dlp = (struct disklabel *)((char *)dlp + sizeof(long))) {
- if (dlp->d_magic != DISKMAGIC || dlp->d_magic2 != DISKMAGIC) {
- if (msg == NULL)
- msg = "no disk label";
- } else if (dlp->d_npartitions > MAXPARTITIONS ||
- dkcksum(dlp) != 0)
- msg = "disk label corrupted";
- else {
- DL_SETDSIZE(dlp, DL_GETDSIZE(lp));
- *lp = *dlp;
- msg = NULL;
- break;
- }
- }
#if defined(CD9660)
- if (msg && iso_disklabelspoof(dev, strat, lp) == 0)
+ if (iso_disklabelspoof(dev, strat, lp) == 0) {
msg = NULL;
+ goto done;
+ }
#endif
#if defined(UDF)
- if (msg && udf_disklabelspoof(dev, strat, lp) == 0)
+ if (udf_disklabelspoof(dev, strat, lp) == 0) {
msg = NULL;
+ goto done;
+ }
#endif
done:
@@ -291,7 +91,6 @@ done:
bp->b_flags |= B_INVAL;
brelse(bp);
}
- disklabeltokernlabel(lp);
return (msg);
}
@@ -303,73 +102,30 @@ int
writedisklabel(dev_t dev, void (*strat)(struct buf *),
struct disklabel *lp, struct cpu_disklabel *osdep)
{
- struct dos_partition dp[NDOSPART], *dp2;
+ int error, partoff = -1, cyl = 0;
struct disklabel *dlp;
struct buf *bp = NULL;
- int error, dospartoff, cyl, i;
- int ourpart = -1;
/* get a buffer and initialize it */
bp = geteblk((int)lp->d_secsize);
bp->b_dev = dev;
- /* do dos partitions in the process of getting disklabel? */
- dospartoff = 0;
- cyl = LABELSECTOR / lp->d_secpercyl;
-
- /* read master boot record */
- 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 ((error = biowait(bp)) != 0)
+ if (readdoslabel(bp, strat, lp, osdep, &partoff, &cyl, 1) != NULL) {
+ error = EIO;
goto done;
-
- /* XXX how do we check veracity/bounds of this? */
- bcopy(bp->b_data + DOSPARTOFF, dp, sizeof(dp));
-
- for (dp2=dp, i=0; i < NDOSPART && ourpart == -1; i++, dp2++)
- if (letoh32(dp2->dp_size) && dp2->dp_typ == DOSPTYP_OPENBSD)
- ourpart = i;
-
- if (ourpart != -1) {
- dp2 = &dp[ourpart];
-
- /*
- * need sector address for SCSI/IDE,
- * cylinder for ESDI/ST506/RLL
- */
- dospartoff = letoh32(dp2->dp_start);
- cyl = DPCYL(dp2->dp_scyl, dp2->dp_ssect);
}
- /* next, dig out disk label */
- bp->b_blkno = dospartoff + LABELSECTOR;
+ /* Read it in, slap the new label in, and write it back out */
+ bp->b_blkno = partoff + LABELSECTOR;
bp->b_cylinder = cyl;
bp->b_bcount = lp->d_secsize;
bp->b_flags = B_BUSY | B_READ;
(*strat)(bp);
-
- /* if successful, locate disk label within block and validate */
if ((error = biowait(bp)) != 0)
goto done;
- for (dlp = (struct disklabel *)bp->b_data;
- dlp <= (struct disklabel *)(bp->b_data + lp->d_secsize - sizeof(*dlp));
- dlp = (struct disklabel *)((char *)dlp + sizeof(long))) {
- if (dlp->d_magic == DISKMAGIC && dlp->d_magic2 == DISKMAGIC &&
- dkcksum(dlp) == 0) {
- *dlp = *lp;
- bp->b_flags = B_BUSY | B_WRITE;
- (*strat)(bp);
- error = biowait(bp);
- goto done;
- }
- }
- /* Write it in the regular place. */
- *(struct disklabel *)bp->b_data = *lp;
+ dlp = (struct disklabel *)(bp->b_data + LABELOFFSET);
+ *dlp = *lp;
bp->b_flags = B_BUSY | B_WRITE;
(*strat)(bp);
error = biowait(bp);
diff --git a/sys/arch/luna88k/include/disklabel.h b/sys/arch/luna88k/include/disklabel.h
index f2eae514c98..73ddbdee561 100644
--- a/sys/arch/luna88k/include/disklabel.h
+++ b/sys/arch/luna88k/include/disklabel.h
@@ -1,5 +1,4 @@
-/* $OpenBSD: disklabel.h,v 1.2 2006/10/04 03:23:01 krw Exp $ */
-/* $NetBSD: disklabel.h,v 1.2 2000/01/28 02:25:24 nisimura Exp $ */
+/* $OpenBSD: disklabel.h,v 1.3 2007/06/17 00:27:27 deraadt Exp $ */
/*
* Copyright (c) 1994 Christopher G. Demetriou
@@ -37,7 +36,6 @@
#define LABELSECTOR 0 /* sector containing label */
#define LABELOFFSET 64 /* offset of label in sector */
#define MAXPARTITIONS 16 /* number of partitions */
-#define RAW_PART 2 /* raw partition: xx?c */
/*
* This holds a copy of the whole label block, saved in here by
diff --git a/sys/arch/luna88k/luna88k/disksubr.c b/sys/arch/luna88k/luna88k/disksubr.c
index e625bac11ab..b09a74d8916 100644
--- a/sys/arch/luna88k/luna88k/disksubr.c
+++ b/sys/arch/luna88k/luna88k/disksubr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: disksubr.c,v 1.29 2007/06/14 03:41:21 deraadt Exp $ */
+/* $OpenBSD: disksubr.c,v 1.30 2007/06/17 00:27:28 deraadt Exp $ */
/* $NetBSD: disksubr.c,v 1.12 2002/02/19 17:09:44 wiz Exp $ */
/*
@@ -34,14 +34,6 @@
* 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.
- *
- * Credits:
- * This file was based mostly on the i386/disksubr.c file:
- * @(#)ufs_disksubr.c 7.16 (Berkeley) 5/4/91
- * The functions: disklabel_sun_to_bsd, disklabel_bsd_to_sun
- * were originally taken from arch/sparc/scsi/sun_disklabel.c
- * (which was written by Theo de Raadt) and then substantially
- * rewritten by Gordon W. Ross.
*/
#include <sys/param.h>
@@ -118,37 +110,19 @@ readdisklabel(dev_t dev, void (*strat)(struct buf *),
struct buf *bp = NULL;
struct disklabel *dlp;
struct sun_disklabel *slp;
- char *msg = NULL;
int error, i;
+ char *msg;
- /* minimal requirements for archetypal disk label */
- if (lp->d_secsize < DEV_BSIZE)
- lp->d_secsize = DEV_BSIZE;
- if (DL_GETDSIZE(lp) == 0)
- DL_SETDSIZE(lp, MAXDISKSIZE);
- if (lp->d_secpercyl == 0) {
- msg = "invalid geometry";
- goto done;
- }
- lp->d_npartitions = RAW_PART + 1;
- for (i = 0; i < RAW_PART; i++) {
- DL_SETPSIZE(&lp->d_partitions[i], 0);
- DL_SETPOFFSET(&lp->d_partitions[i], 0);
- }
- if (DL_GETPSIZE(&lp->d_partitions[RAW_PART]) == 0)
- DL_SETPSIZE(&lp->d_partitions[RAW_PART], DL_GETDSIZE(lp));
- DL_SETPOFFSET(&lp->d_partitions[RAW_PART], 0);
- lp->d_version = 1;
-
- /* don't read the on-disk label if we are in spoofed-only mode */
- if (spoofonly)
+ if ((msg = initdisklabel(lp)))
goto done;
/* obtain buffer to probe drive with */
bp = geteblk((int)lp->d_secsize);
-
- /* next, dig out disk label */
bp->b_dev = dev;
+
+ if (spoofonly)
+ goto done;
+
bp->b_blkno = LABELSECTOR;
bp->b_cylinder = 0;
bp->b_bcount = lp->d_secsize;
@@ -166,6 +140,16 @@ readdisklabel(dev_t dev, void (*strat)(struct buf *),
goto done;
}
+ slp = (struct sun_disklabel *)clp->cd_block;
+ if (slp->sl_magic == SUN_DKMAGIC) {
+ msg = disklabel_om_to_bsd(clp->cd_block, lp);
+ goto done;
+ }
+
+ msg = checkdisklabel(clp->cd_block + LABELOFFSET, lp);
+ if (msg == NULL)
+ goto done;
+
#if defined(CD9660)
if (iso_disklabelspoof(dev, strat, lp) == 0) {
msg = NULL;
@@ -178,27 +162,7 @@ readdisklabel(dev_t dev, void (*strat)(struct buf *),
goto done;
}
#endif
-
- /* Check for a BSD disk label first. */
- dlp = (struct disklabel *)(clp->cd_block + LABELOFFSET);
- if (dlp->d_magic == DISKMAGIC && dlp->d_magic2 == DISKMAGIC) {
- if (dkcksum(dlp) == 0) {
- DL_SETDSIZE(dlp, DL_GETDSIZE(lp));
- *lp = *dlp; /* struct assignment */
- msg = NULL;
- goto done;
- }
- printf("BSD disk label corrupted");
- }
-
- /* Check for a UniOS/ISI disk label. */
- slp = (struct sun_disklabel *)clp->cd_block;
- if (slp->sl_magic == SUN_DKMAGIC) {
- msg = disklabel_om_to_bsd(clp->cd_block, lp);
- goto done;
- }
-
- memset(clp->cd_block, 0, sizeof(clp->cd_block));
+ bzero(clp->cd_block, sizeof(clp->cd_block));
msg = "no disk label";
done:
@@ -206,7 +170,6 @@ done:
bp->b_flags |= B_INVAL;
brelse(bp);
}
- disklabeltokernlabel(lp);
return (msg);
}
diff --git a/sys/arch/mac68k/include/disklabel.h b/sys/arch/mac68k/include/disklabel.h
index 28820db1a61..1f07b724393 100644
--- a/sys/arch/mac68k/include/disklabel.h
+++ b/sys/arch/mac68k/include/disklabel.h
@@ -1,5 +1,4 @@
-/* $OpenBSD: disklabel.h,v 1.6 2002/04/18 22:12:38 miod Exp $ */
-/* $NetBSD: disklabel.h,v 1.2 1996/05/05 06:17:38 briggs Exp $ */
+/* $OpenBSD: disklabel.h,v 1.7 2007/06/17 00:27:27 deraadt Exp $ */
/*
* Copyright (c) 1994 Christopher G. Demetriou
@@ -35,20 +34,10 @@
#define _MAC68K_DISKLABEL_H_
#define LABELSECTOR 0 /* sector containing label */
-#define MAXPARTITIONS 16 /* number of partitions */
-#define RAW_PART 2 /* raw partition: xx?c */
-
-/*
- * There is no physical disklabel on disk, since it is constructed from
- * the MacOS partition table.
- * However, to prevent disklabel -r to kill the disk, define a dummy
- * offset outside of vital structures.
- */
#define LABELOFFSET 64 /* offset of label in sector */
+#define MAXPARTITIONS 16 /* number of partitions */
-/* Just a dummy */
struct cpu_disklabel {
- /* EMPTY */
};
#endif /* _MAC68K_DISKLABEL_H_ */
diff --git a/sys/arch/mac68k/mac68k/disksubr.c b/sys/arch/mac68k/mac68k/disksubr.c
index 1a23e9bcb32..dfc4dfe9e59 100644
--- a/sys/arch/mac68k/mac68k/disksubr.c
+++ b/sys/arch/mac68k/mac68k/disksubr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: disksubr.c,v 1.47 2007/06/14 03:35:29 deraadt Exp $ */
+/* $OpenBSD: disksubr.c,v 1.48 2007/06/17 00:27:28 deraadt Exp $ */
/* $NetBSD: disksubr.c,v 1.22 1997/11/26 04:18:20 briggs Exp $ */
/*
@@ -28,9 +28,8 @@
* 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.
- *
- * @(#)ufs_disksubr.c 7.16 (Berkeley) 5/4/91
*/
+
/*-
* Copyright (C) 1993 Allen K. Briggs, Chris P. Caputo,
* Michael L. Finch, Bradley A. Grantham, and
@@ -87,11 +86,11 @@
#define NUM_PARTS_PROBED 32
-#define ROOT_PART 1
-#define UFS_PART 2
-#define SWAP_PART 3
-#define HFS_PART 4
-#define SCRATCH_PART 5
+#define ROOT_PART 1
+#define UFS_PART 2
+#define SWAP_PART 3
+#define HFS_PART 4
+#define SCRATCH_PART 5
int getFreeLabelEntry(struct disklabel *);
int whichType(struct partmapentry *);
@@ -110,11 +109,10 @@ getFreeLabelEntry(struct disklabel *lp)
int i;
for (i = 0; i < MAXPARTITIONS; i++) {
- if ((i != RAW_PART)
- && (lp->d_partitions[i].p_fstype == FS_UNUSED))
+ if (i != RAW_PART &&
+ lp->d_partitions[i].p_fstype == FS_UNUSED)
return i;
}
-
return -1;
}
@@ -129,15 +127,11 @@ whichType(struct partmapentry *part)
if (part->pmPartType[0] == '\0')
return 0;
- if (strcmp(PART_DRIVER_TYPE, (char *)part->pmPartType) == 0)
- return 0;
- if (strcmp(PART_DRIVER43_TYPE, (char *)part->pmPartType) == 0)
- return 0;
- if (strcmp(PART_DRIVERATA_TYPE, (char *)part->pmPartType) == 0)
- return 0;
- if (strcmp(PART_FWB_COMPONENT_TYPE, (char *)part->pmPartType) == 0)
- return 0;
- if (strcmp(PART_PARTMAP_TYPE, (char *)part->pmPartType) == 0)
+ if (strcmp(PART_DRIVER_TYPE, (char *)part->pmPartType) == 0 ||
+ strcmp(PART_DRIVER43_TYPE, (char *)part->pmPartType) == 0 ||
+ strcmp(PART_DRIVERATA_TYPE, (char *)part->pmPartType) == 0 ||
+ strcmp(PART_FWB_COMPONENT_TYPE, (char *)part->pmPartType) == 0 ||
+ strcmp(PART_PARTMAP_TYPE, (char *)part->pmPartType) == 0 ||
return 0;
if (strcmp(PART_UNIX_TYPE, (char *)part->pmPartType) == 0) {
/* unix part, swap, root, usr */
@@ -148,10 +142,10 @@ whichType(struct partmapentry *part)
if (bzb->bzbFlags & BZB_ROOTFS)
return ROOT_PART;
- if ((bzb->bzbFlags & BZB_USRFS)
- || (bzb->bzbFlags & BZB_EXFS4)
- || (bzb->bzbFlags & BZB_EXFS5)
- || (bzb->bzbFlags & BZB_EXFS6))
+ if ((bzb->bzbFlags & BZB_USRFS) ||
+ (bzb->bzbFlags & BZB_EXFS4) ||
+ (bzb->bzbFlags & BZB_EXFS5) ||
+ (bzb->bzbFlags & BZB_EXFS6))
return UFS_PART;
if (bzb->bzbType == BZB_TYPESWAP)
@@ -176,13 +170,12 @@ whichType(struct partmapentry *part)
int
fixPartTable(struct partmapentry *partTable, long size, char *base)
{
- int i;
struct partmapentry *pmap;
char *s;
+ int i;
for (i = 0; i < NUM_PARTS_PROBED; i++) {
pmap = (struct partmapentry *)((i * size) + base + DEV_BSIZE);
-
partTable[i] = *pmap;
pmap = &partTable[i];
@@ -198,7 +191,6 @@ fixPartTable(struct partmapentry *partTable, long size, char *base)
if ((*s >= 'a') && (*s <= 'z'))
*s = (*s - 'a' + 'A');
}
-
return NUM_PARTS_PROBED;
}
@@ -246,12 +238,10 @@ getNamedType(struct partmapentry *part, int num_parts, struct disklabel *lp,
printf("disksubr.c: can't do type %d\n", type);
break;
}
-
return 0;
}
skip:
}
-
return -1;
}
@@ -289,8 +279,7 @@ read_mac_label(char *dlbuf, struct disklabel *lp, struct cpu_disklabel *osdep)
if (getNamedType(pmap, num_parts, lp, UFS_PART, 0, &maxslot))
getNamedType(pmap, num_parts, lp, UFS_PART, -1, &maxslot);
for (i = 0; i < num_parts; i++) {
- int partType;
- int slot;
+ int partType, slot;
slot = getFreeLabelEntry(lp);
if (slot < 0)
@@ -299,12 +288,7 @@ read_mac_label(char *dlbuf, struct disklabel *lp, struct cpu_disklabel *osdep)
partType = whichType(&(pmap[i]));
switch (partType) {
-
case ROOT_PART:
- /*
- * another root part will turn into a plain old
- * UFS_PART partition, live with it.
- */
case UFS_PART:
setPart(&(pmap[i]), lp, FS_BSDFFS, slot);
if (slot > maxslot)
@@ -330,7 +314,9 @@ read_mac_label(char *dlbuf, struct disklabel *lp, struct cpu_disklabel *osdep)
}
}
lp->d_npartitions = maxslot + 1;
-
+ lp->d_version = 1;
+ lp->d_checksum = 0;
+ lp->d_checksum = dkcksum(lp);
FREE(pmap, M_DEVBUF);
return NULL;
}
@@ -341,83 +327,70 @@ read_mac_label(char *dlbuf, struct disklabel *lp, struct cpu_disklabel *osdep)
* 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.
- *
- * This will read sector zero. If this contains what looks like a valid
- * Macintosh boot sector, we attempt to fill in the disklabel structure.
- * If the first longword of the disk is a OpenBSD disk label magic number,
- * then we assume that it's a real disklabel and return it.
*/
char *
readdisklabel(dev_t dev, void (*strat)(struct buf *),
struct disklabel *lp, struct cpu_disklabel *osdep, int spoofonly)
{
struct buf *bp = NULL;
- char *msg = NULL;
- struct disklabel *dlp;
- int i, size;
-
- /* minimal requirements for archetypal disk label */
- if (lp->d_secsize < DEV_BSIZE)
- lp->d_secsize = DEV_BSIZE;
- if (DL_GETDSIZE(lp) == 0)
- DL_SETDSIZE(lp, MAXDISKSIZE);
- if (lp->d_secpercyl == 0) {
- msg = "invalid geometry";
- goto done;
- }
- lp->d_npartitions = RAW_PART + 1;
- for (i = 0; i < RAW_PART; i++) {
- DL_SETPSIZE(&lp->d_partitions[i], 0);
- DL_SETPOFFSET(&lp->d_partitions[i], 0);
- }
- if (DL_GETPSIZE(&lp->d_partitions[RAW_PART]) == 0)
- DL_SETPSIZE(&lp->d_partitions[RAW_PART], DL_GETDSIZE(lp));
- DL_SETPOFFSET(&lp->d_partitions[RAW_PART], 0);
- lp->d_version = 1;
+ u_int16_t *sbSigp;
+ int size;
+ char *msg;
- /* don't read the on-disk label if we are in spoofed-only mode */
- if (spoofonly)
+ if ((msg = initdisklabel(lp)))
goto done;
size = roundup((NUM_PARTS_PROBED + 1) << DEV_BSHIFT, lp->d_secsize);
bp = geteblk(size);
bp->b_dev = dev;
+
bp->b_blkno = LABELSECTOR;
bp->b_bcount = size;
bp->b_flags = B_BUSY | B_READ;
bp->b_cylinder = LABELSECTOR / lp->d_secpercyl;
(*strat)(bp);
- if (biowait(bp))
+ if (biowait(bp)) {
msg = "disk label I/O error";
- else {
- u_int16_t *sbSigp;
-
- sbSigp = (u_int16_t *)bp->b_data;
- if (*sbSigp == 0x4552) {
- msg = read_mac_label(bp->b_data, lp, osdep);
- } else {
- dlp = (struct disklabel *)(bp->b_data +
- LABELOFFSET);
- if (dlp->d_magic != DISKMAGIC ||
- dlp->d_magic2 != DISKMAGIC) {
- msg = "no OpenBSD or MacOS disk label";
- } else if (dlp->d_npartitions > MAXPARTITIONS ||
- dkcksum(dlp) != 0) {
- msg = "disk label corrupted";
- } else {
- DL_SETDSIZE(dlp, DL_GETDSIZE(lp));
- *lp = *dlp;
- }
- }
+ goto done;
}
+ sbSigp = (u_int16_t *)bp->b_data;
+ if (*sbSigp == 0x4552) {
+ msg = read_mac_label(bp->b_data, lp, osdep);
+ if (msg == NULL)
+ goto done;
+ }
+
+ msg = readdoslabel(bp, strat, lp, osdep, NULL, NULL, spoofonly);
+ if (msg == NULL)
+ goto done;
+
+ /* Get a MI label */
+ bp->b_blkno = LABELSECTOR;
+ bp->b_bcount = lp->d_secsize;
+ bp->b_flags = B_BUSY | B_READ;
+ bp->b_cylinder = LABELSECTOR / lp->d_secpercyl;
+ (*strat)(bp);
+ if (biowait(bp)) {
+ msg = "disk label I/O error";
+ goto done;
+ }
+
+ msg = checkdisklabel(bp->b_data + LABELOFFSET, lp);
+ if (msg == NULL)
+ goto done;
+
#if defined(CD9660)
- if (msg != NULL && iso_disklabelspoof(dev, strat, lp) == 0)
+ if (iso_disklabelspoof(dev, strat, lp) == 0) {
msg = NULL;
+ goto done;
+ }
#endif
#if defined(UDF)
- if (msg && udf_disklabelspoof(dev, strat, lp) == 0)
+ if (udf_disklabelspoof(dev, strat, lp) == 0) {
msg = NULL;
+ goto done;
+ }
#endif
done:
@@ -425,7 +398,6 @@ done:
bp->b_flags |= B_INVAL;
brelse(bp);
}
- disklabeltokernlabel(lp);
return (msg);
}
@@ -441,18 +413,13 @@ writedisklabel(dev_t dev, void (*strat)(struct buf *),
{
struct buf *bp = NULL;
struct disklabel *dlp;
- int labelpart;
int error = 0;
u_int16_t *sbSigp;
- labelpart = DISKPART(dev);
- if (DL_GETPOFFSET(&lp->d_partitions[labelpart]) != 0) {
- if (DL_GETPOFFSET(&lp->d_partitions[0]) != 0)
- return (EXDEV); /* not quite right */
- labelpart = 0;
- }
+ /* get a buffer and initialize it */
bp = geteblk((int)lp->d_secsize);
- bp->b_dev = MAKEDISKDEV(major(dev), DISKUNIT(dev), labelpart);
+ bp->b_dev = dev;
+
bp->b_blkno = LABELSECTOR;
bp->b_bcount = lp->d_secsize;
bp->b_flags = B_BUSY | B_READ;
@@ -461,21 +428,15 @@ writedisklabel(dev_t dev, void (*strat)(struct buf *),
if ((error = biowait(bp)) != 0)
goto done;
- /*
- * Check for MacOS fingerprints
- */
+ /* Check for MacOS fingerprints */
sbSigp = (u_int16_t *)bp->b_data;
if (*sbSigp == 0x4552) {
- /*
- * Read the partition map again, in case it has changed.
- */
- if (readdisklabel(dev, strat, lp, osdep, 0) != NULL)
- error = EINVAL;
+ /* XXX AND THEN DO NOT WRITE?? */
goto done;
}
dlp = (struct disklabel *)(bp->b_data + LABELOFFSET);
- bcopy(lp, dlp, sizeof(struct disklabel));
+ *dlp = *lp;
bp->b_flags = B_BUSY | B_WRITE;
(*strat)(bp);
error = biowait(bp);
diff --git a/sys/arch/macppc/include/disklabel.h b/sys/arch/macppc/include/disklabel.h
index 8f0dc9fd57b..d9d76603828 100644
--- a/sys/arch/macppc/include/disklabel.h
+++ b/sys/arch/macppc/include/disklabel.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: disklabel.h,v 1.11 2006/10/20 23:47:43 krw Exp $ */
+/* $OpenBSD: disklabel.h,v 1.12 2007/06/17 00:27:27 deraadt Exp $ */
/*
* Copyright (c) 1994 Christopher G. Demetriou
@@ -36,51 +36,6 @@
#define LABELSECTOR 1 /* sector containing label */
#define LABELOFFSET 0 /* offset of label in sector */
#define MAXPARTITIONS 16 /* number of partitions */
-#define RAW_PART 2 /* raw partition: ie. rsd0c */
-
-/* MBR partition table */
-#define DOSBBSECTOR 0 /* MBR sector number */
-#define DOSPARTOFF 446 /* Offset of MBR partition table */
-#define NDOSPART 4 /* # of partitions in MBR */
-#define DOSMAGICOFF 510 /* Offset of magic number */
-#define DOSMAGIC 0xaa55 /* Actual magic number */
-#define MBRMAGIC DOSMAGIC
-#define DOSMBR_SIGNATURE MBRMAGIC
-#define DOSMBR_SIGNATURE_OFF DOSMAGICOFF
-#define DOSACTIVE 0x80
-
-struct dos_partition {
- u_int8_t dp_flag; /* default boot flag */
- u_int8_t dp_shd; /* start head, IsN't Always Meaningful */
- u_int8_t dp_ssect; /* start sector, INAM */
- u_int8_t dp_scyl; /* start cylinder, INAM */
- u_int8_t dp_typ; /* partition type */
- u_int8_t dp_ehd; /* end head, INAM */
- u_int8_t dp_esect; /* end sector, INAM */
- u_int8_t dp_ecyl; /* end cylinder, INAM */
- u_int32_t dp_start; /* absolute start sector number */
- u_int32_t dp_size; /* partition size in sectors */
-};
-
-/* Known DOS partition types. */
-#define DOSPTYP_UNUSED 0x00 /* Unused partition */
-#define DOSPTYP_FAT12 0x01 /* 12-bit FAT */
-#define DOSPTYP_FAT16S 0x04 /* 16-bit FAT, less than 32M */
-#define DOSPTYP_EXTEND 0x05 /* Extended; contains sub-partitions */
-#define DOSPTYP_FAT16B 0x06 /* 16-bit FAT, more than 32M */
-#define DOSPTYP_FAT32 0x0b /* 32-bit FAT */
-#define DOSPTYP_FAT32L 0x0c /* 32-bit FAT, LBA-mapped */
-#define DOSPTYP_FAT16L 0x0e /* 16-bit FAT, LBA-mapped */
-#define DOSPTYP_EXTENDL 0x0f /* Extended, LBA-mapped; contains sub-partitions */
-#define DOSPTYP_ONTRACK 0x54
-#define DOSPTYP_LINUX 0x83 /* That other thing */
-#define DOSPTYP_FREEBSD 0xa5 /* FreeBSD partition type */
-#define DOSPTYP_OPENBSD 0xa6 /* OpenBSD partition type */
-#define DOSPTYP_NETBSD 0xa9 /* NetBSD partition type */
-
-/* Isolate the relevant bits to get sector and cylinder. */
-#define DPSECT(s) ((s) & 0x3f)
-#define DPCYL(c, s) ((c) + (((s) & 0xc0) << 2))
/* HFS/DPME */
diff --git a/sys/arch/macppc/macppc/disksubr.c b/sys/arch/macppc/macppc/disksubr.c
index 8f22a779a70..50375684ad4 100644
--- a/sys/arch/macppc/macppc/disksubr.c
+++ b/sys/arch/macppc/macppc/disksubr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: disksubr.c,v 1.54 2007/06/14 03:37:23 deraadt Exp $ */
+/* $OpenBSD: disksubr.c,v 1.55 2007/06/17 00:27:29 deraadt Exp $ */
/* $NetBSD: disksubr.c,v 1.21 1996/05/03 19:42:03 christos Exp $ */
/*
@@ -29,8 +29,6 @@
* 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.
- *
- * @(#)ufs_disksubr.c 7.16 (Berkeley) 5/4/91
*/
#include <sys/param.h>
@@ -66,79 +64,53 @@ char *
readdisklabel(dev_t dev, void (*strat)(struct buf *),
struct disklabel *lp, struct cpu_disklabel *osdep, int spoofonly)
{
- struct dos_partition dp[NDOSPART], *dp2;
struct partition *pp;
- struct disklabel *dlp;
- unsigned long extoff = 0;
- unsigned int fattest;
struct buf *bp = NULL;
- daddr64_t part_blkno = DOSBBSECTOR;
- char *msg = NULL;
- char *s;
- int dospartoff, cyl, i, ourpart = -1;
- int wander = 1, loop = 0;
- /* HFS variables */
- int part_cnt, n, hfspartoff;
+ int i, part_cnt, n, hfspartoff;
struct part_map_entry *part;
+ char *msg;
- /* minimal requirements for archetypal disk label */
- if (lp->d_secsize < DEV_BSIZE)
- lp->d_secsize = DEV_BSIZE;
- if (DL_GETDSIZE(lp) == 0)
- DL_SETDSIZE(lp, MAXDISKSIZE);
- if (lp->d_secpercyl == 0) {
- msg = "invalid geometry";
+ if ((msg = initdisklabel(lp)))
goto done;
- }
- lp->d_npartitions = RAW_PART + 1;
- for (i = 0; i < RAW_PART; i++) {
- DL_SETPSIZE(&lp->d_partitions[i], 0);
- DL_SETPOFFSET(&lp->d_partitions[i], 0);
- }
- if (DL_GETPSIZE(&lp->d_partitions[RAW_PART]) == 0)
- DL_SETPSIZE(&lp->d_partitions[RAW_PART], DL_GETDSIZE(lp));
- DL_SETPOFFSET(&lp->d_partitions[RAW_PART], 0);
- lp->d_version = 1;
/* get a buffer and initialize it */
bp = geteblk((int)lp->d_secsize);
bp->b_dev = dev;
- /* DPME (HFS) disklabel */
-
+ /* First check for a DPME (HFS) disklabel */
bp->b_blkno = 1;
bp->b_bcount = lp->d_secsize;
bp->b_flags = B_BUSY | B_READ;
bp->b_cylinder = 1 / lp->d_secpercyl;
(*strat)(bp);
-
- /* if successful, wander through DPME partition table */
if (biowait(bp)) {
msg = "DPME partition I/O error";
- goto hfs_done;
+ goto doslabel;
}
+ /* if successful, wander through DPME partition table */
part = (struct part_map_entry *)bp->b_data;
/* if first partition is not valid, assume not HFS/DPME partitioned */
- if (part->pmSig != PART_ENTRY_MAGIC) {
+ if (part->pmSig != PART_ENTRY_MAGIC) {
osdep->macparts[0].pmSig = 0; /* make invalid */
- goto hfs_done;
- }
+ goto doslabel;
+ }
osdep->macparts[0] = *part;
part_cnt = part->pmMapBlkCnt;
n = 0;
for (i = 0; i < part_cnt; i++) {
+ char *s;
+
pp = &lp->d_partitions[8+n];
bp->b_blkno = 1+i;
bp->b_bcount = lp->d_secsize;
bp->b_flags = B_BUSY | B_READ;
- bp->b_cylinder = 1+i / lp->d_secpercyl;
+ bp->b_cylinder = (1+i) / lp->d_secpercyl;
(*strat)(bp);
-
if (biowait(bp)) {
msg = "DPME partition I/O error";
- goto hfs_done;
+ goto doslabel;
}
part = (struct part_map_entry *)bp->b_data;
/* toupper the string, in case caps are different... */
@@ -160,219 +132,42 @@ readdisklabel(dev_t dev, void (*strat)(struct buf *),
}
lp->d_npartitions = MAXPARTITIONS;
- /* don't read the on-disk label if we are in spoofed-only mode */
if (spoofonly)
- goto done;
+ goto doslabel;
/* next, dig out disk label */
bp->b_blkno = hfspartoff;
- bp->b_cylinder = hfspartoff/lp->d_secpercyl; /* XXX */
+ bp->b_cylinder = hfspartoff / lp->d_secpercyl;
bp->b_bcount = lp->d_secsize;
bp->b_flags = B_BUSY | B_READ;
(*strat)(bp);
-
- /* if successful, locate disk label within block and validate */
if (biowait(bp)) {
- /* XXX we return the faked label built so far */
msg = "disk label I/O error";
goto done;
}
- goto found_disklabel;
-
-hfs_done:
- /* MBR type disklabel */
- /* do dos partitions in the process of getting disklabel? */
- dospartoff = 0;
- cyl = LABELSECTOR / lp->d_secpercyl;
- n = 0;
-
- /*
- * Read dos partition table, follow extended partitions.
- * Map the partitions to disklabel entries i-p
- */
- while (wander && n < 8 && loop < 8) {
- loop++;
- wander = 0;
- if (part_blkno < extoff)
- part_blkno = extoff;
-
- /* read boot record */
- bp->b_blkno = part_blkno;
- bp->b_bcount = lp->d_secsize;
- bp->b_flags = B_BUSY | B_READ;
- bp->b_cylinder = part_blkno / lp->d_secpercyl;
- (*strat)(bp);
-
- /* if successful, wander through dos partition table */
- if (biowait(bp)) {
- msg = "dos partition I/O error";
- goto done;
- }
- bcopy(bp->b_data + DOSPARTOFF, dp, sizeof(dp));
-
- if (ourpart == -1 && part_blkno == DOSBBSECTOR) {
- /* Search for our MBR partition */
- for (dp2=dp, i=0; i < NDOSPART && ourpart == -1;
- i++, dp2++)
- if (letoh32(dp2->dp_size) &&
- dp2->dp_typ == DOSPTYP_OPENBSD)
- ourpart = i;
- if (ourpart == -1)
- goto donot;
- /*
- * This is our MBR partition.
- * need sector address * for SCSI/IDE,
- * cylinder for ESDI/ST506/RLL
- */
- dp2 = &dp[ourpart];
- dospartoff = letoh32(dp2->dp_start) +
- part_blkno;
- cyl = DPCYL(dp2->dp_scyl, dp2->dp_ssect);
-
- /* XXX build a temporary disklabel */
- DL_SETPSIZE(&lp->d_partitions[0], letoh32(dp2->dp_size));
- DL_SETPOFFSET(&lp->d_partitions[0],
- letoh32(dp2->dp_start) + part_blkno);
- if (lp->d_ntracks == 0)
- lp->d_ntracks = dp2->dp_ehd + 1;
- if (lp->d_nsectors == 0)
- lp->d_nsectors = DPSECT(dp2->dp_esect);
- if (lp->d_secpercyl == 0)
- lp->d_secpercyl = lp->d_ntracks *
- lp->d_nsectors;
- }
-donot:
- /*
- * In case the disklabel read below fails, we want to
- * provide a fake label in i-p.
- */
- for (dp2=dp, i=0; i < NDOSPART && n < 8; i++, dp2++) {
- pp = &lp->d_partitions[8+n];
-
- if (dp2->dp_typ == DOSPTYP_OPENBSD)
- continue;
- if (letoh32(dp2->dp_size) > DL_GETDSIZE(lp))
- continue;
- if (letoh32(dp2->dp_start) > DL_GETDSIZE(lp))
- continue;
- if (letoh32(dp2->dp_size) == 0)
- continue;
- if (letoh32(dp2->dp_start))
- DL_SETPOFFSET(pp,
- letoh32(dp2->dp_start) + part_blkno);
-
- DL_SETPSIZE(pp, letoh32(dp2->dp_size));
-
- switch (dp2->dp_typ) {
- case DOSPTYP_UNUSED:
- pp->p_fstype = FS_UNUSED;
- n++;
- break;
-
- case DOSPTYP_LINUX:
- pp->p_fstype = FS_EXT2FS;
- n++;
- break;
-
- case DOSPTYP_FAT12:
- case DOSPTYP_FAT16S:
- case DOSPTYP_FAT16B:
- case DOSPTYP_FAT16L:
- case DOSPTYP_FAT32:
- case DOSPTYP_FAT32L:
- pp->p_fstype = FS_MSDOS;
- n++;
- break;
- case DOSPTYP_EXTEND:
- case DOSPTYP_EXTENDL:
- part_blkno = letoh32(dp2->dp_start) + extoff;
- if (!extoff) {
- extoff = letoh32(dp2->dp_start);
- part_blkno = 0;
- }
- wander = 1;
- break;
- default:
- pp->p_fstype = FS_OTHER;
- n++;
- break;
- }
- }
- }
- lp->d_bbsize = 8192;
- lp->d_sbsize = 64*1024; /* XXX ? */
- lp->d_npartitions = MAXPARTITIONS;
-
- if (n == 0 && part_blkno == DOSBBSECTOR) {
- /* Check for a short jump instruction. */
- fattest = ((bp->b_data[0] << 8) & 0xff00) | (bp->b_data[2] &
- 0xff);
- if (fattest != 0xeb90 && fattest != 0xe900)
- goto notfat;
-
- /* Check for a valid bytes per sector value. */
- fattest = ((bp->b_data[12] << 8) & 0xff00) | (bp->b_data[11] &
- 0xff);
- if (fattest < 512 || fattest > 4096 || (fattest % 512 != 0))
- goto notfat;
+ goto realdisklabel;
- /* Check the end of sector marker. */
- fattest = ((bp->b_data[510] << 8) & 0xff00) | (bp->b_data[511] &
- 0xff);
- if (fattest != 0x55aa)
- goto notfat;
-
- /* Looks like a FAT filesystem. Spoof 'i'. */
- DL_SETPSIZE(&lp->d_partitions['i' - 'a'],
- DL_GETPSIZE(&lp->d_partitions[RAW_PART]));
- DL_SETPOFFSET(&lp->d_partitions['i' - 'a'], 0);
- lp->d_partitions['i' - 'a'].p_fstype = FS_MSDOS;
- }
-notfat:
-
- /* don't read the on-disk label if we are in spoofed-only mode */
- if (spoofonly)
+doslabel:
+ msg = readdoslabel(bp, strat, lp, osdep, NULL, NULL, spoofonly);
+ if (msg == NULL)
goto done;
- /* next, dig out disk label */
- bp->b_blkno = dospartoff + LABELSECTOR;
- bp->b_cylinder = cyl;
- bp->b_bcount = lp->d_secsize;
- bp->b_flags = B_BUSY | B_READ;
- (*strat)(bp);
-
- /* if successful, locate disk label within block and validate */
- if (biowait(bp)) {
- /* XXX we return the faked label built so far */
- msg = "disk label I/O error";
+realdisklabel:
+ msg = checkdisklabel(bp->b_data + LABELOFFSET, lp);
+ if (msg == NULL)
goto done;
- }
-
-found_disklabel:
- for (dlp = (struct disklabel *)bp->b_data;
- dlp <= (struct disklabel *)(bp->b_data + lp->d_secsize - sizeof(*dlp));
- dlp = (struct disklabel *)((char *)dlp + sizeof(long))) {
- if (dlp->d_magic != DISKMAGIC || dlp->d_magic2 != DISKMAGIC) {
- if (msg == NULL)
- msg = "no disk label";
- } else if (dlp->d_npartitions > MAXPARTITIONS ||
- dkcksum(dlp) != 0)
- msg = "disk label corrupted";
- else {
- DL_SETDSIZE(dlp, DL_GETDSIZE(lp));
- *lp = *dlp;
- msg = NULL;
- break;
- }
- }
#if defined(CD9660)
- if (msg && iso_disklabelspoof(dev, strat, lp) == 0)
+ if (iso_disklabelspoof(dev, strat, lp) == 0) {
msg = NULL;
+ goto done;
+ }
#endif
#if defined(UDF)
- if (msg && udf_disklabelspoof(dev, strat, lp) == 0)
+ if (udf_disklabelspoof(dev, strat, lp) == 0) {
msg = NULL;
+ goto done;
+ }
#endif
done:
@@ -380,23 +175,19 @@ done:
bp->b_flags |= B_INVAL;
brelse(bp);
}
- disklabeltokernlabel(lp);
return (msg);
}
/*
* Write disk label back to device after modification.
- * XXX cannot handle OpenBSD partitions in extended partitions!
*/
int
writedisklabel(dev_t dev, void (*strat)(struct buf *),
struct disklabel *lp, struct cpu_disklabel *osdep)
{
- struct dos_partition dp[NDOSPART], *dp2;
+ int error, partoff = -1, cyl = 0;
struct disklabel *dlp;
struct buf *bp = NULL;
- int error, dospartoff, cyl, i;
- int ourpart = -1;
/* get a buffer and initialize it */
bp = geteblk((int)lp->d_secsize);
@@ -407,79 +198,31 @@ writedisklabel(dev_t dev, void (*strat)(struct buf *),
/* only write if a valid "OpenBSD" partition type exists */
if (osdep->macparts[1].pmSig == PART_ENTRY_MAGIC) {
bp->b_blkno = osdep->macparts[1].pmPyPartStart;
- bp->b_cylinder = bp->b_blkno/lp->d_secpercyl;
+ bp->b_cylinder = bp->b_blkno / lp->d_secpercyl;
bp->b_bcount = lp->d_secsize;
- bp->b_flags = B_BUSY | B_WRITE;
- *(struct disklabel *)bp->b_data = *lp;
- (*strat)(bp);
- error = biowait(bp);
- goto done;
+ goto writeit;
}
-
- /* SHOULD FAIL TO WRITE LABEL IF VALID HFS partition exists
- * and no OpenBSD partition exists
- */
- error = 1; /* EPERM? */
+ error = EIO;
goto done;
}
- /* do dos partitions in the process of getting disklabel? */
- dospartoff = 0;
- cyl = LABELSECTOR / lp->d_secpercyl;
-
- /* read master boot record */
- 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 ((error = biowait(bp)) != 0)
+ if (readdoslabel(bp, strat, lp, osdep, &partoff, &cyl, 1) != NULL) {
+ error = EIO;
goto done;
-
- /* XXX how do we check veracity/bounds of this? */
- bcopy(bp->b_data + DOSPARTOFF, dp, sizeof(dp));
-
- for (dp2=dp, i=0; i < NDOSPART && ourpart == -1; i++, dp2++)
- if (letoh32(dp2->dp_size) && dp2->dp_typ == DOSPTYP_OPENBSD)
- ourpart = i;
-
- if (ourpart != -1) {
- dp2 = &dp[ourpart];
-
- /*
- * need sector address for SCSI/IDE,
- * cylinder for ESDI/ST506/RLL
- */
- dospartoff = letoh32(dp2->dp_start);
- cyl = DPCYL(dp2->dp_scyl, dp2->dp_ssect);
}
- /* next, dig out disk label */
- bp->b_blkno = dospartoff + LABELSECTOR;
+ /* Read it in, slap the new label in, and write it back out */
+ bp->b_blkno = partoff + LABELSECTOR;
bp->b_cylinder = cyl;
bp->b_bcount = lp->d_secsize;
bp->b_flags = B_BUSY | B_READ;
(*strat)(bp);
-
- /* if successful, locate disk label within block and validate */
if ((error = biowait(bp)) != 0)
goto done;
- for (dlp = (struct disklabel *)bp->b_data;
- dlp <= (struct disklabel *)(bp->b_data + lp->d_secsize - sizeof(*dlp));
- dlp = (struct disklabel *)((char *)dlp + sizeof(long))) {
- if (dlp->d_magic == DISKMAGIC && dlp->d_magic2 == DISKMAGIC &&
- dkcksum(dlp) == 0) {
- *dlp = *lp;
- bp->b_flags = B_BUSY | B_WRITE;
- (*strat)(bp);
- error = biowait(bp);
- goto done;
- }
- }
- /* Write it in the regular place. */
- *(struct disklabel *)bp->b_data = *lp;
+writeit:
+ dlp = (struct disklabel *)(bp->b_data + LABELOFFSET);
+ *dlp = *lp;
bp->b_flags = B_BUSY | B_WRITE;
(*strat)(bp);
error = biowait(bp);
diff --git a/sys/arch/mips64/include/disklabel.h b/sys/arch/mips64/include/disklabel.h
index 7d2fac63bb2..adaf30b4d6f 100644
--- a/sys/arch/mips64/include/disklabel.h
+++ b/sys/arch/mips64/include/disklabel.h
@@ -1,5 +1,4 @@
-/* $OpenBSD: disklabel.h,v 1.13 2007/06/07 02:55:12 krw Exp $ */
-/* $NetBSD: disklabel.h,v 1.1 1995/02/13 23:07:34 cgd Exp $ */
+/* $OpenBSD: disklabel.h,v 1.14 2007/06/17 00:27:27 deraadt Exp $ */
/*
* Copyright (c) 1994 Christopher G. Demetriou
@@ -36,50 +35,7 @@
#define LABELSECTOR 1
#define LABELOFFSET 0
-
#define MAXPARTITIONS 16 /* number of partitions */
-#define RAW_PART 2 /* raw partition: xx?c */
-
-/* DOS partition table -- located in boot block */
-#define DOSBBSECTOR 0 /* DOS boot block relative sector # */
-#define DOSPARTOFF 446
-#define DOSACTIVE 0x80
-#define NDOSPART 4
-#define DOSMBR_SIGNATURE 0xaa55
-#define DOSMBR_SIGNATURE_OFF 0x1fe
-
-struct dos_partition {
- u_int8_t dp_flag; /* bootstrap flags */
- u_int8_t dp_shd; /* starting head */
- u_int8_t dp_ssect; /* starting sector */
- u_int8_t dp_scyl; /* starting cylinder */
- u_int8_t dp_typ; /* partition type (see below) */
- u_int8_t dp_ehd; /* end head */
- u_int8_t dp_esect; /* end sector */
- u_int8_t dp_ecyl; /* end cylinder */
- u_int32_t dp_start; /* absolute starting sector number */
- u_int32_t dp_size; /* partition size in sectors */
-};
-
-/* Known DOS partition types. */
-#define DOSPTYP_UNUSED 0x00 /* Unused partition */
-#define DOSPTYP_FAT12 0x01 /* 12-bit FAT */
-#define DOSPTYP_FAT16S 0x04 /* 16-bit FAT, less than 32M */
-#define DOSPTYP_EXTEND 0x05 /* Extended; contains sub-partitions */
-#define DOSPTYP_FAT16B 0x06 /* 16-bit FAT, more than 32M */
-#define DOSPTYP_FAT32 0x0b /* 32-bit FAT */
-#define DOSPTYP_FAT32L 0x0c /* 32-bit FAT, LBA-mapped */
-#define DOSPTYP_FAT16L 0x0e /* 16-bit FAT, LBA-mapped */
-#define DOSPTYP_EXTENDL 0x0f /* Extended, LBA-mapped; contains sub-partitions */
-#define DOSPTYP_ONTRACK 0x54
-#define DOSPTYP_LINUX 0x83 /* That other thing */
-#define DOSPTYP_FREEBSD 0xa5 /* FreeBSD partition type */
-#define DOSPTYP_OPENBSD 0xa6 /* OpenBSD partition type */
-#define DOSPTYP_NETBSD 0xa9 /* NetBSD partition type */
-
-/* Isolate the relevant bits to get sector and cylinder. */
-#define DPSECT(s) ((s) & 0x3f)
-#define DPCYL(c, s) ((c) + (((s) & 0xc0) << 2))
/* SGI */
struct devparms {
diff --git a/sys/arch/mips64/mips64/disksubr.c b/sys/arch/mips64/mips64/disksubr.c
index 7ef6ea693db..17b97a30e9f 100644
--- a/sys/arch/mips64/mips64/disksubr.c
+++ b/sys/arch/mips64/mips64/disksubr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: disksubr.c,v 1.58 2007/06/14 04:56:15 miod Exp $ */
+/* $OpenBSD: disksubr.c,v 1.59 2007/06/17 00:27:29 deraadt Exp $ */
/*
* Copyright (c) 1999 Michael Shalayeff
@@ -30,16 +30,6 @@
* 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.
- *
- * @(#)ufs_disksubr.c 7.16 (Berkeley) 5/4/91
- */
-
-/*
- * This disksubr.c module started to take its present form on OpenBSD/alpha
- * but it was always thought it should be made completely MI and not need to
- * be in that alpha-specific tree at all.
- *
- * XXX HPUX disklabel is not understood yet.
*/
#include <sys/param.h>
@@ -52,11 +42,8 @@
char *readbsdlabel(struct buf *, void (*)(struct buf *), int, int,
int, struct disklabel *, int);
-char *readdoslabel(struct buf *, void (*)(struct buf *),
- struct disklabel *, struct cpu_disklabel *, int *, int *, int);
char *readsgilabel(struct buf *, void (*)(struct buf *),
struct disklabel *, struct cpu_disklabel *, int *, int *, int);
-void map_sgi_label(struct disklabel *, struct sgilabel *);
/*
* Try to read a standard BSD disklabel at a certain sector.
@@ -67,7 +54,6 @@ readbsdlabel(struct buf *bp, void (*strat)(struct buf *),
int spoofonly)
{
struct disklabel *dlp;
- char *msg = NULL;
u_int16_t cksum;
/* don't read the on-disk label if we are in spoofed-only mode */
@@ -81,38 +67,10 @@ readbsdlabel(struct buf *bp, void (*strat)(struct buf *),
(*strat)(bp);
/* if successful, locate disk label within block and validate */
- if (biowait(bp)) {
- /* XXX we return the faked label built so far */
- msg = "disk label I/O error";
- return (msg);
- }
+ if (biowait(bp))
+ return ("disk label I/O error");
- /*
- * If off is negative, search until the end of the sector for
- * the label, otherwise, just look at the specific location
- * we're given.
- */
- dlp = (struct disklabel *)(bp->b_data + (off >= 0 ? off : 0));
- do {
- if (dlp->d_magic != DISKMAGIC || dlp->d_magic2 != DISKMAGIC) {
- if (msg == NULL)
- msg = "no disk label";
- } else {
- cksum = dkcksum(dlp);
- if (dlp->d_npartitions > MAXPARTITIONS || cksum != 0) {
- msg = "disk label corrupted";
- } else {
- *lp = *dlp;
- msg = NULL;
- break;
- }
- }
- if (off >= 0)
- break;
- dlp = (struct disklabel *)((char *)dlp + sizeof(int32_t));
- } while (dlp <= (struct disklabel *)(bp->b_data + lp->d_secsize -
- sizeof(*dlp)));
- return (msg);
+ return checkdisklabel(bp->b_data + LABELOFFSET, lp);
}
/*
@@ -130,294 +88,66 @@ readdisklabel(dev_t dev, void (*strat)(struct buf *),
struct disklabel *lp, struct cpu_disklabel *osdep, int spoofonly)
{
struct buf *bp = NULL;
- char *msg = "no disk label";
- int i;
- struct disklabel minilabel, fallbacklabel;
-
- /* minimal requirements for archetypal disk label */
- if (lp->d_secsize < DEV_BSIZE)
- lp->d_secsize = DEV_BSIZE;
- if (DL_GETDSIZE(lp) == 0)
- DL_SETDSIZE(lp, MAXDISKSIZE);
- if (lp->d_secpercyl == 0) {
- msg = "invalid geometry";
+ char *msg;
+
+ if ((msg = initdisklabel(lp)))
goto done;
- }
- lp->d_npartitions = RAW_PART + 1;
- for (i = 0; i < RAW_PART; i++) {
- DL_SETPSIZE(&lp->d_partitions[i], 0);
- DL_SETPOFFSET(&lp->d_partitions[i], 0);
- }
- if (DL_GETPSIZE(&lp->d_partitions[RAW_PART]) == 0)
- DL_SETPSIZE(&lp->d_partitions[RAW_PART], DL_GETDSIZE(lp));
- DL_SETPOFFSET(&lp->d_partitions[RAW_PART], 0);
- lp->d_version = 1;
- minilabel = fallbacklabel = *lp;
/* get a buffer and initialize it */
bp = geteblk((int)lp->d_secsize);
bp->b_dev = dev;
msg = readsgilabel(bp, strat, lp, osdep, 0, 0, spoofonly);
- if (msg) {
- /* Fallback alternative XXX valid lp returned? */
- fallbacklabel = *lp;
- *lp = minilabel;
- }
- if (msg) {
- msg = readdoslabel(bp, strat, lp, osdep, 0, 0, spoofonly);
- if (msg) {
- /* Fallback alternative XXX always valid? */
- fallbacklabel = *lp;
- *lp = minilabel;
- }
- }
+ if (msg == NULL)
+ goto done;
+
+ msg = readdoslabel(bp, strat, lp, osdep, 0, 0, spoofonly);
+ if (msg == NULL)
+ goto done;
#if defined(CD9660)
- if (msg && iso_disklabelspoof(dev, strat, lp) == 0)
+ if (iso_disklabelspoof(dev, strat, lp) == 0) {
msg = NULL;
+ goto done;
+ }
#endif
#if defined(UDF)
- if (msg && udf_disklabelspoof(dev, strat, lp) == 0)
+ if (udf_disklabelspoof(dev, strat, lp) == 0) {
msg = NULL;
+ goto done;
+ }
#endif
- /* If there was an error, still provide a decent fake one. */
- if (msg)
- *lp = fallbacklabel;
-
done:
if (bp) {
bp->b_flags |= B_INVAL;
brelse(bp);
}
- disklabeltokernlabel(lp);
return (msg);
}
-/*
- * If dos partition table requested, attempt to load it and
- * find disklabel inside a DOS partition. Return buffer
- * for use in signalling errors if requested.
- *
- * We would like to check if each MBR has a valid BOOT_MAGIC, but
- * we cannot because it doesn't always exist. So.. we assume the
- * MBR is valid.
- */
-char *
-readdoslabel(bp, strat, lp, osdep, partoffp, cylp, spoofonly)
- struct buf *bp;
- void (*strat)(struct buf *);
- struct disklabel *lp;
- struct cpu_disklabel *osdep;
- int *partoffp;
- int *cylp;
- int spoofonly;
-{
- struct dos_partition dp[NDOSPART], *dp2;
- struct partition *pp;
- unsigned long extoff = 0;
- unsigned int fattest;
- daddr64_t part_blkno = DOSBBSECTOR;
- char *msg = NULL;
- int dospartoff, cyl, i, ourpart = -1;
- int wander = 1, n = 0, loop = 0;
-
- if (lp->d_secpercyl == 0) {
- msg = "invalid label, d_secpercyl == 0";
- return (msg);
- }
- if (lp->d_secsize == 0) {
- msg = "invalid label, d_secsize == 0";
- return (msg);
- }
-
- /* do dos partitions in the process of getting disklabel? */
- dospartoff = 0;
- cyl = LABELSECTOR / lp->d_secpercyl;
-
- /*
- * Read dos partition table, follow extended partitions.
- * Map the partitions to disklabel entries i-p
- */
- while (wander && n < 8 && loop < 8) {
- loop++;
- wander = 0;
- if (part_blkno < extoff)
- part_blkno = extoff;
-
- /* read boot record */
- bp->b_blkno = part_blkno;
- bp->b_bcount = lp->d_secsize;
- bp->b_flags = B_BUSY | B_READ;
- bp->b_cylinder = part_blkno / lp->d_secpercyl;
- (*strat)(bp);
-
- /* if successful, wander through dos partition table */
- if (biowait(bp)) {
- msg = "dos partition I/O error";
- if (partoffp)
- *partoffp = -1;
- return (msg);
- }
- bcopy(bp->b_data + DOSPARTOFF, dp, sizeof(dp));
-
- if (ourpart == -1 && part_blkno == DOSBBSECTOR) {
- /* Search for our MBR partition */
- for (dp2=dp, i=0; i < NDOSPART && ourpart == -1;
- i++, dp2++)
- if (letoh32(dp2->dp_size) &&
- dp2->dp_typ == DOSPTYP_OPENBSD)
- ourpart = i;
- if (ourpart == -1)
- goto donot;
- /*
- * This is our MBR partition. need sector
- * address for SCSI/IDE, cylinder for
- * ESDI/ST506/RLL
- */
- dp2 = &dp[ourpart];
- dospartoff = letoh32(dp2->dp_start) + part_blkno;
- cyl = DPCYL(dp2->dp_scyl, dp2->dp_ssect);
-
- /* XXX build a temporary disklabel */
- DL_SETPSIZE(&lp->d_partitions[0], letoh32(dp2->dp_size));
- DL_SETPOFFSET(&lp->d_partitions[0],
- letoh32(dp2->dp_start) + part_blkno);
- if (lp->d_ntracks == 0)
- lp->d_ntracks = dp2->dp_ehd + 1;
- if (lp->d_nsectors == 0)
- lp->d_nsectors = DPSECT(dp2->dp_esect);
- if (lp->d_secpercyl == 0)
- lp->d_secpercyl = lp->d_ntracks *
- lp->d_nsectors;
- }
-donot:
- /*
- * In case the disklabel read below fails, we want to
- * provide a fake label in i-p.
- */
- for (dp2=dp, i=0; i < NDOSPART && n < 8; i++, dp2++) {
- pp = &lp->d_partitions[8+n];
-
- if (dp2->dp_typ == DOSPTYP_OPENBSD)
- continue;
- if (letoh32(dp2->dp_size) > DL_GETDSIZE(lp))
- continue;
- if (letoh32(dp2->dp_start) > DL_GETDSIZE(lp))
- continue;
- if (letoh32(dp2->dp_size) == 0)
- continue;
- if (letoh32(dp2->dp_start))
- DL_SETPOFFSET(pp,
- letoh32(dp2->dp_start) + part_blkno);
-
- DL_SETPSIZE(pp, letoh32(dp2->dp_size));
-
- switch (dp2->dp_typ) {
- case DOSPTYP_UNUSED:
- pp->p_fstype = FS_UNUSED;
- n++;
- break;
-
- case DOSPTYP_LINUX:
- pp->p_fstype = FS_EXT2FS;
- n++;
- break;
-
- case DOSPTYP_FAT12:
- case DOSPTYP_FAT16S:
- case DOSPTYP_FAT16B:
- case DOSPTYP_FAT16L:
- case DOSPTYP_FAT32:
- case DOSPTYP_FAT32L:
- pp->p_fstype = FS_MSDOS;
- n++;
- break;
- case DOSPTYP_EXTEND:
- case DOSPTYP_EXTENDL:
- part_blkno = letoh32(dp2->dp_start) + extoff;
- if (!extoff) {
- extoff = letoh32(dp2->dp_start);
- part_blkno = 0;
- }
- wander = 1;
- break;
- default:
- pp->p_fstype = FS_OTHER;
- n++;
- break;
- }
- }
- }
- lp->d_bbsize = 8192;
- lp->d_sbsize = 64*1024; /* XXX ? */
- lp->d_npartitions = MAXPARTITIONS;
-
- if (n == 0 && part_blkno == DOSBBSECTOR) {
- /* Check for a short jump instruction. */
- fattest = ((bp->b_data[0] << 8) & 0xff00) | (bp->b_data[2] &
- 0xff);
- if (fattest != 0xeb90 && fattest != 0xe900)
- goto notfat;
-
- /* Check for a valid bytes per sector value. */
- fattest = ((bp->b_data[12] << 8) & 0xff00) | (bp->b_data[11] &
- 0xff);
- if (fattest < 512 || fattest > 4096 || (fattest % 512 != 0))
- goto notfat;
-
- /* Check the end of sector marker. */
- fattest = ((bp->b_data[510] << 8) & 0xff00) | (bp->b_data[511] &
- 0xff);
- if (fattest != 0x55aa)
- goto notfat;
-
- /* Looks like a FAT filesystem. Spoof 'i'. */
- DL_SETPSIZE(&lp->d_partitions['i' - 'a'],
- DL_GETPSIZE(&lp->d_partitions[RAW_PART]));
- DL_SETPOFFSET(&lp->d_partitions['i' - 'a'], 0);
- lp->d_partitions['i' - 'a'].p_fstype = FS_MSDOS;
- }
-notfat:
-
- /* record the OpenBSD partition's placement for the caller */
- if (partoffp)
- *partoffp = dospartoff;
- if (cylp)
- *cylp = cyl;
-
- /* next, dig out disk label */
- msg = readbsdlabel(bp, strat, cyl, dospartoff + LABELSECTOR, -1,
- lp, spoofonly);
-
- return (msg);
-}
+static struct {
+ int m;
+ int b;
+} maptab[] = {
+ { 0, FS_BSDFFS}, { 1, FS_SWAP}, { 10, FS_BSDFFS},
+ { 3, FS_BSDFFS}, { 4, FS_BSDFFS}, { 5, FS_BSDFFS},
+ { 6, FS_BSDFFS}, { 7, FS_BSDFFS}, { 15, FS_OTHER},
+ { 9, FS_BSDFFS}, { 2, FS_UNUSED}, { 11, FS_BSDFFS},
+ { 12, FS_BSDFFS}, { 13, FS_BSDFFS}, { 14, FS_BSDFFS},
+ { 8, FS_BSDFFS}
+};
-/*
- *
- */
char *
-readsgilabel(bp, strat, lp, osdep, partoffp, cylp, spoofonly)
- struct buf *bp;
- void (*strat)(struct buf *);
- struct disklabel *lp;
- struct cpu_disklabel *osdep;
- int *partoffp;
- int *cylp;
- int spoofonly;
+readsgilabel(struct buf *bp, void (*strat)(struct buf *),
+ struct disklabel *lp, struct cpu_disklabel *osdep,
+ int *partoffp, int *cylp, int spoofonly)
{
struct sgilabel *dlp;
char *msg = NULL;
+ int i, *p, cs = 0;
int fsoffs = 0;
- /* don't read the on-disk label if we are in spoofed-only mode */
- if (spoofonly)
- return (NULL);
-
- if (partoffp)
- *partoffp = -1;
-
bp->b_blkno = 0;
bp->b_cylinder = 0;
bp->b_bcount = lp->d_secsize;
@@ -426,63 +156,41 @@ readsgilabel(bp, strat, lp, osdep, partoffp, cylp, spoofonly)
/* if successful, locate disk label within block and validate */
if (biowait(bp)) {
- if (partoffp)
- *partoffp = -1;
- return "disk label I/O error";
+ msg = "disk label I/O error";
+ goto done;
}
- dlp = (struct sgilabel *)(bp->b_data);
+ dlp = (struct sgilabel *)(bp->b_data + LABELOFFSET);
if (dlp->magic != htobe32(SGILABEL_MAGIC)) {
fsoffs = 0;
- } else {
- int i, *p, cs;
-
- cs = 0;
- p = (int *)dlp;
- i = sizeof(struct sgilabel) / sizeof(int);
- while(i--)
- cs += *p++;
- if (cs != 0)
- return "sgilabel checksum error";
-
- /* Set up partitions i-l if there is no BSD label. */
- lp->d_secsize = dlp->dp.dp_secbytes;
- lp->d_nsectors = dlp->dp.dp_secs;
- lp->d_ntracks = dlp->dp.dp_trks0;
- lp->d_ncylinders = dlp->dp.dp_cyls;
- lp->d_interleave = dlp->dp.dp_interleave;
- lp->d_npartitions = MAXPARTITIONS;
-
- map_sgi_label(lp, dlp);
-
- fsoffs = dlp->partitions[0].first;
- if (dlp->partitions[0].blocks == 0)
- msg = "no BSD partition";
+ goto finished;
}
- if (msg)
- return msg;
-
- if (partoffp)
- *partoffp = fsoffs;
+ if (dlp->partitions[0].blocks == 0) {
+ msg = "no BSD partition";
+ goto done;
+ }
+ fsoffs = dlp->partitions[0].first;
- msg = readbsdlabel(bp, strat, 0, fsoffs + LABELSECTOR,
- LABELOFFSET, lp, spoofonly);
- return msg;
-}
+ if (spoofonly)
+ goto finished;
+
+ p = (int *)dlp;
+ i = sizeof(struct sgilabel) / sizeof(int);
+ while (i--)
+ cs += *p++;
+ if (cs != 0) {
+ msg = "sgilabel checksum error";
+ goto done;
+ }
-void
-map_sgi_label(struct disklabel *lp, struct sgilabel *dlp)
-{
-static struct {int m; int b;} maptab[] = {
- { 0, FS_BSDFFS}, { 1, FS_SWAP}, { 10, FS_BSDFFS},
- { 3, FS_BSDFFS}, { 4, FS_BSDFFS}, { 5, FS_BSDFFS},
- { 6, FS_BSDFFS}, { 7, FS_BSDFFS}, { 15, FS_OTHER},
- { 9, FS_BSDFFS}, { 2, FS_UNUSED}, { 11, FS_BSDFFS},
- { 12, FS_BSDFFS}, { 13, FS_BSDFFS}, { 14, FS_BSDFFS},
- { 8, FS_BSDFFS}
-};
- int i;
+ /* Set up partitions i-l if there is no BSD label. */
+ lp->d_secsize = dlp->dp.dp_secbytes;
+ lp->d_nsectors = dlp->dp.dp_secs;
+ lp->d_ntracks = dlp->dp.dp_trks0;
+ lp->d_ncylinders = dlp->dp.dp_cyls;
+ lp->d_interleave = dlp->dp.dp_interleave;
+ lp->d_npartitions = MAXPARTITIONS;
for (i = 0; i < 16; i++) {
int bsd = maptab[i].m;
@@ -498,6 +206,38 @@ static struct {int m; int b;} maptab[] = {
lp->d_partitions[bsd].p_cpg = 16;
}
}
+
+ lp->d_version = 1;
+ lp->d_flags = D_VENDOR;
+ lp->d_checksum = 0;
+ lp->d_checksum = dkcksum(lp);
+
+
+finished:
+ if (partoffp)
+ *partoffp = fsoffs;
+
+ if (spoofonly)
+ goto done;
+
+ bp->b_blkno = fsoffs + LABELSECTOR;
+ bp->b_cylinder = 0;
+ bp->b_bcount = lp->d_secsize;
+ bp->b_flags = B_BUSY | B_READ;
+ (*strat)(bp);
+ if (biowait(bp)) {
+ msg = "disk label I/O error";
+ goto done;
+ }
+
+ return checkdisklabel(bp->b_data + LABELOFFSET, lp);
+
+done:
+ if (dbp) {
+ dbp->b_flags |= B_INVAL;
+ brelse(dbp);
+ }
+ return (msg);
}
/*
@@ -507,39 +247,36 @@ int
writedisklabel(dev_t dev, void (*strat)(struct buf *),
struct disklabel *lp, struct cpu_disklabel *osdep)
{
+ int error, partoff = -1, cyl = 0;
char *msg = "no disk label";
struct buf *bp = NULL;
- struct disklabel dl;
- struct cpu_disklabel cdl;
- int labeloffset, error, partoff = 0, cyl = 0;
/* get a buffer and initialize it */
bp = geteblk((int)lp->d_secsize);
bp->b_dev = dev;
- dl = *lp;
- msg = readsgilabel(bp, strat, &dl, &cdl, &partoff, &cyl, 0);
- labeloffset = LABELOFFSET;
- if (msg) {
- dl = *lp;
- msg = readdoslabel(bp, strat, &dl, &cdl, &partoff, &cyl, 0);
- labeloffset = LABELOFFSET;
- }
- if (msg) {
- if (partoff == -1) {
- error = EIO;
- goto done;
- }
+ /* find where the disklabel label should be placed */
+ if (readsgilabel(bp, strat, &dl, &cdl, &partoff, &cyl, 1) == NULL)
+ goto writeit;
- /* Write it in the regular place with native byte order. */
- labeloffset = LABELOFFSET;
- bp->b_blkno = partoff + LABELSECTOR;
- bp->b_cylinder = cyl;
- bp->b_bcount = lp->d_secsize;
- }
+ if (readdoslabel(bp, strat, &dl, &cdl, &partoff, &cyl, 1) == NULL)
+ goto writeit;
- *(struct disklabel *)(bp->b_data + labeloffset) = *lp;
+ error = EIO;
+ goto done;
+
+writeit:
+ /* Read it in, slap the new label in, and write it back out */
+ bp->b_blkno = partoff + LABELSECTOR;
+ bp->b_cylinder = cyl;
+ bp->b_bcount = lp->d_secsize;
+ bp->b_flags = B_BUSY | B_READ;
+ (*strat)(bp);
+ if ((error = biowait(bp)) != 0)
+ goto done;
+ dlp = (struct disklabel *)(bp->b_data + LABELOFFSET);
+ *dlp = *lp;
bp->b_flags = B_BUSY | B_WRITE;
(*strat)(bp);
error = biowait(bp);
diff --git a/sys/arch/mvme68k/include/disklabel.h b/sys/arch/mvme68k/include/disklabel.h
index 010ad0deefe..3776099140d 100644
--- a/sys/arch/mvme68k/include/disklabel.h
+++ b/sys/arch/mvme68k/include/disklabel.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: disklabel.h,v 1.8 2003/06/03 21:09:01 deraadt Exp $ */
+/* $OpenBSD: disklabel.h,v 1.9 2007/06/17 00:27:27 deraadt Exp $ */
/*
* Copyright (c) 1996 Nivas Madhur
@@ -34,7 +34,6 @@
#define LABELSECTOR 0 /* sector containing label */
#define LABELOFFSET 0 /* offset of label in sector */
#define MAXPARTITIONS 16 /* number of partitions */
-#define RAW_PART 2 /* raw partition: xx?c */
/*
* a cpu_disklabel is a disklabel that the bug (prom) can understand
@@ -57,8 +56,10 @@
* around, make sure the various members are properly aligned and the
* compiler won't do any additional padding.
*/
-
struct cpu_disklabel {
+};
+
+struct mvmedisklabel {
/* VID */
u_char vid_id[4];
u_char vid_0[16];
diff --git a/sys/arch/mvme68k/mvme68k/disksubr.c b/sys/arch/mvme68k/mvme68k/disksubr.c
index d5fd2e96f37..742e420fdcc 100644
--- a/sys/arch/mvme68k/mvme68k/disksubr.c
+++ b/sys/arch/mvme68k/mvme68k/disksubr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: disksubr.c,v 1.57 2007/06/14 03:37:23 deraadt Exp $ */
+/* $OpenBSD: disksubr.c,v 1.58 2007/06/17 00:27:29 deraadt Exp $ */
/*
* Copyright (c) 1998 Steve Murphree, Jr.
* Copyright (c) 1995 Dale Rahn.
@@ -34,8 +34,8 @@
#include <sys/disklabel.h>
#include <sys/disk.h>
-void bsdtocpulabel(struct disklabel *, struct cpu_disklabel *);
-void cputobsdlabel(struct disklabel *, struct cpu_disklabel *);
+void bsdtocpulabel(struct disklabel *, struct mvmedisklabel *);
+void cputobsdlabel(struct disklabel *, struct mvmedisklabel *);
/*
* Attempt to read a disk label from a device
@@ -51,51 +51,43 @@ readdisklabel(dev_t dev, void (*strat)(struct buf *),
struct disklabel *lp, struct cpu_disklabel *osdep, int spoofonly)
{
struct buf *bp = NULL;
- char *msg = NULL;
- int error, i;
-
- /* minimal requirements for archetypal disk label */
- if (lp->d_secsize < DEV_BSIZE)
- lp->d_secsize = DEV_BSIZE;
- if (DL_GETDSIZE(lp) == 0)
- DL_SETDSIZE(lp, MAXDISKSIZE);
- if (lp->d_secpercyl == 0) {
- msg = "invalid geometry";
- goto done;
- }
- lp->d_npartitions = RAW_PART + 1;
- for (i = 0; i < RAW_PART; i++) {
- DL_SETPSIZE(&lp->d_partitions[i], 0);
- DL_SETPOFFSET(&lp->d_partitions[i], 0);
- }
- if (DL_GETPSIZE(&lp->d_partitions[RAW_PART]) == 0)
- DL_SETPSIZE(&lp->d_partitions[RAW_PART], DL_GETDSIZE(lp));
- DL_SETPOFFSET(&lp->d_partitions[RAW_PART], 0);
- lp->d_version = 1;
+ struct mvmedisklabel *mlp;
+ int error;
+ char *msg;
- /* don't read the on-disk label if we are in spoofed-only mode */
- if (spoofonly)
+ if ((msg = initdisklabel(lp)))
goto done;
/* get a buffer and initialize it */
bp = geteblk((int)lp->d_secsize);
bp->b_dev = dev;
+ /* don't read the on-disk label if we are in spoofed-only mode */
+ if (spoofonly)
+ goto done;
+
bp->b_blkno = LABELSECTOR;
bp->b_cylinder = 0; /* contained in block 0 */
bp->b_bcount = lp->d_secsize;
bp->b_flags = B_BUSY | B_READ;
(*strat)(bp);
-
error = biowait(bp);
- if (error == 0)
- bcopy(bp->b_data, osdep, sizeof (struct cpu_disklabel));
-
if (error) {
msg = "disk label read error";
goto done;
}
+ mlp = (struct mvmedisklabel *)bp->b_data;
+ if (mlp->magic1 != DISKMAGIC || mlp->magic2 != DISKMAGIC) {
+ msg = "no disk label";
+ goto done;
+ }
+
+ cputobsdlabel(lp, mlp);
+ if (dkcksum(lp) == 0)
+ goto done;
+ msg = "disk label corrupted";
+
#if defined(CD9660)
if (iso_disklabelspoof(dev, strat, lp) == 0) {
msg = NULL;
@@ -109,24 +101,11 @@ readdisklabel(dev_t dev, void (*strat)(struct buf *),
}
#endif
- if (osdep->magic1 != DISKMAGIC || osdep->magic2 != DISKMAGIC) {
- msg = "no disk label";
- goto done;
- }
-
- cputobsdlabel(lp, osdep);
-
- if (dkcksum(lp) != 0) {
- msg = "disk label corrupted";
- goto done;
- }
-
done:
if (bp) {
bp->b_flags |= B_INVAL;
brelse(bp);
}
- disklabeltokernlabel(lp);
return (msg);
}
@@ -145,36 +124,18 @@ writedisklabel(dev_t dev, void (*strat)(struct buf *),
bp->b_dev = dev;
bp->b_blkno = LABELSECTOR;
+ bp->b_cylinder = 0; /* contained in block 0 */
bp->b_bcount = lp->d_secsize;
bp->b_flags = B_BUSY | B_READ;
- bp->b_cylinder = 0; /* contained in block 0 */
(*strat)(bp);
-
- if ((error = biowait(bp)) != 0) {
- /* nothing */
- } else {
- bcopy(bp->b_data, osdep, sizeof(struct cpu_disklabel));
- }
-
- if (error)
+ if ((error = biowait(bp)) != 0)
goto done;
- bsdtocpulabel(lp, osdep);
+ bsdtocpulabel(lp, (struct mvmedisklabel *)bp->b_data);
- if (lp->d_magic == DISKMAGIC && lp->d_magic2 == DISKMAGIC &&
- dkcksum(lp) == 0) {
- bcopy(osdep, bp->b_data, sizeof(struct cpu_disklabel));
-
- /* request no partition relocation by driver on I/O operations */
- bp->b_dev = dev;
- bp->b_blkno = 0; /* contained in block 0 */
- bp->b_bcount = lp->d_secsize;
- bp->b_flags = B_BUSY | B_WRITE;
- bp->b_cylinder = 0; /* contained in block 0 */
- (*strat)(bp);
-
- error = biowait(bp);
- }
+ bp->b_flags = B_BUSY | B_WRITE;
+ (*strat)(bp);
+ error = biowait(bp);
done:
if (bp) {
@@ -185,7 +146,7 @@ done:
}
void
-bsdtocpulabel(struct disklabel *lp, struct cpu_disklabel *clp)
+bsdtocpulabel(struct disklabel *lp, struct mvmedisklabel *clp)
{
char *tmot = "MOTOROLA", *id = "M68K", *mot;
int i;
@@ -250,7 +211,7 @@ bsdtocpulabel(struct disklabel *lp, struct cpu_disklabel *clp)
}
void
-cputobsdlabel(struct disklabel *lp, struct cpu_disklabel *clp)
+cputobsdlabel(struct disklabel *lp, struct mvmedisklabel *clp)
{
int i;
@@ -301,7 +262,6 @@ cputobsdlabel(struct disklabel *lp, struct cpu_disklabel *clp)
lp->d_spare[i] = clp->spare[i];
lp->d_magic2 = clp->magic2;
- lp->d_checksum = 0;
lp->d_npartitions = clp->partitions;
lp->d_bbsize = clp->bbsize;
lp->d_sbsize = clp->sbsize;
@@ -309,10 +269,19 @@ cputobsdlabel(struct disklabel *lp, struct cpu_disklabel *clp)
bcopy(clp->vid_4, &lp->d_partitions[0], sizeof(struct partition) * 4);
bcopy(clp->cfg_4, &lp->d_partitions[4], sizeof(struct partition) * 12);
- if (clp->version == 2)
- lp->d_version = 1;
- else
- lp->d_version = 0;
+ if (clp->version < 2) {
+ struct __partitionv0 *v0pp = (struct __partitionv0 *)lp->d_partitions;
+ struct partition *pp = lp->d_partitions;
+
+ for (i = 0; i < lp->d_npartitions; i++, pp++, v0pp++) {
+ pp->p_fragblock = DISKLABELV1_FFS_FRAGBLOCK(v0pp->
+ p_fsize, v0pp->p_frag);
+ pp->p_offseth = 0;
+ pp->p_sizeh = 0;
+ }
+ }
+ lp->d_version = 1;
+ lp->d_checksum = 0;
lp->d_checksum = dkcksum(lp);
}
diff --git a/sys/arch/mvme88k/include/disklabel.h b/sys/arch/mvme88k/include/disklabel.h
index d7ae09fbec9..f70f7a3d739 100644
--- a/sys/arch/mvme88k/include/disklabel.h
+++ b/sys/arch/mvme88k/include/disklabel.h
@@ -1,4 +1,5 @@
-/* $OpenBSD: disklabel.h,v 1.11 2003/10/11 22:08:57 miod Exp $ */
+/* $OpenBSD: disklabel.h,v 1.12 2007/06/17 00:27:27 deraadt Exp $ */
+
/*
* Copyright (c) 1996 Nivas Madhur
* Copyright (c) 1995 Dale Rahn.
@@ -33,15 +34,16 @@
#define LABELSECTOR 0 /* sector containing label */
#define LABELOFFSET 0 /* offset of label in sector */
#define MAXPARTITIONS 16 /* number of partitions */
-#define RAW_PART 2 /* raw partition: xx?c */
/*
* Note: this structure is exactly 512 bytes in size. If you move fields
* around, make sure the various members are properly aligned and the
* compiler won't do any additional padding.
*/
-
struct cpu_disklabel {
+};
+
+struct mvmedisklabel {
/* VID */
u_char vid_id[4];
u_char vid_0[16];
diff --git a/sys/arch/mvme88k/mvme88k/disksubr.c b/sys/arch/mvme88k/mvme88k/disksubr.c
index 85dfa0783ac..9750a54032b 100644
--- a/sys/arch/mvme88k/mvme88k/disksubr.c
+++ b/sys/arch/mvme88k/mvme88k/disksubr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: disksubr.c,v 1.53 2007/06/14 03:37:23 deraadt Exp $ */
+/* $OpenBSD: disksubr.c,v 1.54 2007/06/17 00:27:29 deraadt Exp $ */
/*
* Copyright (c) 1998 Steve Murphree, Jr.
* Copyright (c) 1995 Dale Rahn.
@@ -34,8 +34,8 @@
#include <sys/disklabel.h>
#include <sys/disk.h>
-void bsdtocpulabel(struct disklabel *, struct cpu_disklabel *);
-void cputobsdlabel(struct disklabel *, struct cpu_disklabel *);
+void bsdtocpulabel(struct disklabel *, struct mvmedisklabel *);
+void cputobsdlabel(struct disklabel *, struct mvmedisklabel *);
/*
* Attempt to read a disk label from a device
@@ -51,51 +51,43 @@ readdisklabel(dev_t dev, void (*strat)(struct buf *),
struct disklabel *lp, struct cpu_disklabel *osdep, int spoofonly)
{
struct buf *bp = NULL;
- char *msg = NULL;
- int error, i;
-
- /* minimal requirements for archetypal disk label */
- if (lp->d_secsize < DEV_BSIZE)
- lp->d_secsize = DEV_BSIZE;
- if (DL_GETDSIZE(lp) == 0)
- DL_SETDSIZE(lp, MAXDISKSIZE);
- if (lp->d_secpercyl == 0) {
- msg = "invalid geometry";
- goto done;
- }
- lp->d_npartitions = RAW_PART + 1;
- for (i = 0; i < RAW_PART; i++) {
- DL_SETPSIZE(&lp->d_partitions[i], 0);
- DL_SETPOFFSET(&lp->d_partitions[i], 0);
- }
- if (DL_GETPSIZE(&lp->d_partitions[RAW_PART]) == 0)
- DL_SETPSIZE(&lp->d_partitions[RAW_PART], DL_GETDSIZE(lp));
- DL_SETPOFFSET(&lp->d_partitions[RAW_PART], 0);
- lp->d_version = 1;
+ struct mvmedisklabel *mlp;
+ int error;
+ char *msg;
- /* don't read the on-disk label if we are in spoofed-only mode */
- if (spoofonly)
+ if ((msg = initdisklabel(lp)))
goto done;
/* get a buffer and initialize it */
bp = geteblk((int)lp->d_secsize);
bp->b_dev = dev;
+ /* don't read the on-disk label if we are in spoofed-only mode */
+ if (spoofonly)
+ goto done;
+
bp->b_blkno = LABELSECTOR;
bp->b_cylinder = 0; /* contained in block 0 */
bp->b_bcount = lp->d_secsize;
bp->b_flags = B_BUSY | B_READ;
(*strat)(bp);
-
error = biowait(bp);
- if (error == 0)
- bcopy(bp->b_data, osdep, sizeof (struct cpu_disklabel));
-
if (error) {
msg = "disk label read error";
goto done;
}
+ mlp = (struct mvmedisklabel *)bp->b_data;
+ if (mlp->magic1 != DISKMAGIC || mlp->magic2 != DISKMAGIC) {
+ msg = "no disk label";
+ goto done;
+ }
+
+ cputobsdlabel(lp, mlp);
+ if (dkcksum(lp) == 0)
+ goto done;
+ msg = "disk label corrupted";
+
#if defined(CD9660)
if (iso_disklabelspoof(dev, strat, lp) == 0) {
msg = NULL;
@@ -109,24 +101,11 @@ readdisklabel(dev_t dev, void (*strat)(struct buf *),
}
#endif
- if (osdep->magic1 != DISKMAGIC || osdep->magic2 != DISKMAGIC) {
- msg = "no disk label";
- goto done;
- }
-
- cputobsdlabel(lp, osdep);
-
- if (dkcksum(lp) != 0) {
- msg = "disk label corrupted";
- goto done;
- }
-
done:
if (bp) {
bp->b_flags |= B_INVAL;
brelse(bp);
}
- disklabeltokernlabel(lp);
return (msg);
}
@@ -144,37 +123,20 @@ writedisklabel(dev_t dev, void (*strat)(struct buf *),
bp = geteblk((int)lp->d_secsize);
bp->b_dev = dev;
+ /* Read it in, slap the new label in, and write it back out */
bp->b_blkno = LABELSECTOR;
+ bp->b_cylinder = 0;
bp->b_bcount = lp->d_secsize;
bp->b_flags = B_BUSY | B_READ;
- bp->b_cylinder = 0; /* contained in block 0 */
(*strat)(bp);
-
- if ((error = biowait(bp)) != 0) {
- /* nothing */
- } else {
- bcopy(bp->b_data, osdep, sizeof(struct cpu_disklabel));
- }
-
- if (error)
+ if ((error = biowait(bp)) != 0)
goto done;
- bsdtocpulabel(lp, osdep);
+ bsdtocpulabel(lp, (struct mvmedisklabel *)bp->b_data);
- if (lp->d_magic == DISKMAGIC && lp->d_magic2 == DISKMAGIC &&
- dkcksum(lp) == 0) {
- bcopy(osdep, bp->b_data, sizeof(struct cpu_disklabel));
-
- /* request no partition relocation by driver on I/O operations */
- bp->b_dev = dev;
- bp->b_blkno = 0; /* contained in block 0 */
- bp->b_bcount = lp->d_secsize;
- bp->b_flags = B_BUSY | B_WRITE;
- bp->b_cylinder = 0; /* contained in block 0 */
- (*strat)(bp);
-
- error = biowait(bp);
- }
+ bp->b_flags = B_BUSY | B_WRITE;
+ (*strat)(bp);
+ error = biowait(bp);
done:
if (bp) {
@@ -185,7 +147,7 @@ done:
}
void
-bsdtocpulabel(struct disklabel *lp, struct cpu_disklabel *clp)
+bsdtocpulabel(struct disklabel *lp, struct mvmedisklabel *clp)
{
char *tmot = "MOTOROLA", *id = "M88K", *mot;
int i;
@@ -250,7 +212,7 @@ bsdtocpulabel(struct disklabel *lp, struct cpu_disklabel *clp)
}
void
-cputobsdlabel(struct disklabel *lp, struct cpu_disklabel *clp)
+cputobsdlabel(struct disklabel *lp, struct mvmedisklabel *clp)
{
int i;
@@ -301,7 +263,6 @@ cputobsdlabel(struct disklabel *lp, struct cpu_disklabel *clp)
lp->d_spare[i] = clp->spare[i];
lp->d_magic2 = clp->magic2;
- lp->d_checksum = 0;
lp->d_npartitions = clp->partitions;
lp->d_bbsize = clp->bbsize;
lp->d_sbsize = clp->sbsize;
@@ -309,10 +270,19 @@ cputobsdlabel(struct disklabel *lp, struct cpu_disklabel *clp)
bcopy(clp->vid_4, &lp->d_partitions[0], sizeof(struct partition) * 4);
bcopy(clp->cfg_4, &lp->d_partitions[4], sizeof(struct partition) * 12);
- if (clp->version == 2)
- lp->d_version = 1;
- else
- lp->d_version = 0;
+ if (clp->version < 2) {
+ struct __partitionv0 *v0pp = (struct __partitionv0 *)lp->d_partitions;
+ struct partition *pp = lp->d_partitions;
+
+ for (i = 0; i < lp->d_npartitions; i++, pp++, v0pp++) {
+ pp->p_fragblock = DISKLABELV1_FFS_FRAGBLOCK(v0pp->
+ p_fsize, v0pp->p_frag);
+ pp->p_offseth = 0;
+ pp->p_sizeh = 0;
+ }
+ }
+ lp->d_version = 1;
+ lp->d_checksum = 0;
lp->d_checksum = dkcksum(lp);
}
diff --git a/sys/arch/mvmeppc/include/disklabel.h b/sys/arch/mvmeppc/include/disklabel.h
index f1c07fbb4f2..8639d243d34 100644
--- a/sys/arch/mvmeppc/include/disklabel.h
+++ b/sys/arch/mvmeppc/include/disklabel.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: disklabel.h,v 1.10 2006/10/20 23:47:43 krw Exp $ */
+/* $OpenBSD: disklabel.h,v 1.11 2007/06/17 00:27:27 deraadt Exp $ */
/*
* Copyright (c) 1994 Christopher G. Demetriou
@@ -33,56 +33,11 @@
#ifndef _MACHINE_DISKLABEL_H_
#define _MACHINE_DISKLABEL_H_
-#define LABELSECTOR 1 /* sector containing label */
-#define LABELOFFSET 0 /* offset of label in sector */
-#define MAXPARTITIONS 16 /* number of partitions */
-#define RAW_PART 2 /* raw partition: ie. rsd0c */
-
-/* MBR partition table */
-#define DOSBBSECTOR 0 /* MBR sector number */
-#define DOSPARTOFF 446 /* Offset of MBR partition table */
-#define NDOSPART 4 /* # of partitions in MBR */
-#define DOSMAGICOFF 510 /* Offset of magic number */
-#define DOSMAGIC 0xaa55 /* Actual magic number */
-#define MBRMAGIC DOSMAGIC
-#define DOSMBR_SIGNATURE MBRMAGIC
-#define DOSMBR_SIGNATURE_OFF DOSMAGICOFF
-#define DOSACTIVE 0x80
-
-struct dos_partition {
- u_int8_t dp_flag; /* default boot flag */
- u_int8_t dp_shd; /* start head, IsN't Always Meaningful */
- u_int8_t dp_ssect; /* start sector, INAM */
- u_int8_t dp_scyl; /* start cylinder, INAM */
- u_int8_t dp_typ; /* partition type */
- u_int8_t dp_ehd; /* end head, INAM */
- u_int8_t dp_esect; /* end sector, INAM */
- u_int8_t dp_ecyl; /* end cylinder, INAM */
- u_int32_t dp_start; /* absolute start sector number */
- u_int32_t dp_size; /* partition size in sectors */
-};
-
-/* Known DOS partition types. */
-#define DOSPTYP_UNUSED 0x00 /* Unused partition */
-#define DOSPTYP_FAT12 0x01 /* 12-bit FAT */
-#define DOSPTYP_FAT16S 0x04 /* 16-bit FAT, less than 32M */
-#define DOSPTYP_EXTEND 0x05 /* Extended; contains sub-partitions */
-#define DOSPTYP_FAT16B 0x06 /* 16-bit FAT, more than 32M */
-#define DOSPTYP_FAT32 0x0b /* 32-bit FAT */
-#define DOSPTYP_FAT32L 0x0c /* 32-bit FAT, LBA-mapped */
-#define DOSPTYP_FAT16L 0x0e /* 16-bit FAT, LBA-mapped */
-#define DOSPTYP_EXTENDL 0x0f /* Extended, LBA-mapped; contains sub-partitions */
-#define DOSPTYP_ONTRACK 0x54
-#define DOSPTYP_LINUX 0x83 /* That other thing */
-#define DOSPTYP_FREEBSD 0xa5 /* FreeBSD partition type */
-#define DOSPTYP_OPENBSD 0xa6 /* OpenBSD partition type */
-#define DOSPTYP_NETBSD 0xa9 /* NetBSD partition type */
+#define LABELSECTOR 1 /* sector containing label */
+#define LABELOFFSET 0 /* offset of label in sector */
+#define MAXPARTITIONS 16 /* number of partitions */
struct cpu_disklabel {
};
-/* Isolate the relevant bits to get sector and cylinder. */
-#define DPSECT(s) ((s) & 0x3f)
-#define DPCYL(c, s) ((c) + (((s) & 0xc0) << 2))
-
#endif /* _MACHINE_DISKLABEL_H_ */
diff --git a/sys/arch/mvmeppc/mvmeppc/disksubr.c b/sys/arch/mvmeppc/mvmeppc/disksubr.c
index b1307333c6f..502c0840768 100644
--- a/sys/arch/mvmeppc/mvmeppc/disksubr.c
+++ b/sys/arch/mvmeppc/mvmeppc/disksubr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: disksubr.c,v 1.50 2007/06/14 03:37:23 deraadt Exp $ */
+/* $OpenBSD: disksubr.c,v 1.51 2007/06/17 00:27:29 deraadt Exp $ */
/* $NetBSD: disksubr.c,v 1.21 1996/05/03 19:42:03 christos Exp $ */
/*
@@ -29,21 +29,14 @@
* 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.
- *
- * @(#)ufs_disksubr.c 7.16 (Berkeley) 5/4/91
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/buf.h>
-#include <sys/device.h>
#include <sys/disklabel.h>
-#include <sys/syslog.h>
#include <sys/disk.h>
-#define BOOT_MAGIC 0xAA55
-#define BOOT_MAGIC_OFF (DOSPARTOFF+NDOSPART*sizeof(struct dos_partition))
-
/*
* Attempt to read a disk label from a device
* using the indicated strategy routine.
@@ -56,7 +49,7 @@
* find disklabel inside a DOS partition. Return buffer
* for use in signalling errors if requested.
*
- * We would like to check if each MBR has a valid BOOT_MAGIC, but
+ * We would like to check if each MBR has a valid DOSMBR_SIGNATURE, but
* we cannot because it doesn't always exist. So.. we assume the
* MBR is valid.
*
@@ -66,227 +59,31 @@ char *
readdisklabel(dev_t dev, void (*strat)(struct buf *),
struct disklabel *lp, struct cpu_disklabel *osdep, int spoofonly)
{
- struct dos_partition dp[NDOSPART], *dp2;
- struct partition *pp;
- struct disklabel *dlp;
- unsigned long extoff = 0;
- unsigned int fattest;
struct buf *bp = NULL;
- daddr64_t part_blkno = DOSBBSECTOR;
- char *msg = NULL;
- int dospartoff, cyl, i, ourpart = -1;
- int wander = 1, n = 0, loop = 0;
+ char *msg;
- /* minimal requirements for archetypal disk label */
- if (lp->d_secsize < DEV_BSIZE)
- lp->d_secsize = DEV_BSIZE;
- if (DL_GETDSIZE(lp) == 0)
- DL_SETDSIZE(lp, MAXDISKSIZE);
- if (lp->d_secpercyl == 0) {
- msg = "invalid geometry";
+ if ((msg = initdisklabel(lp)))
goto done;
- }
- lp->d_npartitions = RAW_PART + 1;
- for (i = 0; i < RAW_PART; i++) {
- DL_SETPSIZE(&lp->d_partitions[i], 0);
- DL_SETPOFFSET(&lp->d_partitions[i], 0);
- }
- if (DL_GETPSIZE(&lp->d_partitions[RAW_PART]) == 0)
- DL_SETPSIZE(&lp->d_partitions[RAW_PART], DL_GETDSIZE(lp));
- DL_SETPOFFSET(&lp->d_partitions[RAW_PART], 0);
- lp->d_version = 1;
/* get a buffer and initialize it */
bp = geteblk((int)lp->d_secsize);
bp->b_dev = dev;
- /* do dos partitions in the process of getting disklabel? */
- dospartoff = 0;
- cyl = LABELSECTOR / lp->d_secpercyl;
-
- /*
- * Read dos partition table, follow extended partitions.
- * Map the partitions to disklabel entries i-p
- */
- while (wander && n < 8 && loop < 8) {
- loop++;
- wander = 0;
- if (part_blkno < extoff)
- part_blkno = extoff;
-
- /* read boot record */
- bp->b_blkno = part_blkno;
- bp->b_bcount = lp->d_secsize;
- bp->b_flags = B_BUSY | B_READ;
- bp->b_cylinder = part_blkno / lp->d_secpercyl;
- (*strat)(bp);
-
- /* if successful, wander through dos partition table */
- if (biowait(bp)) {
- msg = "dos partition I/O error";
- goto done;
- }
- bcopy(bp->b_data + DOSPARTOFF, dp, sizeof(dp));
-
- if (ourpart == -1 && part_blkno == DOSBBSECTOR) {
- /* Search for our MBR partition */
- for (dp2=dp, i=0; i < NDOSPART && ourpart == -1;
- i++, dp2++)
- if (letoh32(dp2->dp_size) &&
- dp2->dp_typ == DOSPTYP_OPENBSD)
- ourpart = i;
- if (ourpart == -1)
- goto donot;
- /*
- * This is our MBR partition. need sector address
- * for SCSI/IDE, cylinder for ESDI/ST506/RLL
- */
- dp2 = &dp[ourpart];
- dospartoff = letoh32(dp2->dp_start) + part_blkno;
- cyl = DPCYL(dp2->dp_scyl, dp2->dp_ssect);
-
- /* XXX build a temporary disklabel */
- DL_SETPSIZE(&lp->d_partitions[0], letoh32(dp2->dp_size));
- DL_SETPOFFSET(&lp->d_partitions[0],
- letoh32(dp2->dp_start) + part_blkno);
- if (lp->d_ntracks == 0)
- lp->d_ntracks = dp2->dp_ehd + 1;
- if (lp->d_nsectors == 0)
- lp->d_nsectors = DPSECT(dp2->dp_esect);
- if (lp->d_secpercyl == 0)
- lp->d_secpercyl = lp->d_ntracks *
- lp->d_nsectors;
- }
-donot:
- /*
- * In case the disklabel read below fails, we want to
- * provide a fake label in i-p.
- */
- for (dp2=dp, i=0; i < NDOSPART && n < 8; i++, dp2++) {
- pp = &lp->d_partitions[8+n];
-
- if (dp2->dp_typ == DOSPTYP_OPENBSD)
- continue;
- if (letoh32(dp2->dp_size) > DL_GETDSIZE(lp))
- continue;
- if (letoh32(dp2->dp_start) > DL_GETDSIZE(lp))
- continue;
- if (letoh32(dp2->dp_size) == 0)
- continue;
- if (letoh32(dp2->dp_start))
- DL_SETPOFFSET(pp,
- letoh32(dp2->dp_start) + part_blkno);
-
- DL_SETPSIZE(pp, letoh32(dp2->dp_size));
-
- switch (dp2->dp_typ) {
- case DOSPTYP_UNUSED:
- pp->p_fstype = FS_UNUSED;
- n++;
- break;
-
- case DOSPTYP_LINUX:
- pp->p_fstype = FS_EXT2FS;
- n++;
- break;
-
- case DOSPTYP_FAT12:
- case DOSPTYP_FAT16S:
- case DOSPTYP_FAT16B:
- case DOSPTYP_FAT16L:
- case DOSPTYP_FAT32:
- case DOSPTYP_FAT32L:
- pp->p_fstype = FS_MSDOS;
- n++;
- break;
- case DOSPTYP_EXTEND:
- case DOSPTYP_EXTENDL:
- part_blkno = letoh32(dp2->dp_start) + extoff;
- if (!extoff) {
- extoff = letoh32(dp2->dp_start);
- part_blkno = 0;
- }
- wander = 1;
- break;
- default:
- pp->p_fstype = FS_OTHER;
- n++;
- break;
- }
- }
- }
- lp->d_bbsize = 8192;
- lp->d_sbsize = 64*1024; /* XXX ? */
- lp->d_npartitions = MAXPARTITIONS;
-
- if (n == 0 && part_blkno == DOSBBSECTOR) {
- /* Check for a short jump instruction. */
- fattest = ((bp->b_data[0] << 8) & 0xff00) | (bp->b_data[2] &
- 0xff);
- if (fattest != 0xeb90 && fattest != 0xe900)
- goto notfat;
-
- /* Check for a valid bytes per sector value. */
- fattest = ((bp->b_data[12] << 8) & 0xff00) | (bp->b_data[11] &
- 0xff);
- if (fattest < 512 || fattest > 4096 || (fattest % 512 != 0))
- goto notfat;
-
- /* Check the end of sector marker. */
- fattest = ((bp->b_data[510] << 8) & 0xff00) | (bp->b_data[511] &
- 0xff);
- if (fattest != 0x55aa)
- goto notfat;
-
- /* Looks like a FAT filesystem. Spoof 'i'. */
- DL_SETPSIZE(&lp->d_partitions['i' - 'a'],
- DL_GETPSIZE(&lp->d_partitions[RAW_PART]));
- DL_SETPOFFSET(&lp->d_partitions['i' - 'a'], 0);
- lp->d_partitions['i' - 'a'].p_fstype = FS_MSDOS;
- }
-notfat:
-
- /* don't read the on-disk label if we are in spoofed-only mode */
- if (spoofonly)
+ msg = readdoslabel(bp, strat, lp, osdep, NULL, NULL, spoofonly);
+ if (msg == NULL)
goto done;
- /* next, dig out disk label */
- bp->b_blkno = dospartoff + LABELSECTOR;
- bp->b_cylinder = cyl;
- bp->b_bcount = lp->d_secsize;
- bp->b_flags = B_BUSY | B_READ;
- (*strat)(bp);
-
- /* if successful, locate disk label within block and validate */
- if (biowait(bp)) {
- /* XXX we return the faked label built so far */
- msg = "disk label I/O error";
- goto done;
- }
- for (dlp = (struct disklabel *)bp->b_data;
- dlp <= (struct disklabel *)(bp->b_data + lp->d_secsize - sizeof(*dlp));
- dlp = (struct disklabel *)((char *)dlp + sizeof(long))) {
- if (dlp->d_magic != DISKMAGIC || dlp->d_magic2 != DISKMAGIC) {
- if (msg == NULL)
- msg = "no disk label";
- } else if (dlp->d_npartitions > MAXPARTITIONS ||
- dkcksum(dlp) != 0)
- msg = "disk label corrupted";
- else {
- DL_SETDSIZE(dlp, DL_GETDSIZE(lp));
- *lp = *dlp;
- msg = NULL;
- break;
- }
- }
-
#if defined(CD9660)
- if (msg && iso_disklabelspoof(dev, strat, lp) == 0)
+ if (iso_disklabelspoof(dev, strat, lp) == 0) {
msg = NULL;
+ goto done;
+ }
#endif
#if defined(UDF)
- if (msg && udf_disklabelspoof(dev, strat, lp) == 0)
+ if (udf_disklabelspoof(dev, strat, lp) == 0) {
msg = NULL;
+ goto done;
+ }
#endif
done:
@@ -294,7 +91,6 @@ done:
bp->b_flags |= B_INVAL;
brelse(bp);
}
- disklabeltokernlabel(lp);
return (msg);
}
@@ -306,72 +102,32 @@ int
writedisklabel(dev_t dev, void (*strat)(struct buf *),
struct disklabel *lp, struct cpu_disklabel *osdep)
{
- struct dos_partition dp[NDOSPART], *dp2;
+ int error, partoff = -1, cyl = 0;
struct disklabel *dlp;
struct buf *bp = NULL;
- int error, dospartoff, cyl, i;
- int ourpart = -1;
/* get a buffer and initialize it */
bp = geteblk((int)lp->d_secsize);
bp->b_dev = dev;
- /* do dos partitions in the process of getting disklabel? */
- dospartoff = 0;
- cyl = LABELSECTOR / lp->d_secpercyl;
- /* read master boot record */
- 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 ((error = biowait(bp)) != 0)
- goto done;
-
- /* XXX how do we check veracity/bounds of this? */
- bcopy(bp->b_data + DOSPARTOFF, dp, sizeof(dp));
+ if (readdoslabel(bp, strat, lp, osdep, &partoff, &cyl, 1) == NULL)
+ goto writeit;
- for (dp2=dp, i=0; i < NDOSPART && ourpart == -1; i++, dp2++)
- if (letoh32(dp2->dp_size) && dp2->dp_typ == DOSPTYP_OPENBSD)
- ourpart = i;
+ error = EIO;
+ goto done;
- if (ourpart != -1) {
- dp2 = &dp[ourpart];
-
- /*
- * need sector address for SCSI/IDE,
- * cylinder for ESDI/ST506/RLL
- */
- dospartoff = letoh32(dp2->dp_start);
- cyl = DPCYL(dp2->dp_scyl, dp2->dp_ssect);
- }
-
- /* next, dig out disk label */
- bp->b_blkno = dospartoff + LABELSECTOR;
+writeit:
+ /* Read it in, slap the new label in, and write it back out */
+ bp->b_blkno = partoff + LABELSECTOR;
bp->b_cylinder = cyl;
bp->b_bcount = lp->d_secsize;
bp->b_flags = B_BUSY | B_READ;
(*strat)(bp);
-
- /* if successful, locate disk label within block and validate */
if ((error = biowait(bp)) != 0)
goto done;
- for (dlp = (struct disklabel *)bp->b_data;
- dlp <= (struct disklabel *)(bp->b_data + lp->d_secsize - sizeof(*dlp));
- dlp = (struct disklabel *)((char *)dlp + sizeof(long))) {
- if (dlp->d_magic == DISKMAGIC && dlp->d_magic2 == DISKMAGIC &&
- dkcksum(dlp) == 0) {
- *dlp = *lp;
- bp->b_flags = B_BUSY | B_WRITE;
- (*strat)(bp);
- error = biowait(bp);
- goto done;
- }
- }
- /* Write it in the regular place. */
- *(struct disklabel *)bp->b_data = *lp;
+ dlp = (struct disklabel *)(bp->b_data + LABELOFFSET);
+ *dlp = *lp;
bp->b_flags = B_BUSY | B_WRITE;
(*strat)(bp);
error = biowait(bp);
diff --git a/sys/arch/sh/include/disklabel.h b/sys/arch/sh/include/disklabel.h
index db6ded7f74b..5c38c2bd8c5 100644
--- a/sys/arch/sh/include/disklabel.h
+++ b/sys/arch/sh/include/disklabel.h
@@ -1,5 +1,4 @@
-/* $OpenBSD: disklabel.h,v 1.5 2006/10/20 23:47:43 krw Exp $ */
-/* $NetBSD: disklabel.h,v 1.2 2001/11/25 19:02:03 thorpej Exp $ */
+/* $OpenBSD: disklabel.h,v 1.6 2007/06/17 00:27:28 deraadt Exp $ */
/*
* Copyright (c) 1994 Mark Brinicombe.
@@ -34,14 +33,6 @@
* 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.
- *
- * RiscBSD kernel project
- *
- * disklabel.h
- *
- * machine specific disk label info
- *
- * Created : 04/10/94
*/
#ifndef _ARM_DISKLABEL_H_
@@ -50,58 +41,6 @@
#define LABELSECTOR 1 /* sector containing label */
#define LABELOFFSET 0 /* offset of label in sector */
#define MAXPARTITIONS 16 /* number of partitions */
-#define RAW_PART 2 /* raw partition: XX?c */
-
-#if 0
-#include <arm/disklabel_acorn.h>
-#include <sys/disklabel_mbr.h>
-#endif
-
-/* MBR partition table */
-#define DOSBBSECTOR 0 /* MBR sector number */
-#define DOSPARTOFF 446 /* Offset of MBR partition table */
-#define NDOSPART 4 /* # of partitions in MBR */
-#define DOSMAGICOFF 510 /* Offset of magic number */
-#define DOSMAGIC 0xaa55 /* Actual magic number */
-#define MBRMAGIC DOSMAGIC
-#define DOSMBR_SIGNATURE MBRMAGIC
-#define DOSMBR_SIGNATURE_OFF DOSMAGICOFF
-#define DOSACTIVE 0x80
-
-
-struct dos_partition {
- u_int8_t dp_flag; /* bootstrap flags */
- u_int8_t dp_shd; /* starting head */
- u_int8_t dp_ssect; /* starting sector */
- u_int8_t dp_scyl; /* starting cylinder */
- u_int8_t dp_typ; /* partition type (see below) */
- u_int8_t dp_ehd; /* end head */
- u_int8_t dp_esect; /* end sector */
- u_int8_t dp_ecyl; /* end cylinder */
- u_int32_t dp_start; /* absolute starting sector number */
- u_int32_t dp_size; /* partition size in sectors */
-};
-
-/* Known DOS partition types. */
-#define DOSPTYP_UNUSED 0x00 /* Unused partition */
-#define DOSPTYP_FAT12 0x01 /* 12-bit FAT */
-#define DOSPTYP_FAT16S 0x04 /* 16-bit FAT, less than 32M */
-#define DOSPTYP_EXTEND 0x05 /* Extended; contains sub-partitions */
-#define DOSPTYP_FAT16B 0x06 /* 16-bit FAT, more than 32M */
-#define DOSPTYP_FAT32 0x0b /* 32-bit FAT */
-#define DOSPTYP_FAT32L 0x0c /* 32-bit FAT, LBA-mapped */
-#define DOSPTYP_FAT16L 0x0e /* 16-bit FAT, LBA-mapped */
-#define DOSPTYP_EXTENDL 0x0f /* Extended, LBA-mapped; contains sub-partitions */
-#define DOSPTYP_ONTRACK 0x54
-#define DOSPTYP_LINUX 0x83 /* That other thing */
-#define DOSPTYP_FREEBSD 0xa5 /* FreeBSD partition type */
-#define DOSPTYP_OPENBSD 0xa6 /* OpenBSD partition type */
-#define DOSPTYP_NETBSD 0xa9 /* NetBSD partition type */
-
-/* Isolate the relevant bits to get sector and cylinder. */
-#define DPSECT(s) ((s) & 0x3f)
-#define DPCYL(c, s) ((c) + (((s) & 0xc0) << 2))
-
struct cpu_disklabel {
};
diff --git a/sys/arch/solbourne/include/disklabel.h b/sys/arch/solbourne/include/disklabel.h
index 2b1ab7758f8..ef20a8f131e 100644
--- a/sys/arch/solbourne/include/disklabel.h
+++ b/sys/arch/solbourne/include/disklabel.h
@@ -1,3 +1,3 @@
-/* $OpenBSD: disklabel.h,v 1.1 2005/04/19 21:30:17 miod Exp $ */
-/* public domain */
-#include <sparc/disklabel.h> \ No newline at end of file
+/* $OpenBSD: disklabel.h,v 1.2 2007/06/17 00:27:28 deraadt Exp $ */
+
+#include <sparc/disklabel.h>
diff --git a/sys/arch/sparc/include/disklabel.h b/sys/arch/sparc/include/disklabel.h
index 9c9b28b1e1a..d7021e04b65 100644
--- a/sys/arch/sparc/include/disklabel.h
+++ b/sys/arch/sparc/include/disklabel.h
@@ -1,5 +1,4 @@
-/* $OpenBSD: disklabel.h,v 1.2 1996/09/12 04:33:27 downsj Exp $ */
-/* $NetBSD: disklabel.h,v 1.4 1995/09/01 17:20:31 pk Exp $ */
+/* $OpenBSD: disklabel.h,v 1.3 2007/06/17 00:27:28 deraadt Exp $ */
/*
* Copyright (c) 1994 Christopher G. Demetriou
@@ -37,7 +36,6 @@
#define LABELSECTOR 0 /* sector containing label */
#define LABELOFFSET 64 /* offset of label in sector */
#define MAXPARTITIONS 16 /* number of partitions */
-#define RAW_PART 2 /* raw partition: xx?c */
struct cpu_disklabel {
char cd_block[512];
diff --git a/sys/arch/sparc/sparc/disksubr.c b/sys/arch/sparc/sparc/disksubr.c
index e4d23d91ea2..c37f39a5bb2 100644
--- a/sys/arch/sparc/sparc/disksubr.c
+++ b/sys/arch/sparc/sparc/disksubr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: disksubr.c,v 1.63 2007/06/14 03:41:22 deraadt Exp $ */
+/* $OpenBSD: disksubr.c,v 1.64 2007/06/17 00:27:29 deraadt Exp $ */
/* $NetBSD: disksubr.c,v 1.16 1996/04/28 20:25:59 thorpej Exp $ */
/*
@@ -46,8 +46,8 @@
#include "cd.h"
-static char *disklabel_sun_to_bsd(char *, struct disklabel *);
-static int disklabel_bsd_to_sun(struct disklabel *, char *);
+static char *disklabel_sun_to_bsd(struct sun_disklabel *, struct disklabel *);
+static int disklabel_bsd_to_sun(struct disklabel *, struct sun_disklabel *);
static __inline u_int sun_extended_sum(struct sun_disklabel *, void *);
#if NCD > 0
@@ -68,39 +68,21 @@ extern void cdstrategy(struct buf *);
*/
char *
readdisklabel(dev_t dev, void (*strat)(struct buf *),
- struct disklabel *lp, struct cpu_disklabel *clp, int spoofonly)
+ struct disklabel *lp, struct cpu_disklabel *osdep, int spoofonly)
{
- struct buf *bp = NULL;
- struct disklabel *dlp;
struct sun_disklabel *slp;
- char *msg = NULL;
- int error, i;
-
- /* minimal requirements for archetypal disk label */
- if (lp->d_secsize < DEV_BSIZE)
- lp->d_secsize = DEV_BSIZE;
- if (DL_GETDSIZE(lp) == 0)
- DL_SETDSIZE(lp, MAXDISKSIZE);
- if (lp->d_secpercyl == 0) {
- msg = "invalid geometry";
- goto done;
- }
- lp->d_npartitions = RAW_PART+1;
- for (i = 0; i < RAW_PART; i++) {
- DL_SETPSIZE(&lp->d_partitions[i], 0);
- DL_SETPOFFSET(&lp->d_partitions[i], 0);
- }
- if (DL_GETPSIZE(&lp->d_partitions[RAW_PART]) == 0)
- DL_SETPSIZE(&lp->d_partitions[RAW_PART], DL_GETDSIZE(lp));
- DL_SETPOFFSET(&lp->d_partitions[RAW_PART], 0);
- lp->d_version = 1;
- lp->d_bbsize = 8192;
- lp->d_sbsize = 64*1024; /* XXX ? */
+ struct buf *bp = NULL;
+ char *msg;
- /* don't read the on-disk label if we are in spoofed-only mode */
- if (spoofonly)
+ if ((msg = initdisklabel(lp)))
goto done;
+ /*
+ * On sparc64 we check for a CD label first, because our
+ * CD install media contains both sparc & sparc64 labels.
+ * We want the sparc64 machine to find the "CD label", not
+ * the SunOS label, for loading it's kernel.
+ */
#if NCD > 0
if (strat == cdstrategy) {
#if defined(CD9660)
@@ -118,47 +100,42 @@ readdisklabel(dev_t dev, void (*strat)(struct buf *),
}
#endif /* NCD > 0 */
- /* obtain buffer to probe drive with */
+ /* obtain buffer and initialize it */
bp = geteblk((int)lp->d_secsize);
-
- /* next, dig out disk label */
bp->b_dev = dev;
+
+ if (spoofonly)
+ goto doslabel;
+
bp->b_blkno = LABELSECTOR;
bp->b_cylinder = 0;
bp->b_bcount = lp->d_secsize;
bp->b_flags = B_BUSY | B_READ;
(*strat)(bp);
-
- /* if successful, locate disk label within block and validate */
- error = biowait(bp);
- if (error == 0) {
- /* Save the whole block in case it has info we need. */
- bcopy(bp->b_data, clp->cd_block, sizeof(clp->cd_block));
- }
- if (error) {
+ if (biowait(bp)) {
msg = "disk label read error";
goto done;
}
- slp = (struct sun_disklabel *)clp->cd_block;
+ /* XXX because xd(4) & xy(4) still need it */
+ bcopy(bp->b_data, osdep->cd_block, sizeof(osdep->cd_block));
+
+ slp = (struct sun_disklabel *)bp->b_data;
if (slp->sl_magic == SUN_DKMAGIC) {
- msg = disklabel_sun_to_bsd(clp->cd_block, lp);
+ msg = disklabel_sun_to_bsd(slp, lp);
goto done;
}
- /* Check for a native disk label (PROM can not boot it). */
- dlp = (struct disklabel *)(clp->cd_block + LABELOFFSET);
- if (dlp->d_magic == DISKMAGIC) {
- if (dkcksum(dlp)) {
- msg = "disk label corrupted";
- goto done;
- }
- DL_SETDSIZE(dlp, DL_GETDSIZE(lp));
- *lp = *dlp; /* struct assignment */
- msg = NULL;
+ msg = checkdisklabel(bp->b_data + LABELOFFSET, lp);
+ if (msg == NULL)
goto done;
- }
+doslabel:
+ msg = readdoslabel(bp, strat, lp, osdep, NULL, NULL, spoofonly);
+ if (msg == NULL)
+ goto done;
+
+ /* A CD9660/UDF label may be on a non-CD drive, so recheck */
#if defined(CD9660)
if (iso_disklabelspoof(dev, strat, lp) == 0) {
msg = NULL;
@@ -171,39 +148,34 @@ readdisklabel(dev_t dev, void (*strat)(struct buf *),
goto done;
}
#endif
- bzero(clp->cd_block, sizeof(clp->cd_block));
- msg = "no disk label";
done:
if (bp) {
bp->b_flags |= B_INVAL;
brelse(bp);
}
- disklabeltokernlabel(lp);
return (msg);
}
/*
* Write disk label back to device after modification.
- * Current label is already in clp->cd_block[]
*/
int
writedisklabel(dev_t dev, void (*strat)(struct buf *),
- struct disklabel *lp, struct cpu_disklabel *clp)
+ struct disklabel *lp, struct cpu_disklabel *osdep)
{
struct buf *bp = NULL;
int error;
- error = disklabel_bsd_to_sun(lp, clp->cd_block);
+ /* obtain buffer and initialize it */
+ bp = geteblk((int)lp->d_secsize);
+ bp->b_dev = dev;
+
+ error = disklabel_bsd_to_sun(lp, (struct sun_disklabel *)bp->b_data);
if (error)
goto done;
- /* Get a buffer and copy the new label into it. */
- bp = geteblk((int)lp->d_secsize);
- bcopy(clp->cd_block, bp->b_data, sizeof(clp->cd_block));
-
/* Write out the updated label. */
- bp->b_dev = dev;
bp->b_blkno = LABELSECTOR;
bp->b_cylinder = 0;
bp->b_bcount = lp->d_secsize;
@@ -272,20 +244,16 @@ sun_extended_sum(struct sun_disklabel *sl, void *end)
* The BSD label is cleared out before this is called.
*/
static char *
-disklabel_sun_to_bsd(char *cp, struct disklabel *lp)
+disklabel_sun_to_bsd(struct sun_disklabel *sl, struct disklabel *lp)
{
- struct sun_disklabel *sl;
struct partition *npp;
struct sun_dkpart *spp;
int i, secpercyl;
- u_short cksum, *sp1, *sp2;
-
- sl = (struct sun_disklabel *)cp;
+ u_short cksum = 0, *sp1, *sp2;
/* Verify the XOR check. */
sp1 = (u_short *)sl;
sp2 = (u_short *)(sl + 1);
- cksum = 0;
while (sp1 < sp2)
cksum ^= *sp1++;
if (cksum != 0)
@@ -294,6 +262,7 @@ disklabel_sun_to_bsd(char *cp, struct disklabel *lp)
/* Format conversion. */
lp->d_magic = DISKMAGIC;
lp->d_magic2 = DISKMAGIC;
+ lp->d_flags = D_VENDOR;
memcpy(lp->d_packname, sl->sl_text, sizeof(lp->d_packname));
lp->d_secsize = 512;
@@ -305,7 +274,7 @@ disklabel_sun_to_bsd(char *cp, struct disklabel *lp)
lp->d_secpercyl = secpercyl;
if (DL_GETDSIZE(lp) == 0)
DL_SETDSIZE(lp, (daddr64_t)secpercyl * sl->sl_ncylinders);
- lp->d_version = 1; /* 48 bit addressing */
+ lp->d_version = 1;
lp->d_sparespercyl = sl->sl_sparespercyl;
lp->d_acylinders = sl->sl_acylinders;
@@ -396,9 +365,8 @@ disklabel_sun_to_bsd(char *cp, struct disklabel *lp)
* Returns zero or error code.
*/
static int
-disklabel_bsd_to_sun(struct disklabel *lp, char *cp)
+disklabel_bsd_to_sun(struct disklabel *lp, struct sun_disklabel *sl)
{
- struct sun_disklabel *sl;
struct partition *npp;
struct sun_dkpart *spp;
int i, secpercyl;
@@ -408,8 +376,6 @@ disklabel_bsd_to_sun(struct disklabel *lp, char *cp)
if (lp->d_secsize != 512 || lp->d_nsectors == 0 || lp->d_ntracks == 0)
return (EINVAL);
- sl = (struct sun_disklabel *)cp;
-
/* Format conversion. */
memcpy(sl->sl_text, lp->d_packname, sizeof(lp->d_packname));
sl->sl_rpm = lp->d_rpm;
diff --git a/sys/arch/sparc64/include/disklabel.h b/sys/arch/sparc64/include/disklabel.h
index 1db0609d24e..90be19c3a23 100644
--- a/sys/arch/sparc64/include/disklabel.h
+++ b/sys/arch/sparc64/include/disklabel.h
@@ -1,5 +1,4 @@
-/* $OpenBSD: disklabel.h,v 1.2 2001/09/18 21:04:33 jason Exp $ */
-/* $NetBSD: disklabel.h,v 1.1.1.1 1998/06/20 04:58:51 eeh Exp $ */
+/* $OpenBSD: disklabel.h,v 1.3 2007/06/17 00:27:28 deraadt Exp $ */
/*
* Copyright (c) 1994 Christopher G. Demetriou
@@ -37,10 +36,8 @@
#define LABELSECTOR 0 /* sector containing label */
#define LABELOFFSET 128 /* offset of label in sector */
#define MAXPARTITIONS 16 /* number of partitions */
-#define RAW_PART 2 /* raw partition: xx?c */
struct cpu_disklabel {
- char cd_block[512];
};
#endif /* _MACHINE_DISKLABEL_H_ */
diff --git a/sys/arch/sparc64/sparc64/disksubr.c b/sys/arch/sparc64/sparc64/disksubr.c
index 74ec0a1bf70..ae0475e8e14 100644
--- a/sys/arch/sparc64/sparc64/disksubr.c
+++ b/sys/arch/sparc64/sparc64/disksubr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: disksubr.c,v 1.42 2007/06/14 03:41:22 deraadt Exp $ */
+/* $OpenBSD: disksubr.c,v 1.43 2007/06/17 00:27:29 deraadt Exp $ */
/* $NetBSD: disksubr.c,v 1.13 2000/12/17 22:39:18 pk Exp $ */
/*
@@ -32,21 +32,15 @@
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/buf.h>
-#include <sys/ioccom.h>
-#include <sys/device.h>
#include <sys/disklabel.h>
#include <sys/disk.h>
-#include <machine/cpu.h>
-#include <machine/autoconf.h>
#include <dev/sun/disklabel.h>
-#include <dev/sbus/sbusvar.h>
-
#include "cd.h"
-static char *disklabel_sun_to_bsd(char *, struct disklabel *);
-static int disklabel_bsd_to_sun(struct disklabel *, char *);
+static char *disklabel_sun_to_bsd(struct sun_disklabel *, struct disklabel *);
+static int disklabel_bsd_to_sun(struct disklabel *, struct sun_disklabel *);
static __inline u_int sun_extended_sum(struct sun_disklabel *, void *);
#if NCD > 0
@@ -67,39 +61,21 @@ extern void cdstrategy(struct buf *);
*/
char *
readdisklabel(dev_t dev, void (*strat)(struct buf *),
- struct disklabel *lp, struct cpu_disklabel *clp, int spoofonly)
+ struct disklabel *lp, struct cpu_disklabel *osdep, int spoofonly)
{
- struct buf *bp = NULL;
- struct disklabel *dlp;
struct sun_disklabel *slp;
- char *msg = NULL;
- int error, i;
+ struct buf *bp = NULL;
+ char *msg;
- /* minimal requirements for archetypal disk label */
- if (lp->d_secsize < DEV_BSIZE)
- lp->d_secsize = DEV_BSIZE;
- if (DL_GETDSIZE(lp) == 0)
- DL_SETDSIZE(lp, MAXDISKSIZE);
- if (lp->d_secpercyl == 0) {
- msg = "invalid geometry";
- goto done;
- }
- lp->d_npartitions = RAW_PART+1;
- for (i = 0; i < RAW_PART; i++) {
- DL_SETPSIZE(&lp->d_partitions[i], 0);
- DL_SETPOFFSET(&lp->d_partitions[i], 0);
- }
- if (DL_GETPSIZE(&lp->d_partitions[RAW_PART]) == 0)
- DL_SETPSIZE(&lp->d_partitions[RAW_PART], DL_GETDSIZE(lp));
- DL_SETPOFFSET(&lp->d_partitions[RAW_PART], 0);
- lp->d_version = 1;
- lp->d_bbsize = 8192;
- lp->d_sbsize = 64*1024; /* XXX ? */
-
- /* don't read the on-disk label if we are in spoofed-only mode */
- if (spoofonly)
+ if ((msg = initdisklabel(lp)))
goto done;
+ /*
+ * On sparc64 we check for a CD label first, because our
+ * CD install media contains both sparc & sparc64 labels.
+ * We want the sparc64 machine to find the "CD label", not
+ * the SunOS label, for loading it's kernel.
+ */
#if NCD > 0
if (strat == cdstrategy) {
#if defined(CD9660)
@@ -117,47 +93,39 @@ readdisklabel(dev_t dev, void (*strat)(struct buf *),
}
#endif /* NCD > 0 */
- /* obtain buffer to probe drive with */
+ /* obtain buffer and initialize it */
bp = geteblk((int)lp->d_secsize);
-
- /* next, dig out disk label */
bp->b_dev = dev;
+
+ if (spoofonly)
+ goto doslabel;
+
bp->b_blkno = LABELSECTOR;
bp->b_cylinder = 0;
bp->b_bcount = lp->d_secsize;
bp->b_flags = B_BUSY | B_READ;
(*strat)(bp);
-
- /* if successful, locate disk label within block and validate */
- error = biowait(bp);
- if (error == 0) {
- /* Save the whole block in case it has info we need. */
- bcopy(bp->b_data, clp->cd_block, sizeof(clp->cd_block));
- }
- if (error) {
+ if (biowait(bp)) {
msg = "disk label read error";
goto done;
}
- slp = (struct sun_disklabel *)clp->cd_block;
+ slp = (struct sun_disklabel *)bp->b_data;
if (slp->sl_magic == SUN_DKMAGIC) {
- msg = disklabel_sun_to_bsd(clp->cd_block, lp);
+ msg = disklabel_sun_to_bsd(slp, lp);
goto done;
}
- /* Check for a native disk label (PROM can not boot it). */
- dlp = (struct disklabel *)(clp->cd_block + LABELOFFSET);
- if (dlp->d_magic == DISKMAGIC) {
- if (dkcksum(dlp)) {
- msg = "disk label corrupted";
- goto done;
- }
- DL_SETDSIZE(dlp, DL_GETDSIZE(lp));
- *lp = *dlp; /* struct assignment */
- msg = NULL;
+ msg = checkdisklabel(bp->b_data + LABELOFFSET, lp);
+ if (msg == NULL)
goto done;
- }
+doslabel:
+ msg = readdoslabel(bp, strat, lp, osdep, NULL, NULL, spoofonly);
+ if (msg == NULL)
+ goto done;
+
+ /* A CD9660/UDF label may be on a non-CD drive, so recheck */
#if defined(CD9660)
if (iso_disklabelspoof(dev, strat, lp) == 0) {
msg = NULL;
@@ -170,39 +138,34 @@ readdisklabel(dev_t dev, void (*strat)(struct buf *),
goto done;
}
#endif
- bzero(clp->cd_block, sizeof(clp->cd_block));
- msg = "no disk label";
done:
if (bp) {
bp->b_flags |= B_INVAL;
brelse(bp);
}
- disklabeltokernlabel(lp);
return (msg);
}
/*
* Write disk label back to device after modification.
- * Current label is already in clp->cd_block[]
*/
int
writedisklabel(dev_t dev, void (*strat)(struct buf *),
- struct disklabel *lp, struct cpu_disklabel *clp)
+ struct disklabel *lp, struct cpu_disklabel *osdep)
{
struct buf *bp = NULL;
int error;
- error = disklabel_bsd_to_sun(lp, clp->cd_block);
+ /* obtain buffer and initialize it */
+ bp = geteblk((int)lp->d_secsize);
+ bp->b_dev = dev;
+
+ error = disklabel_bsd_to_sun(lp, (struct sun_disklabel *)bp->b_data);
if (error)
goto done;
- /* Get a buffer and copy the new label into it. */
- bp = geteblk((int)lp->d_secsize);
- bcopy(clp->cd_block, bp->b_data, sizeof(clp->cd_block));
-
/* Write out the updated label. */
- bp->b_dev = dev;
bp->b_blkno = LABELSECTOR;
bp->b_cylinder = 0;
bp->b_bcount = lp->d_secsize;
@@ -271,20 +234,16 @@ sun_extended_sum(struct sun_disklabel *sl, void *end)
* The BSD label is cleared out before this is called.
*/
static char *
-disklabel_sun_to_bsd(char *cp, struct disklabel *lp)
+disklabel_sun_to_bsd(struct sun_disklabel *sl, struct disklabel *lp)
{
- struct sun_disklabel *sl;
struct partition *npp;
struct sun_dkpart *spp;
int i, secpercyl;
- u_short cksum, *sp1, *sp2;
-
- sl = (struct sun_disklabel *)cp;
+ u_short cksum = 0, *sp1, *sp2;
/* Verify the XOR check. */
sp1 = (u_short *)sl;
sp2 = (u_short *)(sl + 1);
- cksum = 0;
while (sp1 < sp2)
cksum ^= *sp1++;
if (cksum != 0)
@@ -293,6 +252,7 @@ disklabel_sun_to_bsd(char *cp, struct disklabel *lp)
/* Format conversion. */
lp->d_magic = DISKMAGIC;
lp->d_magic2 = DISKMAGIC;
+ lp->d_flags = D_VENDOR;
memcpy(lp->d_packname, sl->sl_text, sizeof(lp->d_packname));
lp->d_secsize = 512;
@@ -304,7 +264,7 @@ disklabel_sun_to_bsd(char *cp, struct disklabel *lp)
lp->d_secpercyl = secpercyl;
if (DL_GETDSIZE(lp) == 0)
DL_SETDSIZE(lp, (daddr64_t)secpercyl * sl->sl_ncylinders);
- lp->d_version = 1; /* 48 bit addressing */
+ lp->d_version = 1;
lp->d_sparespercyl = sl->sl_sparespercyl;
lp->d_acylinders = sl->sl_acylinders;
@@ -395,9 +355,8 @@ disklabel_sun_to_bsd(char *cp, struct disklabel *lp)
* Returns zero or error code.
*/
static int
-disklabel_bsd_to_sun(struct disklabel *lp, char *cp)
+disklabel_bsd_to_sun(struct disklabel *lp, struct sun_disklabel *sl)
{
- struct sun_disklabel *sl;
struct partition *npp;
struct sun_dkpart *spp;
int i, secpercyl;
@@ -407,8 +366,6 @@ disklabel_bsd_to_sun(struct disklabel *lp, char *cp)
if (lp->d_secsize != 512 || lp->d_nsectors == 0 || lp->d_ntracks == 0)
return (EINVAL);
- sl = (struct sun_disklabel *)cp;
-
/* Format conversion. */
memcpy(sl->sl_text, lp->d_packname, sizeof(lp->d_packname));
sl->sl_rpm = lp->d_rpm;
diff --git a/sys/arch/vax/include/disklabel.h b/sys/arch/vax/include/disklabel.h
index be218718271..cae29811e77 100644
--- a/sys/arch/vax/include/disklabel.h
+++ b/sys/arch/vax/include/disklabel.h
@@ -1,5 +1,4 @@
-/* $OpenBSD: disklabel.h,v 1.7 2001/12/06 23:47:28 miod Exp $ */
-/* $NetBSD: disklabel.h,v 1.4 1997/03/09 15:55:58 ragge Exp $ */
+/* $OpenBSD: disklabel.h,v 1.8 2007/06/17 00:27:28 deraadt Exp $ */
/*
* Copyright (c) 1994 Christopher G. Demetriou
@@ -37,12 +36,10 @@
#define LABELSECTOR 0 /* sector containing label */
#define LABELOFFSET 64 /* offset of label in sector */
#define MAXPARTITIONS 16 /* number of partitions */
-#define RAW_PART 2 /* raw partition: xx?c */
-/* Just a dummy */
#ifndef _LOCORE
struct cpu_disklabel {
- /* EMPTY */
};
+
#endif
#endif /* _MACHINE_DISKLABEL_H_ */
diff --git a/sys/arch/vax/vax/disksubr.c b/sys/arch/vax/vax/disksubr.c
index 7a49d613ce9..b7a5e1af284 100644
--- a/sys/arch/vax/vax/disksubr.c
+++ b/sys/arch/vax/vax/disksubr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: disksubr.c,v 1.51 2007/06/14 03:37:23 deraadt Exp $ */
+/* $OpenBSD: disksubr.c,v 1.52 2007/06/17 00:27:29 deraadt Exp $ */
/* $NetBSD: disksubr.c,v 1.21 1999/06/30 18:48:06 ragge Exp $ */
/*
@@ -28,8 +28,6 @@
* 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.
- *
- * @(#)ufs_disksubr.c 7.16 (Berkeley) 5/4/91
*/
#include <sys/param.h>
@@ -63,37 +61,17 @@ readdisklabel(dev_t dev, void (*strat)(struct buf *),
struct disklabel *lp, struct cpu_disklabel *osdep, int spoofonly)
{
struct buf *bp = NULL;
- struct disklabel *dlp;
- char *msg = NULL;
- int i;
-
- /* minimal requirements for archetypal disk label */
- if (lp->d_secsize < DEV_BSIZE)
- lp->d_secsize = DEV_BSIZE;
- if (DL_GETDSIZE(lp) == 0)
- DL_SETDSIZE(lp, MAXDISKSIZE);
- if (lp->d_secpercyl == 0) {
- msg = "invalid geometry";
- goto done;
- }
- lp->d_npartitions = RAW_PART + 1;
- for (i = 0; i < RAW_PART; i++) {
- DL_SETPSIZE(&lp->d_partitions[i], 0);
- DL_SETPOFFSET(&lp->d_partitions[i], 0);
- }
- if (DL_GETPSIZE(&lp->d_partitions[RAW_PART]) == 0)
- DL_SETPSIZE(&lp->d_partitions[RAW_PART], DL_GETDSIZE(lp));
- DL_SETPOFFSET(&lp->d_partitions[RAW_PART], 0);
- lp->d_version = 1;
- lp->d_bbsize = 8192;
- lp->d_sbsize = 64 * 1024;
-
- /* don't read the on-disk label if we are in spoofed-only mode */
- if (spoofonly)
+ char *msg;
+
+ if ((msg = initdisklabel(lp)))
goto done;
bp = geteblk((int)lp->d_secsize);
bp->b_dev = dev;
+
+ if (spoofonly)
+ goto done;
+
bp->b_blkno = LABELSECTOR;
bp->b_bcount = lp->d_secsize;
bp->b_flags = B_BUSY | B_READ;
@@ -101,26 +79,24 @@ readdisklabel(dev_t dev, void (*strat)(struct buf *),
(*strat)(bp);
if (biowait(bp)) {
msg = "I/O error";
- } else {
- dlp = (struct disklabel *)(bp->b_data + LABELOFFSET);
- if (dlp->d_magic != DISKMAGIC || dlp->d_magic2 != DISKMAGIC) {
- msg = "no disk label";
- } else if (dlp->d_npartitions > MAXPARTITIONS ||
- dkcksum(dlp) != 0)
- msg = "disk label corrupted";
- else {
- DL_SETDSIZE(dlp, DL_GETDSIZE(lp));
- *lp = *dlp;
- }
+ goto done;
}
+ msg = checkdisklabel(bp->b_data + LABELOFFSET, lp);
+ if (msg == NULL)
+ goto done;
+
#if defined(CD9660)
- if (msg && iso_disklabelspoof(dev, strat, lp) == 0)
+ if (iso_disklabelspoof(dev, strat, lp) == 0) {
msg = NULL;
+ goto done;
+ }
#endif
#if defined(UDF)
- if (msg && udf_disklabelspoof(dev, strat, lp) == 0)
+ if (udf_disklabelspoof(dev, strat, lp) == 0) {
msg = NULL;
+ goto done;
+ }
#endif
done:
@@ -128,7 +104,6 @@ done:
bp->b_flags |= B_INVAL;
brelse(bp);
}
- disklabeltokernlabel(lp);
return (msg);
}
@@ -145,9 +120,11 @@ writedisklabel(dev_t dev, void (*strat)(struct buf *),
int error = 0;
bp = geteblk((int)lp->d_secsize);
- bp->b_dev = MAKEDISKDEV(major(dev), DISKUNIT(dev), RAW_PART);
+ bp->b_dev = dev;
+
+ /* Read it in, slap the new label in, and write it back out */
bp->b_blkno = LABELSECTOR;
- bp->b_cylinder = LABELSECTOR / lp->d_secpercyl;
+ bp->b_cylinder = bp->b_blkno / lp->d_secpercyl;
bp->b_bcount = lp->d_secsize;
bp->b_flags = B_BUSY | B_READ;
(*strat)(bp);
@@ -155,7 +132,7 @@ writedisklabel(dev_t dev, void (*strat)(struct buf *),
goto done;
dlp = (struct disklabel *)(bp->b_data + LABELOFFSET);
- bcopy(lp, dlp, sizeof(struct disklabel));
+ *dlp = *lp;
bp->b_flags = B_BUSY | B_WRITE;
(*strat)(bp);
error = biowait(bp);
diff --git a/sys/arch/zaurus/include/disklabel.h b/sys/arch/zaurus/include/disklabel.h
index 7e63a238746..0c0642c339a 100644
--- a/sys/arch/zaurus/include/disklabel.h
+++ b/sys/arch/zaurus/include/disklabel.h
@@ -1,4 +1,3 @@
-/* $OpenBSD: disklabel.h,v 1.1 2004/12/31 00:04:35 drahn Exp $ */
-/* $NetBSD: disklabel.h,v 1.3 2001/11/25 15:55:55 thorpej Exp $ */
+/* $OpenBSD: disklabel.h,v 1.2 2007/06/17 00:27:28 deraadt Exp $ */
#include <arm/disklabel.h>
diff --git a/sys/kern/subr_disk.c b/sys/kern/subr_disk.c
index 5e2f9064225..40c548d4a76 100644
--- a/sys/kern/subr_disk.c
+++ b/sys/kern/subr_disk.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: subr_disk.c,v 1.59 2007/06/10 16:37:09 deraadt Exp $ */
+/* $OpenBSD: subr_disk.c,v 1.60 2007/06/17 00:27:30 deraadt Exp $ */
/* $NetBSD: subr_disk.c,v 1.17 1996/03/16 23:17:08 christos Exp $ */
/*
@@ -181,67 +181,373 @@ dkcksum(struct disklabel *lp)
return (sum);
}
+char *
+initdisklabel(struct disklabel *lp)
+{
+ int i;
+
+ /* minimal requirements for archetypal disk label */
+ if (lp->d_secsize < DEV_BSIZE)
+ lp->d_secsize = DEV_BSIZE;
+ if (DL_GETDSIZE(lp) == 0)
+ DL_SETDSIZE(lp, MAXDISKSIZE);
+ if (lp->d_secpercyl == 0)
+ return ("invalid geometry");
+ lp->d_npartitions = RAW_PART + 1;
+ for (i = 0; i < RAW_PART; i++) {
+ DL_SETPSIZE(&lp->d_partitions[i], 0);
+ DL_SETPOFFSET(&lp->d_partitions[i], 0);
+ }
+ if (DL_GETPSIZE(&lp->d_partitions[RAW_PART]) == 0)
+ DL_SETPSIZE(&lp->d_partitions[RAW_PART], DL_GETDSIZE(lp));
+ DL_SETPOFFSET(&lp->d_partitions[RAW_PART], 0);
+ lp->d_version = 1;
+ lp->d_bbsize = 8192;
+ lp->d_sbsize = 64*1024; /* XXX ? */
+ return (NULL);
+}
+
/*
- * Convert an on-disk disklabel to a kernel disklabel, converting versions
- * as required and applying constraints that kernel disklabels are guaranteed
- * to satisfy.
+ * Check an incoming block to make sure it is a disklabel, convert it to
+ * a newer version if needed, etc etc.
*/
-void
-disklabeltokernlabel(struct disklabel *lp)
+char *
+checkdisklabel(void *rlp, struct disklabel *lp)
{
- struct __partitionv0 *v0pp = (struct __partitionv0 *)lp->d_partitions;
- struct partition *pp = lp->d_partitions;
- int i, oversion = lp->d_version, changed = 0, okbefore = 0;
+ struct disklabel *dlp = rlp;
+ struct __partitionv0 *v0pp;
+ struct partition *pp;
+ daddr64_t disksize;
+ char *msg = NULL;
+ int i;
+
+ if (dlp->d_magic != DISKMAGIC || dlp->d_magic2 != DISKMAGIC)
+ msg = "no disk label";
+ else if (dlp->d_npartitions > MAXPARTITIONS)
+ msg = "unreasonable partition count";
+ else if (dkcksum(dlp) != 0)
+ msg = "disk label corrupted";
+
+ if (msg) {
+ u_int16_t *start, *end, sum = 0;
+
+ /* If it is byte-swapped, attempt to convert it */
+ if (swap32(dlp->d_magic) != DISKMAGIC ||
+ swap32(dlp->d_magic2) != DISKMAGIC ||
+ swap16(dlp->d_npartitions) > MAXPARTITIONS)
+ return (msg);
+
+ /*
+ * Need a byte-swap aware dkcksum varient
+ * inlined, because dkcksum uses a sub-field
+ */
+ start = (u_int16_t *)dlp;
+ end = (u_int16_t *)&dlp->d_partitions[
+ swap16(dlp->d_npartitions)];
+ while (start < end)
+ sum ^= *start++;
+ if (sum != 0)
+ return (msg);
+
+ dlp->d_magic = swap32(dlp->d_magic);
+ dlp->d_type = swap16(dlp->d_type);
+ dlp->d_subtype = swap16(dlp->d_subtype);
+
+ /* d_typename and d_packname are strings */
+
+ dlp->d_secsize = swap32(dlp->d_secsize);
+ dlp->d_nsectors = swap32(dlp->d_nsectors);
+ dlp->d_ntracks = swap32(dlp->d_ntracks);
+ dlp->d_ncylinders = swap32(dlp->d_ncylinders);
+ dlp->d_secpercyl = swap32(dlp->d_secpercyl);
+ dlp->d_secperunit = swap32(dlp->d_secperunit);
+
+ dlp->d_sparespertrack = swap16(dlp->d_sparespertrack);
+ dlp->d_sparespercyl = swap16(dlp->d_sparespercyl);
+
+ dlp->d_acylinders = swap32(dlp->d_acylinders);
+
+ dlp->d_rpm = swap16(dlp->d_rpm);
+ dlp->d_interleave = swap16(dlp->d_interleave);
+ dlp->d_trackskew = swap16(dlp->d_trackskew);
+ dlp->d_cylskew = swap16(dlp->d_cylskew);
+ dlp->d_headswitch = swap32(dlp->d_headswitch);
+ dlp->d_trkseek = swap32(dlp->d_trkseek);
+ dlp->d_flags = swap32(dlp->d_flags);
+
+ for (i = 0; i < NDDATA; i++)
+ dlp->d_drivedata[i] = swap32(dlp->d_drivedata[i]);
+
+ dlp->d_secperunith = swap16(dlp->d_secperunith);
+ dlp->d_version = swap16(dlp->d_version);
+
+ for (i = 0; i < NSPARE; i++)
+ dlp->d_spare[i] = swap32(dlp->d_spare[i]);
+
+ dlp->d_magic2 = swap32(dlp->d_magic2);
+ dlp->d_checksum = swap16(dlp->d_checksum);
+
+ dlp->d_npartitions = swap16(dlp->d_npartitions);
+ dlp->d_bbsize = swap32(dlp->d_bbsize);
+ dlp->d_sbsize = swap32(dlp->d_sbsize);
+
+ for (i = 0; i < MAXPARTITIONS; i++) {
+ pp = &dlp->d_partitions[i];
+ pp->p_size = swap32(pp->p_size);
+ pp->p_offset = swap32(pp->p_offset);
+ if (dlp->d_version == 0) {
+ v0pp = (struct __partitionv0 *)pp;
+ v0pp->p_fsize = swap32(v0pp->p_fsize);
+ } else {
+ pp->p_offseth = swap16(pp->p_offseth);
+ pp->p_sizeh = swap16(pp->p_sizeh);
+ }
+ pp->p_cpg = swap16(pp->p_cpg);
+ }
+
+ dlp->d_checksum = 0;
+ dlp->d_checksum = dkcksum(dlp);
+ msg = NULL;
+ }
+
+ /* XXX should verify lots of other fields and whine a lot */
+
+ if (msg)
+ return (msg);
+
+ /* Initial passed in lp contains the real disk size */
+ disksize = DL_GETDSIZE(lp);
- if (dkcksum(lp) == 0)
- okbefore = 1;
+ if (lp != dlp)
+ *lp = *dlp;
- if (oversion == 0) {
+ if (lp->d_version == 0) {
lp->d_version = 1;
lp->d_secperunith = 0;
- changed = 1;
- }
- for (i = 0; i < MAXPARTITIONS; i++, pp++, v0pp++) {
- if (oversion == 0) {
+ v0pp = (struct __partitionv0 *)lp->d_partitions;
+ pp = lp->d_partitions;
+ for (i = 0; i < lp->d_npartitions; i++, pp++, v0pp++) {
pp->p_fragblock = DISKLABELV1_FFS_FRAGBLOCK(v0pp->
p_fsize, v0pp->p_frag);
pp->p_offseth = 0;
pp->p_sizeh = 0;
}
+ }
-#ifdef notyet
- /* XXX this should not be here */
-
- /* In a V1 label no partition extends past DL_GETSIZE(lp) - 1. */
- if (DL_GETPOFFSET(pp) > DL_GETDSIZE(lp)) {
- pp->p_fstype = FS_UNUSED;
- DL_SETPSIZE(pp, 0);
- DL_SETPOFFSET(pp, 0);
- } else if (DL_GETPOFFSET(pp) + DL_GETPSIZE(pp) > DL_GETDSIZE(lp)) {
- daddr64_t sz;
-
- printf("%lld %lld %lld\n",
- DL_GETPOFFSET(pp), DL_GETPSIZE(pp),
- DL_GETPOFFSET(pp) + DL_GETPSIZE(pp),
- DL_GETDSIZE(lp));
- pp->p_fstype = FS_UNUSED;
- sz = DL_GETDSIZE(lp) - DL_GETPOFFSET(pp);
- DL_SETPSIZE(pp, sz);
- }
+#ifdef noonecares
+ if (DL_GETDSIZE(lp) != disksize)
+ printf("new disklabel disk size different %lld != %lld\n",
+ DL_GETDSIZE(lp), disksize);
#endif
- }
+ DL_SETDSIZE(lp, disksize);
- /* XXX this should not be here */
- if (DL_GETPOFFSET(&lp->d_partitions[RAW_PART]) != 0) {
- DL_SETPOFFSET(&lp->d_partitions[RAW_PART], 0);
- DL_SETPSIZE(&lp->d_partitions[RAW_PART], DL_GETDSIZE(lp));
- changed = 1;
+ if (DL_GETPSIZE(&lp->d_partitions[RAW_PART]) != DL_GETDSIZE(lp))
+ printf("new disklabel raw disk size different %lld != %lld\n",
+ DL_GETPSIZE(&lp->d_partitions[RAW_PART]), DL_GETDSIZE(lp));
+ DL_SETPSIZE(&lp->d_partitions[RAW_PART], DL_GETDSIZE(lp));
+
+ if (DL_GETPOFFSET(&lp->d_partitions[RAW_PART]) != 0)
+ printf("new disklabel raw disk offset different %lld != %lld\n",
+ DL_GETPOFFSET(&lp->d_partitions[RAW_PART]), 0);
+ DL_SETPOFFSET(&lp->d_partitions[RAW_PART], 0);
+
+ lp->d_checksum = 0;
+ lp->d_checksum = dkcksum(lp);
+ return (msg);
+}
+
+/*
+ * If dos partition table requested, attempt to load it and
+ * find disklabel inside a DOS partition. Return buffer
+ * for use in signalling errors if requested.
+ *
+ * We would like to check if each MBR has a valid BOOT_MAGIC, but
+ * we cannot because it doesn't always exist. So.. we assume the
+ * MBR is valid.
+ */
+char *
+readdoslabel(struct buf *bp, void (*strat)(struct buf *),
+ struct disklabel *lp, struct cpu_disklabel *osdep,
+ int *partoffp, int *cylp, int spoofonly)
+{
+ struct dos_partition dp[NDOSPART], *dp2;
+ u_int32_t extoff = 0;
+ daddr64_t part_blkno = DOSBBSECTOR;
+ int dospartoff = 0, cyl, i, ourpart = -1;
+ int wander = 1, n = 0, loop = 0;
+
+ if (lp->d_secpercyl == 0)
+ return ("invalid label, d_secpercyl == 0");
+ if (lp->d_secsize == 0)
+ return ("invalid label, d_secsize == 0");
+
+ /* do DOS partitions in the process of getting disklabel? */
+ cyl = DOS_LABELSECTOR / lp->d_secpercyl;
+
+ /*
+ * Read dos partition table, follow extended partitions.
+ * Map the partitions to disklabel entries i-p
+ */
+ while (wander && n < 8 && loop < 8) {
+ loop++;
+ wander = 0;
+ if (part_blkno < extoff)
+ part_blkno = extoff;
+
+ /* read boot record */
+ bp->b_blkno = part_blkno;
+ bp->b_bcount = lp->d_secsize;
+ bp->b_flags = B_BUSY | B_READ;
+ bp->b_cylinder = part_blkno / lp->d_secpercyl;
+ (*strat)(bp);
+ if (biowait(bp)) {
+/*wrong*/ if (partoffp)
+/*wrong*/ *partoffp = -1;
+ return ("dos partition I/O error");
+ }
+
+ bcopy(bp->b_data + DOSPARTOFF, dp, sizeof(dp));
+
+ if (ourpart == -1 && part_blkno == DOSBBSECTOR) {
+ /* Search for our MBR partition */
+ for (dp2=dp, i=0; i < NDOSPART && ourpart == -1;
+ i++, dp2++)
+ if (letoh32(dp2->dp_size) &&
+ dp2->dp_typ == DOSPTYP_OPENBSD)
+ ourpart = i;
+ if (ourpart == -1)
+ goto donot;
+ /*
+ * This is our MBR partition. need sector
+ * address for SCSI/IDE, cylinder for
+ * ESDI/ST506/RLL
+ */
+ dp2 = &dp[ourpart];
+ dospartoff = letoh32(dp2->dp_start) + part_blkno;
+ cyl = DPCYL(dp2->dp_scyl, dp2->dp_ssect);
+
+ /* found our OpenBSD partition, finish up */
+ if (partoffp)
+ goto notfat;
+
+ if (lp->d_ntracks == 0)
+ lp->d_ntracks = dp2->dp_ehd + 1;
+ if (lp->d_nsectors == 0)
+ lp->d_nsectors = DPSECT(dp2->dp_esect);
+ if (lp->d_secpercyl == 0)
+ lp->d_secpercyl = lp->d_ntracks *
+ lp->d_nsectors;
+ }
+donot:
+ /*
+ * In case the disklabel read below fails, we want to
+ * provide a fake label in i-p.
+ */
+ for (dp2=dp, i=0; i < NDOSPART && n < 8; i++, dp2++) {
+ struct partition *pp = &lp->d_partitions[8+n];
+
+ if (dp2->dp_typ == DOSPTYP_OPENBSD)
+ continue;
+ if (letoh32(dp2->dp_size) > DL_GETDSIZE(lp))
+ continue;
+ if (letoh32(dp2->dp_start) > DL_GETDSIZE(lp))
+ continue;
+ if (letoh32(dp2->dp_size) == 0)
+ continue;
+ if (letoh32(dp2->dp_start))
+ DL_SETPOFFSET(pp,
+ letoh32(dp2->dp_start) + part_blkno);
+
+ DL_SETPSIZE(pp, letoh32(dp2->dp_size));
+
+ switch (dp2->dp_typ) {
+ case DOSPTYP_UNUSED:
+ pp->p_fstype = FS_UNUSED;
+ n++;
+ break;
+
+ case DOSPTYP_LINUX:
+ pp->p_fstype = FS_EXT2FS;
+ n++;
+ break;
+
+ case DOSPTYP_FAT12:
+ case DOSPTYP_FAT16S:
+ case DOSPTYP_FAT16B:
+ case DOSPTYP_FAT16L:
+ case DOSPTYP_FAT32:
+ case DOSPTYP_FAT32L:
+ pp->p_fstype = FS_MSDOS;
+ n++;
+ break;
+ case DOSPTYP_EXTEND:
+ case DOSPTYP_EXTENDL:
+ part_blkno = letoh32(dp2->dp_start) + extoff;
+ if (!extoff) {
+ extoff = letoh32(dp2->dp_start);
+ part_blkno = 0;
+ }
+ wander = 1;
+ break;
+ default:
+ pp->p_fstype = FS_OTHER;
+ n++;
+ break;
+ }
+ }
}
- if (changed && okbefore) {
- lp->d_checksum = 0;
- lp->d_checksum = dkcksum(lp);
+ lp->d_npartitions = MAXPARTITIONS;
+
+ if (n == 0 && part_blkno == DOSBBSECTOR) {
+ u_int16_t fattest;
+
+ /* Check for a short jump instruction. */
+ fattest = ((bp->b_data[0] << 8) & 0xff00) |
+ (bp->b_data[2] & 0xff);
+ if (fattest != 0xeb90 && fattest != 0xe900)
+ goto notfat;
+
+ /* Check for a valid bytes per sector value. */
+ fattest = ((bp->b_data[12] << 8) & 0xff00) |
+ (bp->b_data[11] & 0xff);
+ if (fattest < 512 || fattest > 4096 || (fattest % 512 != 0))
+ goto notfat;
+
+ /* Check the end of sector marker. */
+ fattest = ((bp->b_data[510] << 8) & 0xff00) |
+ (bp->b_data[511] & 0xff);
+ if (fattest != 0x55aa)
+ goto notfat;
+
+ /* Looks like a FAT filesystem. Spoof 'i'. */
+ DL_SETPSIZE(&lp->d_partitions['i' - 'a'],
+ DL_GETPSIZE(&lp->d_partitions[RAW_PART]));
+ DL_SETPOFFSET(&lp->d_partitions['i' - 'a'], 0);
+ lp->d_partitions['i' - 'a'].p_fstype = FS_MSDOS;
}
+notfat:
+
+ /* record the OpenBSD partition's placement for the caller */
+ if (partoffp)
+ *partoffp = dospartoff;
+ if (cylp)
+ *cylp = cyl;
+
+ /* don't read the on-disk label if we are in spoofed-only mode */
+ if (spoofonly)
+ return (NULL);
+
+ bp->b_blkno = dospartoff + DOS_LABELSECTOR;
+ bp->b_cylinder = cyl;
+ bp->b_bcount = lp->d_secsize;
+ bp->b_flags = B_BUSY | B_READ;
+ (*strat)(bp);
+ if (biowait(bp))
+ return ("disk label I/O error");
+
+ /* sub-MBR disklabels are always at a LABELOFFSET of 0 */
+ return checkdisklabel(bp->b_data + 0, lp);
}
/*
diff --git a/sys/sys/disklabel.h b/sys/sys/disklabel.h
index 7f01f32096e..26c3bbdf008 100644
--- a/sys/sys/disklabel.h
+++ b/sys/sys/disklabel.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: disklabel.h,v 1.36 2007/06/06 16:42:07 deraadt Exp $ */
+/* $OpenBSD: disklabel.h,v 1.37 2007/06/17 00:27:29 deraadt Exp $ */
/* $NetBSD: disklabel.h,v 1.41 1996/05/10 23:07:37 mark Exp $ */
/*
@@ -62,6 +62,7 @@
*/
#define DISKUNIT(dev) (minor(dev) / MAXPARTITIONS)
#define DISKPART(dev) (minor(dev) % MAXPARTITIONS)
+#define RAW_PART 2 /* 'c' partition */
#define DISKMINOR(unit, part) \
(((unit) * MAXPARTITIONS) + (part))
#define MAKEDISKDEV(maj, unit, part) \
@@ -352,6 +353,7 @@ static char *fstypesnames[] = {
* flags shared by various drives:
*/
#define D_BADSECT 0x04 /* supports bad sector forw. */
+#define D_VENDOR 0x08 /* vendor disklabel */
/*
* Drive data for SMD.
@@ -395,11 +397,62 @@ struct partinfo {
struct partition *part;
};
+/* DOS partition table -- located at start of some disks. */
+#define DOS_LABELSECTOR 1
+#define DOSBBSECTOR 0 /* DOS boot block relative sector # */
+#define DOSPARTOFF 446
+#define DOSDISKOFF 444
+#define NDOSPART 4
+#define DOSACTIVE 0x80 /* active partition */
+
+#define DOSMBR_SIGNATURE (0xaa55)
+#define DOSMBR_SIGNATURE_OFF (0x1fe)
+
+struct dos_partition {
+ u_int8_t dp_flag; /* bootstrap flags */
+ u_int8_t dp_shd; /* starting head */
+ u_int8_t dp_ssect; /* starting sector */
+ u_int8_t dp_scyl; /* starting cylinder */
+ u_int8_t dp_typ; /* partition type (see below) */
+ u_int8_t dp_ehd; /* end head */
+ u_int8_t dp_esect; /* end sector */
+ u_int8_t dp_ecyl; /* end cylinder */
+ u_int32_t dp_start; /* absolute starting sector number */
+ u_int32_t dp_size; /* partition size in sectors */
+};
+
+/* Isolate the relevant bits to get sector and cylinder. */
+#define DPSECT(s) ((s) & 0x3f)
+#define DPCYL(c, s) ((c) + (((s) & 0xc0) << 2))
+
+/* Known DOS partition types. */
+#define DOSPTYP_UNUSED 0x00 /* Unused partition */
+#define DOSPTYP_FAT12 0x01 /* 12-bit FAT */
+#define DOSPTYP_FAT16S 0x04 /* 16-bit FAT, less than 32M */
+#define DOSPTYP_EXTEND 0x05 /* Extended; contains sub-partitions */
+#define DOSPTYP_FAT16B 0x06 /* 16-bit FAT, more than 32M */
+#define DOSPTYP_FAT32 0x0b /* 32-bit FAT */
+#define DOSPTYP_FAT32L 0x0c /* 32-bit FAT, LBA-mapped */
+#define DOSPTYP_FAT16L 0x0e /* 16-bit FAT, LBA-mapped */
+#define DOSPTYP_EXTENDL 0x0f /* Extended, LBA-mapped; (sub-partitions) */
+#define DOSPTYP_ONTRACK 0x54
+#define DOSPTYP_LINUX 0x83 /* That other thing */
+#define DOSPTYP_FREEBSD 0xa5 /* FreeBSD partition type */
+#define DOSPTYP_OPENBSD 0xa6 /* OpenBSD partition type */
+#define DOSPTYP_NETBSD 0xa9 /* NetBSD partition type */
+
+struct dos_mbr {
+ u_int8_t dmbr_boot[DOSPARTOFF];
+ struct dos_partition dmbr_parts[NDOSPART];
+ u_int16_t dmbr_sign;
+} __packed;
+
#ifdef _KERNEL
void diskerr(struct buf *, char *, char *, int, int, struct disklabel *);
void disksort(struct buf *, struct buf *);
u_int dkcksum(struct disklabel *);
-void disklabeltokernlabel(struct disklabel *);
+char *initdisklabel(struct disklabel *);
+char *checkdisklabel(void *, struct disklabel *);
int setdisklabel(struct disklabel *, struct disklabel *, u_int,
struct cpu_disklabel *);
char *readdisklabel(dev_t, void (*)(struct buf *), struct disklabel *,
@@ -408,6 +461,8 @@ int writedisklabel(dev_t, void (*)(struct buf *), struct disklabel *,
struct cpu_disklabel *);
int bounds_check_with_label(struct buf *, struct disklabel *,
struct cpu_disklabel *, int);
+char *readdoslabel(struct buf *, void (*)(struct buf *),
+ struct disklabel *, struct cpu_disklabel *, int *, int *, int);
#ifdef CD9660
int iso_disklabelspoof(dev_t dev, void (*strat)(struct buf *),
struct disklabel *lp);