diff options
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); |