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