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