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