121159Sdist /* 239049Smckusick * Copyright (c) 1983, 1989 The Regents of the University of California. 339049Smckusick * All rights reserved. 439049Smckusick * 542704Sbostic * %sccs.include.redist.c% 621159Sdist */ 721159Sdist 810762Ssam #ifndef lint 9*43314Smckusick static char sccsid[] = "@(#)newfs.c 6.22 (Berkeley) 06/19/90"; 1039049Smckusick #endif /* not lint */ 1139049Smckusick 1239049Smckusick #ifndef lint 1321159Sdist char copyright[] = 1439049Smckusick "@(#) Copyright (c) 1983, 1989 Regents of the University of California.\n\ 1521159Sdist All rights reserved.\n"; 1639049Smckusick #endif /* not lint */ 1710762Ssam 1810762Ssam /* 1911069Ssam * newfs: friendly front end to mkfs 2010762Ssam */ 2110762Ssam #include <sys/param.h> 2210762Ssam #include <sys/stat.h> 2338380Smckusick #include <ufs/fs.h> 2438380Smckusick #include <ufs/dir.h> 2530380Smckusick #include <sys/ioctl.h> 2630380Smckusick #include <sys/disklabel.h> 2730380Smckusick #include <sys/file.h> 2839049Smckusick #include <sys/mount.h> 2910762Ssam 3010762Ssam #include <stdio.h> 3130380Smckusick #include <ctype.h> 3237951Sbostic #include <paths.h> 3310762Ssam 3431680Skarels #define COMPAT /* allow non-labeled disks */ 3531680Skarels 3630380Smckusick /* 3730380Smckusick * The following two constants set the default block and fragment sizes. 3830380Smckusick * Both constants must be a power of 2 and meet the following constraints: 3930380Smckusick * MINBSIZE <= DESBLKSIZE <= MAXBSIZE 4030380Smckusick * sectorsize <= DESFRAGSIZE <= DESBLKSIZE 4130380Smckusick * DESBLKSIZE / DESFRAGSIZE <= 8 4230380Smckusick */ 4330380Smckusick #define DFL_FRAGSIZE 1024 4430380Smckusick #define DFL_BLKSIZE 8192 4511183Ssam 4630380Smckusick /* 4734137Smckusick * Cylinder groups may have up to many cylinders. The actual 4830380Smckusick * number used depends upon how much information can be stored 4934137Smckusick * on a single cylinder. The default is to use 16 cylinders 5030380Smckusick * per group. 5130380Smckusick */ 5230380Smckusick #define DESCPG 16 /* desired fs_cpg */ 5330380Smckusick 5430380Smckusick /* 5530380Smckusick * MINFREE gives the minimum acceptable percentage of file system 5630380Smckusick * blocks which may be free. If the freelist drops below this level 5730380Smckusick * only the superuser may continue to allocate blocks. This may 5830380Smckusick * be set to 0 if no reserve of free blocks is deemed necessary, 5930380Smckusick * however throughput drops by fifty percent if the file system 6030380Smckusick * is run at between 90% and 100% full; thus the default value of 6130380Smckusick * fs_minfree is 10%. With 10% free space, fragmentation is not a 6230380Smckusick * problem, so we choose to optimize for time. 6330380Smckusick */ 6430380Smckusick #define MINFREE 10 6530380Smckusick #define DEFAULTOPT FS_OPTTIME 6630380Smckusick 6730380Smckusick /* 6830380Smckusick * ROTDELAY gives the minimum number of milliseconds to initiate 6930380Smckusick * another disk transfer on the same cylinder. It is used in 7030380Smckusick * determining the rotationally optimal layout for disk blocks 7130380Smckusick * within a file; the default of fs_rotdelay is 4ms. 7230380Smckusick */ 7330380Smckusick #define ROTDELAY 4 7430380Smckusick 7530380Smckusick /* 7630380Smckusick * MAXCONTIG sets the default for the maximum number of blocks 7730380Smckusick * that may be allocated sequentially. Since UNIX drivers are 7830380Smckusick * not capable of scheduling multi-block transfers, this defaults 7930380Smckusick * to 1 (ie no contiguous blocks are allocated). 8030380Smckusick */ 8130380Smckusick #define MAXCONTIG 1 8230380Smckusick 8330380Smckusick /* 8432309Smckusick * MAXBLKPG determines the maximum number of data blocks which are 8532309Smckusick * placed in a single cylinder group. The default is one indirect 8632309Smckusick * block worth of data blocks. 8732309Smckusick */ 8832309Smckusick #define MAXBLKPG(bsize) ((bsize) / sizeof(daddr_t)) 8932309Smckusick 9032309Smckusick /* 9130380Smckusick * Each file system has a number of inodes statically allocated. 9239049Smckusick * We allocate one inode slot per NFPI fragments, expecting this 9330380Smckusick * to be far more than we will ever need. 9430380Smckusick */ 9539049Smckusick #define NFPI 4 9630380Smckusick 9734137Smckusick /* 9834137Smckusick * For each cylinder we keep track of the availability of blocks at different 9934137Smckusick * rotational positions, so that we can lay out the data to be picked 10034137Smckusick * up with minimum rotational latency. NRPOS is the default number of 10134137Smckusick * rotational positions that we distinguish. With NRPOS of 8 the resolution 10234137Smckusick * of our summary information is 2ms for a typical 3600 rpm drive. 10334137Smckusick */ 10434137Smckusick #define NRPOS 8 /* number distinct rotational positions */ 10534137Smckusick 10634137Smckusick 10739325Smckusick int mfs; /* run as the memory based filesystem */ 10830380Smckusick int Nflag; /* run without writing file system */ 10910762Ssam int fssize; /* file system size */ 11010762Ssam int ntracks; /* # tracks/cylinder */ 11110762Ssam int nsectors; /* # sectors/track */ 11230386Smckusick int nphyssectors; /* # sectors/track including spares */ 11330380Smckusick int secpercyl; /* sectors per cylinder */ 11430386Smckusick int trackspares = -1; /* spare sectors per track */ 11530386Smckusick int cylspares = -1; /* spare sectors per cylinder */ 11610762Ssam int sectorsize; /* bytes/sector */ 11730691Skarels #ifdef tahoe 11830691Skarels int realsectorsize; /* bytes/sector in hardware */ 11930691Skarels #endif 12011069Ssam int rpm; /* revolutions/minute of drive */ 12130386Smckusick int interleave; /* hardware sector interleave */ 12230386Smckusick int trackskew = -1; /* sector 0 skew, per track */ 12330386Smckusick int headswitch; /* head switch time, usec */ 12430386Smckusick int trackseek; /* track-to-track seek, usec */ 12530862Skarels int fsize = 0; /* fragment size */ 12630862Skarels int bsize = 0; /* block size */ 12730380Smckusick int cpg = DESCPG; /* cylinders/cylinder group */ 12832119Smckusick int cpgflg; /* cylinders/cylinder group flag was given */ 12930380Smckusick int minfree = MINFREE; /* free space threshold */ 13030380Smckusick int opt = DEFAULTOPT; /* optimization preference (space or time) */ 13139049Smckusick int density; /* number of bytes per inode */ 13230380Smckusick int maxcontig = MAXCONTIG; /* max contiguous blocks to allocate */ 13330380Smckusick int rotdelay = ROTDELAY; /* rotational delay between blocks */ 13432309Smckusick int maxbpg; /* maximum blocks per file in a cyl group */ 13534137Smckusick int nrpos = NRPOS; /* # of distinguished rotational positions */ 13630691Skarels int bbsize = BBSIZE; /* boot block size */ 13730691Skarels int sbsize = SBSIZE; /* superblock size */ 13839325Smckusick int mntflags; /* flags to be passed to mount */ 13939049Smckusick u_long memleft; /* virtual memory available */ 14039049Smckusick caddr_t membase; /* start address of memory based filesystem */ 14131680Skarels #ifdef COMPAT 142*43314Smckusick char *disktype; 14331680Skarels int unlabelled; 14431680Skarels #endif 14510762Ssam 14610762Ssam char device[MAXPATHLEN]; 14739049Smckusick char *progname; 14810762Ssam 14930380Smckusick extern int errno; 15010762Ssam char *index(); 15110762Ssam char *rindex(); 15210762Ssam 15310762Ssam main(argc, argv) 15414064Smckusick int argc; 15510762Ssam char *argv[]; 15610762Ssam { 15739049Smckusick char *cp, *special, *rindex(); 15810762Ssam register struct partition *pp; 15930380Smckusick register struct disklabel *lp; 16030380Smckusick struct disklabel *getdisklabel(); 16130380Smckusick struct partition oldpartition; 16239049Smckusick struct mfs_args args; 16310762Ssam struct stat st; 16430380Smckusick int fsi, fso; 16510762Ssam register int i; 16610762Ssam int status; 16739049Smckusick char buf[BUFSIZ]; 16810762Ssam 16939049Smckusick if ((progname = rindex(*argv, '/') + 1) == (char *)1) 17039049Smckusick progname = *argv; 17139325Smckusick if (!strcmp(progname, "mfs")) { 17239049Smckusick Nflag++; 17339325Smckusick mfs++; 17439049Smckusick } 17510762Ssam argc--, argv++; 17610762Ssam while (argc > 0 && argv[0][0] == '-') { 17710762Ssam for (cp = &argv[0][1]; *cp; cp++) 17810762Ssam switch (*cp) { 17910762Ssam 18039325Smckusick case 'F': 18139325Smckusick if (!mfs) 18239325Smckusick fatal("-F: unknown flag"); 18339325Smckusick if (argc < 1) 18439325Smckusick fatal("-F: mount flags"); 18539325Smckusick argc--, argv++; 18639325Smckusick mntflags = atoi(*argv); 18739325Smckusick if (mntflags == 0) 18839325Smckusick fatal("%s: bad mount flags", *argv); 18939325Smckusick goto next; 19039325Smckusick 19116945Smckusick case 'N': 19216945Smckusick Nflag++; 19312334Shelge break; 19412334Shelge 19530380Smckusick case 'S': 19610762Ssam if (argc < 1) 19730380Smckusick fatal("-S: missing sector size"); 19810762Ssam argc--, argv++; 19930380Smckusick sectorsize = atoi(*argv); 20030380Smckusick if (sectorsize <= 0) 20130380Smckusick fatal("%s: bad sector size", *argv); 20210762Ssam goto next; 20310762Ssam 204*43314Smckusick #ifdef COMPAT 205*43314Smckusick case 'T': 206*43314Smckusick if (argc < 1) 207*43314Smckusick fatal("-T: missing disk type"); 208*43314Smckusick argc--, argv++; 209*43314Smckusick disktype = *argv; 210*43314Smckusick goto next; 211*43314Smckusick #endif 212*43314Smckusick 21330380Smckusick case 'a': 21410762Ssam if (argc < 1) 21532309Smckusick fatal("-a: missing max contiguous blocks\n"); 21610762Ssam argc--, argv++; 21732309Smckusick maxcontig = atoi(*argv); 21832309Smckusick if (maxcontig <= 0) 21932309Smckusick fatal("%s: bad max contiguous blocks\n", 22032309Smckusick *argv); 22110762Ssam goto next; 22210762Ssam 22310762Ssam case 'b': 22410762Ssam if (argc < 1) 22510762Ssam fatal("-b: missing block size"); 22610762Ssam argc--, argv++; 22710762Ssam bsize = atoi(*argv); 22830380Smckusick if (bsize < MINBSIZE) 22910762Ssam fatal("%s: bad block size", *argv); 23010762Ssam goto next; 23110762Ssam 23230380Smckusick case 'c': 23330380Smckusick if (argc < 1) 23430380Smckusick fatal("-c: missing cylinders/group"); 23530380Smckusick argc--, argv++; 23630380Smckusick cpg = atoi(*argv); 23730380Smckusick if (cpg <= 0) 23830380Smckusick fatal("%s: bad cylinders/group", *argv); 23932119Smckusick cpgflg++; 24030380Smckusick goto next; 24130380Smckusick 24230380Smckusick case 'd': 24330380Smckusick if (argc < 1) 24432309Smckusick fatal("-d: missing rotational delay\n"); 24530380Smckusick argc--, argv++; 24632309Smckusick rotdelay = atoi(*argv); 24732309Smckusick if (rotdelay < 0) 24832309Smckusick fatal("%s: bad rotational delay\n", 24932309Smckusick *argv); 25030380Smckusick goto next; 25130380Smckusick 25232309Smckusick case 'e': 25332309Smckusick if (argc < 1) 25432309Smckusick fatal("-e: missing blocks pre file in a cyl group\n"); 25532309Smckusick argc--, argv++; 25632309Smckusick maxbpg = atoi(*argv); 25732309Smckusick if (maxbpg <= 0) 25832309Smckusick fatal("%s: bad blocks per file in a cyl group\n", 25932309Smckusick *argv); 26032309Smckusick goto next; 26132309Smckusick 26210762Ssam case 'f': 26310762Ssam if (argc < 1) 26410762Ssam fatal("-f: missing frag size"); 26510762Ssam argc--, argv++; 26610762Ssam fsize = atoi(*argv); 26730380Smckusick if (fsize <= 0) 26810762Ssam fatal("%s: bad frag size", *argv); 26910762Ssam goto next; 27010762Ssam 27130380Smckusick case 'i': 27210762Ssam if (argc < 1) 27330380Smckusick fatal("-i: missing bytes per inode\n"); 27410762Ssam argc--, argv++; 27530380Smckusick density = atoi(*argv); 27630380Smckusick if (density <= 0) 27730380Smckusick fatal("%s: bad bytes per inode\n", 27830380Smckusick *argv); 27910762Ssam goto next; 28010762Ssam 28130386Smckusick case 'k': 28230386Smckusick if (argc < 1) 28330386Smckusick fatal("-k: track skew"); 28430386Smckusick argc--, argv++; 28530386Smckusick trackskew = atoi(*argv); 28630386Smckusick if (trackskew < 0) 28730386Smckusick fatal("%s: bad track skew", *argv); 28830386Smckusick goto next; 28930386Smckusick 29030386Smckusick case 'l': 29130386Smckusick if (argc < 1) 29230386Smckusick fatal("-l: interleave"); 29330386Smckusick argc--, argv++; 29430386Smckusick interleave = atoi(*argv); 29530386Smckusick if (interleave <= 0) 29630386Smckusick fatal("%s: bad interleave", *argv); 29730386Smckusick goto next; 29830386Smckusick 29911069Ssam case 'm': 30011069Ssam if (argc < 1) 30111069Ssam fatal("-m: missing free space %%\n"); 30211069Ssam argc--, argv++; 30311069Ssam minfree = atoi(*argv); 30411069Ssam if (minfree < 0 || minfree > 99) 30511069Ssam fatal("%s: bad free space %%\n", 30611069Ssam *argv); 30711069Ssam goto next; 30811069Ssam 30934137Smckusick case 'n': 31034137Smckusick if (argc < 1) 31134137Smckusick fatal("-n: missing rotational layout count\n"); 31234137Smckusick argc--, argv++; 31334137Smckusick nrpos = atoi(*argv); 31434137Smckusick if (nrpos <= 0) 31534137Smckusick fatal("%s: bad rotational layout count\n", 31634137Smckusick *argv); 31734137Smckusick goto next; 31834137Smckusick 31930380Smckusick case 'o': 32030380Smckusick if (argc < 1) 32130380Smckusick fatal("-o: missing optimization preference"); 32230380Smckusick argc--, argv++; 32330380Smckusick if (strcmp(*argv, "space") == 0) 32430380Smckusick opt = FS_OPTSPACE; 32530380Smckusick else if (strcmp(*argv, "time") == 0) 32630380Smckusick opt = FS_OPTTIME; 32730380Smckusick else 32830380Smckusick fatal("%s: bad optimization preference %s", 32930380Smckusick *argv, 33030380Smckusick "(options are `space' or `time')"); 33130380Smckusick goto next; 33230380Smckusick 33330386Smckusick case 'p': 33430386Smckusick if (argc < 1) 33530386Smckusick fatal("-p: spare sectors per track"); 33630386Smckusick argc--, argv++; 33730386Smckusick trackspares = atoi(*argv); 33830386Smckusick if (trackspares < 0) 33930386Smckusick fatal("%s: bad spare sectors per track", *argv); 34030386Smckusick goto next; 34130386Smckusick 34211069Ssam case 'r': 34311069Ssam if (argc < 1) 34411069Ssam fatal("-r: missing revs/minute\n"); 34511069Ssam argc--, argv++; 34611069Ssam rpm = atoi(*argv); 34730380Smckusick if (rpm <= 0) 34811069Ssam fatal("%s: bad revs/minute\n", *argv); 34911069Ssam goto next; 35011069Ssam 35130380Smckusick case 's': 35214884Smckusick if (argc < 1) 35330380Smckusick fatal("-s: missing file system size"); 35414884Smckusick argc--, argv++; 35530380Smckusick fssize = atoi(*argv); 35630380Smckusick if (fssize <= 0) 35730380Smckusick fatal("%s: bad file system size", 35814884Smckusick *argv); 35914884Smckusick goto next; 36014884Smckusick 36130380Smckusick case 't': 36230380Smckusick if (argc < 1) 36330380Smckusick fatal("-t: missing track total"); 36430380Smckusick argc--, argv++; 36530380Smckusick ntracks = atoi(*argv); 36630380Smckusick if (ntracks <= 0) 36730380Smckusick fatal("%s: bad total tracks", *argv); 36830380Smckusick goto next; 36930380Smckusick 37032309Smckusick case 'u': 37132309Smckusick if (argc < 1) 37232309Smckusick fatal("-u: missing sectors/track"); 37332309Smckusick argc--, argv++; 37432309Smckusick nsectors = atoi(*argv); 37532309Smckusick if (nsectors <= 0) 37632309Smckusick fatal("%s: bad sectors/track", *argv); 37732309Smckusick goto next; 37832309Smckusick 37932309Smckusick case 'x': 38032309Smckusick if (argc < 1) 38132309Smckusick fatal("-x: spare sectors per cylinder"); 38232309Smckusick argc--, argv++; 38332309Smckusick cylspares = atoi(*argv); 38432309Smckusick if (cylspares < 0) 38532309Smckusick fatal("%s: bad spare sectors per cylinder", *argv); 38632309Smckusick goto next; 38732309Smckusick 38810762Ssam default: 38932320Sbostic fatal("-%c: unknown flag", *cp); 39010762Ssam } 39110762Ssam next: 39210762Ssam argc--, argv++; 39310762Ssam } 39430380Smckusick if (argc < 1) { 39539325Smckusick if (mfs) 39639049Smckusick fprintf(stderr, 39739325Smckusick "usage: mfs [ fsoptions ] special-device %s\n", 39839049Smckusick "mount-point"); 39939049Smckusick else 40031680Skarels #ifdef COMPAT 40139049Smckusick fprintf(stderr, "usage: %s\n", 40239049Smckusick "newfs [ fsoptions ] special-device [device-type]"); 40331680Skarels #else 40439049Smckusick fprintf(stderr, 40539049Smckusick "usage: newfs [ fsoptions ] special-device\n"); 40631680Skarels #endif 40730380Smckusick fprintf(stderr, "where fsoptions are:\n"); 40816945Smckusick fprintf(stderr, "\t-N do not create file system, %s\n", 40916945Smckusick "just print out parameters"); 410*43314Smckusick #ifdef COMPAT 411*43314Smckusick fprintf(stderr, "\t-T disktype\n"); 412*43314Smckusick #endif 41311057Ssam fprintf(stderr, "\t-b block size\n"); 41411057Ssam fprintf(stderr, "\t-f frag size\n"); 41511069Ssam fprintf(stderr, "\t-m minimum free space %%\n"); 41624702Smckusick fprintf(stderr, "\t-o optimization preference %s\n", 41724702Smckusick "(`space' or `time')"); 41832309Smckusick fprintf(stderr, "\t-a maximum contiguous blocks\n"); 41932309Smckusick fprintf(stderr, "\t-d rotational delay between %s\n", 42032309Smckusick "contiguous blocks"); 42132309Smckusick fprintf(stderr, "\t-e maximum blocks per file in a %s\n", 42232309Smckusick "cylinder group"); 42330398Smckusick fprintf(stderr, "\t-i number of bytes per inode\n"); 42430398Smckusick fprintf(stderr, "\t-c cylinders/group\n"); 42534137Smckusick fprintf(stderr, "\t-n number of distinguished %s\n", 42634137Smckusick "rotational positions"); 42730398Smckusick fprintf(stderr, "\t-s file system size (sectors)\n"); 42811069Ssam fprintf(stderr, "\t-r revolutions/minute\n"); 42911057Ssam fprintf(stderr, "\t-S sector size\n"); 43032309Smckusick fprintf(stderr, "\t-u sectors/track\n"); 43130398Smckusick fprintf(stderr, "\t-t tracks/cylinder\n"); 43230398Smckusick fprintf(stderr, "\t-p spare sectors per track\n"); 43332309Smckusick fprintf(stderr, "\t-x spare sectors per cylinder\n"); 43430386Smckusick fprintf(stderr, "\t-l hardware sector interleave\n"); 43530386Smckusick fprintf(stderr, "\t-k sector 0 skew, per track\n"); 43610762Ssam exit(1); 43710762Ssam } 43810762Ssam special = argv[0]; 43914064Smckusick cp = rindex(special, '/'); 44014064Smckusick if (cp != 0) 44114064Smckusick special = cp + 1; 442*43314Smckusick if (*special == 'r' 443*43314Smckusick #if defined(vax) || defined(tahoe) 444*43314Smckusick && special[1] != 'a' && special[1] != 'b' 445*43314Smckusick #endif 446*43314Smckusick #if defined(hp300) 447*43314Smckusick && special[1] != 'd' 448*43314Smckusick #endif 449*43314Smckusick ) 45014064Smckusick special++; 45137951Sbostic (void)sprintf(device, "%s/r%s", _PATH_DEV, special); 45232463Sbostic special = device; 45330380Smckusick if (!Nflag) { 45430380Smckusick fso = open(special, O_WRONLY); 45530380Smckusick if (fso < 0) { 45630380Smckusick perror(special); 45739049Smckusick exit(2); 45830380Smckusick } 45930380Smckusick } else 46030380Smckusick fso = -1; 46130380Smckusick fsi = open(special, O_RDONLY); 46230380Smckusick if (fsi < 0) { 46330380Smckusick perror(special); 46439049Smckusick exit(3); 46530380Smckusick } 46630380Smckusick if (fstat(fsi, &st) < 0) { 46739049Smckusick fprintf(stderr, "%s: ", progname); perror(special); 46839049Smckusick exit(4); 46910762Ssam } 47014064Smckusick if ((st.st_mode & S_IFMT) != S_IFCHR) 47114064Smckusick fatal("%s: not a character device", special); 47210762Ssam cp = index(argv[0], '\0') - 1; 47330380Smckusick if (cp == 0 || (*cp < 'a' || *cp > 'h') && !isdigit(*cp)) 47410762Ssam fatal("%s: can't figure out file system partition", argv[0]); 47531680Skarels #ifdef COMPAT 476*43314Smckusick if (!mfs && disktype == NULL) 477*43314Smckusick disktype = argv[1]; 478*43314Smckusick #endif 47930380Smckusick lp = getdisklabel(special, fsi); 48030380Smckusick if (isdigit(*cp)) 48130380Smckusick pp = &lp->d_partitions[0]; 48230380Smckusick else 48330380Smckusick pp = &lp->d_partitions[*cp - 'a']; 48430380Smckusick if (pp->p_size == 0) 48530380Smckusick fatal("%s: `%c' partition is unavailable", argv[0], *cp); 48630380Smckusick if (fssize == 0) 48710762Ssam fssize = pp->p_size; 48839325Smckusick if (fssize > pp->p_size && !mfs) 48930380Smckusick fatal("%s: maximum file system size on the `%c' partition is %d", 49030380Smckusick argv[0], *cp, pp->p_size); 49130380Smckusick if (rpm == 0) { 49230380Smckusick rpm = lp->d_rpm; 49330380Smckusick if (rpm <= 0) 49430743Skarels rpm = 3600; 49510762Ssam } 49630380Smckusick if (ntracks == 0) { 49730380Smckusick ntracks = lp->d_ntracks; 49830380Smckusick if (ntracks <= 0) 49930743Skarels fatal("%s: no default #tracks", argv[0]); 50030380Smckusick } 50110762Ssam if (nsectors == 0) { 50230380Smckusick nsectors = lp->d_nsectors; 50330380Smckusick if (nsectors <= 0) 50430743Skarels fatal("%s: no default #sectors/track", argv[0]); 50510762Ssam } 50610762Ssam if (sectorsize == 0) { 50730380Smckusick sectorsize = lp->d_secsize; 50830380Smckusick if (sectorsize <= 0) 50930743Skarels fatal("%s: no default sector size", argv[0]); 51010762Ssam } 51130386Smckusick if (trackskew == -1) { 51230386Smckusick trackskew = lp->d_trackskew; 51330386Smckusick if (trackskew < 0) 51430743Skarels trackskew = 0; 51530386Smckusick } 51630386Smckusick if (interleave == 0) { 51730386Smckusick interleave = lp->d_interleave; 51830386Smckusick if (interleave <= 0) 51930743Skarels interleave = 1; 52030386Smckusick } 52110762Ssam if (fsize == 0) { 52210762Ssam fsize = pp->p_fsize; 52330380Smckusick if (fsize <= 0) 52430380Smckusick fsize = MAX(DFL_FRAGSIZE, lp->d_secsize); 52510762Ssam } 52630380Smckusick if (bsize == 0) { 52730380Smckusick bsize = pp->p_frag * pp->p_fsize; 52830380Smckusick if (bsize <= 0) 52930380Smckusick bsize = MIN(DFL_BLKSIZE, 8 * fsize); 53011069Ssam } 53139049Smckusick if (density == 0) 53239049Smckusick density = NFPI * fsize; 53324702Smckusick if (minfree < 10 && opt != FS_OPTSPACE) { 53430380Smckusick fprintf(stderr, "Warning: changing optimization to space "); 53530380Smckusick fprintf(stderr, "because minfree is less than 10%%\n"); 53624702Smckusick opt = FS_OPTSPACE; 53724702Smckusick } 53830386Smckusick if (trackspares == -1) { 53930386Smckusick trackspares = lp->d_sparespertrack; 54030386Smckusick if (trackspares < 0) 54130743Skarels trackspares = 0; 54230386Smckusick } 54330386Smckusick nphyssectors = nsectors + trackspares; 54430386Smckusick if (cylspares == -1) { 54530386Smckusick cylspares = lp->d_sparespercyl; 54630386Smckusick if (cylspares < 0) 54730743Skarels cylspares = 0; 54830386Smckusick } 54930386Smckusick secpercyl = nsectors * ntracks - cylspares; 55030380Smckusick if (secpercyl != lp->d_secpercyl) 55130380Smckusick fprintf(stderr, "%s (%d) %s (%d)\n", 55230380Smckusick "Warning: calculated sectors per cylinder", secpercyl, 55330380Smckusick "disagrees with disk label", lp->d_secpercyl); 55432321Smckusick if (maxbpg == 0) 55532321Smckusick maxbpg = MAXBLKPG(bsize); 55630386Smckusick headswitch = lp->d_headswitch; 55730386Smckusick trackseek = lp->d_trkseek; 55830691Skarels bbsize = lp->d_bbsize; 55930691Skarels sbsize = lp->d_sbsize; 56030380Smckusick oldpartition = *pp; 56130691Skarels #ifdef tahoe 56230691Skarels realsectorsize = sectorsize; 56330862Skarels if (sectorsize != DEV_BSIZE) { /* XXX */ 56430691Skarels int secperblk = DEV_BSIZE / sectorsize; 56530691Skarels 56630691Skarels sectorsize = DEV_BSIZE; 56730691Skarels nsectors /= secperblk; 56830691Skarels nphyssectors /= secperblk; 56930691Skarels secpercyl /= secperblk; 57030691Skarels fssize /= secperblk; 57130691Skarels pp->p_size /= secperblk; 57230691Skarels } 57330691Skarels #endif 57430380Smckusick mkfs(pp, special, fsi, fso); 57530691Skarels #ifdef tahoe 57630691Skarels if (realsectorsize != DEV_BSIZE) 57730691Skarels pp->p_size *= DEV_BSIZE / realsectorsize; 57830691Skarels #endif 57930380Smckusick if (!Nflag && bcmp(pp, &oldpartition, sizeof(oldpartition))) 58030380Smckusick rewritelabel(special, fso, lp); 58139049Smckusick if (!Nflag) 58239049Smckusick close(fso); 58339049Smckusick close(fsi); 58439325Smckusick if (mfs) { 58539325Smckusick sprintf(buf, "mfs:%d", getpid()); 58639049Smckusick args.name = buf; 58739049Smckusick args.base = membase; 58839049Smckusick args.size = fssize * sectorsize; 58939325Smckusick if (mount(MOUNT_MFS, argv[1], mntflags, &args) < 0) { 59039325Smckusick perror("mfs: mount"); 59139049Smckusick exit(5); 59239049Smckusick } 59339049Smckusick } 59430380Smckusick exit(0); 59530380Smckusick } 59630380Smckusick 59731680Skarels #ifdef COMPAT 598*43314Smckusick char lmsg[] = "%s: can't read disk label; disk type must be specified"; 599*43314Smckusick #else 600*43314Smckusick char lmsg[] = "%s: can't read disk label"; 601*43314Smckusick #endif 60231680Skarels 60331680Skarels struct disklabel * 60430380Smckusick getdisklabel(s, fd) 60530380Smckusick char *s; 60631680Skarels int fd; 60730380Smckusick { 60830380Smckusick static struct disklabel lab; 60930380Smckusick 61030380Smckusick if (ioctl(fd, DIOCGDINFO, (char *)&lab) < 0) { 611*43314Smckusick #ifdef COMPAT 612*43314Smckusick if (disktype) { 613*43314Smckusick struct disklabel *getdiskbyname(); 614*43314Smckusick 615*43314Smckusick unlabelled++; 616*43314Smckusick return (getdiskbyname(disktype)); 617*43314Smckusick } 618*43314Smckusick #endif 61930380Smckusick perror("ioctl (GDINFO)"); 620*43314Smckusick fatal(lmsg, s); 62110762Ssam } 62230380Smckusick return (&lab); 62330380Smckusick } 62410762Ssam 62530380Smckusick rewritelabel(s, fd, lp) 62630380Smckusick char *s; 62730380Smckusick int fd; 62830380Smckusick register struct disklabel *lp; 62930380Smckusick { 63030380Smckusick 63131680Skarels #ifdef COMPAT 63231680Skarels if (unlabelled) 63331680Skarels return; 63431680Skarels #endif 63530380Smckusick lp->d_checksum = 0; 63630380Smckusick lp->d_checksum = dkcksum(lp); 63730380Smckusick if (ioctl(fd, DIOCWDINFO, (char *)lp) < 0) { 63832786Smckusick perror("ioctl (WDINFO)"); 63930380Smckusick fatal("%s: can't rewrite disk label", s); 64010762Ssam } 64130446Skarels #if vax 64230446Skarels if (lp->d_type == DTYPE_SMD && lp->d_flags & D_BADSECT) { 64330446Skarels register i; 64430691Skarels int cfd; 64530446Skarels daddr_t alt; 64630691Skarels char specname[64]; 64730691Skarels char blk[1024]; 64831045Ssam char *cp; 64930446Skarels 65030691Skarels /* 65130691Skarels * Make name for 'c' partition. 65230691Skarels */ 65330691Skarels strcpy(specname, s); 65430691Skarels cp = specname + strlen(specname) - 1; 65530691Skarels if (!isdigit(*cp)) 65630691Skarels *cp = 'c'; 65730691Skarels cfd = open(specname, O_WRONLY); 65830691Skarels if (cfd < 0) { 65930691Skarels perror(specname); 66039049Smckusick exit(6); 66130691Skarels } 66230691Skarels bzero(blk, sizeof(blk)); 66330691Skarels *(struct disklabel *)(blk + LABELOFFSET) = *lp; 66430446Skarels alt = lp->d_ncylinders * lp->d_secpercyl - lp->d_nsectors; 66530446Skarels for (i = 1; i < 11 && i < lp->d_nsectors; i += 2) { 66631680Skarels if (lseek(cfd, (off_t)(alt + i) * lp->d_secsize, L_SET) == -1) { 66731680Skarels perror("lseek to badsector area"); 66839049Smckusick exit(7); 66931680Skarels } 67030691Skarels if (write(cfd, blk, lp->d_secsize) < lp->d_secsize) { 67130446Skarels int oerrno = errno; 67230446Skarels fprintf(stderr, "alternate label %d ", i/2); 67330446Skarels errno = oerrno; 67430446Skarels perror("write"); 67530446Skarels } 67630380Smckusick } 67739049Smckusick close(cfd); 67830380Smckusick } 67930446Skarels #endif 68010762Ssam } 68110762Ssam 68210762Ssam /*VARARGS*/ 68310762Ssam fatal(fmt, arg1, arg2) 68410762Ssam char *fmt; 68510762Ssam { 68610762Ssam 68739049Smckusick fprintf(stderr, "%s: ", progname); 68810762Ssam fprintf(stderr, fmt, arg1, arg2); 68910762Ssam putc('\n', stderr); 69039049Smckusick exit(8); 69110762Ssam } 692