xref: /csrg-svn/sbin/newfs/newfs.c (revision 30398)
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*30398Smckusick static char sccsid[] = "@(#)newfs.c	6.3 (Berkeley) 01/15/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 */
9411069Ssam int	rpm;			/* revolutions/minute of drive */
9530386Smckusick int	interleave;		/* hardware sector interleave */
9630386Smckusick int	trackskew = -1;		/* sector 0 skew, per track */
9730386Smckusick int	headswitch;		/* head switch time, usec */
9830386Smckusick int	trackseek;		/* track-to-track seek, usec */
9930380Smckusick int	fsize = DFL_FRAGSIZE;	/* fragment size */
10030380Smckusick int	bsize = DFL_BLKSIZE;	/* block size */
10130380Smckusick int	cpg = DESCPG;		/* cylinders/cylinder group */
10230380Smckusick int	minfree = MINFREE;	/* free space threshold */
10330380Smckusick int	opt = DEFAULTOPT;	/* optimization preference (space or time) */
10430380Smckusick int	density = NBPI;		/* number of bytes per inode */
10530380Smckusick int	maxcontig = MAXCONTIG;	/* max contiguous blocks to allocate */
10630380Smckusick int	rotdelay = ROTDELAY;	/* rotational delay between blocks */
10710762Ssam 
10810762Ssam char	device[MAXPATHLEN];
10910762Ssam 
11030380Smckusick extern	int errno;
11110762Ssam char	*index();
11210762Ssam char	*rindex();
11310762Ssam char	*sprintf();
11410762Ssam 
11510762Ssam main(argc, argv)
11614064Smckusick 	int argc;
11710762Ssam 	char *argv[];
11810762Ssam {
11910762Ssam 	char *cp, *special;
12010762Ssam 	register struct partition *pp;
12130380Smckusick 	register struct disklabel *lp;
12230380Smckusick 	struct disklabel *getdisklabel();
12330380Smckusick 	struct partition oldpartition;
12410762Ssam 	struct stat st;
12530380Smckusick 	int fsi, fso;
12610762Ssam 	register int i;
12710762Ssam 	int status;
12810762Ssam 
12910762Ssam 	argc--, argv++;
13010762Ssam 	while (argc > 0 && argv[0][0] == '-') {
13110762Ssam 		for (cp = &argv[0][1]; *cp; cp++)
13210762Ssam 			switch (*cp) {
13310762Ssam 
13416945Smckusick 			case 'N':
13516945Smckusick 				Nflag++;
13612334Shelge 				break;
13712334Shelge 
13830380Smckusick 			case 'S':
13910762Ssam 				if (argc < 1)
14030380Smckusick 					fatal("-S: missing sector size");
14110762Ssam 				argc--, argv++;
14230380Smckusick 				sectorsize = atoi(*argv);
14330380Smckusick 				if (sectorsize <= 0)
14430380Smckusick 					fatal("%s: bad sector size", *argv);
14510762Ssam 				goto next;
14610762Ssam 
14730380Smckusick 			case 'a':
14810762Ssam 				if (argc < 1)
14930380Smckusick 					fatal("-a: spare sectors per cylinder");
15010762Ssam 				argc--, argv++;
15130386Smckusick 				cylspares = atoi(*argv);
15230386Smckusick 				if (cylspares < 0)
15330380Smckusick 					fatal("%s: bad spare sectors per cylinder", *argv);
15410762Ssam 				goto next;
15510762Ssam 
15610762Ssam 			case 'b':
15710762Ssam 				if (argc < 1)
15810762Ssam 					fatal("-b: missing block size");
15910762Ssam 				argc--, argv++;
16010762Ssam 				bsize = atoi(*argv);
16130380Smckusick 				if (bsize < MINBSIZE)
16210762Ssam 					fatal("%s: bad block size", *argv);
16310762Ssam 				goto next;
16410762Ssam 
16530380Smckusick 			case 'c':
16630380Smckusick 				if (argc < 1)
16730380Smckusick 					fatal("-c: missing cylinders/group");
16830380Smckusick 				argc--, argv++;
16930380Smckusick 				cpg = atoi(*argv);
17030380Smckusick 				if (cpg <= 0)
17130380Smckusick 					fatal("%s: bad cylinders/group", *argv);
17230380Smckusick 				goto next;
17330380Smckusick 
17430380Smckusick 			case 'd':
17530380Smckusick 				if (argc < 1)
17630380Smckusick 					fatal("-d: missing sectors/track");
17730380Smckusick 				argc--, argv++;
17830380Smckusick 				nsectors = atoi(*argv);
17930380Smckusick 				if (nsectors <= 0)
18030380Smckusick 					fatal("%s: bad sectors/track", *argv);
18130380Smckusick 				goto next;
18230380Smckusick 
18310762Ssam 			case 'f':
18410762Ssam 				if (argc < 1)
18510762Ssam 					fatal("-f: missing frag size");
18610762Ssam 				argc--, argv++;
18710762Ssam 				fsize = atoi(*argv);
18830380Smckusick 				if (fsize <= 0)
18910762Ssam 					fatal("%s: bad frag size", *argv);
19010762Ssam 				goto next;
19110762Ssam 
19230380Smckusick 			case 'i':
19310762Ssam 				if (argc < 1)
19430380Smckusick 					fatal("-i: missing bytes per inode\n");
19510762Ssam 				argc--, argv++;
19630380Smckusick 				density = atoi(*argv);
19730380Smckusick 				if (density <= 0)
19830380Smckusick 					fatal("%s: bad bytes per inode\n",
19930380Smckusick 						*argv);
20010762Ssam 				goto next;
20110762Ssam 
20230386Smckusick 			case 'k':
20330386Smckusick 				if (argc < 1)
20430386Smckusick 					fatal("-k: track skew");
20530386Smckusick 				argc--, argv++;
20630386Smckusick 				trackskew = atoi(*argv);
20730386Smckusick 				if (trackskew < 0)
20830386Smckusick 					fatal("%s: bad track skew", *argv);
20930386Smckusick 				goto next;
21030386Smckusick 
21130386Smckusick 			case 'l':
21230386Smckusick 				if (argc < 1)
21330386Smckusick 					fatal("-l: interleave");
21430386Smckusick 				argc--, argv++;
21530386Smckusick 				interleave = atoi(*argv);
21630386Smckusick 				if (interleave <= 0)
21730386Smckusick 					fatal("%s: bad interleave", *argv);
21830386Smckusick 				goto next;
21930386Smckusick 
22011069Ssam 			case 'm':
22111069Ssam 				if (argc < 1)
22211069Ssam 					fatal("-m: missing free space %%\n");
22311069Ssam 				argc--, argv++;
22411069Ssam 				minfree = atoi(*argv);
22511069Ssam 				if (minfree < 0 || minfree > 99)
22611069Ssam 					fatal("%s: bad free space %%\n",
22711069Ssam 						*argv);
22811069Ssam 				goto next;
22911069Ssam 
23030380Smckusick 			case 'o':
23130380Smckusick 				if (argc < 1)
23230380Smckusick 					fatal("-o: missing optimization preference");
23330380Smckusick 				argc--, argv++;
23430380Smckusick 				if (strcmp(*argv, "space") == 0)
23530380Smckusick 					opt = FS_OPTSPACE;
23630380Smckusick 				else if (strcmp(*argv, "time") == 0)
23730380Smckusick 					opt = FS_OPTTIME;
23830380Smckusick 				else
23930380Smckusick 					fatal("%s: bad optimization preference %s",
24030380Smckusick 					    *argv,
24130380Smckusick 					    "(options are `space' or `time')");
24230380Smckusick 				goto next;
24330380Smckusick 
24430386Smckusick 			case 'p':
24530386Smckusick 				if (argc < 1)
24630386Smckusick 					fatal("-p: spare sectors per track");
24730386Smckusick 				argc--, argv++;
24830386Smckusick 				trackspares = atoi(*argv);
24930386Smckusick 				if (trackspares < 0)
25030386Smckusick 					fatal("%s: bad spare sectors per track", *argv);
25130386Smckusick 				goto next;
25230386Smckusick 
25311069Ssam 			case 'r':
25411069Ssam 				if (argc < 1)
25511069Ssam 					fatal("-r: missing revs/minute\n");
25611069Ssam 				argc--, argv++;
25711069Ssam 				rpm = atoi(*argv);
25830380Smckusick 				if (rpm <= 0)
25911069Ssam 					fatal("%s: bad revs/minute\n", *argv);
26011069Ssam 				goto next;
26111069Ssam 
26230380Smckusick 			case 's':
26314884Smckusick 				if (argc < 1)
26430380Smckusick 					fatal("-s: missing file system size");
26514884Smckusick 				argc--, argv++;
26630380Smckusick 				fssize = atoi(*argv);
26730380Smckusick 				if (fssize <= 0)
26830380Smckusick 					fatal("%s: bad file system size",
26914884Smckusick 						*argv);
27014884Smckusick 				goto next;
27114884Smckusick 
27230380Smckusick 			case 't':
27330380Smckusick 				if (argc < 1)
27430380Smckusick 					fatal("-t: missing track total");
27530380Smckusick 				argc--, argv++;
27630380Smckusick 				ntracks = atoi(*argv);
27730380Smckusick 				if (ntracks <= 0)
27830380Smckusick 					fatal("%s: bad total tracks", *argv);
27930380Smckusick 				goto next;
28030380Smckusick 
28110762Ssam 			default:
28210762Ssam 				fatal("-%c: unknown flag", cp);
28310762Ssam 			}
28410762Ssam next:
28510762Ssam 		argc--, argv++;
28610762Ssam 	}
28730380Smckusick 	if (argc < 1) {
28830380Smckusick 		fprintf(stderr, "usage: newfs [ fsoptions ] special-device\n");
28930380Smckusick 		fprintf(stderr, "where fsoptions are:\n");
29016945Smckusick 		fprintf(stderr, "\t-N do not create file system, %s\n",
29116945Smckusick 			"just print out parameters");
29211057Ssam 		fprintf(stderr, "\t-b block size\n");
29311057Ssam 		fprintf(stderr, "\t-f frag size\n");
29411069Ssam 		fprintf(stderr, "\t-m minimum free space %%\n");
29524702Smckusick 		fprintf(stderr, "\t-o optimization preference %s\n",
29624702Smckusick 			"(`space' or `time')");
297*30398Smckusick 		fprintf(stderr, "\t-i number of bytes per inode\n");
298*30398Smckusick 		fprintf(stderr, "\t-c cylinders/group\n");
299*30398Smckusick 		fprintf(stderr, "\t-s file system size (sectors)\n");
30011069Ssam 		fprintf(stderr, "\t-r revolutions/minute\n");
30111057Ssam 		fprintf(stderr, "\t-S sector size\n");
302*30398Smckusick 		fprintf(stderr, "\t-d sectors/track\n");
303*30398Smckusick 		fprintf(stderr, "\t-t tracks/cylinder\n");
304*30398Smckusick 		fprintf(stderr, "\t-p spare sectors per track\n");
305*30398Smckusick 		fprintf(stderr, "\t-a spare sectors per cylinder\n");
30630386Smckusick 		fprintf(stderr, "\t-l hardware sector interleave\n");
30730386Smckusick 		fprintf(stderr, "\t-k sector 0 skew, per track\n");
30810762Ssam 		exit(1);
30910762Ssam 	}
31010762Ssam 	special = argv[0];
31114064Smckusick 	cp = rindex(special, '/');
31214064Smckusick 	if (cp != 0)
31314064Smckusick 		special = cp + 1;
31414321Ssam 	if (*special == 'r' && special[1] != 'a' && special[1] != 'b')
31514064Smckusick 		special++;
31614064Smckusick 	special = sprintf(device, "/dev/r%s", special);
31730380Smckusick 	if (!Nflag) {
31830380Smckusick 		fso = open(special, O_WRONLY);
31930380Smckusick 		if (fso < 0) {
32030380Smckusick 			perror(special);
32130380Smckusick 			exit(1);
32230380Smckusick 		}
32330380Smckusick 	} else
32430380Smckusick 		fso = -1;
32530380Smckusick 	fsi = open(special, O_RDONLY);
32630380Smckusick 	if (fsi < 0) {
32730380Smckusick 		perror(special);
32830380Smckusick 		exit(1);
32930380Smckusick 	}
33030380Smckusick 	if (fstat(fsi, &st) < 0) {
33111069Ssam 		fprintf(stderr, "newfs: "); perror(special);
33210762Ssam 		exit(2);
33310762Ssam 	}
33414064Smckusick 	if ((st.st_mode & S_IFMT) != S_IFCHR)
33514064Smckusick 		fatal("%s: not a character device", special);
33610762Ssam 	cp = index(argv[0], '\0') - 1;
33730380Smckusick 	if (cp == 0 || (*cp < 'a' || *cp > 'h') && !isdigit(*cp))
33810762Ssam 		fatal("%s: can't figure out file system partition", argv[0]);
33930380Smckusick 	lp = getdisklabel(special, fsi);
34030380Smckusick 	if (isdigit(*cp))
34130380Smckusick 		pp = &lp->d_partitions[0];
34230380Smckusick 	else
34330380Smckusick 		pp = &lp->d_partitions[*cp - 'a'];
34430380Smckusick 	if (pp->p_size == 0)
34530380Smckusick 		fatal("%s: `%c' partition is unavailable", argv[0], *cp);
34630380Smckusick 	if (fssize == 0)
34710762Ssam 		fssize = pp->p_size;
34830380Smckusick 	if (fssize > pp->p_size)
34930380Smckusick 	       fatal("%s: maximum file system size on the `%c' partition is %d",
35030380Smckusick 			argv[0], *cp, pp->p_size);
35130380Smckusick 	if (rpm == 0) {
35230380Smckusick 		rpm = lp->d_rpm;
35330380Smckusick 		if (rpm <= 0)
35430380Smckusick 			fatal("%s: no default rpm", argv[1]);
35510762Ssam 	}
35630380Smckusick 	if (ntracks == 0) {
35730380Smckusick 		ntracks = lp->d_ntracks;
35830380Smckusick 		if (ntracks <= 0)
35930380Smckusick 			fatal("%s: no default #tracks", argv[1]);
36030380Smckusick 	}
36110762Ssam 	if (nsectors == 0) {
36230380Smckusick 		nsectors = lp->d_nsectors;
36330380Smckusick 		if (nsectors <= 0)
36410762Ssam 			fatal("%s: no default #sectors/track", argv[1]);
36510762Ssam 	}
36610762Ssam 	if (sectorsize == 0) {
36730380Smckusick 		sectorsize = lp->d_secsize;
36830380Smckusick 		if (sectorsize <= 0)
36910762Ssam 			fatal("%s: no default sector size", argv[1]);
37010762Ssam 	}
37130386Smckusick 	if (trackskew == -1) {
37230386Smckusick 		trackskew = lp->d_trackskew;
37330386Smckusick 		if (trackskew < 0)
37430386Smckusick 			fatal("%s: no default track skew", argv[1]);
37530386Smckusick 	}
37630386Smckusick 	if (interleave == 0) {
37730386Smckusick 		interleave = lp->d_interleave;
37830386Smckusick 		if (interleave <= 0)
37930386Smckusick 			fatal("%s: no default interleave", argv[1]);
38030386Smckusick 	}
38110762Ssam 	if (fsize == 0) {
38210762Ssam 		fsize = pp->p_fsize;
38330380Smckusick 		if (fsize <= 0)
38430380Smckusick 			fsize = MAX(DFL_FRAGSIZE, lp->d_secsize);
38510762Ssam 	}
38630380Smckusick 	if (bsize == 0) {
38730380Smckusick 		bsize = pp->p_frag * pp->p_fsize;
38830380Smckusick 		if (bsize <= 0)
38930380Smckusick 			bsize = MIN(DFL_BLKSIZE, 8 * fsize);
39011069Ssam 	}
39124702Smckusick 	if (minfree < 10 && opt != FS_OPTSPACE) {
39230380Smckusick 		fprintf(stderr, "Warning: changing optimization to space ");
39330380Smckusick 		fprintf(stderr, "because minfree is less than 10%%\n");
39424702Smckusick 		opt = FS_OPTSPACE;
39524702Smckusick 	}
39630386Smckusick 	if (trackspares == -1) {
39730386Smckusick 		trackspares = lp->d_sparespertrack;
39830386Smckusick 		if (trackspares < 0)
39930386Smckusick 			fatal("%s: no default spares/track", argv[1]);
40030386Smckusick 	}
40130386Smckusick 	nphyssectors = nsectors + trackspares;
40230386Smckusick 	if (cylspares == -1) {
40330386Smckusick 		cylspares = lp->d_sparespercyl;
40430386Smckusick 		if (cylspares < 0)
40530386Smckusick 			fatal("%s: no default spares/cylinder", argv[1]);
40630386Smckusick 	}
40730386Smckusick 	secpercyl = nsectors * ntracks - cylspares;
40830380Smckusick 	if (secpercyl != lp->d_secpercyl)
40930380Smckusick 		fprintf(stderr, "%s (%d) %s (%d)\n",
41030380Smckusick 			"Warning: calculated sectors per cylinder", secpercyl,
41130380Smckusick 			"disagrees with disk label", lp->d_secpercyl);
41230386Smckusick 	headswitch = lp->d_headswitch;
41330386Smckusick 	trackseek = lp->d_trkseek;
41430380Smckusick 	oldpartition = *pp;
41530380Smckusick 	mkfs(pp, special, fsi, fso);
41630380Smckusick 	if (!Nflag && bcmp(pp, &oldpartition, sizeof(oldpartition)))
41730380Smckusick 		rewritelabel(special, fso, lp);
41830380Smckusick 	exit(0);
41930380Smckusick }
42030380Smckusick 
42130380Smckusick #ifdef byioctl
42230380Smckusick struct disklabel *
42330380Smckusick getdisklabel(s, fd)
42430380Smckusick 	char *s;
42530380Smckusick 	int	fd;
42630380Smckusick {
42730380Smckusick 	static struct disklabel lab;
42830380Smckusick 
42930380Smckusick 	if (ioctl(fd, DIOCGDINFO, (char *)&lab) < 0) {
43030380Smckusick 		perror("ioctl (GDINFO)");
43130380Smckusick 		fatal("%s: can't read disk label", s);
43210762Ssam 	}
43330380Smckusick 	return (&lab);
43430380Smckusick }
43510762Ssam 
43630380Smckusick rewritelabel(s, fd, lp)
43730380Smckusick 	char *s;
43830380Smckusick 	int fd;
43930380Smckusick 	register struct disklabel *lp;
44030380Smckusick {
44130380Smckusick 
44230380Smckusick 	lp->d_checksum = 0;
44330380Smckusick 	lp->d_checksum = dkcksum(lp);
44430380Smckusick 	if (ioctl(fd, DIOCWDINFO, (char *)lp) < 0) {
44530380Smckusick 		perror("ioctl (GWINFO)");
44630380Smckusick 		fatal("%s: can't rewrite disk label", s);
44710762Ssam 	}
44810762Ssam }
44930380Smckusick #else byioctl
45030380Smckusick char specname[64];
45130380Smckusick char boot[BBSIZE];
45210762Ssam 
45330380Smckusick struct disklabel *
45430380Smckusick getdisklabel(s, fd)
45530380Smckusick 	char *s;
45630380Smckusick 	int	fd;
45710762Ssam {
45830380Smckusick 	char *cp;
45930380Smckusick 	u_long magic = htonl(DISKMAGIC);
46030380Smckusick 	register struct disklabel *lp;
46130380Smckusick 	int cfd;
46210762Ssam 
46330380Smckusick 	/*
46430380Smckusick 	 * Make name for 'c' partition.
46530380Smckusick 	 */
46630380Smckusick 	strcpy(specname, s);
46730380Smckusick 	cp = specname + strlen(specname) - 1;
46830380Smckusick 	if (!isdigit(*cp))
46930380Smckusick 		*cp = 'c';
47030380Smckusick 	cfd = open(specname, O_RDONLY);
47130380Smckusick 	if (cfd < 0) {
47230380Smckusick 		perror(specname);
47330380Smckusick 		exit(2);
47410762Ssam 	}
47530380Smckusick 
47630380Smckusick 	if (read(cfd, boot, BBSIZE) < BBSIZE) {
47730380Smckusick 		perror(specname);
47810762Ssam 		exit(2);
47910762Ssam 	}
48030380Smckusick 	close(cfd);
48130380Smckusick 	for (lp = (struct disklabel *)(boot + LABELOFFSET);
48230380Smckusick 	    lp <= (struct disklabel *)(boot + BBSIZE -
48330380Smckusick 	    sizeof(struct disklabel));
48430380Smckusick 	    lp = (struct disklabel *)((char *)lp + 128))
48530380Smckusick 		if (lp->d_magic == magic && lp->d_magic2 == magic)
48630380Smckusick 			break;
48730380Smckusick 	if (lp > (struct disklabel *)(boot + BBSIZE -
48830380Smckusick 	    sizeof(struct disklabel)) ||
48930380Smckusick 	    lp->d_magic != magic || lp->d_magic2 != magic ||
49030380Smckusick 	    dkcksum(lp) != 0) {
49130380Smckusick 		fprintf(stderr,
49230380Smckusick 	"Bad pack magic number (label is damaged, or pack is unlabeled)\n");
49310762Ssam 		exit(1);
49410762Ssam 	}
49530380Smckusick #if ENDIAN != BIG
49630380Smckusick 	swablabel(lp);
49730380Smckusick #endif
49830380Smckusick 	return (lp);
49930380Smckusick }
50030380Smckusick 
50130380Smckusick rewritelabel(s, fd, lp)
50230380Smckusick 	char *s;
50330380Smckusick 	int fd;
50430380Smckusick 	register struct disklabel *lp;
50530380Smckusick {
50630380Smckusick 	daddr_t alt;
50730380Smckusick 	register i;
50830380Smckusick 	int secsize, cfd;
50930380Smckusick 
51030380Smckusick 	secsize = lp->d_secsize;
51130380Smckusick 	alt = lp->d_ncylinders * lp->d_secpercyl - lp->d_nsectors;
51230380Smckusick #if ENDIAN != BIG
51330380Smckusick 	swablabel(lp);
51430380Smckusick #endif
51530380Smckusick 	lp->d_checksum = 0;
51630380Smckusick 	lp->d_checksum = dkcksum(lp);
51730380Smckusick 	cfd = open(specname, O_WRONLY);
51830380Smckusick 	if (cfd < 0) {
51930380Smckusick 		perror(specname);
52010762Ssam 		exit(2);
52110762Ssam 	}
52230380Smckusick 	lseek(cfd, (off_t)0, L_SET);
52330380Smckusick 	if (write(cfd, boot, BBSIZE) < BBSIZE) {
52430380Smckusick 		perror(specname);
52510762Ssam 		exit(2);
52610762Ssam 	}
52730380Smckusick 	for (i = 1; i < 11 && i < lp->d_nsectors; i += 2) {
52830380Smckusick 		lseek(cfd, (off_t)(alt + i) * secsize, L_SET);
52930380Smckusick 		if (write(cfd, boot, secsize) < secsize) {
53030380Smckusick 			int oerrno = errno;
53130380Smckusick 			fprintf(stderr, "alternate label %d ", i/2);
53230380Smckusick 			errno = oerrno;
53330380Smckusick 			perror("write");
53430380Smckusick 		}
53530380Smckusick 	}
53630380Smckusick 	close(cfd);
53710762Ssam }
53830380Smckusick #endif byioctl
53910762Ssam 
54010762Ssam /*VARARGS*/
54110762Ssam fatal(fmt, arg1, arg2)
54210762Ssam 	char *fmt;
54310762Ssam {
54410762Ssam 
54511069Ssam 	fprintf(stderr, "newfs: ");
54610762Ssam 	fprintf(stderr, fmt, arg1, arg2);
54710762Ssam 	putc('\n', stderr);
54810762Ssam 	exit(10);
54910762Ssam }
550