| @@ -1,891 +1,891 @@ | | | @@ -1,891 +1,891 @@ |
1 | /* $NetBSD: disksubr.c,v 1.26 2015/07/04 06:14:41 maxv Exp $ */ | | 1 | /* $NetBSD: disksubr.c,v 1.27 2017/03/05 22:14:51 mrg Exp $ */ |
2 | | | 2 | |
3 | /*- | | 3 | /*- |
4 | * Copyright (c) 2010 Frank Wille. | | 4 | * Copyright (c) 2010 Frank Wille. |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * Written by Frank Wille for The NetBSD Project. | | 7 | * Written by Frank Wille for The NetBSD Project. |
8 | * | | 8 | * |
9 | * Redistribution and use in source and binary forms, with or without | | 9 | * Redistribution and use in source and binary forms, with or without |
10 | * modification, are permitted provided that the following conditions | | 10 | * modification, are permitted provided that the following conditions |
11 | * are met: | | 11 | * are met: |
12 | * 1. Redistributions of source code must retain the above copyright | | 12 | * 1. Redistributions of source code must retain the above copyright |
13 | * notice, this list of conditions and the following disclaimer. | | 13 | * notice, this list of conditions and the following disclaimer. |
14 | * 2. Redistributions in binary form must reproduce the above copyright | | 14 | * 2. Redistributions in binary form must reproduce the above copyright |
15 | * notice, this list of conditions and the following disclaimer in the | | 15 | * notice, this list of conditions and the following disclaimer in the |
16 | * documentation and/or other materials provided with the distribution. | | 16 | * documentation and/or other materials provided with the distribution. |
17 | * | | 17 | * |
18 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS | | 18 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS |
19 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | | 19 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
20 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | | 20 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
21 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | | 21 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS |
22 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | | 22 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | | 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | | 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
25 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | | 25 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
26 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | | 26 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
27 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | | 27 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
28 | * POSSIBILITY OF SUCH DAMAGE. | | 28 | * POSSIBILITY OF SUCH DAMAGE. |
29 | */ | | 29 | */ |
30 | | | 30 | |
31 | /* | | 31 | /* |
32 | * Copyright (c) 1994 Christian E. Hopps | | 32 | * Copyright (c) 1994 Christian E. Hopps |
33 | * | | 33 | * |
34 | * Redistribution and use in source and binary forms, with or without | | 34 | * Redistribution and use in source and binary forms, with or without |
35 | * modification, are permitted provided that the following conditions | | 35 | * modification, are permitted provided that the following conditions |
36 | * are met: | | 36 | * are met: |
37 | * 1. Redistributions of source code must retain the above copyright | | 37 | * 1. Redistributions of source code must retain the above copyright |
38 | * notice, this list of conditions and the following disclaimer. | | 38 | * notice, this list of conditions and the following disclaimer. |
39 | * 2. Redistributions in binary form must reproduce the above copyright | | 39 | * 2. Redistributions in binary form must reproduce the above copyright |
40 | * notice, this list of conditions and the following disclaimer in the | | 40 | * notice, this list of conditions and the following disclaimer in the |
41 | * documentation and/or other materials provided with the distribution. | | 41 | * documentation and/or other materials provided with the distribution. |
42 | * 3. All advertising materials mentioning features or use of this software | | 42 | * 3. All advertising materials mentioning features or use of this software |
43 | * must display the following acknowledgement: | | 43 | * must display the following acknowledgement: |
44 | * This product includes software developed by the University of | | 44 | * This product includes software developed by the University of |
45 | * California, Berkeley and its contributors. | | 45 | * California, Berkeley and its contributors. |
46 | * 4. Neither the name of the University nor the names of its contributors | | 46 | * 4. Neither the name of the University nor the names of its contributors |
47 | * may be used to endorse or promote products derived from this software | | 47 | * may be used to endorse or promote products derived from this software |
48 | * without specific prior written permission. | | 48 | * without specific prior written permission. |
49 | * | | 49 | * |
50 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | | 50 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
51 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | | 51 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
52 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | | 52 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
53 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | | 53 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
54 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | | 54 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
55 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | | 55 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
56 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | | 56 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
57 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | | 57 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
58 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | | 58 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
59 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | | 59 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
60 | * SUCH DAMAGE. | | 60 | * SUCH DAMAGE. |
61 | * | | 61 | * |
62 | * @(#)ufs_disksubr.c 7.16 (Berkeley) 5/4/91 | | 62 | * @(#)ufs_disksubr.c 7.16 (Berkeley) 5/4/91 |
63 | */ | | 63 | */ |
64 | | | 64 | |
65 | #include <sys/cdefs.h> | | 65 | #include <sys/cdefs.h> |
66 | __KERNEL_RCSID(0, "$NetBSD: disksubr.c,v 1.26 2015/07/04 06:14:41 maxv Exp $"); | | 66 | __KERNEL_RCSID(0, "$NetBSD: disksubr.c,v 1.27 2017/03/05 22:14:51 mrg Exp $"); |
67 | | | 67 | |
68 | #include "opt_disksubr.h" | | 68 | #include "opt_disksubr.h" |
69 | | | 69 | |
70 | #include <sys/buf.h> | | 70 | #include <sys/buf.h> |
71 | #include <sys/disklabel.h> | | 71 | #include <sys/disklabel.h> |
72 | #include <sys/bswap.h> | | 72 | #include <sys/bswap.h> |
73 | | | 73 | |
74 | /* | | 74 | /* |
75 | * In /usr/src/sys/dev/scsipi/sd.c, routine sdstart() adjusts the | | 75 | * In /usr/src/sys/dev/scsipi/sd.c, routine sdstart() adjusts the |
76 | * block numbers, it changes from DEV_BSIZE units to physical units: | | 76 | * block numbers, it changes from DEV_BSIZE units to physical units: |
77 | * blkno = bp->b_blkno / (lp->d_secsize / DEV_BSIZE); | | 77 | * blkno = bp->b_blkno / (lp->d_secsize / DEV_BSIZE); |
78 | * As long as media with sector sizes of 512 bytes are used, this | | 78 | * As long as media with sector sizes of 512 bytes are used, this |
79 | * doesn't matter (divide by 1), but for successful usage of media with | | 79 | * doesn't matter (divide by 1), but for successful usage of media with |
80 | * greater sector sizes (e.g. 640MB MO-media with 2048 bytes/sector) | | 80 | * greater sector sizes (e.g. 640MB MO-media with 2048 bytes/sector) |
81 | * we must multiply block numbers with (lp->d_secsize / DEV_BSIZE) | | 81 | * we must multiply block numbers with (lp->d_secsize / DEV_BSIZE) |
82 | * to keep "unchanged" physical block numbers. | | 82 | * to keep "unchanged" physical block numbers. |
83 | */ | | 83 | */ |
84 | #define SD_C_ADJUSTS_NR | | 84 | #define SD_C_ADJUSTS_NR |
85 | | | 85 | |
86 | #define baddr(bp) (void *)((bp)->b_data) | | 86 | #define baddr(bp) (void *)((bp)->b_data) |
87 | | | 87 | |
88 | static const char *read_dos_label(dev_t, void (*)(struct buf *), | | 88 | static const char *read_dos_label(dev_t, void (*)(struct buf *), |
89 | struct disklabel *, struct cpu_disklabel *); | | 89 | struct disklabel *, struct cpu_disklabel *); |
90 | static int getFreeLabelEntry(struct disklabel *); | | 90 | static int getFreeLabelEntry(struct disklabel *); |
91 | static int read_netbsd_label(dev_t, void (*)(struct buf *), struct disklabel *, | | 91 | static int read_netbsd_label(dev_t, void (*)(struct buf *), struct disklabel *, |
92 | struct cpu_disklabel *); | | 92 | struct cpu_disklabel *); |
93 | #ifdef RDB_PART | | 93 | #ifdef RDB_PART |
94 | static const char *read_rdb_label(dev_t, void (*)(struct buf *), | | 94 | static const char *read_rdb_label(dev_t, void (*)(struct buf *), |
95 | struct disklabel *, struct cpu_disklabel *); | | 95 | struct disklabel *, struct cpu_disklabel *); |
96 | static u_long rdbchksum(void *); | | 96 | static u_long rdbchksum(void *); |
97 | static struct adostype getadostype(u_long); | | 97 | static struct adostype getadostype(u_long); |
98 | #endif | | 98 | #endif |
99 | | | 99 | |
100 | /* | | 100 | /* |
101 | * Read MBR partition table. | | 101 | * Read MBR partition table. |
102 | * | | 102 | * |
103 | * XXX - | | 103 | * XXX - |
104 | * Since FFS is endian sensitive, we pay no effort in attempting to | | 104 | * Since FFS is endian sensitive, we pay no effort in attempting to |
105 | * dig up *BSD/i386 disk labels that may be present on the disk. | | 105 | * dig up *BSD/i386 disk labels that may be present on the disk. |
106 | * Hence anything but DOS partitions is treated as unknown FS type, but | | 106 | * Hence anything but DOS partitions is treated as unknown FS type, but |
107 | * this should suffice to mount_msdos Zip and other removable media. | | 107 | * this should suffice to mount_msdos Zip and other removable media. |
108 | */ | | 108 | */ |
109 | static const char * | | 109 | static const char * |
110 | read_dos_label(dev_t dev, void (*strat)(struct buf *), struct disklabel *lp, | | 110 | read_dos_label(dev_t dev, void (*strat)(struct buf *), struct disklabel *lp, |
111 | struct cpu_disklabel *osdep) | | 111 | struct cpu_disklabel *osdep) |
112 | { | | 112 | { |
113 | struct buf *bp; | | 113 | struct buf *bp; |
114 | struct mbr_partition *bsdp, *dp; | | 114 | struct mbr_partition *bsdp, *dp; |
115 | const char *msg = NULL; | | 115 | const char *msg = NULL; |
116 | int i, slot, maxslot = 0; | | 116 | int i, slot, maxslot = 0; |
117 | u_int32_t bsdpartoff; | | 117 | u_int32_t bsdpartoff; |
118 | | | 118 | |
119 | /* get a buffer and initialize it */ | | 119 | /* get a buffer and initialize it */ |
120 | bp = geteblk((int)lp->d_secsize); | | 120 | bp = geteblk((int)lp->d_secsize); |
121 | bp->b_dev = dev; | | 121 | bp->b_dev = dev; |
122 | | | 122 | |
123 | /* read master boot record */ | | 123 | /* read master boot record */ |
124 | bp->b_blkno = MBR_BBSECTOR; | | 124 | bp->b_blkno = MBR_BBSECTOR; |
125 | bp->b_bcount = lp->d_secsize; | | 125 | bp->b_bcount = lp->d_secsize; |
126 | bp->b_flags |= B_READ; | | 126 | bp->b_flags |= B_READ; |
127 | bp->b_cylinder = MBR_BBSECTOR / lp->d_secpercyl; | | 127 | bp->b_cylinder = MBR_BBSECTOR / lp->d_secpercyl; |
128 | (*strat)(bp); | | 128 | (*strat)(bp); |
129 | | | 129 | |
130 | bsdpartoff = 0; | | 130 | bsdpartoff = 0; |
131 | | | 131 | |
132 | /* if successful, wander through dos partition table */ | | 132 | /* if successful, wander through dos partition table */ |
133 | if (biowait(bp)) { | | 133 | if (biowait(bp)) { |
134 | msg = "dos partition I/O error"; | | 134 | msg = "dos partition I/O error"; |
135 | goto done; | | 135 | goto done; |
136 | } | | 136 | } |
137 | /* XXX */ | | 137 | /* XXX */ |
138 | dp = (struct mbr_partition *)((char *)bp->b_data + MBR_PART_OFFSET); | | 138 | dp = (struct mbr_partition *)((char *)bp->b_data + MBR_PART_OFFSET); |
139 | bsdp = NULL; | | 139 | bsdp = NULL; |
140 | for (i = 0; i < MBR_PART_COUNT; i++, dp++) { | | 140 | for (i = 0; i < MBR_PART_COUNT; i++, dp++) { |
141 | switch (dp->mbrp_type) { | | 141 | switch (dp->mbrp_type) { |
142 | case MBR_PTYPE_NETBSD: | | 142 | case MBR_PTYPE_NETBSD: |
143 | bsdp = dp; | | 143 | bsdp = dp; |
144 | break; | | 144 | break; |
145 | case MBR_PTYPE_OPENBSD: | | 145 | case MBR_PTYPE_OPENBSD: |
146 | case MBR_PTYPE_386BSD: | | 146 | case MBR_PTYPE_386BSD: |
147 | if (!bsdp) | | 147 | if (!bsdp) |
148 | bsdp = dp; | | 148 | bsdp = dp; |
149 | break; | | 149 | break; |
150 | } | | 150 | } |
151 | } | | 151 | } |
152 | if (!bsdp) { | | 152 | if (!bsdp) { |
153 | /* generate fake disklabel */ | | 153 | /* generate fake disklabel */ |
154 | dp = (struct mbr_partition *)((char *)bp->b_data + | | 154 | dp = (struct mbr_partition *)((char *)bp->b_data + |
155 | MBR_PART_OFFSET); | | 155 | MBR_PART_OFFSET); |
156 | for (i = 0; i < MBR_PART_COUNT; i++, dp++) { | | 156 | for (i = 0; i < MBR_PART_COUNT; i++, dp++) { |
157 | if (!dp->mbrp_type) | | 157 | if (!dp->mbrp_type) |
158 | continue; | | 158 | continue; |
159 | slot = getFreeLabelEntry(lp); | | 159 | slot = getFreeLabelEntry(lp); |
160 | if (slot < 0) | | 160 | if (slot < 0) |
161 | break; | | 161 | break; |
162 | if (slot > maxslot) | | 162 | if (slot > maxslot) |
163 | maxslot = slot; | | 163 | maxslot = slot; |
164 | | | 164 | |
165 | lp->d_partitions[slot].p_offset = | | 165 | lp->d_partitions[slot].p_offset = |
166 | bswap32(dp->mbrp_start); | | 166 | bswap32(dp->mbrp_start); |
167 | lp->d_partitions[slot].p_size = bswap32(dp->mbrp_size); | | 167 | lp->d_partitions[slot].p_size = bswap32(dp->mbrp_size); |
168 | | | 168 | |
169 | switch (dp->mbrp_type) { | | 169 | switch (dp->mbrp_type) { |
170 | case MBR_PTYPE_FAT12: | | 170 | case MBR_PTYPE_FAT12: |
171 | case MBR_PTYPE_FAT16S: | | 171 | case MBR_PTYPE_FAT16S: |
172 | case MBR_PTYPE_FAT16B: | | 172 | case MBR_PTYPE_FAT16B: |
173 | case MBR_PTYPE_FAT32: | | 173 | case MBR_PTYPE_FAT32: |
174 | case MBR_PTYPE_FAT32L: | | 174 | case MBR_PTYPE_FAT32L: |
175 | case MBR_PTYPE_FAT16L: | | 175 | case MBR_PTYPE_FAT16L: |
176 | lp->d_partitions[slot].p_fstype = FS_MSDOS; | | 176 | lp->d_partitions[slot].p_fstype = FS_MSDOS; |
177 | break; | | 177 | break; |
178 | default: | | 178 | default: |
179 | lp->d_partitions[slot].p_fstype = FS_OTHER; | | 179 | lp->d_partitions[slot].p_fstype = FS_OTHER; |
180 | break; | | 180 | break; |
181 | } | | 181 | } |
182 | } | | 182 | } |
183 | msg = "no NetBSD disk label"; | | 183 | msg = "no NetBSD disk label"; |
184 | } else { | | 184 | } else { |
185 | /* NetBSD partition on MBR */ | | 185 | /* NetBSD partition on MBR */ |
186 | bsdpartoff = bswap32(bsdp->mbrp_start); | | 186 | bsdpartoff = bswap32(bsdp->mbrp_start); |
187 | | | 187 | |
188 | lp->d_partitions[2].p_size = bswap32(bsdp->mbrp_size); | | 188 | lp->d_partitions[2].p_size = bswap32(bsdp->mbrp_size); |
189 | lp->d_partitions[2].p_offset = bswap32(bsdp->mbrp_start); | | 189 | lp->d_partitions[2].p_offset = bswap32(bsdp->mbrp_start); |
190 | if (2 > maxslot) | | 190 | if (2 > maxslot) |
191 | maxslot = 2; | | 191 | maxslot = 2; |
192 | /* read in disklabel, blkno + 1 for DOS disklabel offset */ | | 192 | /* read in disklabel, blkno + 1 for DOS disklabel offset */ |
193 | osdep->cd_labelsector = bsdpartoff + LABELSECTOR; | | 193 | osdep->cd_labelsector = bsdpartoff + LABELSECTOR; |
194 | osdep->cd_labeloffset = LABELOFFSET; | | 194 | osdep->cd_labeloffset = LABELOFFSET; |
195 | if (read_netbsd_label(dev, strat, lp, osdep)) | | 195 | if (read_netbsd_label(dev, strat, lp, osdep)) |
196 | goto done; | | 196 | goto done; |
197 | msg = "no NetBSD disk label"; | | 197 | msg = "no NetBSD disk label"; |
198 | } | | 198 | } |
199 | | | 199 | |
200 | lp->d_npartitions = ((maxslot >= RAW_PART) ? maxslot : RAW_PART) + 1; | | 200 | lp->d_npartitions = ((maxslot >= RAW_PART) ? maxslot : RAW_PART) + 1; |
201 | | | 201 | |
202 | done: | | 202 | done: |
203 | brelse(bp, 0); | | 203 | brelse(bp, 0); |
204 | return msg; | | 204 | return msg; |
205 | } | | 205 | } |
206 | | | 206 | |
207 | /* | | 207 | /* |
208 | * Find an entry in the disk label that is unused and return it | | 208 | * Find an entry in the disk label that is unused and return it |
209 | * or -1 if no entry | | 209 | * or -1 if no entry |
210 | */ | | 210 | */ |
211 | static int | | 211 | static int |
212 | getFreeLabelEntry(struct disklabel *lp) | | 212 | getFreeLabelEntry(struct disklabel *lp) |
213 | { | | 213 | { |
214 | int i; | | 214 | int i; |
215 | | | 215 | |
216 | for (i = 0; i < MAXPARTITIONS; i++) { | | 216 | for (i = 0; i < MAXPARTITIONS; i++) { |
217 | if ((i != RAW_PART) | | 217 | if ((i != RAW_PART) |
218 | && (lp->d_partitions[i].p_fstype == FS_UNUSED)) | | 218 | && (lp->d_partitions[i].p_fstype == FS_UNUSED)) |
219 | return i; | | 219 | return i; |
220 | } | | 220 | } |
221 | return -1; | | 221 | return -1; |
222 | } | | 222 | } |
223 | | | 223 | |
224 | #ifdef RDB_PART | | 224 | #ifdef RDB_PART |
225 | /* | | 225 | /* |
226 | * Read an Amiga RDB partition table. | | 226 | * Read an Amiga RDB partition table. |
227 | */ | | 227 | */ |
228 | static const char * | | 228 | static const char * |
229 | read_rdb_label(dev_t dev, void (*strat)(struct buf *), struct disklabel *lp, | | 229 | read_rdb_label(dev_t dev, void (*strat)(struct buf *), struct disklabel *lp, |
230 | struct cpu_disklabel *osdep) | | 230 | struct cpu_disklabel *osdep) |
231 | { | | 231 | { |
232 | struct adostype adt; | | 232 | struct adostype adt; |
233 | struct buf *bp; | | 233 | struct buf *bp; |
234 | struct partition *pp = NULL; | | 234 | struct partition *pp = NULL; |
235 | struct partblock *pbp; | | 235 | struct partblock *pbp; |
236 | struct rdblock *rbp; | | 236 | struct rdblock *rbp; |
237 | const char *msg; | | 237 | const char *msg; |
238 | char *bcpls, *s, bcpli; | | 238 | char *bcpls, *s, bcpli; |
239 | int cindex, i, nopname; | | 239 | int cindex, i, nopname; |
240 | u_long nextb; | | 240 | u_long nextb; |
241 | | | 241 | |
242 | osdep->rdblock = RDBNULL; | | 242 | osdep->rdblock = RDBNULL; |
243 | lp->d_npartitions = RAW_PART + 1; | | 243 | lp->d_npartitions = RAW_PART + 1; |
244 | | | 244 | |
245 | if (lp->d_partitions[RAW_PART].p_size == 0) | | 245 | if (lp->d_partitions[RAW_PART].p_size == 0) |
246 | lp->d_partitions[RAW_PART].p_size = 0x1fffffff; | | 246 | lp->d_partitions[RAW_PART].p_size = 0x1fffffff; |
247 | lp->d_partitions[RAW_PART].p_offset = 0; | | 247 | lp->d_partitions[RAW_PART].p_offset = 0; |
248 | /* if no 'a' partition, default is to copy from 'c' as BSDFFS */ | | 248 | /* if no 'a' partition, default is to copy from 'c' as BSDFFS */ |
249 | if (lp->d_partitions[0].p_size == 0) { | | 249 | if (lp->d_partitions[0].p_size == 0) { |
250 | lp->d_partitions[0].p_size = lp->d_partitions[RAW_PART].p_size; | | 250 | lp->d_partitions[0].p_size = lp->d_partitions[RAW_PART].p_size; |
251 | lp->d_partitions[0].p_offset = 0; | | 251 | lp->d_partitions[0].p_offset = 0; |
252 | lp->d_partitions[0].p_fstype = FS_BSDFFS; | | 252 | lp->d_partitions[0].p_fstype = FS_BSDFFS; |
253 | lp->d_partitions[0].p_fsize = 1024; | | 253 | lp->d_partitions[0].p_fsize = 1024; |
254 | lp->d_partitions[0].p_frag = 8; | | 254 | lp->d_partitions[0].p_frag = 8; |
255 | lp->d_partitions[0].p_cpg = 0; | | 255 | lp->d_partitions[0].p_cpg = 0; |
256 | } | | 256 | } |
257 | | | 257 | |
258 | /* obtain buffer to probe drive with */ | | 258 | /* obtain buffer to probe drive with */ |
259 | bp = geteblk((int)lp->d_secsize); | | 259 | bp = geteblk((int)lp->d_secsize); |
260 | | | 260 | |
261 | /* | | 261 | /* |
262 | * request no partition relocation by driver on I/O operations | | 262 | * request no partition relocation by driver on I/O operations |
263 | */ | | 263 | */ |
264 | #ifdef _KERNEL | | 264 | #ifdef _KERNEL |
265 | bp->b_dev = MAKEDISKDEV(major(dev), DISKUNIT(dev), RAW_PART); | | 265 | bp->b_dev = MAKEDISKDEV(major(dev), DISKUNIT(dev), RAW_PART); |
266 | #else | | 266 | #else |
267 | bp->b_dev = dev; | | 267 | bp->b_dev = dev; |
268 | #endif | | 268 | #endif |
269 | msg = NULL; | | 269 | msg = NULL; |
270 | | | 270 | |
271 | /* | | 271 | /* |
272 | * find the RDB block | | 272 | * find the RDB block |
273 | */ | | 273 | */ |
274 | for (nextb = 0; nextb < RDB_MAXBLOCKS; nextb++) { | | 274 | for (nextb = 0; nextb < RDB_MAXBLOCKS; nextb++) { |
275 | bp->b_blkno = nextb; | | 275 | bp->b_blkno = nextb; |
276 | bp->b_cylinder = bp->b_blkno / lp->d_secpercyl; | | 276 | bp->b_cylinder = bp->b_blkno / lp->d_secpercyl; |
277 | bp->b_bcount = lp->d_secsize; | | 277 | bp->b_bcount = lp->d_secsize; |
278 | bp->b_oflags &= ~(BO_DONE); | | 278 | bp->b_oflags &= ~(BO_DONE); |
279 | bp->b_flags |= B_READ; | | 279 | bp->b_flags |= B_READ; |
280 | #ifdef SD_C_ADJUSTS_NR | | 280 | #ifdef SD_C_ADJUSTS_NR |
281 | bp->b_blkno *= (lp->d_secsize / DEV_BSIZE); | | 281 | bp->b_blkno *= (lp->d_secsize / DEV_BSIZE); |
282 | #endif | | 282 | #endif |
283 | (*strat)(bp); | | 283 | (*strat)(bp); |
284 | | | 284 | |
285 | if (biowait(bp)) { | | 285 | if (biowait(bp)) { |
286 | msg = "rdb scan I/O error"; | | 286 | msg = "rdb scan I/O error"; |
287 | goto done; | | 287 | goto done; |
288 | } | | 288 | } |
289 | rbp = baddr(bp); | | 289 | rbp = baddr(bp); |
290 | if (rbp->id == RDBLOCK_ID) { | | 290 | if (rbp->id == RDBLOCK_ID) { |
291 | if (rdbchksum(rbp) == 0) | | 291 | if (rdbchksum(rbp) == 0) |
292 | break; | | 292 | break; |
293 | else | | 293 | else |
294 | msg = "rdb bad checksum"; | | 294 | msg = "rdb bad checksum"; |
295 | } | | 295 | } |
296 | } | | 296 | } |
297 | | | 297 | |
298 | if (nextb == RDB_MAXBLOCKS) { | | 298 | if (nextb == RDB_MAXBLOCKS) { |
299 | if (msg == NULL) | | 299 | if (msg == NULL) |
300 | msg = "no disk label"; | | 300 | msg = "no disk label"; |
301 | goto done; | | 301 | goto done; |
302 | } else if (msg != NULL) | | 302 | } else if (msg != NULL) |
303 | /* | | 303 | /* |
304 | * maybe we found an invalid one before a valid. | | 304 | * maybe we found an invalid one before a valid. |
305 | * clear err. | | 305 | * clear err. |
306 | */ | | 306 | */ |
307 | msg = NULL; | | 307 | msg = NULL; |
308 | | | 308 | |
309 | osdep->rdblock = nextb; | | 309 | osdep->rdblock = nextb; |
310 | | | 310 | |
311 | /* RDB present, clear disklabel partition table before doing PART blks */ | | 311 | /* RDB present, clear disklabel partition table before doing PART blks */ |
312 | for (i = 0; i < MAXPARTITIONS; i++) { | | 312 | for (i = 0; i < MAXPARTITIONS; i++) { |
313 | osdep->pbindex[i] = -1; | | 313 | osdep->pbindex[i] = -1; |
314 | osdep->pblist[i] = RDBNULL; | | 314 | osdep->pblist[i] = RDBNULL; |
315 | if (i == RAW_PART) | | 315 | if (i == RAW_PART) |
316 | continue; | | 316 | continue; |
317 | lp->d_partitions[i].p_size = 0; | | 317 | lp->d_partitions[i].p_size = 0; |
318 | lp->d_partitions[i].p_offset = 0; | | 318 | lp->d_partitions[i].p_offset = 0; |
319 | } | | 319 | } |
320 | | | 320 | |
321 | lp->d_secsize = rbp->nbytes; | | 321 | lp->d_secsize = rbp->nbytes; |
322 | lp->d_nsectors = rbp->nsectors; | | 322 | lp->d_nsectors = rbp->nsectors; |
323 | lp->d_ntracks = rbp->nheads; | | 323 | lp->d_ntracks = rbp->nheads; |
324 | /* | | 324 | /* |
325 | * should be rdb->ncylinders however this is a bogus value | | 325 | * should be rdb->ncylinders however this is a bogus value |
326 | * sometimes it seems | | 326 | * sometimes it seems |
327 | */ | | 327 | */ |
328 | if (rbp->highcyl == 0) | | 328 | if (rbp->highcyl == 0) |
329 | lp->d_ncylinders = rbp->ncylinders; | | 329 | lp->d_ncylinders = rbp->ncylinders; |
330 | else | | 330 | else |
331 | lp->d_ncylinders = rbp->highcyl + 1; | | 331 | lp->d_ncylinders = rbp->highcyl + 1; |
332 | /* | | 332 | /* |
333 | * I also don't trust rdb->secpercyl | | 333 | * I also don't trust rdb->secpercyl |
334 | */ | | 334 | */ |
335 | lp->d_secpercyl = min(rbp->secpercyl, lp->d_nsectors * lp->d_ntracks); | | 335 | lp->d_secpercyl = min(rbp->secpercyl, lp->d_nsectors * lp->d_ntracks); |
336 | if (lp->d_secpercyl == 0) | | 336 | if (lp->d_secpercyl == 0) |
337 | lp->d_secpercyl = lp->d_nsectors * lp->d_ntracks; | | 337 | lp->d_secpercyl = lp->d_nsectors * lp->d_ntracks; |
338 | #ifdef DIAGNOSTIC | | 338 | #ifdef DIAGNOSTIC |
339 | if (lp->d_ncylinders != rbp->ncylinders) | | 339 | if (lp->d_ncylinders != rbp->ncylinders) |
340 | printf("warning found rdb->ncylinders(%ld) != " | | 340 | printf("warning found rdb->ncylinders(%u) != " |
341 | "rdb->highcyl(%ld) + 1\n", rbp->ncylinders, | | 341 | "rdb->highcyl(%u) + 1\n", rbp->ncylinders, |
342 | rbp->highcyl); | | 342 | rbp->highcyl); |
343 | if (lp->d_nsectors * lp->d_ntracks != rbp->secpercyl) | | 343 | if (lp->d_nsectors * lp->d_ntracks != rbp->secpercyl) |
344 | printf("warning found rdb->secpercyl(%ld) != " | | 344 | printf("warning found rdb->secpercyl(%u) != " |
345 | "rdb->nsectors(%ld) * rdb->nheads(%ld)\n", rbp->secpercyl, | | 345 | "rdb->nsectors(%u) * rdb->nheads(%u)\n", rbp->secpercyl, |
346 | rbp->nsectors, rbp->nheads); | | 346 | rbp->nsectors, rbp->nheads); |
347 | #endif | | 347 | #endif |
348 | lp->d_sparespercyl = | | 348 | lp->d_sparespercyl = |
349 | max(rbp->secpercyl, lp->d_nsectors * lp->d_ntracks) | | 349 | max(rbp->secpercyl, lp->d_nsectors * lp->d_ntracks) |
350 | - lp->d_secpercyl; | | 350 | - lp->d_secpercyl; |
351 | if (lp->d_sparespercyl == 0) | | 351 | if (lp->d_sparespercyl == 0) |
352 | lp->d_sparespertrack = 0; | | 352 | lp->d_sparespertrack = 0; |
353 | else { | | 353 | else { |
354 | lp->d_sparespertrack = lp->d_sparespercyl / lp->d_ntracks; | | 354 | lp->d_sparespertrack = lp->d_sparespercyl / lp->d_ntracks; |
355 | #ifdef DIAGNOSTIC | | 355 | #ifdef DIAGNOSTIC |
356 | if (lp->d_sparespercyl % lp->d_ntracks) | | 356 | if (lp->d_sparespercyl % lp->d_ntracks) |
357 | printf("warning lp->d_sparespercyl(%d) not multiple " | | 357 | printf("warning lp->d_sparespercyl(%u) not multiple " |
358 | "of lp->d_ntracks(%d)\n", lp->d_sparespercyl, | | 358 | "of lp->d_ntracks(%u)\n", lp->d_sparespercyl, |
359 | lp->d_ntracks); | | 359 | lp->d_ntracks); |
360 | #endif | | 360 | #endif |
361 | } | | 361 | } |
362 | | | 362 | |
363 | lp->d_secperunit = lp->d_secpercyl * lp->d_ncylinders; | | 363 | lp->d_secperunit = lp->d_secpercyl * lp->d_ncylinders; |
364 | lp->d_acylinders = rbp->ncylinders - (rbp->highcyl - rbp->lowcyl + 1); | | 364 | lp->d_acylinders = rbp->ncylinders - (rbp->highcyl - rbp->lowcyl + 1); |
365 | lp->d_rpm = 3600; /* good guess I suppose. */ | | 365 | lp->d_rpm = 3600; /* good guess I suppose. */ |
366 | lp->d_interleave = rbp->interleave; | | 366 | lp->d_interleave = rbp->interleave; |
367 | lp->d_headswitch = lp->d_flags = lp->d_trackskew = lp->d_cylskew = 0; | | 367 | lp->d_headswitch = lp->d_flags = lp->d_trackskew = lp->d_cylskew = 0; |
368 | lp->d_trkseek = /* rbp->steprate */ 0; | | 368 | lp->d_trkseek = /* rbp->steprate */ 0; |
369 | | | 369 | |
370 | /* | | 370 | /* |
371 | * raw partition gets the entire disk | | 371 | * raw partition gets the entire disk |
372 | */ | | 372 | */ |
373 | lp->d_partitions[RAW_PART].p_size = rbp->ncylinders * lp->d_secpercyl; | | 373 | lp->d_partitions[RAW_PART].p_size = rbp->ncylinders * lp->d_secpercyl; |
374 | | | 374 | |
375 | /* | | 375 | /* |
376 | * scan for partition blocks | | 376 | * scan for partition blocks |
377 | */ | | 377 | */ |
378 | nopname = 1; | | 378 | nopname = 1; |
379 | cindex = 0; | | 379 | cindex = 0; |
380 | for (nextb = rbp->partbhead; nextb != RDBNULL; nextb = pbp->next) { | | 380 | for (nextb = rbp->partbhead; nextb != RDBNULL; nextb = pbp->next) { |
381 | bp->b_blkno = nextb; | | 381 | bp->b_blkno = nextb; |
382 | bp->b_cylinder = bp->b_blkno / lp->d_secpercyl; | | 382 | bp->b_cylinder = bp->b_blkno / lp->d_secpercyl; |
383 | bp->b_bcount = lp->d_secsize; | | 383 | bp->b_bcount = lp->d_secsize; |
384 | bp->b_oflags &= ~(BO_DONE); | | 384 | bp->b_oflags &= ~(BO_DONE); |
385 | bp->b_flags |= B_READ; | | 385 | bp->b_flags |= B_READ; |
386 | #ifdef SD_C_ADJUSTS_NR | | 386 | #ifdef SD_C_ADJUSTS_NR |
387 | bp->b_blkno *= (lp->d_secsize / DEV_BSIZE); | | 387 | bp->b_blkno *= (lp->d_secsize / DEV_BSIZE); |
388 | #endif | | 388 | #endif |
389 | strat(bp); | | 389 | strat(bp); |
390 | | | 390 | |
391 | if (biowait(bp)) { | | 391 | if (biowait(bp)) { |
392 | msg = "partition scan I/O error"; | | 392 | msg = "partition scan I/O error"; |
393 | goto done; | | 393 | goto done; |
394 | } | | 394 | } |
395 | pbp = baddr(bp); | | 395 | pbp = baddr(bp); |
396 | | | 396 | |
397 | if (pbp->id != PARTBLOCK_ID) { | | 397 | if (pbp->id != PARTBLOCK_ID) { |
398 | msg = "partition block with bad id"; | | 398 | msg = "partition block with bad id"; |
399 | goto done; | | 399 | goto done; |
400 | } | | 400 | } |
401 | if (rdbchksum(pbp)) { | | 401 | if (rdbchksum(pbp)) { |
402 | msg = "partition block bad checksum"; | | 402 | msg = "partition block bad checksum"; |
403 | goto done; | | 403 | goto done; |
404 | } | | 404 | } |
405 | | | 405 | |
406 | if (pbp->e.tabsize < 11) { | | 406 | if (pbp->e.tabsize < 11) { |
407 | /* | | 407 | /* |
408 | * not enough info, too funky for us. | | 408 | * not enough info, too funky for us. |
409 | * I don't want to skip I want it fixed. | | 409 | * I don't want to skip I want it fixed. |
410 | */ | | 410 | */ |
411 | msg = "bad partition info (environ < 11)"; | | 411 | msg = "bad partition info (environ < 11)"; |
412 | goto done; | | 412 | goto done; |
413 | } | | 413 | } |
414 | | | 414 | |
415 | /* | | 415 | /* |
416 | * XXXX should be ">" however some vendors don't know | | 416 | * XXXX should be ">" however some vendors don't know |
417 | * what a table size is so, we hack for them. | | 417 | * what a table size is so, we hack for them. |
418 | * the other checks can fail for all I care but this | | 418 | * the other checks can fail for all I care but this |
419 | * is a very common value. *sigh*. | | 419 | * is a very common value. *sigh*. |
420 | */ | | 420 | */ |
421 | if (pbp->e.tabsize >= 16) | | 421 | if (pbp->e.tabsize >= 16) |
422 | adt = getadostype(pbp->e.dostype); | | 422 | adt = getadostype(pbp->e.dostype); |
423 | else { | | 423 | else { |
424 | adt.archtype = ADT_UNKNOWN; | | 424 | adt.archtype = ADT_UNKNOWN; |
425 | adt.fstype = FS_UNUSED; | | 425 | adt.fstype = FS_UNUSED; |
426 | } | | 426 | } |
427 | | | 427 | |
428 | switch (adt.archtype) { | | 428 | switch (adt.archtype) { |
429 | case ADT_NETBSDROOT: | | 429 | case ADT_NETBSDROOT: |
430 | pp = &lp->d_partitions[0]; | | 430 | pp = &lp->d_partitions[0]; |
431 | if (pp->p_size) { | | 431 | if (pp->p_size) { |
432 | #ifdef DIAGNOSTIC | | 432 | #ifdef DIAGNOSTIC |
433 | printf("more than one root, ignoring\n"); | | 433 | printf("more than one root, ignoring\n"); |
434 | #endif | | 434 | #endif |
435 | osdep->rdblock = RDBNULL; /* invalidate cpulab */ | | 435 | osdep->rdblock = RDBNULL; /* invalidate cpulab */ |
436 | continue; | | 436 | continue; |
437 | } | | 437 | } |
438 | break; | | 438 | break; |
439 | case ADT_NETBSDSWAP: | | 439 | case ADT_NETBSDSWAP: |
440 | pp = &lp->d_partitions[1]; | | 440 | pp = &lp->d_partitions[1]; |
441 | if (pp->p_size) { | | 441 | if (pp->p_size) { |
442 | #ifdef DIAGNOSTIC | | 442 | #ifdef DIAGNOSTIC |
443 | printf("more than one swap, ignoring\n"); | | 443 | printf("more than one swap, ignoring\n"); |
444 | #endif | | 444 | #endif |
445 | osdep->rdblock = RDBNULL; /* invalidate cpulab */ | | 445 | osdep->rdblock = RDBNULL; /* invalidate cpulab */ |
446 | continue; | | 446 | continue; |
447 | } | | 447 | } |
448 | break; | | 448 | break; |
449 | case ADT_NETBSDUSER: | | 449 | case ADT_NETBSDUSER: |
450 | case ADT_AMIGADOS: | | 450 | case ADT_AMIGADOS: |
451 | case ADT_AMIX: | | 451 | case ADT_AMIX: |
452 | case ADT_EXT2: | | 452 | case ADT_EXT2: |
453 | case ADT_RAID: | | 453 | case ADT_RAID: |
454 | case ADT_MSD: | | 454 | case ADT_MSD: |
455 | case ADT_UNKNOWN: | | 455 | case ADT_UNKNOWN: |
456 | pp = &lp->d_partitions[lp->d_npartitions]; | | 456 | pp = &lp->d_partitions[lp->d_npartitions]; |
457 | break; | | 457 | break; |
458 | } | | 458 | } |
459 | if (lp->d_npartitions <= (pp - lp->d_partitions)) | | 459 | if (lp->d_npartitions <= (pp - lp->d_partitions)) |
460 | lp->d_npartitions = (pp - lp->d_partitions) + 1; | | 460 | lp->d_npartitions = (pp - lp->d_partitions) + 1; |
461 | | | 461 | |
462 | #ifdef DIAGNOSTIC | | 462 | #ifdef DIAGNOSTIC |
463 | if (lp->d_secpercyl * lp->d_secsize != | | 463 | if (lp->d_secpercyl * lp->d_secsize != |
464 | (pbp->e.secpertrk * pbp->e.numheads * pbp->e.sizeblock<<2)) { | | 464 | (pbp->e.secpertrk * pbp->e.numheads * pbp->e.sizeblock<<2)) { |
465 | if (pbp->partname[0] < sizeof(pbp->partname)) | | 465 | if (pbp->partname[0] < sizeof(pbp->partname)) |
466 | pbp->partname[pbp->partname[0] + 1] = 0; | | 466 | pbp->partname[pbp->partname[0] + 1] = 0; |
467 | else | | 467 | else |
468 | pbp->partname[sizeof(pbp->partname) - 1] = 0; | | 468 | pbp->partname[sizeof(pbp->partname) - 1] = 0; |
469 | printf("Partition '%s' geometry %ld/%ld differs", | | 469 | printf("Partition '%s' geometry %u/%u differs", |
470 | pbp->partname + 1, pbp->e.numheads, | | 470 | pbp->partname + 1, pbp->e.numheads, |
471 | pbp->e.secpertrk); | | 471 | pbp->e.secpertrk); |
472 | printf(" from RDB %d/%d=%d\n", lp->d_ntracks, | | 472 | printf(" from RDB %u/%u=%u\n", lp->d_ntracks, |
473 | lp->d_nsectors, lp->d_secpercyl); | | 473 | lp->d_nsectors, lp->d_secpercyl); |
474 | } | | 474 | } |
475 | #endif | | 475 | #endif |
476 | /* | | 476 | /* |
477 | * insert sort in increasing offset order | | 477 | * insert sort in increasing offset order |
478 | */ | | 478 | */ |
479 | while ((pp - lp->d_partitions) > RAW_PART + 1) { | | 479 | while ((pp - lp->d_partitions) > RAW_PART + 1) { |
480 | daddr_t boff; | | 480 | daddr_t boff; |
481 | | | 481 | |
482 | boff = pbp->e.lowcyl * pbp->e.secpertrk | | 482 | boff = pbp->e.lowcyl * pbp->e.secpertrk |
483 | * pbp->e.numheads; | | 483 | * pbp->e.numheads; |
484 | if (boff > (pp - 1)->p_offset) | | 484 | if (boff > (pp - 1)->p_offset) |
485 | break; | | 485 | break; |
486 | *pp = *(pp - 1); /* struct copy */ | | 486 | *pp = *(pp - 1); /* struct copy */ |
487 | pp--; | | 487 | pp--; |
488 | } | | 488 | } |
489 | i = (pp - lp->d_partitions); | | 489 | i = (pp - lp->d_partitions); |
490 | if (nopname || i == 1) { | | 490 | if (nopname || i == 1) { |
491 | /* | | 491 | /* |
492 | * either we have no packname yet or we found | | 492 | * either we have no packname yet or we found |
493 | * the swap partition. copy BCPL string into packname | | 493 | * the swap partition. copy BCPL string into packname |
494 | * [the reason we use the swap partition: the user | | 494 | * [the reason we use the swap partition: the user |
495 | * can supply a decent packname without worry | | 495 | * can supply a decent packname without worry |
496 | * of having to access an odly named partition | | 496 | * of having to access an odly named partition |
497 | * under AmigaDos] | | 497 | * under AmigaDos] |
498 | */ | | 498 | */ |
499 | s = lp->d_packname; | | 499 | s = lp->d_packname; |
500 | bcpls = &pbp->partname[1]; | | 500 | bcpls = &pbp->partname[1]; |
501 | bcpli = pbp->partname[0]; | | 501 | bcpli = pbp->partname[0]; |
502 | if (sizeof(lp->d_packname) <= bcpli) | | 502 | if (sizeof(lp->d_packname) <= bcpli) |
503 | bcpli = sizeof(lp->d_packname) - 1; | | 503 | bcpli = sizeof(lp->d_packname) - 1; |
504 | while (bcpli--) | | 504 | while (bcpli--) |
505 | *s++ = *bcpls++; | | 505 | *s++ = *bcpls++; |
506 | *s = 0; | | 506 | *s = 0; |
507 | nopname = 0; | | 507 | nopname = 0; |
508 | } | | 508 | } |
509 | | | 509 | |
510 | pp->p_size = (pbp->e.highcyl - pbp->e.lowcyl + 1) | | 510 | pp->p_size = (pbp->e.highcyl - pbp->e.lowcyl + 1) |
511 | * pbp->e.secpertrk * pbp->e.numheads | | 511 | * pbp->e.secpertrk * pbp->e.numheads |
512 | * ((pbp->e.sizeblock << 2) / lp->d_secsize); | | 512 | * ((pbp->e.sizeblock << 2) / lp->d_secsize); |
513 | pp->p_offset = pbp->e.lowcyl * pbp->e.secpertrk | | 513 | pp->p_offset = pbp->e.lowcyl * pbp->e.secpertrk |
514 | * pbp->e.numheads | | 514 | * pbp->e.numheads |
515 | * ((pbp->e.sizeblock << 2) / lp->d_secsize); | | 515 | * ((pbp->e.sizeblock << 2) / lp->d_secsize); |
516 | pp->p_fstype = adt.fstype; | | 516 | pp->p_fstype = adt.fstype; |
517 | if (adt.archtype == ADT_AMIGADOS) { | | 517 | if (adt.archtype == ADT_AMIGADOS) { |
518 | /* | | 518 | /* |
519 | * Save reserved blocks at begin in cpg and | | 519 | * Save reserved blocks at begin in cpg and |
520 | * adjust size by reserved blocks at end | | 520 | * adjust size by reserved blocks at end |
521 | */ | | 521 | */ |
522 | int bsize, secperblk, minbsize, prefac; | | 522 | int bsize, secperblk, minbsize, prefac; |
523 | | | 523 | |
524 | minbsize = max(512, lp->d_secsize); | | 524 | minbsize = max(512, lp->d_secsize); |
525 | | | 525 | |
526 | bsize = pbp->e.sizeblock << 2; | | 526 | bsize = pbp->e.sizeblock << 2; |
527 | secperblk = pbp->e.secperblk; | | 527 | secperblk = pbp->e.secperblk; |
528 | prefac = pbp->e.prefac; | | 528 | prefac = pbp->e.prefac; |
529 | | | 529 | |
530 | while (bsize > minbsize) { | | 530 | while (bsize > minbsize) { |
531 | bsize >>= 1; | | 531 | bsize >>= 1; |
532 | secperblk <<= 1; | | 532 | secperblk <<= 1; |
533 | prefac <<= 1; | | 533 | prefac <<= 1; |
534 | } | | 534 | } |
535 | | | 535 | |
536 | if (bsize == minbsize) { | | 536 | if (bsize == minbsize) { |
537 | pp->p_fsize = bsize; | | 537 | pp->p_fsize = bsize; |
538 | pp->p_frag = secperblk; | | 538 | pp->p_frag = secperblk; |
539 | pp->p_cpg = pbp->e.resvblocks; | | 539 | pp->p_cpg = pbp->e.resvblocks; |
540 | pp->p_size -= prefac; | | 540 | pp->p_size -= prefac; |
541 | } else { | | 541 | } else { |
542 | adt.archtype = ADT_UNKNOWN; | | 542 | adt.archtype = ADT_UNKNOWN; |
543 | adt.fstype = FS_UNUSED; | | 543 | adt.fstype = FS_UNUSED; |
544 | } | | 544 | } |
545 | } else if (pbp->e.tabsize > 22 && ISFSARCH_NETBSD(adt)) { | | 545 | } else if (pbp->e.tabsize > 22 && ISFSARCH_NETBSD(adt)) { |
546 | pp->p_fsize = pbp->e.fsize; | | 546 | pp->p_fsize = pbp->e.fsize; |
547 | pp->p_frag = pbp->e.frag; | | 547 | pp->p_frag = pbp->e.frag; |
548 | pp->p_cpg = pbp->e.cpg; | | 548 | pp->p_cpg = pbp->e.cpg; |
549 | } else { | | 549 | } else { |
550 | pp->p_fsize = 1024; | | 550 | pp->p_fsize = 1024; |
551 | pp->p_frag = 8; | | 551 | pp->p_frag = 8; |
552 | pp->p_cpg = 0; | | 552 | pp->p_cpg = 0; |
553 | } | | 553 | } |
554 | | | 554 | |
555 | /* | | 555 | /* |
556 | * store this partitions block number | | 556 | * store this partitions block number |
557 | */ | | 557 | */ |
558 | osdep->pblist[osdep->pbindex[i] = cindex++] = nextb; | | 558 | osdep->pblist[osdep->pbindex[i] = cindex++] = nextb; |
559 | } | | 559 | } |
560 | /* | | 560 | /* |
561 | * calulate new checksum. | | 561 | * calulate new checksum. |
562 | */ | | 562 | */ |
563 | lp->d_magic = lp->d_magic2 = DISKMAGIC; | | 563 | lp->d_magic = lp->d_magic2 = DISKMAGIC; |
564 | lp->d_checksum = 0; | | 564 | lp->d_checksum = 0; |
565 | lp->d_checksum = dkcksum(lp); | | 565 | lp->d_checksum = dkcksum(lp); |
566 | if (osdep->rdblock != RDBNULL) | | 566 | if (osdep->rdblock != RDBNULL) |
567 | osdep->valid = 1; | | 567 | osdep->valid = 1; |
568 | done: | | 568 | done: |
569 | if (osdep->valid == 0) | | 569 | if (osdep->valid == 0) |
570 | osdep->rdblock = RDBNULL; | | 570 | osdep->rdblock = RDBNULL; |
571 | brelse(bp, 0); | | 571 | brelse(bp, 0); |
572 | return msg; | | 572 | return msg; |
573 | } | | 573 | } |
574 | | | 574 | |
575 | static u_long | | 575 | static u_long |
576 | rdbchksum(void *bdata) | | 576 | rdbchksum(void *bdata) |
577 | { | | 577 | { |
578 | u_long *blp, cnt, val; | | 578 | u_long *blp, cnt, val; |
579 | | | 579 | |
580 | blp = bdata; | | 580 | blp = bdata; |
581 | cnt = blp[1]; | | 581 | cnt = blp[1]; |
582 | val = 0; | | 582 | val = 0; |
583 | | | 583 | |
584 | while (cnt--) | | 584 | while (cnt--) |
585 | val += *blp++; | | 585 | val += *blp++; |
586 | return val; | | 586 | return val; |
587 | } | | 587 | } |
588 | | | 588 | |
589 | static struct adostype | | 589 | static struct adostype |
590 | getadostype(u_long dostype) | | 590 | getadostype(u_long dostype) |
591 | { | | 591 | { |
592 | struct adostype adt; | | 592 | struct adostype adt; |
593 | u_long b1, t3; | | 593 | u_long b1, t3; |
594 | | | 594 | |
595 | t3 = dostype & 0xffffff00; | | 595 | t3 = dostype & 0xffffff00; |
596 | b1 = dostype & 0x000000ff; | | 596 | b1 = dostype & 0x000000ff; |
597 | | | 597 | |
598 | adt.fstype = b1; | | 598 | adt.fstype = b1; |
599 | | | 599 | |
600 | switch (t3) { | | 600 | switch (t3) { |
601 | case DOST_NBR: | | 601 | case DOST_NBR: |
602 | adt.archtype = ADT_NETBSDROOT; | | 602 | adt.archtype = ADT_NETBSDROOT; |
603 | return adt; | | 603 | return adt; |
604 | case DOST_NBS: | | 604 | case DOST_NBS: |
605 | adt.archtype = ADT_NETBSDSWAP; | | 605 | adt.archtype = ADT_NETBSDSWAP; |
606 | return adt; | | 606 | return adt; |
607 | case DOST_NBU: | | 607 | case DOST_NBU: |
608 | adt.archtype = ADT_NETBSDUSER; | | 608 | adt.archtype = ADT_NETBSDUSER; |
609 | return adt; | | 609 | return adt; |
610 | case DOST_MUFS: | | 610 | case DOST_MUFS: |
611 | /* check for 'muFS'? */ | | 611 | /* check for 'muFS'? */ |
612 | adt.archtype = ADT_AMIGADOS; | | 612 | adt.archtype = ADT_AMIGADOS; |
613 | adt.fstype = FS_ADOS; | | 613 | adt.fstype = FS_ADOS; |
614 | return adt; | | 614 | return adt; |
615 | case DOST_DOS: | | 615 | case DOST_DOS: |
616 | adt.archtype = ADT_AMIGADOS; | | 616 | adt.archtype = ADT_AMIGADOS; |
617 | if (b1 > 5) | | 617 | if (b1 > 5) |
618 | adt.fstype = FS_UNUSED; | | 618 | adt.fstype = FS_UNUSED; |
619 | else | | 619 | else |
620 | adt.fstype = FS_ADOS; | | 620 | adt.fstype = FS_ADOS; |
621 | return adt; | | 621 | return adt; |
622 | case DOST_AMIX: | | 622 | case DOST_AMIX: |
623 | adt.archtype = ADT_AMIX; | | 623 | adt.archtype = ADT_AMIX; |
624 | if (b1 == 2) | | 624 | if (b1 == 2) |
625 | adt.fstype = FS_BSDFFS; | | 625 | adt.fstype = FS_BSDFFS; |
626 | else | | 626 | else |
627 | adt.fstype = FS_UNUSED; | | 627 | adt.fstype = FS_UNUSED; |
628 | return adt; | | 628 | return adt; |
629 | case DOST_XXXBSD: | | 629 | case DOST_XXXBSD: |
630 | #ifdef DIAGNOSTIC | | 630 | #ifdef DIAGNOSTIC |
631 | printf("found dostype: 0x%lx which is deprecated", dostype); | | 631 | printf("found dostype: 0x%lx which is deprecated", dostype); |
632 | #endif | | 632 | #endif |
633 | if (b1 == 'S') { | | 633 | if (b1 == 'S') { |
634 | dostype = DOST_NBS; | | 634 | dostype = DOST_NBS; |
635 | dostype |= FS_SWAP; | | 635 | dostype |= FS_SWAP; |
636 | } else { | | 636 | } else { |
637 | if (b1 == 'R') | | 637 | if (b1 == 'R') |
638 | dostype = DOST_NBR; | | 638 | dostype = DOST_NBR; |
639 | else | | 639 | else |
640 | dostype = DOST_NBU; | | 640 | dostype = DOST_NBU; |
641 | dostype |= FS_BSDFFS; | | 641 | dostype |= FS_BSDFFS; |
642 | } | | 642 | } |
643 | #ifdef DIAGNOSTIC | | 643 | #ifdef DIAGNOSTIC |
644 | printf(" using: 0x%lx instead\n", dostype); | | 644 | printf(" using: 0x%lx instead\n", dostype); |
645 | #endif | | 645 | #endif |
646 | return(getadostype(dostype)); | | 646 | return(getadostype(dostype)); |
647 | case DOST_EXT2: | | 647 | case DOST_EXT2: |
648 | adt.archtype = ADT_EXT2; | | 648 | adt.archtype = ADT_EXT2; |
649 | adt.fstype = FS_EX2FS; | | 649 | adt.fstype = FS_EX2FS; |
650 | return adt; | | 650 | return adt; |
651 | case DOST_RAID: | | 651 | case DOST_RAID: |
652 | adt.archtype = ADT_RAID; | | 652 | adt.archtype = ADT_RAID; |
653 | adt.fstype = FS_RAID; | | 653 | adt.fstype = FS_RAID; |
654 | return adt; | | 654 | return adt; |
655 | case DOST_MSD: | | 655 | case DOST_MSD: |
656 | adt.archtype = ADT_MSD; | | 656 | adt.archtype = ADT_MSD; |
657 | adt.fstype = FS_MSDOS; | | 657 | adt.fstype = FS_MSDOS; |
658 | return adt; | | 658 | return adt; |
659 | default: | | 659 | default: |
660 | #ifdef DIAGNOSTIC | | 660 | #ifdef DIAGNOSTIC |
661 | printf("warning unknown dostype: 0x%lx marking unused\n", | | 661 | printf("warning unknown dostype: 0x%lx marking unused\n", |
662 | dostype); | | 662 | dostype); |
663 | #endif | | 663 | #endif |
664 | adt.archtype = ADT_UNKNOWN; | | 664 | adt.archtype = ADT_UNKNOWN; |
665 | adt.fstype = FS_UNUSED; | | 665 | adt.fstype = FS_UNUSED; |
666 | return adt; | | 666 | return adt; |
667 | } | | 667 | } |
668 | } | | 668 | } |
669 | #endif /* RDB_PART */ | | 669 | #endif /* RDB_PART */ |
670 | | | 670 | |
671 | /* | | 671 | /* |
672 | * Get raw NetBSD disk label | | 672 | * Get raw NetBSD disk label |
673 | */ | | 673 | */ |
674 | static int | | 674 | static int |
675 | read_netbsd_label(dev_t dev, void (*strat)(struct buf *), struct disklabel *lp, | | 675 | read_netbsd_label(dev_t dev, void (*strat)(struct buf *), struct disklabel *lp, |
676 | struct cpu_disklabel *osdep) | | 676 | struct cpu_disklabel *osdep) |
677 | { | | 677 | { |
678 | struct buf *bp; | | 678 | struct buf *bp; |
679 | struct disklabel *dlp; | | 679 | struct disklabel *dlp; |
680 | | | 680 | |
681 | /* get a buffer and initialize it */ | | 681 | /* get a buffer and initialize it */ |
682 | bp = geteblk((int)lp->d_secsize); | | 682 | bp = geteblk((int)lp->d_secsize); |
683 | bp->b_dev = dev; | | 683 | bp->b_dev = dev; |
684 | | | 684 | |
685 | /* Now get the label block */ | | 685 | /* Now get the label block */ |
686 | bp->b_blkno = osdep->cd_labelsector; | | 686 | bp->b_blkno = osdep->cd_labelsector; |
687 | bp->b_bcount = lp->d_secsize; | | 687 | bp->b_bcount = lp->d_secsize; |
688 | bp->b_flags |= B_READ; | | 688 | bp->b_flags |= B_READ; |
689 | bp->b_cylinder = bp->b_blkno / (lp->d_secsize / DEV_BSIZE) / lp->d_secpercyl; | | 689 | bp->b_cylinder = bp->b_blkno / (lp->d_secsize / DEV_BSIZE) / lp->d_secpercyl; |
690 | (*strat)(bp); | | 690 | (*strat)(bp); |
691 | | | 691 | |
692 | if (biowait(bp)) | | 692 | if (biowait(bp)) |
693 | goto done; | | 693 | goto done; |
694 | | | 694 | |
695 | for (dlp = (struct disklabel *)((char *)bp->b_data + | | 695 | for (dlp = (struct disklabel *)((char *)bp->b_data + |
696 | osdep->cd_labeloffset); | | 696 | osdep->cd_labeloffset); |
697 | dlp <= (struct disklabel *)((char *)bp->b_data + lp->d_secsize - | | 697 | dlp <= (struct disklabel *)((char *)bp->b_data + lp->d_secsize - |
698 | sizeof (*dlp)); | | 698 | sizeof (*dlp)); |
699 | dlp = (struct disklabel *)((char *)dlp + sizeof(long))) { | | 699 | dlp = (struct disklabel *)((char *)dlp + sizeof(long))) { |
700 | if (dlp->d_magic == DISKMAGIC | | 700 | if (dlp->d_magic == DISKMAGIC |
701 | && dlp->d_magic2 == DISKMAGIC | | 701 | && dlp->d_magic2 == DISKMAGIC |
702 | && dlp->d_npartitions <= MAXPARTITIONS | | 702 | && dlp->d_npartitions <= MAXPARTITIONS |
703 | && dkcksum(dlp) == 0) { | | 703 | && dkcksum(dlp) == 0) { |
704 | *lp = *dlp; | | 704 | *lp = *dlp; |
705 | osdep->cd_labeloffset = (char *)dlp - | | 705 | osdep->cd_labeloffset = (char *)dlp - |
706 | (char *)bp->b_data; | | 706 | (char *)bp->b_data; |
707 | brelse(bp, 0); | | 707 | brelse(bp, 0); |
708 | return 1; | | 708 | return 1; |
709 | } | | 709 | } |
710 | } | | 710 | } |
711 | done: | | 711 | done: |
712 | brelse(bp, 0); | | 712 | brelse(bp, 0); |
713 | return 0; | | 713 | return 0; |
714 | } | | 714 | } |
715 | | | 715 | |
716 | /* | | 716 | /* |
717 | * Attempt to read a disk label from a device using the indicated strategy | | 717 | * Attempt to read a disk label from a device using the indicated strategy |
718 | * routine. The label must be partly set up before this: secpercyl and | | 718 | * routine. The label must be partly set up before this: secpercyl and |
719 | * anything required in the strategy routine (e.g., sector size) must be | | 719 | * anything required in the strategy routine (e.g., sector size) must be |
720 | * filled in before calling us. Returns null on success and an error | | 720 | * filled in before calling us. Returns null on success and an error |
721 | * string on failure. | | 721 | * string on failure. |
722 | */ | | 722 | */ |
723 | const char * | | 723 | const char * |
724 | readdisklabel(dev_t dev, void (*strat)(struct buf *), struct disklabel *lp, | | 724 | readdisklabel(dev_t dev, void (*strat)(struct buf *), struct disklabel *lp, |
725 | struct cpu_disklabel *osdep) | | 725 | struct cpu_disklabel *osdep) |
726 | { | | 726 | { |
727 | struct buf *bp; | | 727 | struct buf *bp; |
728 | const char *msg = NULL; | | 728 | const char *msg = NULL; |
729 | | | 729 | |
730 | if (lp->d_secperunit == 0) | | 730 | if (lp->d_secperunit == 0) |
731 | lp->d_secperunit = 0x1fffffff; | | 731 | lp->d_secperunit = 0x1fffffff; |
732 | | | 732 | |
733 | if (lp->d_secpercyl == 0) { | | 733 | if (lp->d_secpercyl == 0) { |
734 | return msg = "Zero secpercyl"; | | 734 | return msg = "Zero secpercyl"; |
735 | } | | 735 | } |
736 | | | 736 | |
737 | /* no valid RDB found */ | | 737 | /* no valid RDB found */ |
738 | osdep->rdblock = RDBNULL; | | 738 | osdep->rdblock = RDBNULL; |
739 | | | 739 | |
740 | /* XXX cd_start is abused as a flag for fictitious disklabel */ | | 740 | /* XXX cd_start is abused as a flag for fictitious disklabel */ |
741 | osdep->cd_start = -1; | | 741 | osdep->cd_start = -1; |
742 | | | 742 | |
743 | osdep->cd_labelsector = LABELSECTOR; | | 743 | osdep->cd_labelsector = LABELSECTOR; |
744 | osdep->cd_labeloffset = LABELOFFSET; | | 744 | osdep->cd_labeloffset = LABELOFFSET; |
745 | | | 745 | |
746 | bp = geteblk((int)lp->d_secsize); | | 746 | bp = geteblk((int)lp->d_secsize); |
747 | | | 747 | |
748 | bp->b_dev = dev; | | 748 | bp->b_dev = dev; |
749 | bp->b_blkno = MBR_BBSECTOR; | | 749 | bp->b_blkno = MBR_BBSECTOR; |
750 | bp->b_resid = 0; | | 750 | bp->b_resid = 0; |
751 | bp->b_bcount = lp->d_secsize; | | 751 | bp->b_bcount = lp->d_secsize; |
752 | bp->b_flags |= B_READ; | | 752 | bp->b_flags |= B_READ; |
753 | bp->b_cylinder = MBR_BBSECTOR / lp->d_secpercyl; | | 753 | bp->b_cylinder = MBR_BBSECTOR / lp->d_secpercyl; |
754 | (*strat)(bp); | | 754 | (*strat)(bp); |
755 | | | 755 | |
756 | if (biowait(bp)) { | | 756 | if (biowait(bp)) { |
757 | msg = "I/O error reading block zero"; | | 757 | msg = "I/O error reading block zero"; |
758 | goto done; | | 758 | goto done; |
759 | } | | 759 | } |
760 | | | 760 | |
761 | if (bswap16(*(u_int16_t *)((char *)bp->b_data + MBR_MAGIC_OFFSET)) | | 761 | if (bswap16(*(u_int16_t *)((char *)bp->b_data + MBR_MAGIC_OFFSET)) |
762 | == MBR_MAGIC) { | | 762 | == MBR_MAGIC) { |
763 | /* | | 763 | /* |
764 | * We've got an MBR partitioned disk. | | 764 | * We've got an MBR partitioned disk. |
765 | * read_dos_label figures out labelsector/offset itself | | 765 | * read_dos_label figures out labelsector/offset itself |
766 | */ | | 766 | */ |
767 | msg = read_dos_label(dev, strat, lp, osdep); | | 767 | msg = read_dos_label(dev, strat, lp, osdep); |
768 | } else { | | 768 | } else { |
769 | #ifdef RDB_PART | | 769 | #ifdef RDB_PART |
770 | /* scan for RDB partitions */ | | 770 | /* scan for RDB partitions */ |
771 | msg = read_rdb_label(dev, strat, lp, osdep); | | 771 | msg = read_rdb_label(dev, strat, lp, osdep); |
772 | #else | | 772 | #else |
773 | msg = "no NetBSD disk label"; | | 773 | msg = "no NetBSD disk label"; |
774 | #endif | | 774 | #endif |
775 | if (msg != NULL) { | | 775 | if (msg != NULL) { |
776 | /* try reading a raw NetBSD disklabel at last */ | | 776 | /* try reading a raw NetBSD disklabel at last */ |
777 | if (read_netbsd_label(dev, strat, lp, osdep)) | | 777 | if (read_netbsd_label(dev, strat, lp, osdep)) |
778 | msg = NULL; | | 778 | msg = NULL; |
779 | } | | 779 | } |
780 | } | | 780 | } |
781 | if (msg == NULL) | | 781 | if (msg == NULL) |
782 | osdep->cd_start = 0; | | 782 | osdep->cd_start = 0; |
783 | | | 783 | |
784 | done: | | 784 | done: |
785 | brelse(bp, 0); | | 785 | brelse(bp, 0); |
786 | return msg; | | 786 | return msg; |
787 | } | | 787 | } |
788 | | | 788 | |
789 | /* | | 789 | /* |
790 | * Check new disk label for sensibility before setting it. | | 790 | * Check new disk label for sensibility before setting it. |
791 | */ | | 791 | */ |
792 | int | | 792 | int |
793 | setdisklabel(struct disklabel *olp, struct disklabel *nlp, u_long openmask, | | 793 | setdisklabel(struct disklabel *olp, struct disklabel *nlp, u_long openmask, |
794 | struct cpu_disklabel *osdep) | | 794 | struct cpu_disklabel *osdep) |
795 | { | | 795 | { |
796 | int i; | | 796 | int i; |
797 | struct partition *opp, *npp; | | 797 | struct partition *opp, *npp; |
798 | | | 798 | |
799 | /* sanity clause */ | | 799 | /* sanity clause */ |
800 | if (nlp->d_secpercyl == 0 || nlp->d_secsize == 0 | | 800 | if (nlp->d_secpercyl == 0 || nlp->d_secsize == 0 |
801 | || (nlp->d_secsize % DEV_BSIZE) != 0) | | 801 | || (nlp->d_secsize % DEV_BSIZE) != 0) |
802 | return EINVAL; | | 802 | return EINVAL; |
803 | | | 803 | |
804 | /* special case to allow disklabel to be invalidated */ | | 804 | /* special case to allow disklabel to be invalidated */ |
805 | if (nlp->d_magic == 0xffffffff) { | | 805 | if (nlp->d_magic == 0xffffffff) { |
806 | *olp = *nlp; | | 806 | *olp = *nlp; |
807 | return 0; | | 807 | return 0; |
808 | } | | 808 | } |
809 | | | 809 | |
810 | if (nlp->d_magic != DISKMAGIC || nlp->d_magic2 != DISKMAGIC | | 810 | if (nlp->d_magic != DISKMAGIC || nlp->d_magic2 != DISKMAGIC |
811 | || dkcksum(nlp) != 0) | | 811 | || dkcksum(nlp) != 0) |
812 | return EINVAL; | | 812 | return EINVAL; |
813 | | | 813 | |
814 | while ((i = ffs(openmask)) != 0) { | | 814 | while ((i = ffs(openmask)) != 0) { |
815 | i--; | | 815 | i--; |
816 | openmask &= ~(1 << i); | | 816 | openmask &= ~(1 << i); |
817 | if (nlp->d_npartitions <= i) | | 817 | if (nlp->d_npartitions <= i) |
818 | return EBUSY; | | 818 | return EBUSY; |
819 | opp = &olp->d_partitions[i]; | | 819 | opp = &olp->d_partitions[i]; |
820 | npp = &nlp->d_partitions[i]; | | 820 | npp = &nlp->d_partitions[i]; |
821 | if (npp->p_offset != opp->p_offset || npp->p_size < opp->p_size) | | 821 | if (npp->p_offset != opp->p_offset || npp->p_size < opp->p_size) |
822 | return EBUSY; | | 822 | return EBUSY; |
823 | /* | | 823 | /* |
824 | * Copy internally-set partition information | | 824 | * Copy internally-set partition information |
825 | * if new label doesn't include it. XXX | | 825 | * if new label doesn't include it. XXX |
826 | */ | | 826 | */ |
827 | if (npp->p_fstype == FS_UNUSED && opp->p_fstype != FS_UNUSED) { | | 827 | if (npp->p_fstype == FS_UNUSED && opp->p_fstype != FS_UNUSED) { |
828 | npp->p_fstype = opp->p_fstype; | | 828 | npp->p_fstype = opp->p_fstype; |
829 | npp->p_fsize = opp->p_fsize; | | 829 | npp->p_fsize = opp->p_fsize; |
830 | npp->p_frag = opp->p_frag; | | 830 | npp->p_frag = opp->p_frag; |
831 | npp->p_cpg = opp->p_cpg; | | 831 | npp->p_cpg = opp->p_cpg; |
832 | } | | 832 | } |
833 | } | | 833 | } |
834 | nlp->d_checksum = 0; | | 834 | nlp->d_checksum = 0; |
835 | nlp->d_checksum = dkcksum(nlp); | | 835 | nlp->d_checksum = dkcksum(nlp); |
836 | | | 836 | |
837 | *olp = *nlp; | | 837 | *olp = *nlp; |
838 | return 0; | | 838 | return 0; |
839 | } | | 839 | } |
840 | | | 840 | |
841 | /* | | 841 | /* |
842 | * Write disk label back to device after modification. | | 842 | * Write disk label back to device after modification. |
843 | */ | | 843 | */ |
844 | int | | 844 | int |
845 | writedisklabel(dev_t dev, void (*strat)(struct buf *), struct disklabel *lp, | | 845 | writedisklabel(dev_t dev, void (*strat)(struct buf *), struct disklabel *lp, |
846 | struct cpu_disklabel *osdep) | | 846 | struct cpu_disklabel *osdep) |
847 | { | | 847 | { |
848 | struct buf *bp; | | 848 | struct buf *bp; |
849 | int error; | | 849 | int error; |
850 | struct disklabel label; | | 850 | struct disklabel label; |
851 | | | 851 | |
852 | /* | | 852 | /* |
853 | * Try to re-read a disklabel, in case the MBR was modified. | | 853 | * Try to re-read a disklabel, in case the MBR was modified. |
854 | */ | | 854 | */ |
855 | label = *lp; | | 855 | label = *lp; |
856 | readdisklabel(dev, strat, &label, osdep); | | 856 | readdisklabel(dev, strat, &label, osdep); |
857 | | | 857 | |
858 | /* If an RDB was present, we don't support writing it yet. */ | | 858 | /* If an RDB was present, we don't support writing it yet. */ |
859 | if (osdep->rdblock != RDBNULL) | | 859 | if (osdep->rdblock != RDBNULL) |
860 | return EINVAL; | | 860 | return EINVAL; |
861 | | | 861 | |
862 | /* get a buffer and initialize it */ | | 862 | /* get a buffer and initialize it */ |
863 | bp = geteblk(lp->d_secsize); | | 863 | bp = geteblk(lp->d_secsize); |
864 | bp->b_dev = dev; | | 864 | bp->b_dev = dev; |
865 | | | 865 | |
866 | bp->b_blkno = osdep->cd_labelsector; | | 866 | bp->b_blkno = osdep->cd_labelsector; |
867 | bp->b_cylinder = bp->b_blkno / (lp->d_secsize / DEV_BSIZE) / | | 867 | bp->b_cylinder = bp->b_blkno / (lp->d_secsize / DEV_BSIZE) / |
868 | lp->d_secpercyl; | | 868 | lp->d_secpercyl; |
869 | bp->b_bcount = lp->d_secsize; | | 869 | bp->b_bcount = lp->d_secsize; |
870 | | | 870 | |
871 | bp->b_flags |= B_READ; | | 871 | bp->b_flags |= B_READ; |
872 | (*strat)(bp); | | 872 | (*strat)(bp); |
873 | error = biowait(bp); | | 873 | error = biowait(bp); |
874 | if (error != 0) | | 874 | if (error != 0) |
875 | goto done; | | 875 | goto done; |
876 | | | 876 | |
877 | bp->b_flags &= ~B_READ; | | 877 | bp->b_flags &= ~B_READ; |
878 | bp->b_flags |= B_WRITE; | | 878 | bp->b_flags |= B_WRITE; |
879 | bp->b_oflags &= ~BO_DONE; | | 879 | bp->b_oflags &= ~BO_DONE; |
880 | | | 880 | |
881 | memcpy((char *)bp->b_data + osdep->cd_labeloffset, (void *)lp, | | 881 | memcpy((char *)bp->b_data + osdep->cd_labeloffset, (void *)lp, |
882 | sizeof *lp); | | 882 | sizeof *lp); |
883 | | | 883 | |
884 | (*strat)(bp); | | 884 | (*strat)(bp); |
885 | error = biowait(bp); | | 885 | error = biowait(bp); |
886 | | | 886 | |
887 | done: | | 887 | done: |
888 | brelse(bp, 0); | | 888 | brelse(bp, 0); |
889 | | | 889 | |
890 | return error; | | 890 | return error; |
891 | } | | 891 | } |