File: | src/usr.sbin/makefs/msdos/msdosfs_vfsops.c |
Warning: | line 110, column 2 Value stored to 'bsize' is never read |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* $OpenBSD: msdosfs_vfsops.c,v 1.13 2021/10/06 00:40:41 deraadt Exp $ */ |
2 | |
3 | /*- |
4 | * Copyright (C) 1994, 1995, 1997 Wolfgang Solfrank. |
5 | * Copyright (C) 1994, 1995, 1997 TooLs GmbH. |
6 | * All rights reserved. |
7 | * Original code by Paul Popelka (paulp@uts.amdahl.com) (see below). |
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. All advertising materials mentioning features or use of this software |
18 | * must display the following acknowledgement: |
19 | * This product includes software developed by TooLs GmbH. |
20 | * 4. The name of TooLs GmbH may not be used to endorse or promote products |
21 | * derived from this software without specific prior written permission. |
22 | * |
23 | * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR |
24 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
25 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
26 | * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
27 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
28 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; |
29 | * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, |
30 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR |
31 | * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF |
32 | * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
33 | */ |
34 | /* |
35 | * Written by Paul Popelka (paulp@uts.amdahl.com) |
36 | * |
37 | * You can do anything you want with this software, just don't say you wrote |
38 | * it, and don't remove this notice. |
39 | * |
40 | * This software is provided "as is". |
41 | * |
42 | * The author supplies this software to be publicly redistributed on the |
43 | * understanding that the author is not responsible for the correct |
44 | * functioning of this software in any circumstances and is not liable for |
45 | * any damages caused by this software. |
46 | * |
47 | * October 1992 |
48 | */ |
49 | |
50 | |
51 | #include <sys/param.h> /* MAXBSIZE */ |
52 | #include <sys/types.h> |
53 | |
54 | #include "ffs/buf.h" |
55 | |
56 | #include <msdosfs/bpb.h> |
57 | #include <msdosfs/bootsect.h> |
58 | #include "msdos/direntry.h" |
59 | #include "msdos/denode.h" |
60 | #include "msdos/msdosfsmount.h" |
61 | #include "msdos/fat.h" |
62 | |
63 | #include <stdio.h> |
64 | #include <errno(*__errno()).h> |
65 | #include <stdlib.h> |
66 | #include <string.h> |
67 | #include <util.h> |
68 | |
69 | #include "makefs.h" |
70 | #include "msdos.h" |
71 | #include "msdos/mkfs_msdos.h" |
72 | |
73 | #ifdef MSDOSFS_DEBUG |
74 | #define DPRINTF(a) printf a |
75 | #else |
76 | #define DPRINTF(a) |
77 | #endif |
78 | |
79 | struct msdosfsmount * |
80 | msdosfs_mount(struct mkfsvnode *devvp, int flags) |
81 | { |
82 | struct msdosfsmount *pmp = NULL((void*)0); |
83 | struct mkfsbuf *bp; |
84 | union bootsector *bsp; |
85 | struct byte_bpb33 *b33; |
86 | struct byte_bpb50 *b50; |
87 | struct byte_bpb710 *b710; |
88 | uint8_t SecPerClust; |
89 | int ronly = 0, error; |
90 | int bsize; |
91 | unsigned secsize = 512; |
92 | |
93 | DPRINTF(("%s(bread 0)\n", __func__)); |
94 | if ((error = bread(devvp, 0, secsize, 0, &bp)) != 0) |
95 | goto error_exit; |
96 | |
97 | bsp = (union bootsector *)bp->b_data; |
98 | b33 = (struct byte_bpb33 *)bsp->bs33.bsBPB; |
99 | b50 = (struct byte_bpb50 *)bsp->bs50.bsBPB; |
100 | b710 = (struct byte_bpb710 *)bsp->bs710.bsBPB; |
101 | |
102 | if (bsp->bs50.bsBootSectSig0 != BOOTSIG00x55 |
103 | || bsp->bs50.bsBootSectSig1 != BOOTSIG10xaa) { |
104 | DPRINTF(("bootsig0 %d bootsig1 %d\n", |
105 | bsp->bs50.bsBootSectSig0, |
106 | bsp->bs50.bsBootSectSig1)); |
107 | error = EINVAL22; |
108 | goto error_exit; |
109 | } |
110 | bsize = 0; |
Value stored to 'bsize' is never read | |
111 | |
112 | pmp = ecalloc(1, sizeof *pmp); |
113 | /* |
114 | * Compute several useful quantities from the bpb in the |
115 | * bootsector. Copy in the dos 5 variant of the bpb then fix up |
116 | * the fields that are different between dos 5 and dos 3.3. |
117 | */ |
118 | SecPerClust = b50->bpbSecPerClust; |
119 | pmp->pm_BytesPerSecpm_bpb.bpbBytesPerSec = getushort(b50->bpbBytesPerSec)*((u_int16_t *)(b50->bpbBytesPerSec)); |
120 | pmp->pm_ResSectorspm_bpb.bpbResSectors = getushort(b50->bpbResSectors)*((u_int16_t *)(b50->bpbResSectors)); |
121 | pmp->pm_FATspm_bpb.bpbFATs = b50->bpbFATs; |
122 | pmp->pm_RootDirEntspm_bpb.bpbRootDirEnts = getushort(b50->bpbRootDirEnts)*((u_int16_t *)(b50->bpbRootDirEnts)); |
123 | pmp->pm_Sectorspm_bpb.bpbSectors = getushort(b50->bpbSectors)*((u_int16_t *)(b50->bpbSectors)); |
124 | pmp->pm_FATsecs = getushort(b50->bpbFATsecs)*((u_int16_t *)(b50->bpbFATsecs)); |
125 | pmp->pm_SecPerTrackpm_bpb.bpbSecPerTrack = getushort(b50->bpbSecPerTrack)*((u_int16_t *)(b50->bpbSecPerTrack)); |
126 | pmp->pm_Headspm_bpb.bpbHeads = getushort(b50->bpbHeads)*((u_int16_t *)(b50->bpbHeads)); |
127 | pmp->pm_Mediapm_bpb.bpbMedia = b50->bpbMedia; |
128 | pmp->pm_minuteswest = 0; |
129 | |
130 | DPRINTF(("%s(BytesPerSec=%u, ResSectors=%u, FATs=%d, RootDirEnts=%u, " |
131 | "Sectors=%u, FATsecs=%lu, SecPerTrack=%u, Heads=%u, Media=%u)\n", |
132 | __func__, pmp->pm_BytesPerSec, pmp->pm_ResSectors, pmp->pm_FATs, |
133 | pmp->pm_RootDirEnts, pmp->pm_Sectors, pmp->pm_FATsecs, |
134 | pmp->pm_SecPerTrack, pmp->pm_Heads, pmp->pm_Media)); |
135 | /* XXX - We should probably check more values here */ |
136 | if (!pmp->pm_BytesPerSecpm_bpb.bpbBytesPerSec || !SecPerClust |
137 | || pmp->pm_SecPerTrackpm_bpb.bpbSecPerTrack > 63) { |
138 | DPRINTF(("bytespersec %d secperclust %d " |
139 | "secpertrack %d\n", |
140 | pmp->pm_BytesPerSec, SecPerClust, |
141 | pmp->pm_SecPerTrack)); |
142 | error = EINVAL22; |
143 | goto error_exit; |
144 | } |
145 | |
146 | pmp->pm_flags = flags & MSDOSFSMNT_MNTOPT(1|2|4 |16); |
147 | if (pmp->pm_flags & MSDOSFSMNT_NOWIN954) |
148 | pmp->pm_flags |= MSDOSFSMNT_SHORTNAME1; |
149 | |
150 | if (pmp->pm_Sectorspm_bpb.bpbSectors == 0) { |
151 | pmp->pm_HiddenSectspm_bpb.bpbHiddenSecs = getulong(b50->bpbHiddenSecs)*((u_int32_t *)(b50->bpbHiddenSecs)); |
152 | pmp->pm_HugeSectorspm_bpb.bpbHugeSectors = getulong(b50->bpbHugeSectors)*((u_int32_t *)(b50->bpbHugeSectors)); |
153 | } else { |
154 | pmp->pm_HiddenSectspm_bpb.bpbHiddenSecs = getushort(b33->bpbHiddenSecs)*((u_int16_t *)(b33->bpbHiddenSecs)); |
155 | pmp->pm_HugeSectorspm_bpb.bpbHugeSectors = pmp->pm_Sectorspm_bpb.bpbSectors; |
156 | } |
157 | |
158 | if (pmp->pm_RootDirEntspm_bpb.bpbRootDirEnts == 0) { |
159 | unsigned short vers = getushort(b710->bpbFSVers)*((u_int16_t *)(b710->bpbFSVers)); |
160 | /* |
161 | * Some say that bsBootSectSig[23] must be zero, but |
162 | * Windows does not require this and some digital cameras |
163 | * do not set these to zero. Therefore, do not insist. |
164 | */ |
165 | if (pmp->pm_Sectorspm_bpb.bpbSectors || pmp->pm_FATsecs || vers) { |
166 | DPRINTF(("sectors %d fatsecs %lu vers %d\n", |
167 | pmp->pm_Sectors, pmp->pm_FATsecs, vers)); |
168 | error = EINVAL22; |
169 | goto error_exit; |
170 | } |
171 | pmp->pm_fatmask = FAT32_MASK0x0fffffff; |
172 | pmp->pm_fatmult = 4; |
173 | pmp->pm_fatdiv = 1; |
174 | pmp->pm_FATsecs = getulong(b710->bpbBigFATsecs)*((u_int32_t *)(b710->bpbBigFATsecs)); |
175 | |
176 | /* mirrorring is enabled if the FATMIRROR bit is not set */ |
177 | if ((getushort(b710->bpbExtFlags)*((u_int16_t *)(b710->bpbExtFlags)) & FATMIRROR0x80) == 0) |
178 | pmp->pm_flags |= MSDOSFS_FATMIRROR0x20000000; |
179 | else |
180 | pmp->pm_curfat = getushort(b710->bpbExtFlags)*((u_int16_t *)(b710->bpbExtFlags)) & FATNUM0xf; |
181 | } else |
182 | pmp->pm_flags |= MSDOSFS_FATMIRROR0x20000000; |
183 | |
184 | /* Check that fs has nonzero FAT size */ |
185 | if (pmp->pm_FATsecs == 0) { |
186 | DPRINTF(("FATsecs is 0\n")); |
187 | error = EINVAL22; |
188 | goto error_exit; |
189 | } |
190 | |
191 | pmp->pm_fatblk = pmp->pm_ResSectorspm_bpb.bpbResSectors; |
192 | if (FAT32(pmp)(pmp->pm_fatmask == 0x0fffffff)) { |
193 | pmp->pm_rootdirblk = getulong(b710->bpbRootClust)*((u_int32_t *)(b710->bpbRootClust)); |
194 | pmp->pm_firstcluster = pmp->pm_fatblk |
195 | + (pmp->pm_FATspm_bpb.bpbFATs * pmp->pm_FATsecs); |
196 | pmp->pm_fsinfo = getushort(b710->bpbFSInfo)*((u_int16_t *)(b710->bpbFSInfo)); |
197 | } else { |
198 | pmp->pm_rootdirblk = pmp->pm_fatblk + |
199 | (pmp->pm_FATspm_bpb.bpbFATs * pmp->pm_FATsecs); |
200 | pmp->pm_rootdirsize = (pmp->pm_RootDirEntspm_bpb.bpbRootDirEnts * sizeof(struct direntry) |
201 | + pmp->pm_BytesPerSecpm_bpb.bpbBytesPerSec - 1) |
202 | / pmp->pm_BytesPerSecpm_bpb.bpbBytesPerSec;/* in sectors */ |
203 | pmp->pm_firstcluster = pmp->pm_rootdirblk + pmp->pm_rootdirsize; |
204 | } |
205 | |
206 | pmp->pm_nmbrofclusters = (pmp->pm_HugeSectorspm_bpb.bpbHugeSectors - pmp->pm_firstcluster) / |
207 | SecPerClust; |
208 | pmp->pm_maxcluster = pmp->pm_nmbrofclusters + 1; |
209 | pmp->pm_fatsize = pmp->pm_FATsecs * pmp->pm_BytesPerSecpm_bpb.bpbBytesPerSec; |
210 | |
211 | if (pmp->pm_fatmask == 0) { |
212 | if (pmp->pm_maxcluster |
213 | <= ((CLUST_RSRVD0xfffffff6 - CLUST_FIRST2) & FAT12_MASK0x00000fff)) { |
214 | /* |
215 | * This will usually be a floppy disk. This size makes |
216 | * sure that one FAT entry will not be split across |
217 | * multiple blocks. |
218 | */ |
219 | pmp->pm_fatmask = FAT12_MASK0x00000fff; |
220 | pmp->pm_fatmult = 3; |
221 | pmp->pm_fatdiv = 2; |
222 | } else { |
223 | pmp->pm_fatmask = FAT16_MASK0x0000ffff; |
224 | pmp->pm_fatmult = 2; |
225 | pmp->pm_fatdiv = 1; |
226 | } |
227 | } |
228 | if (FAT12(pmp)(pmp->pm_fatmask == 0x00000fff)) |
229 | pmp->pm_fatblocksize = 3 * pmp->pm_BytesPerSecpm_bpb.bpbBytesPerSec; |
230 | else |
231 | pmp->pm_fatblocksize = MAXBSIZE(64 * 1024); |
232 | |
233 | pmp->pm_fatblocksec = pmp->pm_fatblocksize / pmp->pm_BytesPerSecpm_bpb.bpbBytesPerSec; |
234 | pmp->pm_bnshift = ffs(pmp->pm_BytesPerSecpm_bpb.bpbBytesPerSec) - 1; |
235 | |
236 | /* |
237 | * Compute mask and shift value for isolating cluster relative byte |
238 | * offsets and cluster numbers from a file offset. |
239 | */ |
240 | pmp->pm_bpcluster = SecPerClust * pmp->pm_BytesPerSecpm_bpb.bpbBytesPerSec; |
241 | pmp->pm_crbomask = pmp->pm_bpcluster - 1; |
242 | pmp->pm_cnshift = ffs(pmp->pm_bpcluster) - 1; |
243 | |
244 | DPRINTF(("%s(fatmask=%lu, fatmult=%u, fatdiv=%u, fatblocksize=%lu, " |
245 | "fatblocksec=%lu, bnshift=%lu, pbcluster=%lu, crbomask=%lu, " |
246 | "cnshift=%lu)\n", |
247 | __func__, pmp->pm_fatmask, pmp->pm_fatmult, pmp->pm_fatdiv, |
248 | pmp->pm_fatblocksize, pmp->pm_fatblocksec, pmp->pm_bnshift, |
249 | pmp->pm_bpcluster, pmp->pm_crbomask, pmp->pm_cnshift)); |
250 | /* |
251 | * Check for valid cluster size |
252 | * must be a power of 2 |
253 | */ |
254 | if (pmp->pm_bpcluster ^ (1 << pmp->pm_cnshift)) { |
255 | DPRINTF(("bpcluster %lu cnshift %lu\n", |
256 | pmp->pm_bpcluster, pmp->pm_cnshift)); |
257 | error = EINVAL22; |
258 | goto error_exit; |
259 | } |
260 | |
261 | /* |
262 | * Release the bootsector buffer. |
263 | */ |
264 | brelse(bp, BC_AGE0); |
265 | bp = NULL((void*)0); |
266 | |
267 | /* |
268 | * Check FSInfo. |
269 | */ |
270 | if (pmp->pm_fsinfo) { |
271 | struct fsinfo *fp; |
272 | |
273 | /* |
274 | * XXX If the fsinfo block is stored on media with |
275 | * 2KB or larger sectors, is the fsinfo structure |
276 | * padded at the end or in the middle? |
277 | */ |
278 | DPRINTF(("%s(bread %lu)\n", __func__, |
279 | (unsigned long)de_bn2kb(pmp, pmp->pm_fsinfo))); |
280 | if ((error = bread(devvp, de_bn2kb(pmp, pmp->pm_fsinfo)((pmp->pm_fsinfo) << ((pmp)->pm_bnshift - 9)), |
281 | pmp->pm_BytesPerSecpm_bpb.bpbBytesPerSec, 0, &bp)) != 0) |
282 | goto error_exit; |
283 | fp = (struct fsinfo *)bp->b_data; |
284 | if (!memcmp(fp->fsisig1, "RRaA", 4) |
285 | && !memcmp(fp->fsisig2, "rrAa", 4) |
286 | && !memcmp(fp->fsisig3, "\0\0\125\252", 4) |
287 | && !memcmp(fp->fsisig4, "\0\0\125\252", 4)) |
288 | pmp->pm_nxtfree = getulong(fp->fsinxtfree)*((u_int32_t *)(fp->fsinxtfree)); |
289 | else |
290 | pmp->pm_fsinfo = 0; |
291 | brelse(bp, 0); |
292 | bp = NULL((void*)0); |
293 | } |
294 | |
295 | /* |
296 | * Check and validate (or perhaps invalidate?) the fsinfo structure? |
297 | * XXX |
298 | */ |
299 | if (pmp->pm_fsinfo) { |
300 | if ((pmp->pm_nxtfree == 0xffffffffUL) || |
301 | (pmp->pm_nxtfree > pmp->pm_maxcluster)) |
302 | pmp->pm_fsinfo = 0; |
303 | } |
304 | |
305 | /* |
306 | * Allocate memory for the bitmap of allocated clusters, and then |
307 | * fill it in. |
308 | */ |
309 | pmp->pm_inusemap = ecalloc(sizeof(*pmp->pm_inusemap), |
310 | ((pmp->pm_maxcluster + N_INUSEBITS(8 * sizeof(u_int))) / N_INUSEBITS(8 * sizeof(u_int)))); |
311 | /* |
312 | * fillinusemap() needs pm_devvp. |
313 | */ |
314 | pmp->pm_dev = 0; |
315 | pmp->pm_devvp = devvp; |
316 | |
317 | /* |
318 | * Have the inuse map filled in. |
319 | */ |
320 | if ((error = fillinusemap(pmp)) != 0) { |
321 | DPRINTF(("fillinusemap %d\n", error)); |
322 | goto error_exit; |
323 | } |
324 | |
325 | /* |
326 | * Finish up. |
327 | */ |
328 | if (ronly) |
329 | pmp->pm_flags |= MSDOSFSMNT_RONLY0x80000000; |
330 | else |
331 | pmp->pm_fmod = 1; |
332 | |
333 | return pmp; |
334 | |
335 | error_exit: |
336 | if (bp) |
337 | brelse(bp, BC_AGE0); |
338 | if (pmp) { |
339 | if (pmp->pm_inusemap) |
340 | free(pmp->pm_inusemap); |
341 | free(pmp); |
342 | } |
343 | errno(*__errno()) = error; |
344 | return NULL((void*)0); |
345 | } |
346 | |
347 | int |
348 | msdosfs_root(struct msdosfsmount *pmp, struct mkfsvnode *vp) { |
349 | struct denode *ndep; |
350 | int error; |
351 | |
352 | *vp = *pmp->pm_devvp; |
353 | if ((error = deget(pmp, MSDOSFSROOT0, MSDOSFSROOT_OFS0x1fffffff, &ndep)) != 0) { |
354 | errno(*__errno()) = error; |
355 | return -1; |
356 | } |
357 | vp->v_data = ndep; |
358 | return 0; |
359 | } |