diff options
author | Theo de Raadt <deraadt@cvs.openbsd.org> | 2007-06-17 00:27:31 +0000 |
---|---|---|
committer | Theo de Raadt <deraadt@cvs.openbsd.org> | 2007-06-17 00:27:31 +0000 |
commit | 81f9f199b5e2a6741e5a9a68d39dd00dadaa4e18 (patch) | |
tree | aa5797e58e49aa5ab1063818eacfa236c19c2adf /sys/arch/hppa64 | |
parent | 49e31b3e7fe854aae88f968da9911e2a4fd5d878 (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.c | 614 | ||||
-rw-r--r-- | sys/arch/hppa64/include/disklabel.h | 46 |
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 |