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*34137Smckusick static char sccsid[] = "@(#)newfs.c 6.16 (Berkeley) 05/01/88"; 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 3131680Skarels #define COMPAT /* allow non-labeled disks */ 3231680Skarels 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 /* 44*34137Smckusick * Cylinder groups may have up to many cylinders. The actual 4530380Smckusick * number used depends upon how much information can be stored 46*34137Smckusick * on a single cylinder. The default is to use 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 /* 8132309Smckusick * MAXBLKPG determines the maximum number of data blocks which are 8232309Smckusick * placed in a single cylinder group. The default is one indirect 8332309Smckusick * block worth of data blocks. 8432309Smckusick */ 8532309Smckusick #define MAXBLKPG(bsize) ((bsize) / sizeof(daddr_t)) 8632309Smckusick 8732309Smckusick /* 8830380Smckusick * Each file system has a number of inodes statically allocated. 8930380Smckusick * We allocate one inode slot per NBPI bytes, expecting this 9030380Smckusick * to be far more than we will ever need. 9130380Smckusick */ 9230380Smckusick #define NBPI 2048 9330380Smckusick 94*34137Smckusick /* 95*34137Smckusick * For each cylinder we keep track of the availability of blocks at different 96*34137Smckusick * rotational positions, so that we can lay out the data to be picked 97*34137Smckusick * up with minimum rotational latency. NRPOS is the default number of 98*34137Smckusick * rotational positions that we distinguish. With NRPOS of 8 the resolution 99*34137Smckusick * of our summary information is 2ms for a typical 3600 rpm drive. 100*34137Smckusick */ 101*34137Smckusick #define NRPOS 8 /* number distinct rotational positions */ 102*34137Smckusick 103*34137Smckusick 10430380Smckusick int Nflag; /* run without writing file system */ 10510762Ssam int fssize; /* file system size */ 10610762Ssam int ntracks; /* # tracks/cylinder */ 10710762Ssam int nsectors; /* # sectors/track */ 10830386Smckusick int nphyssectors; /* # sectors/track including spares */ 10930380Smckusick int secpercyl; /* sectors per cylinder */ 11030386Smckusick int trackspares = -1; /* spare sectors per track */ 11130386Smckusick int cylspares = -1; /* spare sectors per cylinder */ 11210762Ssam int sectorsize; /* bytes/sector */ 11330691Skarels #ifdef tahoe 11430691Skarels int realsectorsize; /* bytes/sector in hardware */ 11530691Skarels #endif 11611069Ssam int rpm; /* revolutions/minute of drive */ 11730386Smckusick int interleave; /* hardware sector interleave */ 11830386Smckusick int trackskew = -1; /* sector 0 skew, per track */ 11930386Smckusick int headswitch; /* head switch time, usec */ 12030386Smckusick int trackseek; /* track-to-track seek, usec */ 12130862Skarels int fsize = 0; /* fragment size */ 12230862Skarels int bsize = 0; /* block size */ 12330380Smckusick int cpg = DESCPG; /* cylinders/cylinder group */ 12432119Smckusick int cpgflg; /* cylinders/cylinder group flag was given */ 12530380Smckusick int minfree = MINFREE; /* free space threshold */ 12630380Smckusick int opt = DEFAULTOPT; /* optimization preference (space or time) */ 12730380Smckusick int density = NBPI; /* number of bytes per inode */ 12830380Smckusick int maxcontig = MAXCONTIG; /* max contiguous blocks to allocate */ 12930380Smckusick int rotdelay = ROTDELAY; /* rotational delay between blocks */ 13032309Smckusick int maxbpg; /* maximum blocks per file in a cyl group */ 131*34137Smckusick int nrpos = NRPOS; /* # of distinguished rotational positions */ 13230691Skarels int bbsize = BBSIZE; /* boot block size */ 13330691Skarels int sbsize = SBSIZE; /* superblock size */ 13431680Skarels #ifdef COMPAT 13531680Skarels int unlabelled; 13631680Skarels #endif 13710762Ssam 13810762Ssam char device[MAXPATHLEN]; 13910762Ssam 14030380Smckusick extern int errno; 14110762Ssam char *index(); 14210762Ssam char *rindex(); 14310762Ssam 14410762Ssam main(argc, argv) 14514064Smckusick int argc; 14610762Ssam char *argv[]; 14710762Ssam { 14810762Ssam char *cp, *special; 14910762Ssam register struct partition *pp; 15030380Smckusick register struct disklabel *lp; 15130380Smckusick struct disklabel *getdisklabel(); 15230380Smckusick struct partition oldpartition; 15310762Ssam struct stat st; 15430380Smckusick int fsi, fso; 15510762Ssam register int i; 15610762Ssam int status; 15710762Ssam 15810762Ssam argc--, argv++; 15910762Ssam while (argc > 0 && argv[0][0] == '-') { 16010762Ssam for (cp = &argv[0][1]; *cp; cp++) 16110762Ssam switch (*cp) { 16210762Ssam 16316945Smckusick case 'N': 16416945Smckusick Nflag++; 16512334Shelge break; 16612334Shelge 16730380Smckusick case 'S': 16810762Ssam if (argc < 1) 16930380Smckusick fatal("-S: missing sector size"); 17010762Ssam argc--, argv++; 17130380Smckusick sectorsize = atoi(*argv); 17230380Smckusick if (sectorsize <= 0) 17330380Smckusick fatal("%s: bad sector size", *argv); 17410762Ssam goto next; 17510762Ssam 17630380Smckusick case 'a': 17710762Ssam if (argc < 1) 17832309Smckusick fatal("-a: missing max contiguous blocks\n"); 17910762Ssam argc--, argv++; 18032309Smckusick maxcontig = atoi(*argv); 18132309Smckusick if (maxcontig <= 0) 18232309Smckusick fatal("%s: bad max contiguous blocks\n", 18332309Smckusick *argv); 18410762Ssam goto next; 18510762Ssam 18610762Ssam case 'b': 18710762Ssam if (argc < 1) 18810762Ssam fatal("-b: missing block size"); 18910762Ssam argc--, argv++; 19010762Ssam bsize = atoi(*argv); 19130380Smckusick if (bsize < MINBSIZE) 19210762Ssam fatal("%s: bad block size", *argv); 19310762Ssam goto next; 19410762Ssam 19530380Smckusick case 'c': 19630380Smckusick if (argc < 1) 19730380Smckusick fatal("-c: missing cylinders/group"); 19830380Smckusick argc--, argv++; 19930380Smckusick cpg = atoi(*argv); 20030380Smckusick if (cpg <= 0) 20130380Smckusick fatal("%s: bad cylinders/group", *argv); 20232119Smckusick cpgflg++; 20330380Smckusick goto next; 20430380Smckusick 20530380Smckusick case 'd': 20630380Smckusick if (argc < 1) 20732309Smckusick fatal("-d: missing rotational delay\n"); 20830380Smckusick argc--, argv++; 20932309Smckusick rotdelay = atoi(*argv); 21032309Smckusick if (rotdelay < 0) 21132309Smckusick fatal("%s: bad rotational delay\n", 21232309Smckusick *argv); 21330380Smckusick goto next; 21430380Smckusick 21532309Smckusick case 'e': 21632309Smckusick if (argc < 1) 21732309Smckusick fatal("-e: missing blocks pre file in a cyl group\n"); 21832309Smckusick argc--, argv++; 21932309Smckusick maxbpg = atoi(*argv); 22032309Smckusick if (maxbpg <= 0) 22132309Smckusick fatal("%s: bad blocks per file in a cyl group\n", 22232309Smckusick *argv); 22332309Smckusick goto next; 22432309Smckusick 22510762Ssam case 'f': 22610762Ssam if (argc < 1) 22710762Ssam fatal("-f: missing frag size"); 22810762Ssam argc--, argv++; 22910762Ssam fsize = atoi(*argv); 23030380Smckusick if (fsize <= 0) 23110762Ssam fatal("%s: bad frag size", *argv); 23210762Ssam goto next; 23310762Ssam 23430380Smckusick case 'i': 23510762Ssam if (argc < 1) 23630380Smckusick fatal("-i: missing bytes per inode\n"); 23710762Ssam argc--, argv++; 23830380Smckusick density = atoi(*argv); 23930380Smckusick if (density <= 0) 24030380Smckusick fatal("%s: bad bytes per inode\n", 24130380Smckusick *argv); 24210762Ssam goto next; 24310762Ssam 24430386Smckusick case 'k': 24530386Smckusick if (argc < 1) 24630386Smckusick fatal("-k: track skew"); 24730386Smckusick argc--, argv++; 24830386Smckusick trackskew = atoi(*argv); 24930386Smckusick if (trackskew < 0) 25030386Smckusick fatal("%s: bad track skew", *argv); 25130386Smckusick goto next; 25230386Smckusick 25330386Smckusick case 'l': 25430386Smckusick if (argc < 1) 25530386Smckusick fatal("-l: interleave"); 25630386Smckusick argc--, argv++; 25730386Smckusick interleave = atoi(*argv); 25830386Smckusick if (interleave <= 0) 25930386Smckusick fatal("%s: bad interleave", *argv); 26030386Smckusick goto next; 26130386Smckusick 26211069Ssam case 'm': 26311069Ssam if (argc < 1) 26411069Ssam fatal("-m: missing free space %%\n"); 26511069Ssam argc--, argv++; 26611069Ssam minfree = atoi(*argv); 26711069Ssam if (minfree < 0 || minfree > 99) 26811069Ssam fatal("%s: bad free space %%\n", 26911069Ssam *argv); 27011069Ssam goto next; 27111069Ssam 272*34137Smckusick case 'n': 273*34137Smckusick if (argc < 1) 274*34137Smckusick fatal("-n: missing rotational layout count\n"); 275*34137Smckusick argc--, argv++; 276*34137Smckusick nrpos = atoi(*argv); 277*34137Smckusick if (nrpos <= 0) 278*34137Smckusick fatal("%s: bad rotational layout count\n", 279*34137Smckusick *argv); 280*34137Smckusick goto next; 281*34137Smckusick 28230380Smckusick case 'o': 28330380Smckusick if (argc < 1) 28430380Smckusick fatal("-o: missing optimization preference"); 28530380Smckusick argc--, argv++; 28630380Smckusick if (strcmp(*argv, "space") == 0) 28730380Smckusick opt = FS_OPTSPACE; 28830380Smckusick else if (strcmp(*argv, "time") == 0) 28930380Smckusick opt = FS_OPTTIME; 29030380Smckusick else 29130380Smckusick fatal("%s: bad optimization preference %s", 29230380Smckusick *argv, 29330380Smckusick "(options are `space' or `time')"); 29430380Smckusick goto next; 29530380Smckusick 29630386Smckusick case 'p': 29730386Smckusick if (argc < 1) 29830386Smckusick fatal("-p: spare sectors per track"); 29930386Smckusick argc--, argv++; 30030386Smckusick trackspares = atoi(*argv); 30130386Smckusick if (trackspares < 0) 30230386Smckusick fatal("%s: bad spare sectors per track", *argv); 30330386Smckusick goto next; 30430386Smckusick 30511069Ssam case 'r': 30611069Ssam if (argc < 1) 30711069Ssam fatal("-r: missing revs/minute\n"); 30811069Ssam argc--, argv++; 30911069Ssam rpm = atoi(*argv); 31030380Smckusick if (rpm <= 0) 31111069Ssam fatal("%s: bad revs/minute\n", *argv); 31211069Ssam goto next; 31311069Ssam 31430380Smckusick case 's': 31514884Smckusick if (argc < 1) 31630380Smckusick fatal("-s: missing file system size"); 31714884Smckusick argc--, argv++; 31830380Smckusick fssize = atoi(*argv); 31930380Smckusick if (fssize <= 0) 32030380Smckusick fatal("%s: bad file system size", 32114884Smckusick *argv); 32214884Smckusick goto next; 32314884Smckusick 32430380Smckusick case 't': 32530380Smckusick if (argc < 1) 32630380Smckusick fatal("-t: missing track total"); 32730380Smckusick argc--, argv++; 32830380Smckusick ntracks = atoi(*argv); 32930380Smckusick if (ntracks <= 0) 33030380Smckusick fatal("%s: bad total tracks", *argv); 33130380Smckusick goto next; 33230380Smckusick 33332309Smckusick case 'u': 33432309Smckusick if (argc < 1) 33532309Smckusick fatal("-u: missing sectors/track"); 33632309Smckusick argc--, argv++; 33732309Smckusick nsectors = atoi(*argv); 33832309Smckusick if (nsectors <= 0) 33932309Smckusick fatal("%s: bad sectors/track", *argv); 34032309Smckusick goto next; 34132309Smckusick 34232309Smckusick case 'x': 34332309Smckusick if (argc < 1) 34432309Smckusick fatal("-x: spare sectors per cylinder"); 34532309Smckusick argc--, argv++; 34632309Smckusick cylspares = atoi(*argv); 34732309Smckusick if (cylspares < 0) 34832309Smckusick fatal("%s: bad spare sectors per cylinder", *argv); 34932309Smckusick goto next; 35032309Smckusick 35110762Ssam default: 35232320Sbostic fatal("-%c: unknown flag", *cp); 35310762Ssam } 35410762Ssam next: 35510762Ssam argc--, argv++; 35610762Ssam } 35730380Smckusick if (argc < 1) { 35831680Skarels #ifdef COMPAT 35931680Skarels fprintf(stderr, 36031680Skarels "usage: newfs [ fsoptions ] special-device [device-type]\n"); 36131680Skarels #else 36230380Smckusick fprintf(stderr, "usage: newfs [ fsoptions ] special-device\n"); 36331680Skarels #endif 36430380Smckusick fprintf(stderr, "where fsoptions are:\n"); 36516945Smckusick fprintf(stderr, "\t-N do not create file system, %s\n", 36616945Smckusick "just print out parameters"); 36711057Ssam fprintf(stderr, "\t-b block size\n"); 36811057Ssam fprintf(stderr, "\t-f frag size\n"); 36911069Ssam fprintf(stderr, "\t-m minimum free space %%\n"); 37024702Smckusick fprintf(stderr, "\t-o optimization preference %s\n", 37124702Smckusick "(`space' or `time')"); 37232309Smckusick fprintf(stderr, "\t-a maximum contiguous blocks\n"); 37332309Smckusick fprintf(stderr, "\t-d rotational delay between %s\n", 37432309Smckusick "contiguous blocks"); 37532309Smckusick fprintf(stderr, "\t-e maximum blocks per file in a %s\n", 37632309Smckusick "cylinder group"); 37730398Smckusick fprintf(stderr, "\t-i number of bytes per inode\n"); 37830398Smckusick fprintf(stderr, "\t-c cylinders/group\n"); 379*34137Smckusick fprintf(stderr, "\t-n number of distinguished %s\n", 380*34137Smckusick "rotational positions"); 38130398Smckusick fprintf(stderr, "\t-s file system size (sectors)\n"); 38211069Ssam fprintf(stderr, "\t-r revolutions/minute\n"); 38311057Ssam fprintf(stderr, "\t-S sector size\n"); 38432309Smckusick fprintf(stderr, "\t-u sectors/track\n"); 38530398Smckusick fprintf(stderr, "\t-t tracks/cylinder\n"); 38630398Smckusick fprintf(stderr, "\t-p spare sectors per track\n"); 38732309Smckusick fprintf(stderr, "\t-x spare sectors per cylinder\n"); 38830386Smckusick fprintf(stderr, "\t-l hardware sector interleave\n"); 38930386Smckusick fprintf(stderr, "\t-k sector 0 skew, per track\n"); 39010762Ssam exit(1); 39110762Ssam } 39210762Ssam special = argv[0]; 39314064Smckusick cp = rindex(special, '/'); 39414064Smckusick if (cp != 0) 39514064Smckusick special = cp + 1; 39614321Ssam if (*special == 'r' && special[1] != 'a' && special[1] != 'b') 39714064Smckusick special++; 39832463Sbostic (void)sprintf(device, "/dev/r%s", special); 39932463Sbostic special = device; 40030380Smckusick if (!Nflag) { 40130380Smckusick fso = open(special, O_WRONLY); 40230380Smckusick if (fso < 0) { 40330380Smckusick perror(special); 40430380Smckusick exit(1); 40530380Smckusick } 40630380Smckusick } else 40730380Smckusick fso = -1; 40830380Smckusick fsi = open(special, O_RDONLY); 40930380Smckusick if (fsi < 0) { 41030380Smckusick perror(special); 41130380Smckusick exit(1); 41230380Smckusick } 41330380Smckusick if (fstat(fsi, &st) < 0) { 41411069Ssam fprintf(stderr, "newfs: "); perror(special); 41510762Ssam exit(2); 41610762Ssam } 41714064Smckusick if ((st.st_mode & S_IFMT) != S_IFCHR) 41814064Smckusick fatal("%s: not a character device", special); 41910762Ssam cp = index(argv[0], '\0') - 1; 42030380Smckusick if (cp == 0 || (*cp < 'a' || *cp > 'h') && !isdigit(*cp)) 42110762Ssam fatal("%s: can't figure out file system partition", argv[0]); 42231680Skarels #ifdef COMPAT 42331680Skarels lp = getdisklabel(special, fsi, argv[1]); 42431680Skarels #else 42530380Smckusick lp = getdisklabel(special, fsi); 42631680Skarels #endif 42730380Smckusick if (isdigit(*cp)) 42830380Smckusick pp = &lp->d_partitions[0]; 42930380Smckusick else 43030380Smckusick pp = &lp->d_partitions[*cp - 'a']; 43130380Smckusick if (pp->p_size == 0) 43230380Smckusick fatal("%s: `%c' partition is unavailable", argv[0], *cp); 43330380Smckusick if (fssize == 0) 43410762Ssam fssize = pp->p_size; 43530380Smckusick if (fssize > pp->p_size) 43630380Smckusick fatal("%s: maximum file system size on the `%c' partition is %d", 43730380Smckusick argv[0], *cp, pp->p_size); 43830380Smckusick if (rpm == 0) { 43930380Smckusick rpm = lp->d_rpm; 44030380Smckusick if (rpm <= 0) 44130743Skarels rpm = 3600; 44210762Ssam } 44330380Smckusick if (ntracks == 0) { 44430380Smckusick ntracks = lp->d_ntracks; 44530380Smckusick if (ntracks <= 0) 44630743Skarels fatal("%s: no default #tracks", argv[0]); 44730380Smckusick } 44810762Ssam if (nsectors == 0) { 44930380Smckusick nsectors = lp->d_nsectors; 45030380Smckusick if (nsectors <= 0) 45130743Skarels fatal("%s: no default #sectors/track", argv[0]); 45210762Ssam } 45310762Ssam if (sectorsize == 0) { 45430380Smckusick sectorsize = lp->d_secsize; 45530380Smckusick if (sectorsize <= 0) 45630743Skarels fatal("%s: no default sector size", argv[0]); 45710762Ssam } 45830386Smckusick if (trackskew == -1) { 45930386Smckusick trackskew = lp->d_trackskew; 46030386Smckusick if (trackskew < 0) 46130743Skarels trackskew = 0; 46230386Smckusick } 46330386Smckusick if (interleave == 0) { 46430386Smckusick interleave = lp->d_interleave; 46530386Smckusick if (interleave <= 0) 46630743Skarels interleave = 1; 46730386Smckusick } 46810762Ssam if (fsize == 0) { 46910762Ssam fsize = pp->p_fsize; 47030380Smckusick if (fsize <= 0) 47130380Smckusick fsize = MAX(DFL_FRAGSIZE, lp->d_secsize); 47210762Ssam } 47330380Smckusick if (bsize == 0) { 47430380Smckusick bsize = pp->p_frag * pp->p_fsize; 47530380Smckusick if (bsize <= 0) 47630380Smckusick bsize = MIN(DFL_BLKSIZE, 8 * fsize); 47711069Ssam } 47824702Smckusick if (minfree < 10 && opt != FS_OPTSPACE) { 47930380Smckusick fprintf(stderr, "Warning: changing optimization to space "); 48030380Smckusick fprintf(stderr, "because minfree is less than 10%%\n"); 48124702Smckusick opt = FS_OPTSPACE; 48224702Smckusick } 48330386Smckusick if (trackspares == -1) { 48430386Smckusick trackspares = lp->d_sparespertrack; 48530386Smckusick if (trackspares < 0) 48630743Skarels trackspares = 0; 48730386Smckusick } 48830386Smckusick nphyssectors = nsectors + trackspares; 48930386Smckusick if (cylspares == -1) { 49030386Smckusick cylspares = lp->d_sparespercyl; 49130386Smckusick if (cylspares < 0) 49230743Skarels cylspares = 0; 49330386Smckusick } 49430386Smckusick secpercyl = nsectors * ntracks - cylspares; 49530380Smckusick if (secpercyl != lp->d_secpercyl) 49630380Smckusick fprintf(stderr, "%s (%d) %s (%d)\n", 49730380Smckusick "Warning: calculated sectors per cylinder", secpercyl, 49830380Smckusick "disagrees with disk label", lp->d_secpercyl); 49932321Smckusick if (maxbpg == 0) 50032321Smckusick maxbpg = MAXBLKPG(bsize); 50130386Smckusick headswitch = lp->d_headswitch; 50230386Smckusick trackseek = lp->d_trkseek; 50330691Skarels bbsize = lp->d_bbsize; 50430691Skarels sbsize = lp->d_sbsize; 50530380Smckusick oldpartition = *pp; 50630691Skarels #ifdef tahoe 50730691Skarels realsectorsize = sectorsize; 50830862Skarels if (sectorsize != DEV_BSIZE) { /* XXX */ 50930691Skarels int secperblk = DEV_BSIZE / sectorsize; 51030691Skarels 51130691Skarels sectorsize = DEV_BSIZE; 51230691Skarels nsectors /= secperblk; 51330691Skarels nphyssectors /= secperblk; 51430691Skarels secpercyl /= secperblk; 51530691Skarels fssize /= secperblk; 51630691Skarels pp->p_size /= secperblk; 51730691Skarels } 51830691Skarels #endif 51930380Smckusick mkfs(pp, special, fsi, fso); 52030691Skarels #ifdef tahoe 52130691Skarels if (realsectorsize != DEV_BSIZE) 52230691Skarels pp->p_size *= DEV_BSIZE / realsectorsize; 52330691Skarels #endif 52430380Smckusick if (!Nflag && bcmp(pp, &oldpartition, sizeof(oldpartition))) 52530380Smckusick rewritelabel(special, fso, lp); 52630380Smckusick exit(0); 52730380Smckusick } 52830380Smckusick 52931680Skarels #ifdef COMPAT 53030380Smckusick struct disklabel * 53131680Skarels getdisklabel(s, fd, type) 53231680Skarels char *s, *type; 53331680Skarels int fd; 53431680Skarels { 53531680Skarels static struct disklabel lab; 53631680Skarels struct disklabel *getdiskbyname(); 53731680Skarels 53831680Skarels if (ioctl(fd, DIOCGDINFO, (char *)&lab) < 0) { 53931680Skarels if (type == NULL) { 54031680Skarels perror("ioctl (GDINFO)"); 54131680Skarels fatal( 54231680Skarels "%s: can't read disk label; disk type must be specified", s); 54331680Skarels } 54431680Skarels unlabelled++; 54531680Skarels return (getdiskbyname(type)); 54631680Skarels } 54731680Skarels return (&lab); 54831680Skarels } 54931680Skarels #else 55031680Skarels struct disklabel * 55130380Smckusick getdisklabel(s, fd) 55230380Smckusick char *s; 55331680Skarels int fd; 55430380Smckusick { 55530380Smckusick static struct disklabel lab; 55630380Smckusick 55730380Smckusick if (ioctl(fd, DIOCGDINFO, (char *)&lab) < 0) { 55830380Smckusick perror("ioctl (GDINFO)"); 55930380Smckusick fatal("%s: can't read disk label", s); 56010762Ssam } 56130380Smckusick return (&lab); 56230380Smckusick } 56331680Skarels #endif 56410762Ssam 56530380Smckusick rewritelabel(s, fd, lp) 56630380Smckusick char *s; 56730380Smckusick int fd; 56830380Smckusick register struct disklabel *lp; 56930380Smckusick { 57030380Smckusick 57131680Skarels #ifdef COMPAT 57231680Skarels if (unlabelled) 57331680Skarels return; 57431680Skarels #endif 57530380Smckusick lp->d_checksum = 0; 57630380Smckusick lp->d_checksum = dkcksum(lp); 57730380Smckusick if (ioctl(fd, DIOCWDINFO, (char *)lp) < 0) { 57832786Smckusick perror("ioctl (WDINFO)"); 57930380Smckusick fatal("%s: can't rewrite disk label", s); 58010762Ssam } 58130446Skarels #if vax 58230446Skarels if (lp->d_type == DTYPE_SMD && lp->d_flags & D_BADSECT) { 58330446Skarels register i; 58430691Skarels int cfd; 58530446Skarels daddr_t alt; 58630691Skarels char specname[64]; 58730691Skarels char blk[1024]; 58831045Ssam char *cp; 58930446Skarels 59030691Skarels /* 59130691Skarels * Make name for 'c' partition. 59230691Skarels */ 59330691Skarels strcpy(specname, s); 59430691Skarels cp = specname + strlen(specname) - 1; 59530691Skarels if (!isdigit(*cp)) 59630691Skarels *cp = 'c'; 59730691Skarels cfd = open(specname, O_WRONLY); 59830691Skarels if (cfd < 0) { 59930691Skarels perror(specname); 60030691Skarels exit(2); 60130691Skarels } 60230691Skarels bzero(blk, sizeof(blk)); 60330691Skarels *(struct disklabel *)(blk + LABELOFFSET) = *lp; 60430446Skarels alt = lp->d_ncylinders * lp->d_secpercyl - lp->d_nsectors; 60530446Skarels for (i = 1; i < 11 && i < lp->d_nsectors; i += 2) { 60631680Skarels if (lseek(cfd, (off_t)(alt + i) * lp->d_secsize, L_SET) == -1) { 60731680Skarels perror("lseek to badsector area"); 60831680Skarels exit(30); 60931680Skarels } 61030691Skarels if (write(cfd, blk, lp->d_secsize) < lp->d_secsize) { 61130446Skarels int oerrno = errno; 61230446Skarels fprintf(stderr, "alternate label %d ", i/2); 61330446Skarels errno = oerrno; 61430446Skarels perror("write"); 61530446Skarels } 61630380Smckusick } 61730380Smckusick } 61830446Skarels #endif 61910762Ssam } 62010762Ssam 62110762Ssam /*VARARGS*/ 62210762Ssam fatal(fmt, arg1, arg2) 62310762Ssam char *fmt; 62410762Ssam { 62510762Ssam 62611069Ssam fprintf(stderr, "newfs: "); 62710762Ssam fprintf(stderr, fmt, arg1, arg2); 62810762Ssam putc('\n', stderr); 62910762Ssam exit(10); 63010762Ssam } 631