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*37951Sbostic static char sccsid[] = "@(#)newfs.c 6.17 (Berkeley) 05/11/89"; 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> 30*37951Sbostic #include <paths.h> 3110762Ssam 3231680Skarels #define COMPAT /* allow non-labeled disks */ 3331680Skarels 3430380Smckusick /* 3530380Smckusick * The following two constants set the default block and fragment sizes. 3630380Smckusick * Both constants must be a power of 2 and meet the following constraints: 3730380Smckusick * MINBSIZE <= DESBLKSIZE <= MAXBSIZE 3830380Smckusick * sectorsize <= DESFRAGSIZE <= DESBLKSIZE 3930380Smckusick * DESBLKSIZE / DESFRAGSIZE <= 8 4030380Smckusick */ 4130380Smckusick #define DFL_FRAGSIZE 1024 4230380Smckusick #define DFL_BLKSIZE 8192 4311183Ssam 4430380Smckusick /* 4534137Smckusick * Cylinder groups may have up to many cylinders. The actual 4630380Smckusick * number used depends upon how much information can be stored 4734137Smckusick * on a single cylinder. The default is to use 16 cylinders 4830380Smckusick * per group. 4930380Smckusick */ 5030380Smckusick #define DESCPG 16 /* desired fs_cpg */ 5130380Smckusick 5230380Smckusick /* 5330380Smckusick * MINFREE gives the minimum acceptable percentage of file system 5430380Smckusick * blocks which may be free. If the freelist drops below this level 5530380Smckusick * only the superuser may continue to allocate blocks. This may 5630380Smckusick * be set to 0 if no reserve of free blocks is deemed necessary, 5730380Smckusick * however throughput drops by fifty percent if the file system 5830380Smckusick * is run at between 90% and 100% full; thus the default value of 5930380Smckusick * fs_minfree is 10%. With 10% free space, fragmentation is not a 6030380Smckusick * problem, so we choose to optimize for time. 6130380Smckusick */ 6230380Smckusick #define MINFREE 10 6330380Smckusick #define DEFAULTOPT FS_OPTTIME 6430380Smckusick 6530380Smckusick /* 6630380Smckusick * ROTDELAY gives the minimum number of milliseconds to initiate 6730380Smckusick * another disk transfer on the same cylinder. It is used in 6830380Smckusick * determining the rotationally optimal layout for disk blocks 6930380Smckusick * within a file; the default of fs_rotdelay is 4ms. 7030380Smckusick */ 7130380Smckusick #define ROTDELAY 4 7230380Smckusick 7330380Smckusick /* 7430380Smckusick * MAXCONTIG sets the default for the maximum number of blocks 7530380Smckusick * that may be allocated sequentially. Since UNIX drivers are 7630380Smckusick * not capable of scheduling multi-block transfers, this defaults 7730380Smckusick * to 1 (ie no contiguous blocks are allocated). 7830380Smckusick */ 7930380Smckusick #define MAXCONTIG 1 8030380Smckusick 8130380Smckusick /* 8232309Smckusick * MAXBLKPG determines the maximum number of data blocks which are 8332309Smckusick * placed in a single cylinder group. The default is one indirect 8432309Smckusick * block worth of data blocks. 8532309Smckusick */ 8632309Smckusick #define MAXBLKPG(bsize) ((bsize) / sizeof(daddr_t)) 8732309Smckusick 8832309Smckusick /* 8930380Smckusick * Each file system has a number of inodes statically allocated. 9030380Smckusick * We allocate one inode slot per NBPI bytes, expecting this 9130380Smckusick * to be far more than we will ever need. 9230380Smckusick */ 9330380Smckusick #define NBPI 2048 9430380Smckusick 9534137Smckusick /* 9634137Smckusick * For each cylinder we keep track of the availability of blocks at different 9734137Smckusick * rotational positions, so that we can lay out the data to be picked 9834137Smckusick * up with minimum rotational latency. NRPOS is the default number of 9934137Smckusick * rotational positions that we distinguish. With NRPOS of 8 the resolution 10034137Smckusick * of our summary information is 2ms for a typical 3600 rpm drive. 10134137Smckusick */ 10234137Smckusick #define NRPOS 8 /* number distinct rotational positions */ 10334137Smckusick 10434137Smckusick 10530380Smckusick int Nflag; /* run without writing file system */ 10610762Ssam int fssize; /* file system size */ 10710762Ssam int ntracks; /* # tracks/cylinder */ 10810762Ssam int nsectors; /* # sectors/track */ 10930386Smckusick int nphyssectors; /* # sectors/track including spares */ 11030380Smckusick int secpercyl; /* sectors per cylinder */ 11130386Smckusick int trackspares = -1; /* spare sectors per track */ 11230386Smckusick int cylspares = -1; /* spare sectors per cylinder */ 11310762Ssam int sectorsize; /* bytes/sector */ 11430691Skarels #ifdef tahoe 11530691Skarels int realsectorsize; /* bytes/sector in hardware */ 11630691Skarels #endif 11711069Ssam int rpm; /* revolutions/minute of drive */ 11830386Smckusick int interleave; /* hardware sector interleave */ 11930386Smckusick int trackskew = -1; /* sector 0 skew, per track */ 12030386Smckusick int headswitch; /* head switch time, usec */ 12130386Smckusick int trackseek; /* track-to-track seek, usec */ 12230862Skarels int fsize = 0; /* fragment size */ 12330862Skarels int bsize = 0; /* block size */ 12430380Smckusick int cpg = DESCPG; /* cylinders/cylinder group */ 12532119Smckusick int cpgflg; /* cylinders/cylinder group flag was given */ 12630380Smckusick int minfree = MINFREE; /* free space threshold */ 12730380Smckusick int opt = DEFAULTOPT; /* optimization preference (space or time) */ 12830380Smckusick int density = NBPI; /* number of bytes per inode */ 12930380Smckusick int maxcontig = MAXCONTIG; /* max contiguous blocks to allocate */ 13030380Smckusick int rotdelay = ROTDELAY; /* rotational delay between blocks */ 13132309Smckusick int maxbpg; /* maximum blocks per file in a cyl group */ 13234137Smckusick int nrpos = NRPOS; /* # of distinguished rotational positions */ 13330691Skarels int bbsize = BBSIZE; /* boot block size */ 13430691Skarels int sbsize = SBSIZE; /* superblock size */ 13531680Skarels #ifdef COMPAT 13631680Skarels int unlabelled; 13731680Skarels #endif 13810762Ssam 13910762Ssam char device[MAXPATHLEN]; 14010762Ssam 14130380Smckusick extern int errno; 14210762Ssam char *index(); 14310762Ssam char *rindex(); 14410762Ssam 14510762Ssam main(argc, argv) 14614064Smckusick int argc; 14710762Ssam char *argv[]; 14810762Ssam { 14910762Ssam char *cp, *special; 15010762Ssam register struct partition *pp; 15130380Smckusick register struct disklabel *lp; 15230380Smckusick struct disklabel *getdisklabel(); 15330380Smckusick struct partition oldpartition; 15410762Ssam struct stat st; 15530380Smckusick int fsi, fso; 15610762Ssam register int i; 15710762Ssam int status; 15810762Ssam 15910762Ssam argc--, argv++; 16010762Ssam while (argc > 0 && argv[0][0] == '-') { 16110762Ssam for (cp = &argv[0][1]; *cp; cp++) 16210762Ssam switch (*cp) { 16310762Ssam 16416945Smckusick case 'N': 16516945Smckusick Nflag++; 16612334Shelge break; 16712334Shelge 16830380Smckusick case 'S': 16910762Ssam if (argc < 1) 17030380Smckusick fatal("-S: missing sector size"); 17110762Ssam argc--, argv++; 17230380Smckusick sectorsize = atoi(*argv); 17330380Smckusick if (sectorsize <= 0) 17430380Smckusick fatal("%s: bad sector size", *argv); 17510762Ssam goto next; 17610762Ssam 17730380Smckusick case 'a': 17810762Ssam if (argc < 1) 17932309Smckusick fatal("-a: missing max contiguous blocks\n"); 18010762Ssam argc--, argv++; 18132309Smckusick maxcontig = atoi(*argv); 18232309Smckusick if (maxcontig <= 0) 18332309Smckusick fatal("%s: bad max contiguous blocks\n", 18432309Smckusick *argv); 18510762Ssam goto next; 18610762Ssam 18710762Ssam case 'b': 18810762Ssam if (argc < 1) 18910762Ssam fatal("-b: missing block size"); 19010762Ssam argc--, argv++; 19110762Ssam bsize = atoi(*argv); 19230380Smckusick if (bsize < MINBSIZE) 19310762Ssam fatal("%s: bad block size", *argv); 19410762Ssam goto next; 19510762Ssam 19630380Smckusick case 'c': 19730380Smckusick if (argc < 1) 19830380Smckusick fatal("-c: missing cylinders/group"); 19930380Smckusick argc--, argv++; 20030380Smckusick cpg = atoi(*argv); 20130380Smckusick if (cpg <= 0) 20230380Smckusick fatal("%s: bad cylinders/group", *argv); 20332119Smckusick cpgflg++; 20430380Smckusick goto next; 20530380Smckusick 20630380Smckusick case 'd': 20730380Smckusick if (argc < 1) 20832309Smckusick fatal("-d: missing rotational delay\n"); 20930380Smckusick argc--, argv++; 21032309Smckusick rotdelay = atoi(*argv); 21132309Smckusick if (rotdelay < 0) 21232309Smckusick fatal("%s: bad rotational delay\n", 21332309Smckusick *argv); 21430380Smckusick goto next; 21530380Smckusick 21632309Smckusick case 'e': 21732309Smckusick if (argc < 1) 21832309Smckusick fatal("-e: missing blocks pre file in a cyl group\n"); 21932309Smckusick argc--, argv++; 22032309Smckusick maxbpg = atoi(*argv); 22132309Smckusick if (maxbpg <= 0) 22232309Smckusick fatal("%s: bad blocks per file in a cyl group\n", 22332309Smckusick *argv); 22432309Smckusick goto next; 22532309Smckusick 22610762Ssam case 'f': 22710762Ssam if (argc < 1) 22810762Ssam fatal("-f: missing frag size"); 22910762Ssam argc--, argv++; 23010762Ssam fsize = atoi(*argv); 23130380Smckusick if (fsize <= 0) 23210762Ssam fatal("%s: bad frag size", *argv); 23310762Ssam goto next; 23410762Ssam 23530380Smckusick case 'i': 23610762Ssam if (argc < 1) 23730380Smckusick fatal("-i: missing bytes per inode\n"); 23810762Ssam argc--, argv++; 23930380Smckusick density = atoi(*argv); 24030380Smckusick if (density <= 0) 24130380Smckusick fatal("%s: bad bytes per inode\n", 24230380Smckusick *argv); 24310762Ssam goto next; 24410762Ssam 24530386Smckusick case 'k': 24630386Smckusick if (argc < 1) 24730386Smckusick fatal("-k: track skew"); 24830386Smckusick argc--, argv++; 24930386Smckusick trackskew = atoi(*argv); 25030386Smckusick if (trackskew < 0) 25130386Smckusick fatal("%s: bad track skew", *argv); 25230386Smckusick goto next; 25330386Smckusick 25430386Smckusick case 'l': 25530386Smckusick if (argc < 1) 25630386Smckusick fatal("-l: interleave"); 25730386Smckusick argc--, argv++; 25830386Smckusick interleave = atoi(*argv); 25930386Smckusick if (interleave <= 0) 26030386Smckusick fatal("%s: bad interleave", *argv); 26130386Smckusick goto next; 26230386Smckusick 26311069Ssam case 'm': 26411069Ssam if (argc < 1) 26511069Ssam fatal("-m: missing free space %%\n"); 26611069Ssam argc--, argv++; 26711069Ssam minfree = atoi(*argv); 26811069Ssam if (minfree < 0 || minfree > 99) 26911069Ssam fatal("%s: bad free space %%\n", 27011069Ssam *argv); 27111069Ssam goto next; 27211069Ssam 27334137Smckusick case 'n': 27434137Smckusick if (argc < 1) 27534137Smckusick fatal("-n: missing rotational layout count\n"); 27634137Smckusick argc--, argv++; 27734137Smckusick nrpos = atoi(*argv); 27834137Smckusick if (nrpos <= 0) 27934137Smckusick fatal("%s: bad rotational layout count\n", 28034137Smckusick *argv); 28134137Smckusick goto next; 28234137Smckusick 28330380Smckusick case 'o': 28430380Smckusick if (argc < 1) 28530380Smckusick fatal("-o: missing optimization preference"); 28630380Smckusick argc--, argv++; 28730380Smckusick if (strcmp(*argv, "space") == 0) 28830380Smckusick opt = FS_OPTSPACE; 28930380Smckusick else if (strcmp(*argv, "time") == 0) 29030380Smckusick opt = FS_OPTTIME; 29130380Smckusick else 29230380Smckusick fatal("%s: bad optimization preference %s", 29330380Smckusick *argv, 29430380Smckusick "(options are `space' or `time')"); 29530380Smckusick goto next; 29630380Smckusick 29730386Smckusick case 'p': 29830386Smckusick if (argc < 1) 29930386Smckusick fatal("-p: spare sectors per track"); 30030386Smckusick argc--, argv++; 30130386Smckusick trackspares = atoi(*argv); 30230386Smckusick if (trackspares < 0) 30330386Smckusick fatal("%s: bad spare sectors per track", *argv); 30430386Smckusick goto next; 30530386Smckusick 30611069Ssam case 'r': 30711069Ssam if (argc < 1) 30811069Ssam fatal("-r: missing revs/minute\n"); 30911069Ssam argc--, argv++; 31011069Ssam rpm = atoi(*argv); 31130380Smckusick if (rpm <= 0) 31211069Ssam fatal("%s: bad revs/minute\n", *argv); 31311069Ssam goto next; 31411069Ssam 31530380Smckusick case 's': 31614884Smckusick if (argc < 1) 31730380Smckusick fatal("-s: missing file system size"); 31814884Smckusick argc--, argv++; 31930380Smckusick fssize = atoi(*argv); 32030380Smckusick if (fssize <= 0) 32130380Smckusick fatal("%s: bad file system size", 32214884Smckusick *argv); 32314884Smckusick goto next; 32414884Smckusick 32530380Smckusick case 't': 32630380Smckusick if (argc < 1) 32730380Smckusick fatal("-t: missing track total"); 32830380Smckusick argc--, argv++; 32930380Smckusick ntracks = atoi(*argv); 33030380Smckusick if (ntracks <= 0) 33130380Smckusick fatal("%s: bad total tracks", *argv); 33230380Smckusick goto next; 33330380Smckusick 33432309Smckusick case 'u': 33532309Smckusick if (argc < 1) 33632309Smckusick fatal("-u: missing sectors/track"); 33732309Smckusick argc--, argv++; 33832309Smckusick nsectors = atoi(*argv); 33932309Smckusick if (nsectors <= 0) 34032309Smckusick fatal("%s: bad sectors/track", *argv); 34132309Smckusick goto next; 34232309Smckusick 34332309Smckusick case 'x': 34432309Smckusick if (argc < 1) 34532309Smckusick fatal("-x: spare sectors per cylinder"); 34632309Smckusick argc--, argv++; 34732309Smckusick cylspares = atoi(*argv); 34832309Smckusick if (cylspares < 0) 34932309Smckusick fatal("%s: bad spare sectors per cylinder", *argv); 35032309Smckusick goto next; 35132309Smckusick 35210762Ssam default: 35332320Sbostic fatal("-%c: unknown flag", *cp); 35410762Ssam } 35510762Ssam next: 35610762Ssam argc--, argv++; 35710762Ssam } 35830380Smckusick if (argc < 1) { 35931680Skarels #ifdef COMPAT 36031680Skarels fprintf(stderr, 36131680Skarels "usage: newfs [ fsoptions ] special-device [device-type]\n"); 36231680Skarels #else 36330380Smckusick fprintf(stderr, "usage: newfs [ fsoptions ] special-device\n"); 36431680Skarels #endif 36530380Smckusick fprintf(stderr, "where fsoptions are:\n"); 36616945Smckusick fprintf(stderr, "\t-N do not create file system, %s\n", 36716945Smckusick "just print out parameters"); 36811057Ssam fprintf(stderr, "\t-b block size\n"); 36911057Ssam fprintf(stderr, "\t-f frag size\n"); 37011069Ssam fprintf(stderr, "\t-m minimum free space %%\n"); 37124702Smckusick fprintf(stderr, "\t-o optimization preference %s\n", 37224702Smckusick "(`space' or `time')"); 37332309Smckusick fprintf(stderr, "\t-a maximum contiguous blocks\n"); 37432309Smckusick fprintf(stderr, "\t-d rotational delay between %s\n", 37532309Smckusick "contiguous blocks"); 37632309Smckusick fprintf(stderr, "\t-e maximum blocks per file in a %s\n", 37732309Smckusick "cylinder group"); 37830398Smckusick fprintf(stderr, "\t-i number of bytes per inode\n"); 37930398Smckusick fprintf(stderr, "\t-c cylinders/group\n"); 38034137Smckusick fprintf(stderr, "\t-n number of distinguished %s\n", 38134137Smckusick "rotational positions"); 38230398Smckusick fprintf(stderr, "\t-s file system size (sectors)\n"); 38311069Ssam fprintf(stderr, "\t-r revolutions/minute\n"); 38411057Ssam fprintf(stderr, "\t-S sector size\n"); 38532309Smckusick fprintf(stderr, "\t-u sectors/track\n"); 38630398Smckusick fprintf(stderr, "\t-t tracks/cylinder\n"); 38730398Smckusick fprintf(stderr, "\t-p spare sectors per track\n"); 38832309Smckusick fprintf(stderr, "\t-x spare sectors per cylinder\n"); 38930386Smckusick fprintf(stderr, "\t-l hardware sector interleave\n"); 39030386Smckusick fprintf(stderr, "\t-k sector 0 skew, per track\n"); 39110762Ssam exit(1); 39210762Ssam } 39310762Ssam special = argv[0]; 39414064Smckusick cp = rindex(special, '/'); 39514064Smckusick if (cp != 0) 39614064Smckusick special = cp + 1; 39714321Ssam if (*special == 'r' && special[1] != 'a' && special[1] != 'b') 39814064Smckusick special++; 399*37951Sbostic (void)sprintf(device, "%s/r%s", _PATH_DEV, special); 40032463Sbostic special = device; 40130380Smckusick if (!Nflag) { 40230380Smckusick fso = open(special, O_WRONLY); 40330380Smckusick if (fso < 0) { 40430380Smckusick perror(special); 40530380Smckusick exit(1); 40630380Smckusick } 40730380Smckusick } else 40830380Smckusick fso = -1; 40930380Smckusick fsi = open(special, O_RDONLY); 41030380Smckusick if (fsi < 0) { 41130380Smckusick perror(special); 41230380Smckusick exit(1); 41330380Smckusick } 41430380Smckusick if (fstat(fsi, &st) < 0) { 41511069Ssam fprintf(stderr, "newfs: "); perror(special); 41610762Ssam exit(2); 41710762Ssam } 41814064Smckusick if ((st.st_mode & S_IFMT) != S_IFCHR) 41914064Smckusick fatal("%s: not a character device", special); 42010762Ssam cp = index(argv[0], '\0') - 1; 42130380Smckusick if (cp == 0 || (*cp < 'a' || *cp > 'h') && !isdigit(*cp)) 42210762Ssam fatal("%s: can't figure out file system partition", argv[0]); 42331680Skarels #ifdef COMPAT 42431680Skarels lp = getdisklabel(special, fsi, argv[1]); 42531680Skarels #else 42630380Smckusick lp = getdisklabel(special, fsi); 42731680Skarels #endif 42830380Smckusick if (isdigit(*cp)) 42930380Smckusick pp = &lp->d_partitions[0]; 43030380Smckusick else 43130380Smckusick pp = &lp->d_partitions[*cp - 'a']; 43230380Smckusick if (pp->p_size == 0) 43330380Smckusick fatal("%s: `%c' partition is unavailable", argv[0], *cp); 43430380Smckusick if (fssize == 0) 43510762Ssam fssize = pp->p_size; 43630380Smckusick if (fssize > pp->p_size) 43730380Smckusick fatal("%s: maximum file system size on the `%c' partition is %d", 43830380Smckusick argv[0], *cp, pp->p_size); 43930380Smckusick if (rpm == 0) { 44030380Smckusick rpm = lp->d_rpm; 44130380Smckusick if (rpm <= 0) 44230743Skarels rpm = 3600; 44310762Ssam } 44430380Smckusick if (ntracks == 0) { 44530380Smckusick ntracks = lp->d_ntracks; 44630380Smckusick if (ntracks <= 0) 44730743Skarels fatal("%s: no default #tracks", argv[0]); 44830380Smckusick } 44910762Ssam if (nsectors == 0) { 45030380Smckusick nsectors = lp->d_nsectors; 45130380Smckusick if (nsectors <= 0) 45230743Skarels fatal("%s: no default #sectors/track", argv[0]); 45310762Ssam } 45410762Ssam if (sectorsize == 0) { 45530380Smckusick sectorsize = lp->d_secsize; 45630380Smckusick if (sectorsize <= 0) 45730743Skarels fatal("%s: no default sector size", argv[0]); 45810762Ssam } 45930386Smckusick if (trackskew == -1) { 46030386Smckusick trackskew = lp->d_trackskew; 46130386Smckusick if (trackskew < 0) 46230743Skarels trackskew = 0; 46330386Smckusick } 46430386Smckusick if (interleave == 0) { 46530386Smckusick interleave = lp->d_interleave; 46630386Smckusick if (interleave <= 0) 46730743Skarels interleave = 1; 46830386Smckusick } 46910762Ssam if (fsize == 0) { 47010762Ssam fsize = pp->p_fsize; 47130380Smckusick if (fsize <= 0) 47230380Smckusick fsize = MAX(DFL_FRAGSIZE, lp->d_secsize); 47310762Ssam } 47430380Smckusick if (bsize == 0) { 47530380Smckusick bsize = pp->p_frag * pp->p_fsize; 47630380Smckusick if (bsize <= 0) 47730380Smckusick bsize = MIN(DFL_BLKSIZE, 8 * fsize); 47811069Ssam } 47924702Smckusick if (minfree < 10 && opt != FS_OPTSPACE) { 48030380Smckusick fprintf(stderr, "Warning: changing optimization to space "); 48130380Smckusick fprintf(stderr, "because minfree is less than 10%%\n"); 48224702Smckusick opt = FS_OPTSPACE; 48324702Smckusick } 48430386Smckusick if (trackspares == -1) { 48530386Smckusick trackspares = lp->d_sparespertrack; 48630386Smckusick if (trackspares < 0) 48730743Skarels trackspares = 0; 48830386Smckusick } 48930386Smckusick nphyssectors = nsectors + trackspares; 49030386Smckusick if (cylspares == -1) { 49130386Smckusick cylspares = lp->d_sparespercyl; 49230386Smckusick if (cylspares < 0) 49330743Skarels cylspares = 0; 49430386Smckusick } 49530386Smckusick secpercyl = nsectors * ntracks - cylspares; 49630380Smckusick if (secpercyl != lp->d_secpercyl) 49730380Smckusick fprintf(stderr, "%s (%d) %s (%d)\n", 49830380Smckusick "Warning: calculated sectors per cylinder", secpercyl, 49930380Smckusick "disagrees with disk label", lp->d_secpercyl); 50032321Smckusick if (maxbpg == 0) 50132321Smckusick maxbpg = MAXBLKPG(bsize); 50230386Smckusick headswitch = lp->d_headswitch; 50330386Smckusick trackseek = lp->d_trkseek; 50430691Skarels bbsize = lp->d_bbsize; 50530691Skarels sbsize = lp->d_sbsize; 50630380Smckusick oldpartition = *pp; 50730691Skarels #ifdef tahoe 50830691Skarels realsectorsize = sectorsize; 50930862Skarels if (sectorsize != DEV_BSIZE) { /* XXX */ 51030691Skarels int secperblk = DEV_BSIZE / sectorsize; 51130691Skarels 51230691Skarels sectorsize = DEV_BSIZE; 51330691Skarels nsectors /= secperblk; 51430691Skarels nphyssectors /= secperblk; 51530691Skarels secpercyl /= secperblk; 51630691Skarels fssize /= secperblk; 51730691Skarels pp->p_size /= secperblk; 51830691Skarels } 51930691Skarels #endif 52030380Smckusick mkfs(pp, special, fsi, fso); 52130691Skarels #ifdef tahoe 52230691Skarels if (realsectorsize != DEV_BSIZE) 52330691Skarels pp->p_size *= DEV_BSIZE / realsectorsize; 52430691Skarels #endif 52530380Smckusick if (!Nflag && bcmp(pp, &oldpartition, sizeof(oldpartition))) 52630380Smckusick rewritelabel(special, fso, lp); 52730380Smckusick exit(0); 52830380Smckusick } 52930380Smckusick 53031680Skarels #ifdef COMPAT 53130380Smckusick struct disklabel * 53231680Skarels getdisklabel(s, fd, type) 53331680Skarels char *s, *type; 53431680Skarels int fd; 53531680Skarels { 53631680Skarels static struct disklabel lab; 53731680Skarels struct disklabel *getdiskbyname(); 53831680Skarels 53931680Skarels if (ioctl(fd, DIOCGDINFO, (char *)&lab) < 0) { 54031680Skarels if (type == NULL) { 54131680Skarels perror("ioctl (GDINFO)"); 54231680Skarels fatal( 54331680Skarels "%s: can't read disk label; disk type must be specified", s); 54431680Skarels } 54531680Skarels unlabelled++; 54631680Skarels return (getdiskbyname(type)); 54731680Skarels } 54831680Skarels return (&lab); 54931680Skarels } 55031680Skarels #else 55131680Skarels struct disklabel * 55230380Smckusick getdisklabel(s, fd) 55330380Smckusick char *s; 55431680Skarels int fd; 55530380Smckusick { 55630380Smckusick static struct disklabel lab; 55730380Smckusick 55830380Smckusick if (ioctl(fd, DIOCGDINFO, (char *)&lab) < 0) { 55930380Smckusick perror("ioctl (GDINFO)"); 56030380Smckusick fatal("%s: can't read disk label", s); 56110762Ssam } 56230380Smckusick return (&lab); 56330380Smckusick } 56431680Skarels #endif 56510762Ssam 56630380Smckusick rewritelabel(s, fd, lp) 56730380Smckusick char *s; 56830380Smckusick int fd; 56930380Smckusick register struct disklabel *lp; 57030380Smckusick { 57130380Smckusick 57231680Skarels #ifdef COMPAT 57331680Skarels if (unlabelled) 57431680Skarels return; 57531680Skarels #endif 57630380Smckusick lp->d_checksum = 0; 57730380Smckusick lp->d_checksum = dkcksum(lp); 57830380Smckusick if (ioctl(fd, DIOCWDINFO, (char *)lp) < 0) { 57932786Smckusick perror("ioctl (WDINFO)"); 58030380Smckusick fatal("%s: can't rewrite disk label", s); 58110762Ssam } 58230446Skarels #if vax 58330446Skarels if (lp->d_type == DTYPE_SMD && lp->d_flags & D_BADSECT) { 58430446Skarels register i; 58530691Skarels int cfd; 58630446Skarels daddr_t alt; 58730691Skarels char specname[64]; 58830691Skarels char blk[1024]; 58931045Ssam char *cp; 59030446Skarels 59130691Skarels /* 59230691Skarels * Make name for 'c' partition. 59330691Skarels */ 59430691Skarels strcpy(specname, s); 59530691Skarels cp = specname + strlen(specname) - 1; 59630691Skarels if (!isdigit(*cp)) 59730691Skarels *cp = 'c'; 59830691Skarels cfd = open(specname, O_WRONLY); 59930691Skarels if (cfd < 0) { 60030691Skarels perror(specname); 60130691Skarels exit(2); 60230691Skarels } 60330691Skarels bzero(blk, sizeof(blk)); 60430691Skarels *(struct disklabel *)(blk + LABELOFFSET) = *lp; 60530446Skarels alt = lp->d_ncylinders * lp->d_secpercyl - lp->d_nsectors; 60630446Skarels for (i = 1; i < 11 && i < lp->d_nsectors; i += 2) { 60731680Skarels if (lseek(cfd, (off_t)(alt + i) * lp->d_secsize, L_SET) == -1) { 60831680Skarels perror("lseek to badsector area"); 60931680Skarels exit(30); 61031680Skarels } 61130691Skarels if (write(cfd, blk, lp->d_secsize) < lp->d_secsize) { 61230446Skarels int oerrno = errno; 61330446Skarels fprintf(stderr, "alternate label %d ", i/2); 61430446Skarels errno = oerrno; 61530446Skarels perror("write"); 61630446Skarels } 61730380Smckusick } 61830380Smckusick } 61930446Skarels #endif 62010762Ssam } 62110762Ssam 62210762Ssam /*VARARGS*/ 62310762Ssam fatal(fmt, arg1, arg2) 62410762Ssam char *fmt; 62510762Ssam { 62610762Ssam 62711069Ssam fprintf(stderr, "newfs: "); 62810762Ssam fprintf(stderr, fmt, arg1, arg2); 62910762Ssam putc('\n', stderr); 63010762Ssam exit(10); 63110762Ssam } 632