summaryrefslogtreecommitdiff
path: root/sys/arch/hppa64
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>2007-06-17 00:27:31 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>2007-06-17 00:27:31 +0000
commit81f9f199b5e2a6741e5a9a68d39dd00dadaa4e18 (patch)
treeaa5797e58e49aa5ab1063818eacfa236c19c2adf /sys/arch/hppa64
parent49e31b3e7fe854aae88f968da9911e2a4fd5d878 (diff)
significantly simplified disklabel infrastructure. MBR handling becomes MI
to support hotplug media on most architectures. disklabel setup and verification done using new helper functions. Disklabels must *always* have a correct checksum now. Same code paths are used to learn on-disk location disklabels, to avoid new errors sneaking in. Tested on almost all cases, testing help from todd, kettenis, krw, otto, dlg, robert, gwk, drahn
Diffstat (limited to 'sys/arch/hppa64')
-rw-r--r--sys/arch/hppa64/hppa64/disksubr.c614
-rw-r--r--sys/arch/hppa64/include/disklabel.h46
2 files changed, 164 insertions, 496 deletions
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