Commit | Line | Data |
---|---|---|
c018628f DF |
1 | /* |
2 | * Copyright (c) 1983 Regents of the University of California. | |
3 | * All rights reserved. The Berkeley software License Agreement | |
4 | * specifies the terms and conditions for redistribution. | |
5 | */ | |
6 | ||
7 | #ifndef lint | |
8 | char copyright[] = | |
9 | "@(#) Copyright (c) 1983 Regents of the University of California.\n\ | |
10 | All rights reserved.\n"; | |
11 | #endif not lint | |
12 | ||
a54c0b3f | 13 | #ifndef lint |
38f1cd11 | 14 | static char sccsid[] = "@(#)newfs.c 6.16 (Berkeley) %G%"; |
c018628f | 15 | #endif not lint |
a54c0b3f SL |
16 | |
17 | /* | |
c6003316 | 18 | * newfs: friendly front end to mkfs |
a54c0b3f SL |
19 | */ |
20 | #include <sys/param.h> | |
21 | #include <sys/stat.h> | |
22 | #include <sys/fs.h> | |
14b4eb74 | 23 | #include <sys/dir.h> |
8485bb11 KM |
24 | #include <sys/ioctl.h> |
25 | #include <sys/disklabel.h> | |
26 | #include <sys/file.h> | |
a54c0b3f SL |
27 | |
28 | #include <stdio.h> | |
8485bb11 | 29 | #include <ctype.h> |
a54c0b3f | 30 | |
f24e4d82 MK |
31 | #define COMPAT /* allow non-labeled disks */ |
32 | ||
8485bb11 KM |
33 | /* |
34 | * The following two constants set the default block and fragment sizes. | |
35 | * Both constants must be a power of 2 and meet the following constraints: | |
36 | * MINBSIZE <= DESBLKSIZE <= MAXBSIZE | |
37 | * sectorsize <= DESFRAGSIZE <= DESBLKSIZE | |
38 | * DESBLKSIZE / DESFRAGSIZE <= 8 | |
39 | */ | |
40 | #define DFL_FRAGSIZE 1024 | |
41 | #define DFL_BLKSIZE 8192 | |
42 | ||
43 | /* | |
38f1cd11 | 44 | * Cylinder groups may have up to many cylinders. The actual |
8485bb11 | 45 | * number used depends upon how much information can be stored |
38f1cd11 | 46 | * on a single cylinder. The default is to use 16 cylinders |
8485bb11 KM |
47 | * per group. |
48 | */ | |
49 | #define DESCPG 16 /* desired fs_cpg */ | |
89241117 | 50 | |
8485bb11 KM |
51 | /* |
52 | * MINFREE gives the minimum acceptable percentage of file system | |
53 | * blocks which may be free. If the freelist drops below this level | |
54 | * only the superuser may continue to allocate blocks. This may | |
55 | * be set to 0 if no reserve of free blocks is deemed necessary, | |
56 | * however throughput drops by fifty percent if the file system | |
57 | * is run at between 90% and 100% full; thus the default value of | |
58 | * fs_minfree is 10%. With 10% free space, fragmentation is not a | |
59 | * problem, so we choose to optimize for time. | |
60 | */ | |
61 | #define MINFREE 10 | |
62 | #define DEFAULTOPT FS_OPTTIME | |
63 | ||
64 | /* | |
65 | * ROTDELAY gives the minimum number of milliseconds to initiate | |
66 | * another disk transfer on the same cylinder. It is used in | |
67 | * determining the rotationally optimal layout for disk blocks | |
68 | * within a file; the default of fs_rotdelay is 4ms. | |
69 | */ | |
70 | #define ROTDELAY 4 | |
71 | ||
72 | /* | |
73 | * MAXCONTIG sets the default for the maximum number of blocks | |
74 | * that may be allocated sequentially. Since UNIX drivers are | |
75 | * not capable of scheduling multi-block transfers, this defaults | |
76 | * to 1 (ie no contiguous blocks are allocated). | |
77 | */ | |
78 | #define MAXCONTIG 1 | |
79 | ||
3d632f12 KM |
80 | /* |
81 | * MAXBLKPG determines the maximum number of data blocks which are | |
82 | * placed in a single cylinder group. The default is one indirect | |
83 | * block worth of data blocks. | |
84 | */ | |
85 | #define MAXBLKPG(bsize) ((bsize) / sizeof(daddr_t)) | |
86 | ||
8485bb11 KM |
87 | /* |
88 | * Each file system has a number of inodes statically allocated. | |
89 | * We allocate one inode slot per NBPI bytes, expecting this | |
90 | * to be far more than we will ever need. | |
91 | */ | |
92 | #define NBPI 2048 | |
93 | ||
38f1cd11 KM |
94 | /* |
95 | * For each cylinder we keep track of the availability of blocks at different | |
96 | * rotational positions, so that we can lay out the data to be picked | |
97 | * up with minimum rotational latency. NRPOS is the default number of | |
98 | * rotational positions that we distinguish. With NRPOS of 8 the resolution | |
99 | * of our summary information is 2ms for a typical 3600 rpm drive. | |
100 | */ | |
101 | #define NRPOS 8 /* number distinct rotational positions */ | |
102 | ||
103 | ||
8485bb11 | 104 | int Nflag; /* run without writing file system */ |
a54c0b3f | 105 | int fssize; /* file system size */ |
a54c0b3f SL |
106 | int ntracks; /* # tracks/cylinder */ |
107 | int nsectors; /* # sectors/track */ | |
a20edd44 | 108 | int nphyssectors; /* # sectors/track including spares */ |
8485bb11 | 109 | int secpercyl; /* sectors per cylinder */ |
a20edd44 KM |
110 | int trackspares = -1; /* spare sectors per track */ |
111 | int cylspares = -1; /* spare sectors per cylinder */ | |
a54c0b3f | 112 | int sectorsize; /* bytes/sector */ |
c5d3fd78 MK |
113 | #ifdef tahoe |
114 | int realsectorsize; /* bytes/sector in hardware */ | |
115 | #endif | |
c6003316 | 116 | int rpm; /* revolutions/minute of drive */ |
a20edd44 KM |
117 | int interleave; /* hardware sector interleave */ |
118 | int trackskew = -1; /* sector 0 skew, per track */ | |
119 | int headswitch; /* head switch time, usec */ | |
120 | int trackseek; /* track-to-track seek, usec */ | |
187d180d MK |
121 | int fsize = 0; /* fragment size */ |
122 | int bsize = 0; /* block size */ | |
8485bb11 | 123 | int cpg = DESCPG; /* cylinders/cylinder group */ |
f40b03d9 | 124 | int cpgflg; /* cylinders/cylinder group flag was given */ |
8485bb11 KM |
125 | int minfree = MINFREE; /* free space threshold */ |
126 | int opt = DEFAULTOPT; /* optimization preference (space or time) */ | |
127 | int density = NBPI; /* number of bytes per inode */ | |
128 | int maxcontig = MAXCONTIG; /* max contiguous blocks to allocate */ | |
129 | int rotdelay = ROTDELAY; /* rotational delay between blocks */ | |
3d632f12 | 130 | int maxbpg; /* maximum blocks per file in a cyl group */ |
38f1cd11 | 131 | int nrpos = NRPOS; /* # of distinguished rotational positions */ |
c5d3fd78 MK |
132 | int bbsize = BBSIZE; /* boot block size */ |
133 | int sbsize = SBSIZE; /* superblock size */ | |
f24e4d82 MK |
134 | #ifdef COMPAT |
135 | int unlabelled; | |
136 | #endif | |
8485bb11 | 137 | |
a54c0b3f | 138 | char device[MAXPATHLEN]; |
a54c0b3f | 139 | |
8485bb11 | 140 | extern int errno; |
a54c0b3f SL |
141 | char *index(); |
142 | char *rindex(); | |
a54c0b3f SL |
143 | |
144 | main(argc, argv) | |
1b8b6e44 | 145 | int argc; |
a54c0b3f SL |
146 | char *argv[]; |
147 | { | |
148 | char *cp, *special; | |
a54c0b3f | 149 | register struct partition *pp; |
8485bb11 KM |
150 | register struct disklabel *lp; |
151 | struct disklabel *getdisklabel(); | |
152 | struct partition oldpartition; | |
a54c0b3f | 153 | struct stat st; |
8485bb11 | 154 | int fsi, fso; |
a54c0b3f SL |
155 | register int i; |
156 | int status; | |
157 | ||
158 | argc--, argv++; | |
159 | while (argc > 0 && argv[0][0] == '-') { | |
160 | for (cp = &argv[0][1]; *cp; cp++) | |
161 | switch (*cp) { | |
162 | ||
28b1d98d KM |
163 | case 'N': |
164 | Nflag++; | |
11b2fe08 HS |
165 | break; |
166 | ||
8485bb11 | 167 | case 'S': |
a54c0b3f | 168 | if (argc < 1) |
8485bb11 | 169 | fatal("-S: missing sector size"); |
a54c0b3f | 170 | argc--, argv++; |
8485bb11 KM |
171 | sectorsize = atoi(*argv); |
172 | if (sectorsize <= 0) | |
173 | fatal("%s: bad sector size", *argv); | |
a54c0b3f SL |
174 | goto next; |
175 | ||
8485bb11 | 176 | case 'a': |
75e589fc | 177 | if (argc < 1) |
3d632f12 | 178 | fatal("-a: missing max contiguous blocks\n"); |
75e589fc | 179 | argc--, argv++; |
3d632f12 KM |
180 | maxcontig = atoi(*argv); |
181 | if (maxcontig <= 0) | |
182 | fatal("%s: bad max contiguous blocks\n", | |
183 | *argv); | |
75e589fc KM |
184 | goto next; |
185 | ||
a54c0b3f SL |
186 | case 'b': |
187 | if (argc < 1) | |
188 | fatal("-b: missing block size"); | |
189 | argc--, argv++; | |
190 | bsize = atoi(*argv); | |
8485bb11 | 191 | if (bsize < MINBSIZE) |
a54c0b3f SL |
192 | fatal("%s: bad block size", *argv); |
193 | goto next; | |
194 | ||
8485bb11 | 195 | case 'c': |
a54c0b3f | 196 | if (argc < 1) |
8485bb11 | 197 | fatal("-c: missing cylinders/group"); |
a54c0b3f | 198 | argc--, argv++; |
8485bb11 KM |
199 | cpg = atoi(*argv); |
200 | if (cpg <= 0) | |
201 | fatal("%s: bad cylinders/group", *argv); | |
f40b03d9 | 202 | cpgflg++; |
a54c0b3f SL |
203 | goto next; |
204 | ||
8485bb11 | 205 | case 'd': |
a54c0b3f | 206 | if (argc < 1) |
3d632f12 | 207 | fatal("-d: missing rotational delay\n"); |
a54c0b3f | 208 | argc--, argv++; |
3d632f12 KM |
209 | rotdelay = atoi(*argv); |
210 | if (rotdelay < 0) | |
211 | fatal("%s: bad rotational delay\n", | |
212 | *argv); | |
213 | goto next; | |
214 | ||
215 | case 'e': | |
216 | if (argc < 1) | |
217 | fatal("-e: missing blocks pre file in a cyl group\n"); | |
218 | argc--, argv++; | |
219 | maxbpg = atoi(*argv); | |
220 | if (maxbpg <= 0) | |
221 | fatal("%s: bad blocks per file in a cyl group\n", | |
222 | *argv); | |
a54c0b3f SL |
223 | goto next; |
224 | ||
8485bb11 | 225 | case 'f': |
a54c0b3f | 226 | if (argc < 1) |
8485bb11 | 227 | fatal("-f: missing frag size"); |
a54c0b3f | 228 | argc--, argv++; |
8485bb11 KM |
229 | fsize = atoi(*argv); |
230 | if (fsize <= 0) | |
231 | fatal("%s: bad frag size", *argv); | |
232 | goto next; | |
233 | ||
234 | case 'i': | |
235 | if (argc < 1) | |
236 | fatal("-i: missing bytes per inode\n"); | |
237 | argc--, argv++; | |
238 | density = atoi(*argv); | |
239 | if (density <= 0) | |
240 | fatal("%s: bad bytes per inode\n", | |
241 | *argv); | |
a54c0b3f SL |
242 | goto next; |
243 | ||
a20edd44 KM |
244 | case 'k': |
245 | if (argc < 1) | |
246 | fatal("-k: track skew"); | |
247 | argc--, argv++; | |
248 | trackskew = atoi(*argv); | |
249 | if (trackskew < 0) | |
250 | fatal("%s: bad track skew", *argv); | |
251 | goto next; | |
252 | ||
253 | case 'l': | |
254 | if (argc < 1) | |
255 | fatal("-l: interleave"); | |
256 | argc--, argv++; | |
257 | interleave = atoi(*argv); | |
258 | if (interleave <= 0) | |
259 | fatal("%s: bad interleave", *argv); | |
260 | goto next; | |
261 | ||
c6003316 SL |
262 | case 'm': |
263 | if (argc < 1) | |
264 | fatal("-m: missing free space %%\n"); | |
265 | argc--, argv++; | |
266 | minfree = atoi(*argv); | |
267 | if (minfree < 0 || minfree > 99) | |
268 | fatal("%s: bad free space %%\n", | |
269 | *argv); | |
270 | goto next; | |
271 | ||
38f1cd11 KM |
272 | case 'n': |
273 | if (argc < 1) | |
274 | fatal("-n: missing rotational layout count\n"); | |
275 | argc--, argv++; | |
276 | nrpos = atoi(*argv); | |
277 | if (nrpos <= 0) | |
278 | fatal("%s: bad rotational layout count\n", | |
279 | *argv); | |
280 | goto next; | |
281 | ||
8485bb11 KM |
282 | case 'o': |
283 | if (argc < 1) | |
284 | fatal("-o: missing optimization preference"); | |
285 | argc--, argv++; | |
286 | if (strcmp(*argv, "space") == 0) | |
287 | opt = FS_OPTSPACE; | |
288 | else if (strcmp(*argv, "time") == 0) | |
289 | opt = FS_OPTTIME; | |
290 | else | |
291 | fatal("%s: bad optimization preference %s", | |
292 | *argv, | |
293 | "(options are `space' or `time')"); | |
294 | goto next; | |
295 | ||
a20edd44 KM |
296 | case 'p': |
297 | if (argc < 1) | |
298 | fatal("-p: spare sectors per track"); | |
299 | argc--, argv++; | |
300 | trackspares = atoi(*argv); | |
301 | if (trackspares < 0) | |
302 | fatal("%s: bad spare sectors per track", *argv); | |
303 | goto next; | |
304 | ||
c6003316 SL |
305 | case 'r': |
306 | if (argc < 1) | |
307 | fatal("-r: missing revs/minute\n"); | |
308 | argc--, argv++; | |
309 | rpm = atoi(*argv); | |
8485bb11 | 310 | if (rpm <= 0) |
c6003316 SL |
311 | fatal("%s: bad revs/minute\n", *argv); |
312 | goto next; | |
313 | ||
8485bb11 | 314 | case 's': |
685a1465 | 315 | if (argc < 1) |
8485bb11 | 316 | fatal("-s: missing file system size"); |
685a1465 | 317 | argc--, argv++; |
8485bb11 KM |
318 | fssize = atoi(*argv); |
319 | if (fssize <= 0) | |
320 | fatal("%s: bad file system size", | |
685a1465 KM |
321 | *argv); |
322 | goto next; | |
323 | ||
8485bb11 KM |
324 | case 't': |
325 | if (argc < 1) | |
326 | fatal("-t: missing track total"); | |
327 | argc--, argv++; | |
328 | ntracks = atoi(*argv); | |
329 | if (ntracks <= 0) | |
330 | fatal("%s: bad total tracks", *argv); | |
331 | goto next; | |
332 | ||
3d632f12 KM |
333 | case 'u': |
334 | if (argc < 1) | |
335 | fatal("-u: missing sectors/track"); | |
336 | argc--, argv++; | |
337 | nsectors = atoi(*argv); | |
338 | if (nsectors <= 0) | |
339 | fatal("%s: bad sectors/track", *argv); | |
340 | goto next; | |
341 | ||
342 | case 'x': | |
343 | if (argc < 1) | |
344 | fatal("-x: spare sectors per cylinder"); | |
345 | argc--, argv++; | |
346 | cylspares = atoi(*argv); | |
347 | if (cylspares < 0) | |
348 | fatal("%s: bad spare sectors per cylinder", *argv); | |
349 | goto next; | |
350 | ||
a54c0b3f | 351 | default: |
fbf84598 | 352 | fatal("-%c: unknown flag", *cp); |
a54c0b3f SL |
353 | } |
354 | next: | |
355 | argc--, argv++; | |
356 | } | |
8485bb11 | 357 | if (argc < 1) { |
f24e4d82 MK |
358 | #ifdef COMPAT |
359 | fprintf(stderr, | |
360 | "usage: newfs [ fsoptions ] special-device [device-type]\n"); | |
361 | #else | |
8485bb11 | 362 | fprintf(stderr, "usage: newfs [ fsoptions ] special-device\n"); |
f24e4d82 | 363 | #endif |
8485bb11 | 364 | fprintf(stderr, "where fsoptions are:\n"); |
28b1d98d KM |
365 | fprintf(stderr, "\t-N do not create file system, %s\n", |
366 | "just print out parameters"); | |
e6b4584b SL |
367 | fprintf(stderr, "\t-b block size\n"); |
368 | fprintf(stderr, "\t-f frag size\n"); | |
c6003316 | 369 | fprintf(stderr, "\t-m minimum free space %%\n"); |
75e589fc KM |
370 | fprintf(stderr, "\t-o optimization preference %s\n", |
371 | "(`space' or `time')"); | |
3d632f12 KM |
372 | fprintf(stderr, "\t-a maximum contiguous blocks\n"); |
373 | fprintf(stderr, "\t-d rotational delay between %s\n", | |
374 | "contiguous blocks"); | |
375 | fprintf(stderr, "\t-e maximum blocks per file in a %s\n", | |
376 | "cylinder group"); | |
685a1465 | 377 | fprintf(stderr, "\t-i number of bytes per inode\n"); |
6bd85141 | 378 | fprintf(stderr, "\t-c cylinders/group\n"); |
38f1cd11 KM |
379 | fprintf(stderr, "\t-n number of distinguished %s\n", |
380 | "rotational positions"); | |
6bd85141 KM |
381 | fprintf(stderr, "\t-s file system size (sectors)\n"); |
382 | fprintf(stderr, "\t-r revolutions/minute\n"); | |
8485bb11 | 383 | fprintf(stderr, "\t-S sector size\n"); |
3d632f12 | 384 | fprintf(stderr, "\t-u sectors/track\n"); |
6bd85141 | 385 | fprintf(stderr, "\t-t tracks/cylinder\n"); |
a20edd44 | 386 | fprintf(stderr, "\t-p spare sectors per track\n"); |
3d632f12 | 387 | fprintf(stderr, "\t-x spare sectors per cylinder\n"); |
6bd85141 KM |
388 | fprintf(stderr, "\t-l hardware sector interleave\n"); |
389 | fprintf(stderr, "\t-k sector 0 skew, per track\n"); | |
a54c0b3f SL |
390 | exit(1); |
391 | } | |
392 | special = argv[0]; | |
1b8b6e44 KM |
393 | cp = rindex(special, '/'); |
394 | if (cp != 0) | |
395 | special = cp + 1; | |
2f56e34c | 396 | if (*special == 'r' && special[1] != 'a' && special[1] != 'b') |
1b8b6e44 | 397 | special++; |
9bd38ba8 KB |
398 | (void)sprintf(device, "/dev/r%s", special); |
399 | special = device; | |
8485bb11 KM |
400 | if (!Nflag) { |
401 | fso = open(special, O_WRONLY); | |
402 | if (fso < 0) { | |
403 | perror(special); | |
404 | exit(1); | |
405 | } | |
406 | } else | |
407 | fso = -1; | |
408 | fsi = open(special, O_RDONLY); | |
409 | if (fsi < 0) { | |
410 | perror(special); | |
411 | exit(1); | |
412 | } | |
413 | if (fstat(fsi, &st) < 0) { | |
c6003316 | 414 | fprintf(stderr, "newfs: "); perror(special); |
a54c0b3f SL |
415 | exit(2); |
416 | } | |
1b8b6e44 KM |
417 | if ((st.st_mode & S_IFMT) != S_IFCHR) |
418 | fatal("%s: not a character device", special); | |
a54c0b3f | 419 | cp = index(argv[0], '\0') - 1; |
8485bb11 | 420 | if (cp == 0 || (*cp < 'a' || *cp > 'h') && !isdigit(*cp)) |
a54c0b3f | 421 | fatal("%s: can't figure out file system partition", argv[0]); |
f24e4d82 MK |
422 | #ifdef COMPAT |
423 | lp = getdisklabel(special, fsi, argv[1]); | |
424 | #else | |
8485bb11 | 425 | lp = getdisklabel(special, fsi); |
f24e4d82 | 426 | #endif |
8485bb11 KM |
427 | if (isdigit(*cp)) |
428 | pp = &lp->d_partitions[0]; | |
429 | else | |
430 | pp = &lp->d_partitions[*cp - 'a']; | |
431 | if (pp->p_size == 0) | |
432 | fatal("%s: `%c' partition is unavailable", argv[0], *cp); | |
433 | if (fssize == 0) | |
a54c0b3f | 434 | fssize = pp->p_size; |
8485bb11 KM |
435 | if (fssize > pp->p_size) |
436 | fatal("%s: maximum file system size on the `%c' partition is %d", | |
437 | argv[0], *cp, pp->p_size); | |
438 | if (rpm == 0) { | |
439 | rpm = lp->d_rpm; | |
440 | if (rpm <= 0) | |
6181c540 | 441 | rpm = 3600; |
a54c0b3f SL |
442 | } |
443 | if (ntracks == 0) { | |
8485bb11 KM |
444 | ntracks = lp->d_ntracks; |
445 | if (ntracks <= 0) | |
6181c540 | 446 | fatal("%s: no default #tracks", argv[0]); |
a54c0b3f | 447 | } |
8485bb11 KM |
448 | if (nsectors == 0) { |
449 | nsectors = lp->d_nsectors; | |
450 | if (nsectors <= 0) | |
6181c540 | 451 | fatal("%s: no default #sectors/track", argv[0]); |
8485bb11 | 452 | } |
a54c0b3f | 453 | if (sectorsize == 0) { |
8485bb11 KM |
454 | sectorsize = lp->d_secsize; |
455 | if (sectorsize <= 0) | |
6181c540 | 456 | fatal("%s: no default sector size", argv[0]); |
a54c0b3f | 457 | } |
a20edd44 KM |
458 | if (trackskew == -1) { |
459 | trackskew = lp->d_trackskew; | |
460 | if (trackskew < 0) | |
6181c540 | 461 | trackskew = 0; |
a20edd44 KM |
462 | } |
463 | if (interleave == 0) { | |
464 | interleave = lp->d_interleave; | |
465 | if (interleave <= 0) | |
6181c540 | 466 | interleave = 1; |
a20edd44 | 467 | } |
a54c0b3f SL |
468 | if (fsize == 0) { |
469 | fsize = pp->p_fsize; | |
8485bb11 KM |
470 | if (fsize <= 0) |
471 | fsize = MAX(DFL_FRAGSIZE, lp->d_secsize); | |
a54c0b3f | 472 | } |
8485bb11 KM |
473 | if (bsize == 0) { |
474 | bsize = pp->p_frag * pp->p_fsize; | |
475 | if (bsize <= 0) | |
476 | bsize = MIN(DFL_BLKSIZE, 8 * fsize); | |
c6003316 | 477 | } |
75e589fc | 478 | if (minfree < 10 && opt != FS_OPTSPACE) { |
8485bb11 KM |
479 | fprintf(stderr, "Warning: changing optimization to space "); |
480 | fprintf(stderr, "because minfree is less than 10%%\n"); | |
75e589fc KM |
481 | opt = FS_OPTSPACE; |
482 | } | |
a20edd44 KM |
483 | if (trackspares == -1) { |
484 | trackspares = lp->d_sparespertrack; | |
485 | if (trackspares < 0) | |
6181c540 | 486 | trackspares = 0; |
a20edd44 KM |
487 | } |
488 | nphyssectors = nsectors + trackspares; | |
489 | if (cylspares == -1) { | |
490 | cylspares = lp->d_sparespercyl; | |
491 | if (cylspares < 0) | |
6181c540 | 492 | cylspares = 0; |
a20edd44 KM |
493 | } |
494 | secpercyl = nsectors * ntracks - cylspares; | |
8485bb11 KM |
495 | if (secpercyl != lp->d_secpercyl) |
496 | fprintf(stderr, "%s (%d) %s (%d)\n", | |
497 | "Warning: calculated sectors per cylinder", secpercyl, | |
498 | "disagrees with disk label", lp->d_secpercyl); | |
c9b3f9df KM |
499 | if (maxbpg == 0) |
500 | maxbpg = MAXBLKPG(bsize); | |
a20edd44 KM |
501 | headswitch = lp->d_headswitch; |
502 | trackseek = lp->d_trkseek; | |
c5d3fd78 MK |
503 | bbsize = lp->d_bbsize; |
504 | sbsize = lp->d_sbsize; | |
8485bb11 | 505 | oldpartition = *pp; |
c5d3fd78 MK |
506 | #ifdef tahoe |
507 | realsectorsize = sectorsize; | |
187d180d | 508 | if (sectorsize != DEV_BSIZE) { /* XXX */ |
c5d3fd78 MK |
509 | int secperblk = DEV_BSIZE / sectorsize; |
510 | ||
511 | sectorsize = DEV_BSIZE; | |
512 | nsectors /= secperblk; | |
513 | nphyssectors /= secperblk; | |
514 | secpercyl /= secperblk; | |
515 | fssize /= secperblk; | |
516 | pp->p_size /= secperblk; | |
517 | } | |
518 | #endif | |
8485bb11 | 519 | mkfs(pp, special, fsi, fso); |
c5d3fd78 MK |
520 | #ifdef tahoe |
521 | if (realsectorsize != DEV_BSIZE) | |
522 | pp->p_size *= DEV_BSIZE / realsectorsize; | |
523 | #endif | |
8485bb11 KM |
524 | if (!Nflag && bcmp(pp, &oldpartition, sizeof(oldpartition))) |
525 | rewritelabel(special, fso, lp); | |
a54c0b3f SL |
526 | exit(0); |
527 | } | |
528 | ||
f24e4d82 MK |
529 | #ifdef COMPAT |
530 | struct disklabel * | |
531 | getdisklabel(s, fd, type) | |
532 | char *s, *type; | |
533 | int fd; | |
534 | { | |
535 | static struct disklabel lab; | |
536 | struct disklabel *getdiskbyname(); | |
537 | ||
538 | if (ioctl(fd, DIOCGDINFO, (char *)&lab) < 0) { | |
539 | if (type == NULL) { | |
540 | perror("ioctl (GDINFO)"); | |
541 | fatal( | |
542 | "%s: can't read disk label; disk type must be specified", s); | |
543 | } | |
544 | unlabelled++; | |
545 | return (getdiskbyname(type)); | |
546 | } | |
547 | return (&lab); | |
548 | } | |
549 | #else | |
8485bb11 KM |
550 | struct disklabel * |
551 | getdisklabel(s, fd) | |
552 | char *s; | |
f24e4d82 | 553 | int fd; |
a54c0b3f | 554 | { |
8485bb11 KM |
555 | static struct disklabel lab; |
556 | ||
557 | if (ioctl(fd, DIOCGDINFO, (char *)&lab) < 0) { | |
558 | perror("ioctl (GDINFO)"); | |
559 | fatal("%s: can't read disk label", s); | |
560 | } | |
561 | return (&lab); | |
562 | } | |
f24e4d82 | 563 | #endif |
8485bb11 KM |
564 | |
565 | rewritelabel(s, fd, lp) | |
566 | char *s; | |
a54c0b3f | 567 | int fd; |
8485bb11 KM |
568 | register struct disklabel *lp; |
569 | { | |
570 | ||
f24e4d82 MK |
571 | #ifdef COMPAT |
572 | if (unlabelled) | |
573 | return; | |
574 | #endif | |
8485bb11 KM |
575 | lp->d_checksum = 0; |
576 | lp->d_checksum = dkcksum(lp); | |
577 | if (ioctl(fd, DIOCWDINFO, (char *)lp) < 0) { | |
aaa1c5f0 | 578 | perror("ioctl (WDINFO)"); |
8485bb11 | 579 | fatal("%s: can't rewrite disk label", s); |
a54c0b3f | 580 | } |
bf8f0524 MK |
581 | #if vax |
582 | if (lp->d_type == DTYPE_SMD && lp->d_flags & D_BADSECT) { | |
583 | register i; | |
c5d3fd78 | 584 | int cfd; |
bf8f0524 | 585 | daddr_t alt; |
c5d3fd78 MK |
586 | char specname[64]; |
587 | char blk[1024]; | |
866736b4 | 588 | char *cp; |
c5d3fd78 MK |
589 | |
590 | /* | |
591 | * Make name for 'c' partition. | |
592 | */ | |
593 | strcpy(specname, s); | |
594 | cp = specname + strlen(specname) - 1; | |
595 | if (!isdigit(*cp)) | |
596 | *cp = 'c'; | |
597 | cfd = open(specname, O_WRONLY); | |
598 | if (cfd < 0) { | |
599 | perror(specname); | |
600 | exit(2); | |
601 | } | |
602 | bzero(blk, sizeof(blk)); | |
603 | *(struct disklabel *)(blk + LABELOFFSET) = *lp; | |
bf8f0524 MK |
604 | alt = lp->d_ncylinders * lp->d_secpercyl - lp->d_nsectors; |
605 | for (i = 1; i < 11 && i < lp->d_nsectors; i += 2) { | |
f24e4d82 MK |
606 | if (lseek(cfd, (off_t)(alt + i) * lp->d_secsize, L_SET) == -1) { |
607 | perror("lseek to badsector area"); | |
608 | exit(30); | |
609 | } | |
c5d3fd78 | 610 | if (write(cfd, blk, lp->d_secsize) < lp->d_secsize) { |
bf8f0524 MK |
611 | int oerrno = errno; |
612 | fprintf(stderr, "alternate label %d ", i/2); | |
613 | errno = oerrno; | |
614 | perror("write"); | |
615 | } | |
8485bb11 KM |
616 | } |
617 | } | |
bf8f0524 | 618 | #endif |
a54c0b3f SL |
619 | } |
620 | ||
621 | /*VARARGS*/ | |
622 | fatal(fmt, arg1, arg2) | |
623 | char *fmt; | |
624 | { | |
625 | ||
c6003316 | 626 | fprintf(stderr, "newfs: "); |
a54c0b3f SL |
627 | fprintf(stderr, fmt, arg1, arg2); |
628 | putc('\n', stderr); | |
629 | exit(10); | |
630 | } |