xref: /csrg-svn/sbin/newfs/newfs.c (revision 31680)
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*31680Skarels static char sccsid[] = "@(#)newfs.c	6.9 (Berkeley) 06/23/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 
31*31680Skarels #define COMPAT			/* allow non-labeled disks */
32*31680Skarels 
3330380Smckusick /*
3430380Smckusick  * The following two constants set the default block and fragment sizes.
3530380Smckusick  * Both constants must be a power of 2 and meet the following constraints:
3630380Smckusick  *	MINBSIZE <= DESBLKSIZE <= MAXBSIZE
3730380Smckusick  *	sectorsize <= DESFRAGSIZE <= DESBLKSIZE
3830380Smckusick  *	DESBLKSIZE / DESFRAGSIZE <= 8
3930380Smckusick  */
4030380Smckusick #define	DFL_FRAGSIZE	1024
4130380Smckusick #define	DFL_BLKSIZE	8192
4211183Ssam 
4330380Smckusick /*
4430380Smckusick  * Cylinder groups may have up to MAXCPG cylinders. The actual
4530380Smckusick  * number used depends upon how much information can be stored
4630380Smckusick  * on a single cylinder. The default is to used 16 cylinders
4730380Smckusick  * per group.
4830380Smckusick  */
4930380Smckusick #define	DESCPG		16	/* desired fs_cpg */
5030380Smckusick 
5130380Smckusick /*
5230380Smckusick  * MINFREE gives the minimum acceptable percentage of file system
5330380Smckusick  * blocks which may be free. If the freelist drops below this level
5430380Smckusick  * only the superuser may continue to allocate blocks. This may
5530380Smckusick  * be set to 0 if no reserve of free blocks is deemed necessary,
5630380Smckusick  * however throughput drops by fifty percent if the file system
5730380Smckusick  * is run at between 90% and 100% full; thus the default value of
5830380Smckusick  * fs_minfree is 10%. With 10% free space, fragmentation is not a
5930380Smckusick  * problem, so we choose to optimize for time.
6030380Smckusick  */
6130380Smckusick #define MINFREE		10
6230380Smckusick #define DEFAULTOPT	FS_OPTTIME
6330380Smckusick 
6430380Smckusick /*
6530380Smckusick  * ROTDELAY gives the minimum number of milliseconds to initiate
6630380Smckusick  * another disk transfer on the same cylinder. It is used in
6730380Smckusick  * determining the rotationally optimal layout for disk blocks
6830380Smckusick  * within a file; the default of fs_rotdelay is 4ms.
6930380Smckusick  */
7030380Smckusick #define ROTDELAY	4
7130380Smckusick 
7230380Smckusick /*
7330380Smckusick  * MAXCONTIG sets the default for the maximum number of blocks
7430380Smckusick  * that may be allocated sequentially. Since UNIX drivers are
7530380Smckusick  * not capable of scheduling multi-block transfers, this defaults
7630380Smckusick  * to 1 (ie no contiguous blocks are allocated).
7730380Smckusick  */
7830380Smckusick #define MAXCONTIG	1
7930380Smckusick 
8030380Smckusick /*
8130380Smckusick  * Each file system has a number of inodes statically allocated.
8230380Smckusick  * We allocate one inode slot per NBPI bytes, expecting this
8330380Smckusick  * to be far more than we will ever need.
8430380Smckusick  */
8530380Smckusick #define	NBPI		2048
8630380Smckusick 
8730380Smckusick int	Nflag;			/* run without writing file system */
8810762Ssam int	fssize;			/* file system size */
8910762Ssam int	ntracks;		/* # tracks/cylinder */
9010762Ssam int	nsectors;		/* # sectors/track */
9130386Smckusick int	nphyssectors;		/* # sectors/track including spares */
9230380Smckusick int	secpercyl;		/* sectors per cylinder */
9330386Smckusick int	trackspares = -1;	/* spare sectors per track */
9430386Smckusick int	cylspares = -1;		/* spare sectors per cylinder */
9510762Ssam int	sectorsize;		/* bytes/sector */
9630691Skarels #ifdef tahoe
9730691Skarels int	realsectorsize;		/* bytes/sector in hardware */
9830691Skarels #endif
9911069Ssam int	rpm;			/* revolutions/minute of drive */
10030386Smckusick int	interleave;		/* hardware sector interleave */
10130386Smckusick int	trackskew = -1;		/* sector 0 skew, per track */
10230386Smckusick int	headswitch;		/* head switch time, usec */
10330386Smckusick int	trackseek;		/* track-to-track seek, usec */
10430862Skarels int	fsize = 0;		/* fragment size */
10530862Skarels int	bsize = 0;		/* block size */
10630380Smckusick int	cpg = DESCPG;		/* cylinders/cylinder group */
10730380Smckusick int	minfree = MINFREE;	/* free space threshold */
10830380Smckusick int	opt = DEFAULTOPT;	/* optimization preference (space or time) */
10930380Smckusick int	density = NBPI;		/* number of bytes per inode */
11030380Smckusick int	maxcontig = MAXCONTIG;	/* max contiguous blocks to allocate */
11130380Smckusick int	rotdelay = ROTDELAY;	/* rotational delay between blocks */
11230691Skarels int	bbsize = BBSIZE;	/* boot block size */
11330691Skarels int	sbsize = SBSIZE;	/* superblock size */
114*31680Skarels #ifdef COMPAT
115*31680Skarels int	unlabelled;
116*31680Skarels #endif
11710762Ssam 
11810762Ssam char	device[MAXPATHLEN];
11910762Ssam 
12030380Smckusick extern	int errno;
12110762Ssam char	*index();
12210762Ssam char	*rindex();
12310762Ssam char	*sprintf();
12410762Ssam 
12510762Ssam main(argc, argv)
12614064Smckusick 	int argc;
12710762Ssam 	char *argv[];
12810762Ssam {
12910762Ssam 	char *cp, *special;
13010762Ssam 	register struct partition *pp;
13130380Smckusick 	register struct disklabel *lp;
13230380Smckusick 	struct disklabel *getdisklabel();
13330380Smckusick 	struct partition oldpartition;
13410762Ssam 	struct stat st;
13530380Smckusick 	int fsi, fso;
13610762Ssam 	register int i;
13710762Ssam 	int status;
13810762Ssam 
13910762Ssam 	argc--, argv++;
14010762Ssam 	while (argc > 0 && argv[0][0] == '-') {
14110762Ssam 		for (cp = &argv[0][1]; *cp; cp++)
14210762Ssam 			switch (*cp) {
14310762Ssam 
14416945Smckusick 			case 'N':
14516945Smckusick 				Nflag++;
14612334Shelge 				break;
14712334Shelge 
14830380Smckusick 			case 'S':
14910762Ssam 				if (argc < 1)
15030380Smckusick 					fatal("-S: missing sector size");
15110762Ssam 				argc--, argv++;
15230380Smckusick 				sectorsize = atoi(*argv);
15330380Smckusick 				if (sectorsize <= 0)
15430380Smckusick 					fatal("%s: bad sector size", *argv);
15510762Ssam 				goto next;
15610762Ssam 
15730380Smckusick 			case 'a':
15810762Ssam 				if (argc < 1)
15930380Smckusick 					fatal("-a: spare sectors per cylinder");
16010762Ssam 				argc--, argv++;
16130386Smckusick 				cylspares = atoi(*argv);
16230386Smckusick 				if (cylspares < 0)
16330380Smckusick 					fatal("%s: bad spare sectors per cylinder", *argv);
16410762Ssam 				goto next;
16510762Ssam 
16610762Ssam 			case 'b':
16710762Ssam 				if (argc < 1)
16810762Ssam 					fatal("-b: missing block size");
16910762Ssam 				argc--, argv++;
17010762Ssam 				bsize = atoi(*argv);
17130380Smckusick 				if (bsize < MINBSIZE)
17210762Ssam 					fatal("%s: bad block size", *argv);
17310762Ssam 				goto next;
17410762Ssam 
17530380Smckusick 			case 'c':
17630380Smckusick 				if (argc < 1)
17730380Smckusick 					fatal("-c: missing cylinders/group");
17830380Smckusick 				argc--, argv++;
17930380Smckusick 				cpg = atoi(*argv);
18030380Smckusick 				if (cpg <= 0)
18130380Smckusick 					fatal("%s: bad cylinders/group", *argv);
18230380Smckusick 				goto next;
18330380Smckusick 
18430380Smckusick 			case 'd':
18530380Smckusick 				if (argc < 1)
18630380Smckusick 					fatal("-d: missing sectors/track");
18730380Smckusick 				argc--, argv++;
18830380Smckusick 				nsectors = atoi(*argv);
18930380Smckusick 				if (nsectors <= 0)
19030380Smckusick 					fatal("%s: bad sectors/track", *argv);
19130380Smckusick 				goto next;
19230380Smckusick 
19310762Ssam 			case 'f':
19410762Ssam 				if (argc < 1)
19510762Ssam 					fatal("-f: missing frag size");
19610762Ssam 				argc--, argv++;
19710762Ssam 				fsize = atoi(*argv);
19830380Smckusick 				if (fsize <= 0)
19910762Ssam 					fatal("%s: bad frag size", *argv);
20010762Ssam 				goto next;
20110762Ssam 
20230380Smckusick 			case 'i':
20310762Ssam 				if (argc < 1)
20430380Smckusick 					fatal("-i: missing bytes per inode\n");
20510762Ssam 				argc--, argv++;
20630380Smckusick 				density = atoi(*argv);
20730380Smckusick 				if (density <= 0)
20830380Smckusick 					fatal("%s: bad bytes per inode\n",
20930380Smckusick 						*argv);
21010762Ssam 				goto next;
21110762Ssam 
21230386Smckusick 			case 'k':
21330386Smckusick 				if (argc < 1)
21430386Smckusick 					fatal("-k: track skew");
21530386Smckusick 				argc--, argv++;
21630386Smckusick 				trackskew = atoi(*argv);
21730386Smckusick 				if (trackskew < 0)
21830386Smckusick 					fatal("%s: bad track skew", *argv);
21930386Smckusick 				goto next;
22030386Smckusick 
22130386Smckusick 			case 'l':
22230386Smckusick 				if (argc < 1)
22330386Smckusick 					fatal("-l: interleave");
22430386Smckusick 				argc--, argv++;
22530386Smckusick 				interleave = atoi(*argv);
22630386Smckusick 				if (interleave <= 0)
22730386Smckusick 					fatal("%s: bad interleave", *argv);
22830386Smckusick 				goto next;
22930386Smckusick 
23011069Ssam 			case 'm':
23111069Ssam 				if (argc < 1)
23211069Ssam 					fatal("-m: missing free space %%\n");
23311069Ssam 				argc--, argv++;
23411069Ssam 				minfree = atoi(*argv);
23511069Ssam 				if (minfree < 0 || minfree > 99)
23611069Ssam 					fatal("%s: bad free space %%\n",
23711069Ssam 						*argv);
23811069Ssam 				goto next;
23911069Ssam 
24030380Smckusick 			case 'o':
24130380Smckusick 				if (argc < 1)
24230380Smckusick 					fatal("-o: missing optimization preference");
24330380Smckusick 				argc--, argv++;
24430380Smckusick 				if (strcmp(*argv, "space") == 0)
24530380Smckusick 					opt = FS_OPTSPACE;
24630380Smckusick 				else if (strcmp(*argv, "time") == 0)
24730380Smckusick 					opt = FS_OPTTIME;
24830380Smckusick 				else
24930380Smckusick 					fatal("%s: bad optimization preference %s",
25030380Smckusick 					    *argv,
25130380Smckusick 					    "(options are `space' or `time')");
25230380Smckusick 				goto next;
25330380Smckusick 
25430386Smckusick 			case 'p':
25530386Smckusick 				if (argc < 1)
25630386Smckusick 					fatal("-p: spare sectors per track");
25730386Smckusick 				argc--, argv++;
25830386Smckusick 				trackspares = atoi(*argv);
25930386Smckusick 				if (trackspares < 0)
26030386Smckusick 					fatal("%s: bad spare sectors per track", *argv);
26130386Smckusick 				goto next;
26230386Smckusick 
26311069Ssam 			case 'r':
26411069Ssam 				if (argc < 1)
26511069Ssam 					fatal("-r: missing revs/minute\n");
26611069Ssam 				argc--, argv++;
26711069Ssam 				rpm = atoi(*argv);
26830380Smckusick 				if (rpm <= 0)
26911069Ssam 					fatal("%s: bad revs/minute\n", *argv);
27011069Ssam 				goto next;
27111069Ssam 
27230380Smckusick 			case 's':
27314884Smckusick 				if (argc < 1)
27430380Smckusick 					fatal("-s: missing file system size");
27514884Smckusick 				argc--, argv++;
27630380Smckusick 				fssize = atoi(*argv);
27730380Smckusick 				if (fssize <= 0)
27830380Smckusick 					fatal("%s: bad file system size",
27914884Smckusick 						*argv);
28014884Smckusick 				goto next;
28114884Smckusick 
28230380Smckusick 			case 't':
28330380Smckusick 				if (argc < 1)
28430380Smckusick 					fatal("-t: missing track total");
28530380Smckusick 				argc--, argv++;
28630380Smckusick 				ntracks = atoi(*argv);
28730380Smckusick 				if (ntracks <= 0)
28830380Smckusick 					fatal("%s: bad total tracks", *argv);
28930380Smckusick 				goto next;
29030380Smckusick 
29110762Ssam 			default:
29210762Ssam 				fatal("-%c: unknown flag", cp);
29310762Ssam 			}
29410762Ssam next:
29510762Ssam 		argc--, argv++;
29610762Ssam 	}
29730380Smckusick 	if (argc < 1) {
298*31680Skarels #ifdef COMPAT
299*31680Skarels 		fprintf(stderr,
300*31680Skarels 		"usage: newfs [ fsoptions ] special-device [device-type]\n");
301*31680Skarels #else
30230380Smckusick 		fprintf(stderr, "usage: newfs [ fsoptions ] special-device\n");
303*31680Skarels #endif
30430380Smckusick 		fprintf(stderr, "where fsoptions are:\n");
30516945Smckusick 		fprintf(stderr, "\t-N do not create file system, %s\n",
30616945Smckusick 			"just print out parameters");
30711057Ssam 		fprintf(stderr, "\t-b block size\n");
30811057Ssam 		fprintf(stderr, "\t-f frag size\n");
30911069Ssam 		fprintf(stderr, "\t-m minimum free space %%\n");
31024702Smckusick 		fprintf(stderr, "\t-o optimization preference %s\n",
31124702Smckusick 			"(`space' or `time')");
31230398Smckusick 		fprintf(stderr, "\t-i number of bytes per inode\n");
31330398Smckusick 		fprintf(stderr, "\t-c cylinders/group\n");
31430398Smckusick 		fprintf(stderr, "\t-s file system size (sectors)\n");
31511069Ssam 		fprintf(stderr, "\t-r revolutions/minute\n");
31611057Ssam 		fprintf(stderr, "\t-S sector size\n");
31730398Smckusick 		fprintf(stderr, "\t-d sectors/track\n");
31830398Smckusick 		fprintf(stderr, "\t-t tracks/cylinder\n");
31930398Smckusick 		fprintf(stderr, "\t-p spare sectors per track\n");
32030398Smckusick 		fprintf(stderr, "\t-a spare sectors per cylinder\n");
32130386Smckusick 		fprintf(stderr, "\t-l hardware sector interleave\n");
32230386Smckusick 		fprintf(stderr, "\t-k sector 0 skew, per track\n");
32310762Ssam 		exit(1);
32410762Ssam 	}
32510762Ssam 	special = argv[0];
32614064Smckusick 	cp = rindex(special, '/');
32714064Smckusick 	if (cp != 0)
32814064Smckusick 		special = cp + 1;
32914321Ssam 	if (*special == 'r' && special[1] != 'a' && special[1] != 'b')
33014064Smckusick 		special++;
33114064Smckusick 	special = sprintf(device, "/dev/r%s", special);
33230380Smckusick 	if (!Nflag) {
33330380Smckusick 		fso = open(special, O_WRONLY);
33430380Smckusick 		if (fso < 0) {
33530380Smckusick 			perror(special);
33630380Smckusick 			exit(1);
33730380Smckusick 		}
33830380Smckusick 	} else
33930380Smckusick 		fso = -1;
34030380Smckusick 	fsi = open(special, O_RDONLY);
34130380Smckusick 	if (fsi < 0) {
34230380Smckusick 		perror(special);
34330380Smckusick 		exit(1);
34430380Smckusick 	}
34530380Smckusick 	if (fstat(fsi, &st) < 0) {
34611069Ssam 		fprintf(stderr, "newfs: "); perror(special);
34710762Ssam 		exit(2);
34810762Ssam 	}
34914064Smckusick 	if ((st.st_mode & S_IFMT) != S_IFCHR)
35014064Smckusick 		fatal("%s: not a character device", special);
35110762Ssam 	cp = index(argv[0], '\0') - 1;
35230380Smckusick 	if (cp == 0 || (*cp < 'a' || *cp > 'h') && !isdigit(*cp))
35310762Ssam 		fatal("%s: can't figure out file system partition", argv[0]);
354*31680Skarels #ifdef COMPAT
355*31680Skarels 	lp = getdisklabel(special, fsi, argv[1]);
356*31680Skarels #else
35730380Smckusick 	lp = getdisklabel(special, fsi);
358*31680Skarels #endif
35930380Smckusick 	if (isdigit(*cp))
36030380Smckusick 		pp = &lp->d_partitions[0];
36130380Smckusick 	else
36230380Smckusick 		pp = &lp->d_partitions[*cp - 'a'];
36330380Smckusick 	if (pp->p_size == 0)
36430380Smckusick 		fatal("%s: `%c' partition is unavailable", argv[0], *cp);
36530380Smckusick 	if (fssize == 0)
36610762Ssam 		fssize = pp->p_size;
36730380Smckusick 	if (fssize > pp->p_size)
36830380Smckusick 	       fatal("%s: maximum file system size on the `%c' partition is %d",
36930380Smckusick 			argv[0], *cp, pp->p_size);
37030380Smckusick 	if (rpm == 0) {
37130380Smckusick 		rpm = lp->d_rpm;
37230380Smckusick 		if (rpm <= 0)
37330743Skarels 			rpm = 3600;
37410762Ssam 	}
37530380Smckusick 	if (ntracks == 0) {
37630380Smckusick 		ntracks = lp->d_ntracks;
37730380Smckusick 		if (ntracks <= 0)
37830743Skarels 			fatal("%s: no default #tracks", argv[0]);
37930380Smckusick 	}
38010762Ssam 	if (nsectors == 0) {
38130380Smckusick 		nsectors = lp->d_nsectors;
38230380Smckusick 		if (nsectors <= 0)
38330743Skarels 			fatal("%s: no default #sectors/track", argv[0]);
38410762Ssam 	}
38510762Ssam 	if (sectorsize == 0) {
38630380Smckusick 		sectorsize = lp->d_secsize;
38730380Smckusick 		if (sectorsize <= 0)
38830743Skarels 			fatal("%s: no default sector size", argv[0]);
38910762Ssam 	}
39030386Smckusick 	if (trackskew == -1) {
39130386Smckusick 		trackskew = lp->d_trackskew;
39230386Smckusick 		if (trackskew < 0)
39330743Skarels 			trackskew = 0;
39430386Smckusick 	}
39530386Smckusick 	if (interleave == 0) {
39630386Smckusick 		interleave = lp->d_interleave;
39730386Smckusick 		if (interleave <= 0)
39830743Skarels 			interleave = 1;
39930386Smckusick 	}
40010762Ssam 	if (fsize == 0) {
40110762Ssam 		fsize = pp->p_fsize;
40230380Smckusick 		if (fsize <= 0)
40330380Smckusick 			fsize = MAX(DFL_FRAGSIZE, lp->d_secsize);
40410762Ssam 	}
40530380Smckusick 	if (bsize == 0) {
40630380Smckusick 		bsize = pp->p_frag * pp->p_fsize;
40730380Smckusick 		if (bsize <= 0)
40830380Smckusick 			bsize = MIN(DFL_BLKSIZE, 8 * fsize);
40911069Ssam 	}
41024702Smckusick 	if (minfree < 10 && opt != FS_OPTSPACE) {
41130380Smckusick 		fprintf(stderr, "Warning: changing optimization to space ");
41230380Smckusick 		fprintf(stderr, "because minfree is less than 10%%\n");
41324702Smckusick 		opt = FS_OPTSPACE;
41424702Smckusick 	}
41530386Smckusick 	if (trackspares == -1) {
41630386Smckusick 		trackspares = lp->d_sparespertrack;
41730386Smckusick 		if (trackspares < 0)
41830743Skarels 			trackspares = 0;
41930386Smckusick 	}
42030386Smckusick 	nphyssectors = nsectors + trackspares;
42130386Smckusick 	if (cylspares == -1) {
42230386Smckusick 		cylspares = lp->d_sparespercyl;
42330386Smckusick 		if (cylspares < 0)
42430743Skarels 			cylspares = 0;
42530386Smckusick 	}
42630386Smckusick 	secpercyl = nsectors * ntracks - cylspares;
42730380Smckusick 	if (secpercyl != lp->d_secpercyl)
42830380Smckusick 		fprintf(stderr, "%s (%d) %s (%d)\n",
42930380Smckusick 			"Warning: calculated sectors per cylinder", secpercyl,
43030380Smckusick 			"disagrees with disk label", lp->d_secpercyl);
43130386Smckusick 	headswitch = lp->d_headswitch;
43230386Smckusick 	trackseek = lp->d_trkseek;
43330691Skarels 	bbsize = lp->d_bbsize;
43430691Skarels 	sbsize = lp->d_sbsize;
43530380Smckusick 	oldpartition = *pp;
43630691Skarels #ifdef tahoe
43730691Skarels 	realsectorsize = sectorsize;
43830862Skarels 	if (sectorsize != DEV_BSIZE) {		/* XXX */
43930691Skarels 		int secperblk = DEV_BSIZE / sectorsize;
44030691Skarels 
44130691Skarels 		sectorsize = DEV_BSIZE;
44230691Skarels 		nsectors /= secperblk;
44330691Skarels 		nphyssectors /= secperblk;
44430691Skarels 		secpercyl /= secperblk;
44530691Skarels 		fssize /= secperblk;
44630691Skarels 		pp->p_size /= secperblk;
44730691Skarels 	}
44830691Skarels #endif
44930380Smckusick 	mkfs(pp, special, fsi, fso);
45030691Skarels #ifdef tahoe
45130691Skarels 	if (realsectorsize != DEV_BSIZE)
45230691Skarels 		pp->p_size *= DEV_BSIZE / realsectorsize;
45330691Skarels #endif
45430380Smckusick 	if (!Nflag && bcmp(pp, &oldpartition, sizeof(oldpartition)))
45530380Smckusick 		rewritelabel(special, fso, lp);
45630380Smckusick 	exit(0);
45730380Smckusick }
45830380Smckusick 
459*31680Skarels #ifdef COMPAT
46030380Smckusick struct disklabel *
461*31680Skarels getdisklabel(s, fd, type)
462*31680Skarels 	char *s, *type;
463*31680Skarels 	int fd;
464*31680Skarels {
465*31680Skarels 	static struct disklabel lab;
466*31680Skarels 	struct disklabel *getdiskbyname();
467*31680Skarels 
468*31680Skarels 	if (ioctl(fd, DIOCGDINFO, (char *)&lab) < 0) {
469*31680Skarels 		if (type == NULL) {
470*31680Skarels 			perror("ioctl (GDINFO)");
471*31680Skarels 			fatal(
472*31680Skarels 		   "%s: can't read disk label; disk type must be specified", s);
473*31680Skarels 		}
474*31680Skarels 		unlabelled++;
475*31680Skarels 		return (getdiskbyname(type));
476*31680Skarels 	}
477*31680Skarels 	return (&lab);
478*31680Skarels }
479*31680Skarels #else
480*31680Skarels struct disklabel *
48130380Smckusick getdisklabel(s, fd)
48230380Smckusick 	char *s;
483*31680Skarels 	int fd;
48430380Smckusick {
48530380Smckusick 	static struct disklabel lab;
48630380Smckusick 
48730380Smckusick 	if (ioctl(fd, DIOCGDINFO, (char *)&lab) < 0) {
48830380Smckusick 		perror("ioctl (GDINFO)");
48930380Smckusick 		fatal("%s: can't read disk label", s);
49010762Ssam 	}
49130380Smckusick 	return (&lab);
49230380Smckusick }
493*31680Skarels #endif
49410762Ssam 
49530380Smckusick rewritelabel(s, fd, lp)
49630380Smckusick 	char *s;
49730380Smckusick 	int fd;
49830380Smckusick 	register struct disklabel *lp;
49930380Smckusick {
50030380Smckusick 
501*31680Skarels #ifdef COMPAT
502*31680Skarels 	if (unlabelled)
503*31680Skarels 		return;
504*31680Skarels #endif
50530380Smckusick 	lp->d_checksum = 0;
50630380Smckusick 	lp->d_checksum = dkcksum(lp);
50730380Smckusick 	if (ioctl(fd, DIOCWDINFO, (char *)lp) < 0) {
50830380Smckusick 		perror("ioctl (GWINFO)");
50930380Smckusick 		fatal("%s: can't rewrite disk label", s);
51010762Ssam 	}
51130446Skarels #if vax
51230446Skarels 	if (lp->d_type == DTYPE_SMD && lp->d_flags & D_BADSECT) {
51330446Skarels 		register i;
51430691Skarels 		int cfd;
51530446Skarels 		daddr_t alt;
51630691Skarels 		char specname[64];
51730691Skarels 		char blk[1024];
51831045Ssam 		char *cp;
51930446Skarels 
52030691Skarels 		/*
52130691Skarels 		 * Make name for 'c' partition.
52230691Skarels 		 */
52330691Skarels 		strcpy(specname, s);
52430691Skarels 		cp = specname + strlen(specname) - 1;
52530691Skarels 		if (!isdigit(*cp))
52630691Skarels 			*cp = 'c';
52730691Skarels 		cfd = open(specname, O_WRONLY);
52830691Skarels 		if (cfd < 0) {
52930691Skarels 			perror(specname);
53030691Skarels 			exit(2);
53130691Skarels 		}
53230691Skarels 		bzero(blk, sizeof(blk));
53330691Skarels 		*(struct disklabel *)(blk + LABELOFFSET) = *lp;
53430446Skarels 		alt = lp->d_ncylinders * lp->d_secpercyl - lp->d_nsectors;
53530446Skarels 		for (i = 1; i < 11 && i < lp->d_nsectors; i += 2) {
536*31680Skarels 			if (lseek(cfd, (off_t)(alt + i) * lp->d_secsize, L_SET) == -1) {
537*31680Skarels 				perror("lseek to badsector area");
538*31680Skarels 				exit(30);
539*31680Skarels 			}
54030691Skarels 			if (write(cfd, blk, lp->d_secsize) < lp->d_secsize) {
54130446Skarels 				int oerrno = errno;
54230446Skarels 				fprintf(stderr, "alternate label %d ", i/2);
54330446Skarels 				errno = oerrno;
54430446Skarels 				perror("write");
54530446Skarels 			}
54630380Smckusick 		}
54730380Smckusick 	}
54830446Skarels #endif
54910762Ssam }
55010762Ssam 
55110762Ssam /*VARARGS*/
55210762Ssam fatal(fmt, arg1, arg2)
55310762Ssam 	char *fmt;
55410762Ssam {
55510762Ssam 
55611069Ssam 	fprintf(stderr, "newfs: ");
55710762Ssam 	fprintf(stderr, fmt, arg1, arg2);
55810762Ssam 	putc('\n', stderr);
55910762Ssam 	exit(10);
56010762Ssam }
561