[BACK]Return to disksubr.c CVS log [TXT][DIR] Up to [local] / sys / arch / macppc / macppc

Annotation of sys/arch/macppc/macppc/disksubr.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: disksubr.c,v 1.57 2007/06/20 18:15:46 deraadt Exp $   */
                      2: /*     $NetBSD: disksubr.c,v 1.21 1996/05/03 19:42:03 christos Exp $   */
                      3:
                      4: /*
                      5:  * Copyright (c) 1996 Theo de Raadt
                      6:  * Copyright (c) 1982, 1986, 1988 Regents of the University of California.
                      7:  * All rights reserved.
                      8:  *
                      9:  * Redistribution and use in source and binary forms, with or without
                     10:  * modification, are permitted provided that the following conditions
                     11:  * are met:
                     12:  * 1. Redistributions of source code must retain the above copyright
                     13:  *    notice, this list of conditions and the following disclaimer.
                     14:  * 2. Redistributions in binary form must reproduce the above copyright
                     15:  *    notice, this list of conditions and the following disclaimer in the
                     16:  *    documentation and/or other materials provided with the distribution.
                     17:  * 3. Neither the name of the University nor the names of its contributors
                     18:  *    may be used to endorse or promote products derived from this software
                     19:  *    without specific prior written permission.
                     20:  *
                     21:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     22:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     23:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     24:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     25:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     26:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     27:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     28:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     29:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     30:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     31:  * SUCH DAMAGE.
                     32:  */
                     33:
                     34: #include <sys/param.h>
                     35: #include <sys/systm.h>
                     36: #include <sys/buf.h>
                     37: #include <sys/disklabel.h>
                     38: #include <sys/disk.h>
                     39:
                     40: char   *readdpmelabel(struct buf *, void (*)(struct buf *),
                     41:            struct disklabel *, int *, int);
                     42:
                     43: /*
                     44:  * Attempt to read a disk label from a device
                     45:  * using the indicated strategy routine.
                     46:  * The label must be partly set up before this:
                     47:  * secpercyl, secsize and anything required for a block i/o read
                     48:  * operation in the driver's strategy/start routines
                     49:  * must be filled in before calling us.
                     50:  *
                     51:  * If dos partition table requested, attempt to load it and
                     52:  * find disklabel inside a DOS partition. Return buffer
                     53:  * for use in signalling errors if requested.
                     54:  *
                     55:  * We would like to check if each MBR has a valid DOSMBR_SIGNATURE, but
                     56:  * we cannot because it doesn't always exist. So.. we assume the
                     57:  * MBR is valid.
                     58:  *
                     59:  * Returns null on success and an error string on failure.
                     60:  */
                     61: char *
                     62: readdisklabel(dev_t dev, void (*strat)(struct buf *),
                     63:     struct disklabel *lp, int spoofonly)
                     64: {
                     65:        struct buf *bp = NULL;
                     66:        char *msg;
                     67:
                     68:        if ((msg = initdisklabel(lp)))
                     69:                goto done;
                     70:
                     71:        /* get a buffer and initialize it */
                     72:        bp = geteblk((int)lp->d_secsize);
                     73:        bp->b_dev = dev;
                     74:
                     75:        msg = readdpmelabel(bp, strat, lp, NULL, spoofonly);
                     76:        if (msg == NULL)
                     77:                goto done;
                     78:
                     79:        msg = readdoslabel(bp, strat, lp, NULL, spoofonly);
                     80:        if (msg == NULL)
                     81:                goto done;
                     82:
                     83: #if defined(CD9660)
                     84:        if (iso_disklabelspoof(dev, strat, lp) == 0) {
                     85:                msg = NULL;
                     86:                goto done;
                     87:        }
                     88: #endif
                     89: #if defined(UDF)
                     90:        if (udf_disklabelspoof(dev, strat, lp) == 0) {
                     91:                msg = NULL;
                     92:                goto done;
                     93:        }
                     94: #endif
                     95:
                     96: done:
                     97:        if (bp) {
                     98:                bp->b_flags |= B_INVAL;
                     99:                brelse(bp);
                    100:        }
                    101:        return (msg);
                    102: }
                    103:
                    104: char *
                    105: readdpmelabel(struct buf *bp, void (*strat)(struct buf *),
                    106:     struct disklabel *lp, int *partoffp, int spoofonly)
                    107: {
                    108:        int i, part_cnt, n, hfspartoff = -1;
                    109:        struct part_map_entry *part;
                    110:
                    111:        /* First check for a DPME (HFS) disklabel */
                    112:        bp->b_blkno = 1;
                    113:        bp->b_bcount = lp->d_secsize;
                    114:        bp->b_flags = B_BUSY | B_READ;
                    115:        (*strat)(bp);
                    116:        if (biowait(bp))
                    117:                return ("DPME partition I/O error");
                    118:
                    119:        /* if successful, wander through DPME partition table */
                    120:        part = (struct part_map_entry *)bp->b_data;
                    121:        /* if first partition is not valid, assume not HFS/DPME partitioned */
                    122:        if (part->pmSig != PART_ENTRY_MAGIC)
                    123:                return ("not a DPMI partition");
                    124:        part_cnt = part->pmMapBlkCnt;
                    125:        n = 0;
                    126:        for (i = 0; i < part_cnt; i++) {
                    127:                struct partition *pp = &lp->d_partitions[8+n];
                    128:                char *s;
                    129:
                    130:                bp->b_blkno = 1+i;
                    131:                bp->b_bcount = lp->d_secsize;
                    132:                bp->b_flags = B_BUSY | B_READ;
                    133:                (*strat)(bp);
                    134:                if (biowait(bp))
                    135:                        return ("DPME partition I/O error");
                    136:
                    137:                part = (struct part_map_entry *)bp->b_data;
                    138:                /* toupper the string, in case caps are different... */
                    139:                for (s = part->pmPartType; *s; s++)
                    140:                        if ((*s >= 'a') && (*s <= 'z'))
                    141:                                *s = (*s - 'a' + 'A');
                    142:
                    143:                if (strcmp(part->pmPartType, PART_TYPE_OPENBSD) == 0)
                    144:                        hfspartoff = part->pmPyPartStart - LABELSECTOR;
                    145:
                    146:                /* currently we ignore all but HFS partitions */
                    147:                if (strcmp(part->pmPartType, PART_TYPE_MAC) == 0) {
                    148:                        DL_SETPOFFSET(pp, part->pmPyPartStart);
                    149:                        DL_SETPSIZE(pp, part->pmPartBlkCnt);
                    150:                        pp->p_fstype = FS_HFS;
                    151:                        n++;
                    152:                }
                    153:        }
                    154:        lp->d_npartitions = MAXPARTITIONS;
                    155:
                    156:        if (hfspartoff == -1)
                    157:                return ("no OpenBSD parition inside DPME label");
                    158:
                    159:        if (partoffp)
                    160:                *partoffp = hfspartoff;
                    161:
                    162:        if (spoofonly)
                    163:                return (NULL);
                    164:
                    165:        /* next, dig out disk label */
                    166:        bp->b_blkno = hfspartoff + LABELSECTOR;
                    167:        bp->b_bcount = lp->d_secsize;
                    168:        bp->b_flags = B_BUSY | B_READ;
                    169:        (*strat)(bp);
                    170:        if (biowait(bp))
                    171:                return("disk label I/O error");
                    172:
                    173:        return checkdisklabel(bp->b_data + LABELOFFSET, lp);
                    174: }
                    175:
                    176: /*
                    177:  * Write disk label back to device after modification.
                    178:  */
                    179: int
                    180: writedisklabel(dev_t dev, void (*strat)(struct buf *), struct disklabel *lp)
                    181: {
                    182:        int error = EIO, partoff = -1;
                    183:        struct disklabel *dlp;
                    184:        struct buf *bp = NULL;
                    185:
                    186:        /* get a buffer and initialize it */
                    187:        bp = geteblk((int)lp->d_secsize);
                    188:        bp->b_dev = dev;
                    189:
                    190:        if (readdpmelabel(bp, strat, lp, &partoff, 1) != NULL &&
                    191:            readdoslabel(bp, strat, lp, &partoff, 1) != NULL)
                    192:                goto done;
                    193:
                    194:        /* Read it in, slap the new label in, and write it back out */
                    195:        bp->b_blkno = partoff + LABELSECTOR;
                    196:        bp->b_bcount = lp->d_secsize;
                    197:        bp->b_flags = B_BUSY | B_READ;
                    198:        (*strat)(bp);
                    199:        if ((error = biowait(bp)) != 0)
                    200:                goto done;
                    201:
                    202:        dlp = (struct disklabel *)(bp->b_data + LABELOFFSET);
                    203:        *dlp = *lp;
                    204:        bp->b_flags = B_BUSY | B_WRITE;
                    205:        (*strat)(bp);
                    206:        error = biowait(bp);
                    207:
                    208: done:
                    209:        if (bp) {
                    210:                bp->b_flags |= B_INVAL;
                    211:                brelse(bp);
                    212:        }
                    213:        return (error);
                    214: }

CVSweb