xref: /csrg-svn/sbin/newfs/newfs.c (revision 31045)
121159Sdist /*
221159Sdist  * Copyright (c) 1983 Regents of the University of California.
321159Sdist  * All rights reserved.  The Berkeley software License Agreement
421159Sdist  * specifies the terms and conditions for redistribution.
521159Sdist  */
621159Sdist 
710762Ssam #ifndef lint
821159Sdist char copyright[] =
921159Sdist "@(#) Copyright (c) 1983 Regents of the University of California.\n\
1021159Sdist  All rights reserved.\n";
1121159Sdist #endif not lint
1210762Ssam 
1321159Sdist #ifndef lint
14*31045Ssam static char sccsid[] = "@(#)newfs.c	6.8 (Berkeley) 05/08/87";
1521159Sdist #endif not lint
1621159Sdist 
1710762Ssam /*
1811069Ssam  * newfs: friendly front end to mkfs
1910762Ssam  */
2010762Ssam #include <sys/param.h>
2110762Ssam #include <sys/stat.h>
2210762Ssam #include <sys/fs.h>
2313603Ssam #include <sys/dir.h>
2430380Smckusick #include <sys/ioctl.h>
2530380Smckusick #include <sys/disklabel.h>
2630380Smckusick #include <sys/file.h>
2710762Ssam 
2810762Ssam #include <stdio.h>
2930380Smckusick #include <ctype.h>
3010762Ssam 
3130380Smckusick /*
3230380Smckusick  * The following two constants set the default block and fragment sizes.
3330380Smckusick  * Both constants must be a power of 2 and meet the following constraints:
3430380Smckusick  *	MINBSIZE <= DESBLKSIZE <= MAXBSIZE
3530380Smckusick  *	sectorsize <= DESFRAGSIZE <= DESBLKSIZE
3630380Smckusick  *	DESBLKSIZE / DESFRAGSIZE <= 8
3730380Smckusick  */
3830380Smckusick #define	DFL_FRAGSIZE	1024
3930380Smckusick #define	DFL_BLKSIZE	8192
4011183Ssam 
4130380Smckusick /*
4230380Smckusick  * Cylinder groups may have up to MAXCPG cylinders. The actual
4330380Smckusick  * number used depends upon how much information can be stored
4430380Smckusick  * on a single cylinder. The default is to used 16 cylinders
4530380Smckusick  * per group.
4630380Smckusick  */
4730380Smckusick #define	DESCPG		16	/* desired fs_cpg */
4830380Smckusick 
4930380Smckusick /*
5030380Smckusick  * MINFREE gives the minimum acceptable percentage of file system
5130380Smckusick  * blocks which may be free. If the freelist drops below this level
5230380Smckusick  * only the superuser may continue to allocate blocks. This may
5330380Smckusick  * be set to 0 if no reserve of free blocks is deemed necessary,
5430380Smckusick  * however throughput drops by fifty percent if the file system
5530380Smckusick  * is run at between 90% and 100% full; thus the default value of
5630380Smckusick  * fs_minfree is 10%. With 10% free space, fragmentation is not a
5730380Smckusick  * problem, so we choose to optimize for time.
5830380Smckusick  */
5930380Smckusick #define MINFREE		10
6030380Smckusick #define DEFAULTOPT	FS_OPTTIME
6130380Smckusick 
6230380Smckusick /*
6330380Smckusick  * ROTDELAY gives the minimum number of milliseconds to initiate
6430380Smckusick  * another disk transfer on the same cylinder. It is used in
6530380Smckusick  * determining the rotationally optimal layout for disk blocks
6630380Smckusick  * within a file; the default of fs_rotdelay is 4ms.
6730380Smckusick  */
6830380Smckusick #define ROTDELAY	4
6930380Smckusick 
7030380Smckusick /*
7130380Smckusick  * MAXCONTIG sets the default for the maximum number of blocks
7230380Smckusick  * that may be allocated sequentially. Since UNIX drivers are
7330380Smckusick  * not capable of scheduling multi-block transfers, this defaults
7430380Smckusick  * to 1 (ie no contiguous blocks are allocated).
7530380Smckusick  */
7630380Smckusick #define MAXCONTIG	1
7730380Smckusick 
7830380Smckusick /*
7930380Smckusick  * Each file system has a number of inodes statically allocated.
8030380Smckusick  * We allocate one inode slot per NBPI bytes, expecting this
8130380Smckusick  * to be far more than we will ever need.
8230380Smckusick  */
8330380Smckusick #define	NBPI		2048
8430380Smckusick 
8530380Smckusick int	Nflag;			/* run without writing file system */
8610762Ssam int	fssize;			/* file system size */
8710762Ssam int	ntracks;		/* # tracks/cylinder */
8810762Ssam int	nsectors;		/* # sectors/track */
8930386Smckusick int	nphyssectors;		/* # sectors/track including spares */
9030380Smckusick int	secpercyl;		/* sectors per cylinder */
9130386Smckusick int	trackspares = -1;	/* spare sectors per track */
9230386Smckusick int	cylspares = -1;		/* spare sectors per cylinder */
9310762Ssam int	sectorsize;		/* bytes/sector */
9430691Skarels #ifdef tahoe
9530691Skarels int	realsectorsize;		/* bytes/sector in hardware */
9630691Skarels #endif
9711069Ssam int	rpm;			/* revolutions/minute of drive */
9830386Smckusick int	interleave;		/* hardware sector interleave */
9930386Smckusick int	trackskew = -1;		/* sector 0 skew, per track */
10030386Smckusick int	headswitch;		/* head switch time, usec */
10130386Smckusick int	trackseek;		/* track-to-track seek, usec */
10230862Skarels int	fsize = 0;		/* fragment size */
10330862Skarels int	bsize = 0;		/* block size */
10430380Smckusick int	cpg = DESCPG;		/* cylinders/cylinder group */
10530380Smckusick int	minfree = MINFREE;	/* free space threshold */
10630380Smckusick int	opt = DEFAULTOPT;	/* optimization preference (space or time) */
10730380Smckusick int	density = NBPI;		/* number of bytes per inode */
10830380Smckusick int	maxcontig = MAXCONTIG;	/* max contiguous blocks to allocate */
10930380Smckusick int	rotdelay = ROTDELAY;	/* rotational delay between blocks */
11030691Skarels int	bbsize = BBSIZE;	/* boot block size */
11130691Skarels int	sbsize = SBSIZE;	/* superblock size */
11210762Ssam 
11310762Ssam char	device[MAXPATHLEN];
11410762Ssam 
11530380Smckusick extern	int errno;
11610762Ssam char	*index();
11710762Ssam char	*rindex();
11810762Ssam char	*sprintf();
11910762Ssam 
12010762Ssam main(argc, argv)
12114064Smckusick 	int argc;
12210762Ssam 	char *argv[];
12310762Ssam {
12410762Ssam 	char *cp, *special;
12510762Ssam 	register struct partition *pp;
12630380Smckusick 	register struct disklabel *lp;
12730380Smckusick 	struct disklabel *getdisklabel();
12830380Smckusick 	struct partition oldpartition;
12910762Ssam 	struct stat st;
13030380Smckusick 	int fsi, fso;
13110762Ssam 	register int i;
13210762Ssam 	int status;
13310762Ssam 
13410762Ssam 	argc--, argv++;
13510762Ssam 	while (argc > 0 && argv[0][0] == '-') {
13610762Ssam 		for (cp = &argv[0][1]; *cp; cp++)
13710762Ssam 			switch (*cp) {
13810762Ssam 
13916945Smckusick 			case 'N':
14016945Smckusick 				Nflag++;
14112334Shelge 				break;
14212334Shelge 
14330380Smckusick 			case 'S':
14410762Ssam 				if (argc < 1)
14530380Smckusick 					fatal("-S: missing sector size");
14610762Ssam 				argc--, argv++;
14730380Smckusick 				sectorsize = atoi(*argv);
14830380Smckusick 				if (sectorsize <= 0)
14930380Smckusick 					fatal("%s: bad sector size", *argv);
15010762Ssam 				goto next;
15110762Ssam 
15230380Smckusick 			case 'a':
15310762Ssam 				if (argc < 1)
15430380Smckusick 					fatal("-a: spare sectors per cylinder");
15510762Ssam 				argc--, argv++;
15630386Smckusick 				cylspares = atoi(*argv);
15730386Smckusick 				if (cylspares < 0)
15830380Smckusick 					fatal("%s: bad spare sectors per cylinder", *argv);
15910762Ssam 				goto next;
16010762Ssam 
16110762Ssam 			case 'b':
16210762Ssam 				if (argc < 1)
16310762Ssam 					fatal("-b: missing block size");
16410762Ssam 				argc--, argv++;
16510762Ssam 				bsize = atoi(*argv);
16630380Smckusick 				if (bsize < MINBSIZE)
16710762Ssam 					fatal("%s: bad block size", *argv);
16810762Ssam 				goto next;
16910762Ssam 
17030380Smckusick 			case 'c':
17130380Smckusick 				if (argc < 1)
17230380Smckusick 					fatal("-c: missing cylinders/group");
17330380Smckusick 				argc--, argv++;
17430380Smckusick 				cpg = atoi(*argv);
17530380Smckusick 				if (cpg <= 0)
17630380Smckusick 					fatal("%s: bad cylinders/group", *argv);
17730380Smckusick 				goto next;
17830380Smckusick 
17930380Smckusick 			case 'd':
18030380Smckusick 				if (argc < 1)
18130380Smckusick 					fatal("-d: missing sectors/track");
18230380Smckusick 				argc--, argv++;
18330380Smckusick 				nsectors = atoi(*argv);
18430380Smckusick 				if (nsectors <= 0)
18530380Smckusick 					fatal("%s: bad sectors/track", *argv);
18630380Smckusick 				goto next;
18730380Smckusick 
18810762Ssam 			case 'f':
18910762Ssam 				if (argc < 1)
19010762Ssam 					fatal("-f: missing frag size");
19110762Ssam 				argc--, argv++;
19210762Ssam 				fsize = atoi(*argv);
19330380Smckusick 				if (fsize <= 0)
19410762Ssam 					fatal("%s: bad frag size", *argv);
19510762Ssam 				goto next;
19610762Ssam 
19730380Smckusick 			case 'i':
19810762Ssam 				if (argc < 1)
19930380Smckusick 					fatal("-i: missing bytes per inode\n");
20010762Ssam 				argc--, argv++;
20130380Smckusick 				density = atoi(*argv);
20230380Smckusick 				if (density <= 0)
20330380Smckusick 					fatal("%s: bad bytes per inode\n",
20430380Smckusick 						*argv);
20510762Ssam 				goto next;
20610762Ssam 
20730386Smckusick 			case 'k':
20830386Smckusick 				if (argc < 1)
20930386Smckusick 					fatal("-k: track skew");
21030386Smckusick 				argc--, argv++;
21130386Smckusick 				trackskew = atoi(*argv);
21230386Smckusick 				if (trackskew < 0)
21330386Smckusick 					fatal("%s: bad track skew", *argv);
21430386Smckusick 				goto next;
21530386Smckusick 
21630386Smckusick 			case 'l':
21730386Smckusick 				if (argc < 1)
21830386Smckusick 					fatal("-l: interleave");
21930386Smckusick 				argc--, argv++;
22030386Smckusick 				interleave = atoi(*argv);
22130386Smckusick 				if (interleave <= 0)
22230386Smckusick 					fatal("%s: bad interleave", *argv);
22330386Smckusick 				goto next;
22430386Smckusick 
22511069Ssam 			case 'm':
22611069Ssam 				if (argc < 1)
22711069Ssam 					fatal("-m: missing free space %%\n");
22811069Ssam 				argc--, argv++;
22911069Ssam 				minfree = atoi(*argv);
23011069Ssam 				if (minfree < 0 || minfree > 99)
23111069Ssam 					fatal("%s: bad free space %%\n",
23211069Ssam 						*argv);
23311069Ssam 				goto next;
23411069Ssam 
23530380Smckusick 			case 'o':
23630380Smckusick 				if (argc < 1)
23730380Smckusick 					fatal("-o: missing optimization preference");
23830380Smckusick 				argc--, argv++;
23930380Smckusick 				if (strcmp(*argv, "space") == 0)
24030380Smckusick 					opt = FS_OPTSPACE;
24130380Smckusick 				else if (strcmp(*argv, "time") == 0)
24230380Smckusick 					opt = FS_OPTTIME;
24330380Smckusick 				else
24430380Smckusick 					fatal("%s: bad optimization preference %s",
24530380Smckusick 					    *argv,
24630380Smckusick 					    "(options are `space' or `time')");
24730380Smckusick 				goto next;
24830380Smckusick 
24930386Smckusick 			case 'p':
25030386Smckusick 				if (argc < 1)
25130386Smckusick 					fatal("-p: spare sectors per track");
25230386Smckusick 				argc--, argv++;
25330386Smckusick 				trackspares = atoi(*argv);
25430386Smckusick 				if (trackspares < 0)
25530386Smckusick 					fatal("%s: bad spare sectors per track", *argv);
25630386Smckusick 				goto next;
25730386Smckusick 
25811069Ssam 			case 'r':
25911069Ssam 				if (argc < 1)
26011069Ssam 					fatal("-r: missing revs/minute\n");
26111069Ssam 				argc--, argv++;
26211069Ssam 				rpm = atoi(*argv);
26330380Smckusick 				if (rpm <= 0)
26411069Ssam 					fatal("%s: bad revs/minute\n", *argv);
26511069Ssam 				goto next;
26611069Ssam 
26730380Smckusick 			case 's':
26814884Smckusick 				if (argc < 1)
26930380Smckusick 					fatal("-s: missing file system size");
27014884Smckusick 				argc--, argv++;
27130380Smckusick 				fssize = atoi(*argv);
27230380Smckusick 				if (fssize <= 0)
27330380Smckusick 					fatal("%s: bad file system size",
27414884Smckusick 						*argv);
27514884Smckusick 				goto next;
27614884Smckusick 
27730380Smckusick 			case 't':
27830380Smckusick 				if (argc < 1)
27930380Smckusick 					fatal("-t: missing track total");
28030380Smckusick 				argc--, argv++;
28130380Smckusick 				ntracks = atoi(*argv);
28230380Smckusick 				if (ntracks <= 0)
28330380Smckusick 					fatal("%s: bad total tracks", *argv);
28430380Smckusick 				goto next;
28530380Smckusick 
28610762Ssam 			default:
28710762Ssam 				fatal("-%c: unknown flag", cp);
28810762Ssam 			}
28910762Ssam next:
29010762Ssam 		argc--, argv++;
29110762Ssam 	}
29230380Smckusick 	if (argc < 1) {
29330380Smckusick 		fprintf(stderr, "usage: newfs [ fsoptions ] special-device\n");
29430380Smckusick 		fprintf(stderr, "where fsoptions are:\n");
29516945Smckusick 		fprintf(stderr, "\t-N do not create file system, %s\n",
29616945Smckusick 			"just print out parameters");
29711057Ssam 		fprintf(stderr, "\t-b block size\n");
29811057Ssam 		fprintf(stderr, "\t-f frag size\n");
29911069Ssam 		fprintf(stderr, "\t-m minimum free space %%\n");
30024702Smckusick 		fprintf(stderr, "\t-o optimization preference %s\n",
30124702Smckusick 			"(`space' or `time')");
30230398Smckusick 		fprintf(stderr, "\t-i number of bytes per inode\n");
30330398Smckusick 		fprintf(stderr, "\t-c cylinders/group\n");
30430398Smckusick 		fprintf(stderr, "\t-s file system size (sectors)\n");
30511069Ssam 		fprintf(stderr, "\t-r revolutions/minute\n");
30611057Ssam 		fprintf(stderr, "\t-S sector size\n");
30730398Smckusick 		fprintf(stderr, "\t-d sectors/track\n");
30830398Smckusick 		fprintf(stderr, "\t-t tracks/cylinder\n");
30930398Smckusick 		fprintf(stderr, "\t-p spare sectors per track\n");
31030398Smckusick 		fprintf(stderr, "\t-a spare sectors per cylinder\n");
31130386Smckusick 		fprintf(stderr, "\t-l hardware sector interleave\n");
31230386Smckusick 		fprintf(stderr, "\t-k sector 0 skew, per track\n");
31310762Ssam 		exit(1);
31410762Ssam 	}
31510762Ssam 	special = argv[0];
31614064Smckusick 	cp = rindex(special, '/');
31714064Smckusick 	if (cp != 0)
31814064Smckusick 		special = cp + 1;
31914321Ssam 	if (*special == 'r' && special[1] != 'a' && special[1] != 'b')
32014064Smckusick 		special++;
32114064Smckusick 	special = sprintf(device, "/dev/r%s", special);
32230380Smckusick 	if (!Nflag) {
32330380Smckusick 		fso = open(special, O_WRONLY);
32430380Smckusick 		if (fso < 0) {
32530380Smckusick 			perror(special);
32630380Smckusick 			exit(1);
32730380Smckusick 		}
32830380Smckusick 	} else
32930380Smckusick 		fso = -1;
33030380Smckusick 	fsi = open(special, O_RDONLY);
33130380Smckusick 	if (fsi < 0) {
33230380Smckusick 		perror(special);
33330380Smckusick 		exit(1);
33430380Smckusick 	}
33530380Smckusick 	if (fstat(fsi, &st) < 0) {
33611069Ssam 		fprintf(stderr, "newfs: "); perror(special);
33710762Ssam 		exit(2);
33810762Ssam 	}
33914064Smckusick 	if ((st.st_mode & S_IFMT) != S_IFCHR)
34014064Smckusick 		fatal("%s: not a character device", special);
34110762Ssam 	cp = index(argv[0], '\0') - 1;
34230380Smckusick 	if (cp == 0 || (*cp < 'a' || *cp > 'h') && !isdigit(*cp))
34310762Ssam 		fatal("%s: can't figure out file system partition", argv[0]);
34430380Smckusick 	lp = getdisklabel(special, fsi);
34530380Smckusick 	if (isdigit(*cp))
34630380Smckusick 		pp = &lp->d_partitions[0];
34730380Smckusick 	else
34830380Smckusick 		pp = &lp->d_partitions[*cp - 'a'];
34930380Smckusick 	if (pp->p_size == 0)
35030380Smckusick 		fatal("%s: `%c' partition is unavailable", argv[0], *cp);
35130380Smckusick 	if (fssize == 0)
35210762Ssam 		fssize = pp->p_size;
35330380Smckusick 	if (fssize > pp->p_size)
35430380Smckusick 	       fatal("%s: maximum file system size on the `%c' partition is %d",
35530380Smckusick 			argv[0], *cp, pp->p_size);
35630380Smckusick 	if (rpm == 0) {
35730380Smckusick 		rpm = lp->d_rpm;
35830380Smckusick 		if (rpm <= 0)
35930743Skarels 			rpm = 3600;
36010762Ssam 	}
36130380Smckusick 	if (ntracks == 0) {
36230380Smckusick 		ntracks = lp->d_ntracks;
36330380Smckusick 		if (ntracks <= 0)
36430743Skarels 			fatal("%s: no default #tracks", argv[0]);
36530380Smckusick 	}
36610762Ssam 	if (nsectors == 0) {
36730380Smckusick 		nsectors = lp->d_nsectors;
36830380Smckusick 		if (nsectors <= 0)
36930743Skarels 			fatal("%s: no default #sectors/track", argv[0]);
37010762Ssam 	}
37110762Ssam 	if (sectorsize == 0) {
37230380Smckusick 		sectorsize = lp->d_secsize;
37330380Smckusick 		if (sectorsize <= 0)
37430743Skarels 			fatal("%s: no default sector size", argv[0]);
37510762Ssam 	}
37630386Smckusick 	if (trackskew == -1) {
37730386Smckusick 		trackskew = lp->d_trackskew;
37830386Smckusick 		if (trackskew < 0)
37930743Skarels 			trackskew = 0;
38030386Smckusick 	}
38130386Smckusick 	if (interleave == 0) {
38230386Smckusick 		interleave = lp->d_interleave;
38330386Smckusick 		if (interleave <= 0)
38430743Skarels 			interleave = 1;
38530386Smckusick 	}
38610762Ssam 	if (fsize == 0) {
38710762Ssam 		fsize = pp->p_fsize;
38830380Smckusick 		if (fsize <= 0)
38930380Smckusick 			fsize = MAX(DFL_FRAGSIZE, lp->d_secsize);
39010762Ssam 	}
39130380Smckusick 	if (bsize == 0) {
39230380Smckusick 		bsize = pp->p_frag * pp->p_fsize;
39330380Smckusick 		if (bsize <= 0)
39430380Smckusick 			bsize = MIN(DFL_BLKSIZE, 8 * fsize);
39511069Ssam 	}
39624702Smckusick 	if (minfree < 10 && opt != FS_OPTSPACE) {
39730380Smckusick 		fprintf(stderr, "Warning: changing optimization to space ");
39830380Smckusick 		fprintf(stderr, "because minfree is less than 10%%\n");
39924702Smckusick 		opt = FS_OPTSPACE;
40024702Smckusick 	}
40130386Smckusick 	if (trackspares == -1) {
40230386Smckusick 		trackspares = lp->d_sparespertrack;
40330386Smckusick 		if (trackspares < 0)
40430743Skarels 			trackspares = 0;
40530386Smckusick 	}
40630386Smckusick 	nphyssectors = nsectors + trackspares;
40730386Smckusick 	if (cylspares == -1) {
40830386Smckusick 		cylspares = lp->d_sparespercyl;
40930386Smckusick 		if (cylspares < 0)
41030743Skarels 			cylspares = 0;
41130386Smckusick 	}
41230386Smckusick 	secpercyl = nsectors * ntracks - cylspares;
41330380Smckusick 	if (secpercyl != lp->d_secpercyl)
41430380Smckusick 		fprintf(stderr, "%s (%d) %s (%d)\n",
41530380Smckusick 			"Warning: calculated sectors per cylinder", secpercyl,
41630380Smckusick 			"disagrees with disk label", lp->d_secpercyl);
41730386Smckusick 	headswitch = lp->d_headswitch;
41830386Smckusick 	trackseek = lp->d_trkseek;
41930691Skarels 	bbsize = lp->d_bbsize;
42030691Skarels 	sbsize = lp->d_sbsize;
42130380Smckusick 	oldpartition = *pp;
42230691Skarels #ifdef tahoe
42330691Skarels 	realsectorsize = sectorsize;
42430862Skarels 	if (sectorsize != DEV_BSIZE) {		/* XXX */
42530691Skarels 		int secperblk = DEV_BSIZE / sectorsize;
42630691Skarels 
42730691Skarels 		sectorsize = DEV_BSIZE;
42830691Skarels 		nsectors /= secperblk;
42930691Skarels 		nphyssectors /= secperblk;
43030691Skarels 		secpercyl /= secperblk;
43130691Skarels 		fssize /= secperblk;
43230691Skarels 		pp->p_size /= secperblk;
43330691Skarels 	}
43430691Skarels #endif
43530380Smckusick 	mkfs(pp, special, fsi, fso);
43630691Skarels #ifdef tahoe
43730691Skarels 	if (realsectorsize != DEV_BSIZE)
43830691Skarels 		pp->p_size *= DEV_BSIZE / realsectorsize;
43930691Skarels #endif
44030380Smckusick 	if (!Nflag && bcmp(pp, &oldpartition, sizeof(oldpartition)))
44130380Smckusick 		rewritelabel(special, fso, lp);
44230380Smckusick 	exit(0);
44330380Smckusick }
44430380Smckusick 
44530380Smckusick struct disklabel *
44630380Smckusick getdisklabel(s, fd)
44730380Smckusick 	char *s;
44830380Smckusick 	int	fd;
44930380Smckusick {
45030380Smckusick 	static struct disklabel lab;
45130380Smckusick 
45230380Smckusick 	if (ioctl(fd, DIOCGDINFO, (char *)&lab) < 0) {
45330380Smckusick 		perror("ioctl (GDINFO)");
45430380Smckusick 		fatal("%s: can't read disk label", s);
45510762Ssam 	}
45630380Smckusick 	return (&lab);
45730380Smckusick }
45810762Ssam 
45930380Smckusick rewritelabel(s, fd, lp)
46030380Smckusick 	char *s;
46130380Smckusick 	int fd;
46230380Smckusick 	register struct disklabel *lp;
46330380Smckusick {
46430380Smckusick 
46530380Smckusick 	lp->d_checksum = 0;
46630380Smckusick 	lp->d_checksum = dkcksum(lp);
46730380Smckusick 	if (ioctl(fd, DIOCWDINFO, (char *)lp) < 0) {
46830380Smckusick 		perror("ioctl (GWINFO)");
46930380Smckusick 		fatal("%s: can't rewrite disk label", s);
47010762Ssam 	}
47130446Skarels #if vax
47230446Skarels 	if (lp->d_type == DTYPE_SMD && lp->d_flags & D_BADSECT) {
47330446Skarels 		register i;
47430691Skarels 		int cfd;
47530446Skarels 		daddr_t alt;
47630691Skarels 		char specname[64];
47730691Skarels 		char blk[1024];
478*31045Ssam 		char *cp;
47930446Skarels 
48030691Skarels 		/*
48130691Skarels 		 * Make name for 'c' partition.
48230691Skarels 		 */
48330691Skarels 		strcpy(specname, s);
48430691Skarels 		cp = specname + strlen(specname) - 1;
48530691Skarels 		if (!isdigit(*cp))
48630691Skarels 			*cp = 'c';
48730691Skarels 		cfd = open(specname, O_WRONLY);
48830691Skarels 		if (cfd < 0) {
48930691Skarels 			perror(specname);
49030691Skarels 			exit(2);
49130691Skarels 		}
49230691Skarels 		bzero(blk, sizeof(blk));
49330691Skarels 		*(struct disklabel *)(blk + LABELOFFSET) = *lp;
49430446Skarels 		alt = lp->d_ncylinders * lp->d_secpercyl - lp->d_nsectors;
49530446Skarels 		for (i = 1; i < 11 && i < lp->d_nsectors; i += 2) {
49630446Skarels 			lseek(cfd, (off_t)(alt + i) * lp->d_secsize, L_SET);
49730691Skarels 			if (write(cfd, blk, lp->d_secsize) < lp->d_secsize) {
49830446Skarels 				int oerrno = errno;
49930446Skarels 				fprintf(stderr, "alternate label %d ", i/2);
50030446Skarels 				errno = oerrno;
50130446Skarels 				perror("write");
50230446Skarels 			}
50330380Smckusick 		}
50430380Smckusick 	}
50530446Skarels #endif
50610762Ssam }
50710762Ssam 
50810762Ssam /*VARARGS*/
50910762Ssam fatal(fmt, arg1, arg2)
51010762Ssam 	char *fmt;
51110762Ssam {
51210762Ssam 
51311069Ssam 	fprintf(stderr, "newfs: ");
51410762Ssam 	fprintf(stderr, fmt, arg1, arg2);
51510762Ssam 	putc('\n', stderr);
51610762Ssam 	exit(10);
51710762Ssam }
518