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