newfs.c revision 1558
11558Srgrimes/* 21558Srgrimes * Copyright (c) 1983, 1989, 1993, 1994 31558Srgrimes * The Regents of the University of California. All rights reserved. 41558Srgrimes * 51558Srgrimes * Redistribution and use in source and binary forms, with or without 61558Srgrimes * modification, are permitted provided that the following conditions 71558Srgrimes * are met: 81558Srgrimes * 1. Redistributions of source code must retain the above copyright 91558Srgrimes * notice, this list of conditions and the following disclaimer. 101558Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 111558Srgrimes * notice, this list of conditions and the following disclaimer in the 121558Srgrimes * documentation and/or other materials provided with the distribution. 131558Srgrimes * 3. All advertising materials mentioning features or use of this software 141558Srgrimes * must display the following acknowledgement: 151558Srgrimes * This product includes software developed by the University of 161558Srgrimes * California, Berkeley and its contributors. 171558Srgrimes * 4. Neither the name of the University nor the names of its contributors 181558Srgrimes * may be used to endorse or promote products derived from this software 191558Srgrimes * without specific prior written permission. 201558Srgrimes * 211558Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 221558Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 231558Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 241558Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 251558Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 261558Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 271558Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 281558Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 291558Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 301558Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 311558Srgrimes * SUCH DAMAGE. 321558Srgrimes */ 331558Srgrimes 341558Srgrimes#ifndef lint 351558Srgrimesstatic char sccsid[] = "@(#)newfs.c 8.8 (Berkeley) 4/18/94"; 361558Srgrimes#endif /* not lint */ 371558Srgrimes 381558Srgrimes#ifndef lint 391558Srgrimesstatic char copyright[] = 401558Srgrimes"@(#) Copyright (c) 1983, 1989, 1993, 1994\n\ 411558Srgrimes The Regents of the University of California. All rights reserved.\n"; 421558Srgrimes#endif /* not lint */ 431558Srgrimes 441558Srgrimes/* 451558Srgrimes * newfs: friendly front end to mkfs 461558Srgrimes */ 471558Srgrimes#include <sys/param.h> 481558Srgrimes#include <sys/stat.h> 491558Srgrimes#include <sys/ioctl.h> 501558Srgrimes#include <sys/disklabel.h> 511558Srgrimes#include <sys/file.h> 521558Srgrimes#include <sys/mount.h> 531558Srgrimes 541558Srgrimes#include <ufs/ufs/dir.h> 551558Srgrimes#include <ufs/ffs/fs.h> 561558Srgrimes 571558Srgrimes#include <ctype.h> 581558Srgrimes#include <errno.h> 591558Srgrimes#include <paths.h> 601558Srgrimes#include <stdio.h> 611558Srgrimes#include <stdlib.h> 621558Srgrimes#include <string.h> 631558Srgrimes#include <syslog.h> 641558Srgrimes#include <unistd.h> 651558Srgrimes 661558Srgrimes#if __STDC__ 671558Srgrimes#include <stdarg.h> 681558Srgrimes#else 691558Srgrimes#include <varargs.h> 701558Srgrimes#endif 711558Srgrimes 721558Srgrimes#include "mntopts.h" 731558Srgrimes 741558Srgrimesstruct mntopt mopts[] = { 751558Srgrimes MOPT_STDOPTS, 761558Srgrimes MOPT_ASYNC, 771558Srgrimes { NULL }, 781558Srgrimes}; 791558Srgrimes 801558Srgrimes#if __STDC__ 811558Srgrimesvoid fatal(const char *fmt, ...); 821558Srgrimes#else 831558Srgrimesvoid fatal(); 841558Srgrimes#endif 851558Srgrimes 861558Srgrimes#define COMPAT /* allow non-labeled disks */ 871558Srgrimes 881558Srgrimes/* 891558Srgrimes * The following two constants set the default block and fragment sizes. 901558Srgrimes * Both constants must be a power of 2 and meet the following constraints: 911558Srgrimes * MINBSIZE <= DESBLKSIZE <= MAXBSIZE 921558Srgrimes * sectorsize <= DESFRAGSIZE <= DESBLKSIZE 931558Srgrimes * DESBLKSIZE / DESFRAGSIZE <= 8 941558Srgrimes */ 951558Srgrimes#define DFL_FRAGSIZE 1024 961558Srgrimes#define DFL_BLKSIZE 8192 971558Srgrimes 981558Srgrimes/* 991558Srgrimes * Cylinder groups may have up to many cylinders. The actual 1001558Srgrimes * number used depends upon how much information can be stored 1011558Srgrimes * on a single cylinder. The default is to use 16 cylinders 1021558Srgrimes * per group. 1031558Srgrimes */ 1041558Srgrimes#define DESCPG 16 /* desired fs_cpg */ 1051558Srgrimes 1061558Srgrimes/* 1071558Srgrimes * ROTDELAY gives the minimum number of milliseconds to initiate 1081558Srgrimes * another disk transfer on the same cylinder. It is used in 1091558Srgrimes * determining the rotationally optimal layout for disk blocks 1101558Srgrimes * within a file; the default of fs_rotdelay is 4ms. 1111558Srgrimes */ 1121558Srgrimes#define ROTDELAY 4 1131558Srgrimes 1141558Srgrimes/* 1151558Srgrimes * MAXBLKPG determines the maximum number of data blocks which are 1161558Srgrimes * placed in a single cylinder group. The default is one indirect 1171558Srgrimes * block worth of data blocks. 1181558Srgrimes */ 1191558Srgrimes#define MAXBLKPG(bsize) ((bsize) / sizeof(daddr_t)) 1201558Srgrimes 1211558Srgrimes/* 1221558Srgrimes * Each file system has a number of inodes statically allocated. 1231558Srgrimes * We allocate one inode slot per NFPI fragments, expecting this 1241558Srgrimes * to be far more than we will ever need. 1251558Srgrimes */ 1261558Srgrimes#define NFPI 4 1271558Srgrimes 1281558Srgrimes/* 1291558Srgrimes * For each cylinder we keep track of the availability of blocks at different 1301558Srgrimes * rotational positions, so that we can lay out the data to be picked 1311558Srgrimes * up with minimum rotational latency. NRPOS is the default number of 1321558Srgrimes * rotational positions that we distinguish. With NRPOS of 8 the resolution 1331558Srgrimes * of our summary information is 2ms for a typical 3600 rpm drive. 1341558Srgrimes */ 1351558Srgrimes#define NRPOS 8 /* number distinct rotational positions */ 1361558Srgrimes 1371558Srgrimes 1381558Srgrimesint mfs; /* run as the memory based filesystem */ 1391558Srgrimesint Nflag; /* run without writing file system */ 1401558Srgrimesint Oflag; /* format as an 4.3BSD file system */ 1411558Srgrimesint fssize; /* file system size */ 1421558Srgrimesint ntracks; /* # tracks/cylinder */ 1431558Srgrimesint nsectors; /* # sectors/track */ 1441558Srgrimesint nphyssectors; /* # sectors/track including spares */ 1451558Srgrimesint secpercyl; /* sectors per cylinder */ 1461558Srgrimesint trackspares = -1; /* spare sectors per track */ 1471558Srgrimesint cylspares = -1; /* spare sectors per cylinder */ 1481558Srgrimesint sectorsize; /* bytes/sector */ 1491558Srgrimes#ifdef tahoe 1501558Srgrimesint realsectorsize; /* bytes/sector in hardware */ 1511558Srgrimes#endif 1521558Srgrimesint rpm; /* revolutions/minute of drive */ 1531558Srgrimesint interleave; /* hardware sector interleave */ 1541558Srgrimesint trackskew = -1; /* sector 0 skew, per track */ 1551558Srgrimesint headswitch; /* head switch time, usec */ 1561558Srgrimesint trackseek; /* track-to-track seek, usec */ 1571558Srgrimesint fsize = 0; /* fragment size */ 1581558Srgrimesint bsize = 0; /* block size */ 1591558Srgrimesint cpg = DESCPG; /* cylinders/cylinder group */ 1601558Srgrimesint cpgflg; /* cylinders/cylinder group flag was given */ 1611558Srgrimesint minfree = MINFREE; /* free space threshold */ 1621558Srgrimesint opt = DEFAULTOPT; /* optimization preference (space or time) */ 1631558Srgrimesint density; /* number of bytes per inode */ 1641558Srgrimesint maxcontig = 0; /* max contiguous blocks to allocate */ 1651558Srgrimesint rotdelay = ROTDELAY; /* rotational delay between blocks */ 1661558Srgrimesint maxbpg; /* maximum blocks per file in a cyl group */ 1671558Srgrimesint nrpos = NRPOS; /* # of distinguished rotational positions */ 1681558Srgrimesint bbsize = BBSIZE; /* boot block size */ 1691558Srgrimesint sbsize = SBSIZE; /* superblock size */ 1701558Srgrimesint mntflags = MNT_ASYNC; /* flags to be passed to mount */ 1711558Srgrimesu_long memleft; /* virtual memory available */ 1721558Srgrimescaddr_t membase; /* start address of memory based filesystem */ 1731558Srgrimes#ifdef COMPAT 1741558Srgrimeschar *disktype; 1751558Srgrimesint unlabeled; 1761558Srgrimes#endif 1771558Srgrimes 1781558Srgrimeschar device[MAXPATHLEN]; 1791558Srgrimeschar *progname; 1801558Srgrimes 1811558Srgrimesint 1821558Srgrimesmain(argc, argv) 1831558Srgrimes int argc; 1841558Srgrimes char *argv[]; 1851558Srgrimes{ 1861558Srgrimes extern char *optarg; 1871558Srgrimes extern int optind; 1881558Srgrimes register int ch; 1891558Srgrimes register struct partition *pp; 1901558Srgrimes register struct disklabel *lp; 1911558Srgrimes struct disklabel *getdisklabel(); 1921558Srgrimes struct partition oldpartition; 1931558Srgrimes struct stat st; 1941558Srgrimes struct statfs *mp; 1951558Srgrimes int fsi, fso, len, n; 1961558Srgrimes char *cp, *s1, *s2, *special, *opstring, buf[BUFSIZ]; 1971558Srgrimes 1981558Srgrimes if (progname = rindex(*argv, '/')) 1991558Srgrimes ++progname; 2001558Srgrimes else 2011558Srgrimes progname = *argv; 2021558Srgrimes 2031558Srgrimes if (strstr(progname, "mfs")) { 2041558Srgrimes mfs = 1; 2051558Srgrimes Nflag++; 2061558Srgrimes } 2071558Srgrimes 2081558Srgrimes opstring = mfs ? 2091558Srgrimes "NT:a:b:c:d:e:f:i:m:o:s:" : 2101558Srgrimes "NOS:T:a:b:c:d:e:f:i:k:l:m:n:o:p:r:s:t:u:x:"; 2111558Srgrimes while ((ch = getopt(argc, argv, opstring)) != EOF) 2121558Srgrimes switch (ch) { 2131558Srgrimes case 'N': 2141558Srgrimes Nflag = 1; 2151558Srgrimes break; 2161558Srgrimes case 'O': 2171558Srgrimes Oflag = 1; 2181558Srgrimes break; 2191558Srgrimes case 'S': 2201558Srgrimes if ((sectorsize = atoi(optarg)) <= 0) 2211558Srgrimes fatal("%s: bad sector size", optarg); 2221558Srgrimes break; 2231558Srgrimes#ifdef COMPAT 2241558Srgrimes case 'T': 2251558Srgrimes disktype = optarg; 2261558Srgrimes break; 2271558Srgrimes#endif 2281558Srgrimes case 'a': 2291558Srgrimes if ((maxcontig = atoi(optarg)) <= 0) 2301558Srgrimes fatal("%s: bad maximum contiguous blocks\n", 2311558Srgrimes optarg); 2321558Srgrimes break; 2331558Srgrimes case 'b': 2341558Srgrimes if ((bsize = atoi(optarg)) < MINBSIZE) 2351558Srgrimes fatal("%s: bad block size", optarg); 2361558Srgrimes break; 2371558Srgrimes case 'c': 2381558Srgrimes if ((cpg = atoi(optarg)) <= 0) 2391558Srgrimes fatal("%s: bad cylinders/group", optarg); 2401558Srgrimes cpgflg++; 2411558Srgrimes break; 2421558Srgrimes case 'd': 2431558Srgrimes if ((rotdelay = atoi(optarg)) < 0) 2441558Srgrimes fatal("%s: bad rotational delay\n", optarg); 2451558Srgrimes break; 2461558Srgrimes case 'e': 2471558Srgrimes if ((maxbpg = atoi(optarg)) <= 0) 2481558Srgrimes fatal("%s: bad blocks per file in a cylinder group\n", 2491558Srgrimes optarg); 2501558Srgrimes break; 2511558Srgrimes case 'f': 2521558Srgrimes if ((fsize = atoi(optarg)) <= 0) 2531558Srgrimes fatal("%s: bad fragment size", optarg); 2541558Srgrimes break; 2551558Srgrimes case 'i': 2561558Srgrimes if ((density = atoi(optarg)) <= 0) 2571558Srgrimes fatal("%s: bad bytes per inode\n", optarg); 2581558Srgrimes break; 2591558Srgrimes case 'k': 2601558Srgrimes if ((trackskew = atoi(optarg)) < 0) 2611558Srgrimes fatal("%s: bad track skew", optarg); 2621558Srgrimes break; 2631558Srgrimes case 'l': 2641558Srgrimes if ((interleave = atoi(optarg)) <= 0) 2651558Srgrimes fatal("%s: bad interleave", optarg); 2661558Srgrimes break; 2671558Srgrimes case 'm': 2681558Srgrimes if ((minfree = atoi(optarg)) < 0 || minfree > 99) 2691558Srgrimes fatal("%s: bad free space %%\n", optarg); 2701558Srgrimes break; 2711558Srgrimes case 'n': 2721558Srgrimes if ((nrpos = atoi(optarg)) <= 0) 2731558Srgrimes fatal("%s: bad rotational layout count\n", 2741558Srgrimes optarg); 2751558Srgrimes break; 2761558Srgrimes case 'o': 2771558Srgrimes if (mfs) 2781558Srgrimes getmntopts(optarg, mopts, &mntflags); 2791558Srgrimes else { 2801558Srgrimes if (strcmp(optarg, "space") == 0) 2811558Srgrimes opt = FS_OPTSPACE; 2821558Srgrimes else if (strcmp(optarg, "time") == 0) 2831558Srgrimes opt = FS_OPTTIME; 2841558Srgrimes else 2851558Srgrimes fatal("%s: unknown optimization preference: use `space' or `time'."); 2861558Srgrimes } 2871558Srgrimes break; 2881558Srgrimes case 'p': 2891558Srgrimes if ((trackspares = atoi(optarg)) < 0) 2901558Srgrimes fatal("%s: bad spare sectors per track", 2911558Srgrimes optarg); 2921558Srgrimes break; 2931558Srgrimes case 'r': 2941558Srgrimes if ((rpm = atoi(optarg)) <= 0) 2951558Srgrimes fatal("%s: bad revolutions/minute\n", optarg); 2961558Srgrimes break; 2971558Srgrimes case 's': 2981558Srgrimes if ((fssize = atoi(optarg)) <= 0) 2991558Srgrimes fatal("%s: bad file system size", optarg); 3001558Srgrimes break; 3011558Srgrimes case 't': 3021558Srgrimes if ((ntracks = atoi(optarg)) <= 0) 3031558Srgrimes fatal("%s: bad total tracks", optarg); 3041558Srgrimes break; 3051558Srgrimes case 'u': 3061558Srgrimes if ((nsectors = atoi(optarg)) <= 0) 3071558Srgrimes fatal("%s: bad sectors/track", optarg); 3081558Srgrimes break; 3091558Srgrimes case 'x': 3101558Srgrimes if ((cylspares = atoi(optarg)) < 0) 3111558Srgrimes fatal("%s: bad spare sectors per cylinder", 3121558Srgrimes optarg); 3131558Srgrimes break; 3141558Srgrimes case '?': 3151558Srgrimes default: 3161558Srgrimes usage(); 3171558Srgrimes } 3181558Srgrimes argc -= optind; 3191558Srgrimes argv += optind; 3201558Srgrimes 3211558Srgrimes if (argc != 2 && (mfs || argc != 1)) 3221558Srgrimes usage(); 3231558Srgrimes 3241558Srgrimes special = argv[0]; 3251558Srgrimes cp = rindex(special, '/'); 3261558Srgrimes if (cp == 0) { 3271558Srgrimes /* 3281558Srgrimes * No path prefix; try /dev/r%s then /dev/%s. 3291558Srgrimes */ 3301558Srgrimes (void)sprintf(device, "%sr%s", _PATH_DEV, special); 3311558Srgrimes if (stat(device, &st) == -1) 3321558Srgrimes (void)sprintf(device, "%s%s", _PATH_DEV, special); 3331558Srgrimes special = device; 3341558Srgrimes } 3351558Srgrimes if (Nflag) { 3361558Srgrimes fso = -1; 3371558Srgrimes } else { 3381558Srgrimes fso = open(special, O_WRONLY); 3391558Srgrimes if (fso < 0) 3401558Srgrimes fatal("%s: %s", special, strerror(errno)); 3411558Srgrimes 3421558Srgrimes /* Bail if target special is mounted */ 3431558Srgrimes n = getmntinfo(&mp, MNT_NOWAIT); 3441558Srgrimes if (n == 0) 3451558Srgrimes fatal("%s: getmntinfo: %s", special, strerror(errno)); 3461558Srgrimes 3471558Srgrimes len = sizeof(_PATH_DEV) - 1; 3481558Srgrimes s1 = special; 3491558Srgrimes if (strncmp(_PATH_DEV, s1, len) == 0) 3501558Srgrimes s1 += len; 3511558Srgrimes 3521558Srgrimes while (--n >= 0) { 3531558Srgrimes s2 = mp->f_mntfromname; 3541558Srgrimes if (strncmp(_PATH_DEV, s2, len) == 0) { 3551558Srgrimes s2 += len - 1; 3561558Srgrimes *s2 = 'r'; 3571558Srgrimes } 3581558Srgrimes if (strcmp(s1, s2) == 0 || strcmp(s1, &s2[1]) == 0) 3591558Srgrimes fatal("%s is mounted on %s", 3601558Srgrimes special, mp->f_mntonname); 3611558Srgrimes ++mp; 3621558Srgrimes } 3631558Srgrimes } 3641558Srgrimes if (mfs && disktype != NULL) { 3651558Srgrimes lp = (struct disklabel *)getdiskbyname(disktype); 3661558Srgrimes if (lp == NULL) 3671558Srgrimes fatal("%s: unknown disk type", disktype); 3681558Srgrimes pp = &lp->d_partitions[1]; 3691558Srgrimes } else { 3701558Srgrimes fsi = open(special, O_RDONLY); 3711558Srgrimes if (fsi < 0) 3721558Srgrimes fatal("%s: %s", special, strerror(errno)); 3731558Srgrimes if (fstat(fsi, &st) < 0) 3741558Srgrimes fatal("%s: %s", special, strerror(errno)); 3751558Srgrimes if ((st.st_mode & S_IFMT) != S_IFCHR && !mfs) 3761558Srgrimes printf("%s: %s: not a character-special device\n", 3771558Srgrimes progname, special); 3781558Srgrimes cp = index(argv[0], '\0') - 1; 3791558Srgrimes if (cp == 0 || (*cp < 'a' || *cp > 'h') && !isdigit(*cp)) 3801558Srgrimes fatal("%s: can't figure out file system partition", 3811558Srgrimes argv[0]); 3821558Srgrimes#ifdef COMPAT 3831558Srgrimes if (!mfs && disktype == NULL) 3841558Srgrimes disktype = argv[1]; 3851558Srgrimes#endif 3861558Srgrimes lp = getdisklabel(special, fsi); 3871558Srgrimes if (isdigit(*cp)) 3881558Srgrimes pp = &lp->d_partitions[0]; 3891558Srgrimes else 3901558Srgrimes pp = &lp->d_partitions[*cp - 'a']; 3911558Srgrimes if (pp->p_size == 0) 3921558Srgrimes fatal("%s: `%c' partition is unavailable", 3931558Srgrimes argv[0], *cp); 3941558Srgrimes if (pp->p_fstype == FS_BOOT) 3951558Srgrimes fatal("%s: `%c' partition overlaps boot program", 3961558Srgrimes argv[0], *cp); 3971558Srgrimes } 3981558Srgrimes if (fssize == 0) 3991558Srgrimes fssize = pp->p_size; 4001558Srgrimes if (fssize > pp->p_size && !mfs) 4011558Srgrimes fatal("%s: maximum file system size on the `%c' partition is %d", 4021558Srgrimes argv[0], *cp, pp->p_size); 4031558Srgrimes if (rpm == 0) { 4041558Srgrimes rpm = lp->d_rpm; 4051558Srgrimes if (rpm <= 0) 4061558Srgrimes rpm = 3600; 4071558Srgrimes } 4081558Srgrimes if (ntracks == 0) { 4091558Srgrimes ntracks = lp->d_ntracks; 4101558Srgrimes if (ntracks <= 0) 4111558Srgrimes fatal("%s: no default #tracks", argv[0]); 4121558Srgrimes } 4131558Srgrimes if (nsectors == 0) { 4141558Srgrimes nsectors = lp->d_nsectors; 4151558Srgrimes if (nsectors <= 0) 4161558Srgrimes fatal("%s: no default #sectors/track", argv[0]); 4171558Srgrimes } 4181558Srgrimes if (sectorsize == 0) { 4191558Srgrimes sectorsize = lp->d_secsize; 4201558Srgrimes if (sectorsize <= 0) 4211558Srgrimes fatal("%s: no default sector size", argv[0]); 4221558Srgrimes } 4231558Srgrimes if (trackskew == -1) { 4241558Srgrimes trackskew = lp->d_trackskew; 4251558Srgrimes if (trackskew < 0) 4261558Srgrimes trackskew = 0; 4271558Srgrimes } 4281558Srgrimes if (interleave == 0) { 4291558Srgrimes interleave = lp->d_interleave; 4301558Srgrimes if (interleave <= 0) 4311558Srgrimes interleave = 1; 4321558Srgrimes } 4331558Srgrimes if (fsize == 0) { 4341558Srgrimes fsize = pp->p_fsize; 4351558Srgrimes if (fsize <= 0) 4361558Srgrimes fsize = MAX(DFL_FRAGSIZE, lp->d_secsize); 4371558Srgrimes } 4381558Srgrimes if (bsize == 0) { 4391558Srgrimes bsize = pp->p_frag * pp->p_fsize; 4401558Srgrimes if (bsize <= 0) 4411558Srgrimes bsize = MIN(DFL_BLKSIZE, 8 * fsize); 4421558Srgrimes } 4431558Srgrimes /* 4441558Srgrimes * Maxcontig sets the default for the maximum number of blocks 4451558Srgrimes * that may be allocated sequentially. With filesystem clustering 4461558Srgrimes * it is possible to allocate contiguous blocks up to the maximum 4471558Srgrimes * transfer size permitted by the controller or buffering. 4481558Srgrimes */ 4491558Srgrimes if (maxcontig == 0) 4501558Srgrimes maxcontig = MAX(1, MIN(MAXPHYS, MAXBSIZE) / bsize - 1); 4511558Srgrimes if (density == 0) 4521558Srgrimes density = NFPI * fsize; 4531558Srgrimes if (minfree < MINFREE && opt != FS_OPTSPACE) { 4541558Srgrimes fprintf(stderr, "Warning: changing optimization to space "); 4551558Srgrimes fprintf(stderr, "because minfree is less than %d%%\n", MINFREE); 4561558Srgrimes opt = FS_OPTSPACE; 4571558Srgrimes } 4581558Srgrimes if (trackspares == -1) { 4591558Srgrimes trackspares = lp->d_sparespertrack; 4601558Srgrimes if (trackspares < 0) 4611558Srgrimes trackspares = 0; 4621558Srgrimes } 4631558Srgrimes nphyssectors = nsectors + trackspares; 4641558Srgrimes if (cylspares == -1) { 4651558Srgrimes cylspares = lp->d_sparespercyl; 4661558Srgrimes if (cylspares < 0) 4671558Srgrimes cylspares = 0; 4681558Srgrimes } 4691558Srgrimes secpercyl = nsectors * ntracks - cylspares; 4701558Srgrimes if (secpercyl != lp->d_secpercyl) 4711558Srgrimes fprintf(stderr, "%s (%d) %s (%lu)\n", 4721558Srgrimes "Warning: calculated sectors per cylinder", secpercyl, 4731558Srgrimes "disagrees with disk label", lp->d_secpercyl); 4741558Srgrimes if (maxbpg == 0) 4751558Srgrimes maxbpg = MAXBLKPG(bsize); 4761558Srgrimes headswitch = lp->d_headswitch; 4771558Srgrimes trackseek = lp->d_trkseek; 4781558Srgrimes#ifdef notdef /* label may be 0 if faked up by kernel */ 4791558Srgrimes bbsize = lp->d_bbsize; 4801558Srgrimes sbsize = lp->d_sbsize; 4811558Srgrimes#endif 4821558Srgrimes oldpartition = *pp; 4831558Srgrimes#ifdef tahoe 4841558Srgrimes realsectorsize = sectorsize; 4851558Srgrimes if (sectorsize != DEV_BSIZE) { /* XXX */ 4861558Srgrimes int secperblk = DEV_BSIZE / sectorsize; 4871558Srgrimes 4881558Srgrimes sectorsize = DEV_BSIZE; 4891558Srgrimes nsectors /= secperblk; 4901558Srgrimes nphyssectors /= secperblk; 4911558Srgrimes secpercyl /= secperblk; 4921558Srgrimes fssize /= secperblk; 4931558Srgrimes pp->p_size /= secperblk; 4941558Srgrimes } 4951558Srgrimes#endif 4961558Srgrimes mkfs(pp, special, fsi, fso); 4971558Srgrimes#ifdef tahoe 4981558Srgrimes if (realsectorsize != DEV_BSIZE) 4991558Srgrimes pp->p_size *= DEV_BSIZE / realsectorsize; 5001558Srgrimes#endif 5011558Srgrimes if (!Nflag && bcmp(pp, &oldpartition, sizeof(oldpartition))) 5021558Srgrimes rewritelabel(special, fso, lp); 5031558Srgrimes if (!Nflag) 5041558Srgrimes close(fso); 5051558Srgrimes close(fsi); 5061558Srgrimes#ifdef MFS 5071558Srgrimes if (mfs) { 5081558Srgrimes struct mfs_args args; 5091558Srgrimes 5101558Srgrimes sprintf(buf, "mfs:%d", getpid()); 5111558Srgrimes args.fspec = buf; 5121558Srgrimes args.export.ex_root = -2; 5131558Srgrimes if (mntflags & MNT_RDONLY) 5141558Srgrimes args.export.ex_flags = MNT_EXRDONLY; 5151558Srgrimes else 5161558Srgrimes args.export.ex_flags = 0; 5171558Srgrimes args.base = membase; 5181558Srgrimes args.size = fssize * sectorsize; 5191558Srgrimes if (mount(MOUNT_MFS, argv[1], mntflags, &args) < 0) 5201558Srgrimes fatal("%s: %s", argv[1], strerror(errno)); 5211558Srgrimes } 5221558Srgrimes#endif 5231558Srgrimes exit(0); 5241558Srgrimes} 5251558Srgrimes 5261558Srgrimes#ifdef COMPAT 5271558Srgrimeschar lmsg[] = "%s: can't read disk label; disk type must be specified"; 5281558Srgrimes#else 5291558Srgrimeschar lmsg[] = "%s: can't read disk label"; 5301558Srgrimes#endif 5311558Srgrimes 5321558Srgrimesstruct disklabel * 5331558Srgrimesgetdisklabel(s, fd) 5341558Srgrimes char *s; 5351558Srgrimes int fd; 5361558Srgrimes{ 5371558Srgrimes static struct disklabel lab; 5381558Srgrimes 5391558Srgrimes if (ioctl(fd, DIOCGDINFO, (char *)&lab) < 0) { 5401558Srgrimes#ifdef COMPAT 5411558Srgrimes if (disktype) { 5421558Srgrimes struct disklabel *lp, *getdiskbyname(); 5431558Srgrimes 5441558Srgrimes unlabeled++; 5451558Srgrimes lp = getdiskbyname(disktype); 5461558Srgrimes if (lp == NULL) 5471558Srgrimes fatal("%s: unknown disk type", disktype); 5481558Srgrimes return (lp); 5491558Srgrimes } 5501558Srgrimes#endif 5511558Srgrimes warn("ioctl (GDINFO)"); 5521558Srgrimes fatal(lmsg, s); 5531558Srgrimes } 5541558Srgrimes return (&lab); 5551558Srgrimes} 5561558Srgrimes 5571558Srgrimesrewritelabel(s, fd, lp) 5581558Srgrimes char *s; 5591558Srgrimes int fd; 5601558Srgrimes register struct disklabel *lp; 5611558Srgrimes{ 5621558Srgrimes#ifdef COMPAT 5631558Srgrimes if (unlabeled) 5641558Srgrimes return; 5651558Srgrimes#endif 5661558Srgrimes lp->d_checksum = 0; 5671558Srgrimes lp->d_checksum = dkcksum(lp); 5681558Srgrimes if (ioctl(fd, DIOCWDINFO, (char *)lp) < 0) { 5691558Srgrimes warn("ioctl (WDINFO)"); 5701558Srgrimes fatal("%s: can't rewrite disk label", s); 5711558Srgrimes } 5721558Srgrimes#if vax 5731558Srgrimes if (lp->d_type == DTYPE_SMD && lp->d_flags & D_BADSECT) { 5741558Srgrimes register i; 5751558Srgrimes int cfd; 5761558Srgrimes daddr_t alt; 5771558Srgrimes char specname[64]; 5781558Srgrimes char blk[1024]; 5791558Srgrimes char *cp; 5801558Srgrimes 5811558Srgrimes /* 5821558Srgrimes * Make name for 'c' partition. 5831558Srgrimes */ 5841558Srgrimes strcpy(specname, s); 5851558Srgrimes cp = specname + strlen(specname) - 1; 5861558Srgrimes if (!isdigit(*cp)) 5871558Srgrimes *cp = 'c'; 5881558Srgrimes cfd = open(specname, O_WRONLY); 5891558Srgrimes if (cfd < 0) 5901558Srgrimes fatal("%s: %s", specname, strerror(errno)); 5911558Srgrimes bzero(blk, sizeof(blk)); 5921558Srgrimes *(struct disklabel *)(blk + LABELOFFSET) = *lp; 5931558Srgrimes alt = lp->d_ncylinders * lp->d_secpercyl - lp->d_nsectors; 5941558Srgrimes for (i = 1; i < 11 && i < lp->d_nsectors; i += 2) { 5951558Srgrimes if (lseek(cfd, (off_t)(alt + i) * lp->d_secsize, 5961558Srgrimes L_SET) == -1) 5971558Srgrimes fatal("lseek to badsector area: %s", 5981558Srgrimes strerror(errno)); 5991558Srgrimes if (write(cfd, blk, lp->d_secsize) < lp->d_secsize) 6001558Srgrimes warn("alternate label %d write", i/2); 6011558Srgrimes } 6021558Srgrimes close(cfd); 6031558Srgrimes } 6041558Srgrimes#endif 6051558Srgrimes} 6061558Srgrimes 6071558Srgrimes/*VARARGS*/ 6081558Srgrimesvoid 6091558Srgrimes#if __STDC__ 6101558Srgrimesfatal(const char *fmt, ...) 6111558Srgrimes#else 6121558Srgrimesfatal(fmt, va_alist) 6131558Srgrimes char *fmt; 6141558Srgrimes va_dcl 6151558Srgrimes#endif 6161558Srgrimes{ 6171558Srgrimes va_list ap; 6181558Srgrimes 6191558Srgrimes#if __STDC__ 6201558Srgrimes va_start(ap, fmt); 6211558Srgrimes#else 6221558Srgrimes va_start(ap); 6231558Srgrimes#endif 6241558Srgrimes if (fcntl(STDERR_FILENO, F_GETFL) < 0) { 6251558Srgrimes openlog(progname, LOG_CONS, LOG_DAEMON); 6261558Srgrimes vsyslog(LOG_ERR, fmt, ap); 6271558Srgrimes closelog(); 6281558Srgrimes } else { 6291558Srgrimes vwarnx(fmt, ap); 6301558Srgrimes } 6311558Srgrimes va_end(ap); 6321558Srgrimes exit(1); 6331558Srgrimes /*NOTREACHED*/ 6341558Srgrimes} 6351558Srgrimes 6361558Srgrimesusage() 6371558Srgrimes{ 6381558Srgrimes if (mfs) { 6391558Srgrimes fprintf(stderr, 6401558Srgrimes "usage: %s [ -fsoptions ] special-device mount-point\n", 6411558Srgrimes progname); 6421558Srgrimes } else 6431558Srgrimes fprintf(stderr, 6441558Srgrimes "usage: %s [ -fsoptions ] special-device%s\n", 6451558Srgrimes progname, 6461558Srgrimes#ifdef COMPAT 6471558Srgrimes " [device-type]"); 6481558Srgrimes#else 6491558Srgrimes ""); 6501558Srgrimes#endif 6511558Srgrimes fprintf(stderr, "where fsoptions are:\n"); 6521558Srgrimes fprintf(stderr, 6531558Srgrimes "\t-N do not create file system, just print out parameters\n"); 6541558Srgrimes fprintf(stderr, "\t-O create a 4.3BSD format filesystem\n"); 6551558Srgrimes fprintf(stderr, "\t-S sector size\n"); 6561558Srgrimes#ifdef COMPAT 6571558Srgrimes fprintf(stderr, "\t-T disktype\n"); 6581558Srgrimes#endif 6591558Srgrimes fprintf(stderr, "\t-a maximum contiguous blocks\n"); 6601558Srgrimes fprintf(stderr, "\t-b block size\n"); 6611558Srgrimes fprintf(stderr, "\t-c cylinders/group\n"); 6621558Srgrimes fprintf(stderr, "\t-d rotational delay between contiguous blocks\n"); 6631558Srgrimes fprintf(stderr, "\t-e maximum blocks per file in a cylinder group\n"); 6641558Srgrimes fprintf(stderr, "\t-f frag size\n"); 6651558Srgrimes fprintf(stderr, "\t-i number of bytes per inode\n"); 6661558Srgrimes fprintf(stderr, "\t-k sector 0 skew, per track\n"); 6671558Srgrimes fprintf(stderr, "\t-l hardware sector interleave\n"); 6681558Srgrimes fprintf(stderr, "\t-m minimum free space %%\n"); 6691558Srgrimes fprintf(stderr, "\t-n number of distinguished rotational positions\n"); 6701558Srgrimes fprintf(stderr, "\t-o optimization preference (`space' or `time')\n"); 6711558Srgrimes fprintf(stderr, "\t-p spare sectors per track\n"); 6721558Srgrimes fprintf(stderr, "\t-s file system size (sectors)\n"); 6731558Srgrimes fprintf(stderr, "\t-r revolutions/minute\n"); 6741558Srgrimes fprintf(stderr, "\t-t tracks/cylinder\n"); 6751558Srgrimes fprintf(stderr, "\t-u sectors/track\n"); 6761558Srgrimes fprintf(stderr, "\t-x spare sectors per cylinder\n"); 6771558Srgrimes exit(1); 6781558Srgrimes} 679