151151Sbostic /* 251151Sbostic * Copyright (c) 1983, 1989 The Regents of the University of California. 351151Sbostic * All rights reserved. 451151Sbostic * 551151Sbostic * Redistribution and use in source and binary forms, with or without 651151Sbostic * modification, are permitted provided that the following conditions 751151Sbostic * are met: 851151Sbostic * 1. Redistributions of source code must retain the above copyright 951151Sbostic * notice, this list of conditions and the following disclaimer. 1051151Sbostic * 2. Redistributions in binary form must reproduce the above copyright 1151151Sbostic * notice, this list of conditions and the following disclaimer in the 1251151Sbostic * documentation and/or other materials provided with the distribution. 1351151Sbostic * 3. All advertising materials mentioning features or use of this software 1451151Sbostic * must display the following acknowledgement: 1551151Sbostic * This product includes software developed by the University of 1651151Sbostic * California, Berkeley and its contributors. 1751151Sbostic * 4. Neither the name of the University nor the names of its contributors 1851151Sbostic * may be used to endorse or promote products derived from this software 1951151Sbostic * without specific prior written permission. 2051151Sbostic * 2151151Sbostic * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2251151Sbostic * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2351151Sbostic * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2451151Sbostic * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2551151Sbostic * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2651151Sbostic * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2751151Sbostic * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2851151Sbostic * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2951151Sbostic * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3051151Sbostic * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3151151Sbostic * SUCH DAMAGE. 3251151Sbostic */ 3351151Sbostic 3451151Sbostic #ifndef lint 3551151Sbostic static char sccsid[] = "@(#)newfs.c 6.28 (Berkeley) 8/6/91"; 3651151Sbostic #endif /* not lint */ 3751151Sbostic 3851151Sbostic #ifndef lint 3951151Sbostic char copyright[] = 4051151Sbostic "@(#) Copyright (c) 1983, 1989 Regents of the University of California.\n\ 4151151Sbostic All rights reserved.\n"; 4251151Sbostic #endif /* not lint */ 4351151Sbostic 4451151Sbostic /* 4551151Sbostic * newfs: friendly front end to mkfs 4651151Sbostic */ 4751151Sbostic #include <sys/param.h> 4851151Sbostic #include <sys/stat.h> 4951151Sbostic #include <ufs/fs.h> 5051151Sbostic #include <ufs/dir.h> 5151151Sbostic #include <ufs/dinode.h> 5251151Sbostic #include <sys/ioctl.h> 5351151Sbostic #include <sys/disklabel.h> 5451151Sbostic #include <sys/file.h> 5551151Sbostic #include <sys/mount.h> 5651151Sbostic 5751151Sbostic #include <errno.h> 5851151Sbostic #include <unistd.h> 5951151Sbostic #include <stdio.h> 6051151Sbostic #include <stdlib.h> 6151151Sbostic #include <ctype.h> 6251151Sbostic #include <string.h> 6351151Sbostic #include <paths.h> 6451151Sbostic #include "config.h" 6551151Sbostic #include "extern.h" 6651151Sbostic 6751151Sbostic #define COMPAT /* allow non-labeled disks */ 6851151Sbostic 6951151Sbostic int mfs; /* run as the memory based filesystem */ 7051151Sbostic int Nflag; /* run without writing file system */ 7151151Sbostic int fssize; /* file system size */ 7251151Sbostic int ntracks; /* # tracks/cylinder */ 7351151Sbostic int nsectors; /* # sectors/track */ 7451151Sbostic int nphyssectors; /* # sectors/track including spares */ 7551151Sbostic int secpercyl; /* sectors per cylinder */ 7651151Sbostic int trackspares = -1; /* spare sectors per track */ 7751151Sbostic int cylspares = -1; /* spare sectors per cylinder */ 7851151Sbostic int sectorsize; /* bytes/sector */ 7951151Sbostic #ifdef tahoe 8051151Sbostic int realsectorsize; /* bytes/sector in hardware */ 8151151Sbostic #endif 8251151Sbostic int rpm; /* revolutions/minute of drive */ 8351151Sbostic int interleave; /* hardware sector interleave */ 8451151Sbostic int trackskew = -1; /* sector 0 skew, per track */ 8551151Sbostic int headswitch; /* head switch time, usec */ 8651151Sbostic int trackseek; /* track-to-track seek, usec */ 8751151Sbostic int fsize = 0; /* fragment size */ 8851151Sbostic int bsize = 0; /* block size */ 8951151Sbostic int cpg = DESCPG; /* cylinders/cylinder group */ 9051151Sbostic int cpgflg; /* cylinders/cylinder group flag was given */ 9151151Sbostic int minfree = MINFREE; /* free space threshold */ 9251151Sbostic int opt = DEFAULTOPT; /* optimization preference (space or time) */ 9351151Sbostic int density; /* number of bytes per inode */ 9451151Sbostic int maxcontig = MAXCONTIG; /* max contiguous blocks to allocate */ 9551151Sbostic int rotdelay = ROTDELAY; /* rotational delay between blocks */ 9651151Sbostic int maxbpg; /* maximum blocks per file in a cyl group */ 9751151Sbostic int nrpos = NRPOS; /* # of distinguished rotational positions */ 9851151Sbostic int bbsize = BBSIZE; /* boot block size */ 9951151Sbostic int sbsize = SBSIZE; /* superblock size */ 10051151Sbostic int mntflags; /* flags to be passed to mount */ 10151151Sbostic u_long memleft; /* virtual memory available */ 10251151Sbostic caddr_t membase; /* start address of memory based filesystem */ 10351151Sbostic #ifdef COMPAT 10451151Sbostic char *disktype; 10551151Sbostic int unlabeled; 10651151Sbostic #endif 10751151Sbostic 10851151Sbostic char device[MAXPATHLEN]; 10951151Sbostic char *progname, *special; 11051151Sbostic 11151151Sbostic static struct disklabel *getdisklabel __P((char *, int)); 11251151Sbostic static struct disklabel *debug_readlabel __P((int)); 11351151Sbostic static void rewritelabel __P((char *, int, struct disklabel *)); 11451151Sbostic static void usage __P((void)); 11551151Sbostic 11651151Sbostic int 11751151Sbostic main(argc, argv) 11851151Sbostic int argc; 11951151Sbostic char *argv[]; 12051151Sbostic { 12151151Sbostic register int ch; 12251151Sbostic register struct partition *pp; 12351151Sbostic register struct disklabel *lp; 12451151Sbostic struct partition oldpartition; 12551151Sbostic struct stat st; 12651151Sbostic int debug, lfs, fsi, fso, segsize; 12751151Sbostic char *cp, *opstring; 12851151Sbostic 12951151Sbostic if (progname = rindex(*argv, '/')) 13051151Sbostic ++progname; 13151151Sbostic else 13251151Sbostic progname = *argv; 13351151Sbostic 13451151Sbostic if (strstr(progname, "mfs")) { 13551151Sbostic mfs = 1; 13651151Sbostic Nflag++; 13751151Sbostic } 13851151Sbostic 13951151Sbostic /* -F is mfs only and MUST come first! */ 14051151Sbostic opstring = "F:B:DLNS:T:a:b:c:d:e:f:i:k:l:m:n:o:p:r:s:t:u:x:"; 14151151Sbostic if (!mfs) 14251151Sbostic opstring += 2; 14351151Sbostic 14451151Sbostic debug = lfs = segsize = 0; 14551151Sbostic while ((ch = getopt(argc, argv, opstring)) != EOF) 14651151Sbostic switch(ch) { 14751151Sbostic case 'B': /* LFS segment size */ 14851151Sbostic if ((segsize = atoi(optarg)) < LFS_MINSEGSIZE) 14951151Sbostic fatal("%s: bad segment size", optarg); 15051151Sbostic break; 15151151Sbostic case 'D': 15251151Sbostic debug = 1; 15351151Sbostic break; 15451151Sbostic case 'F': 15551151Sbostic if ((mntflags = atoi(optarg)) == 0) 15651151Sbostic fatal("%s: bad mount flags", optarg); 15751151Sbostic break; 15851151Sbostic case 'L': /* Create lfs */ 15951151Sbostic lfs = 1; 16051151Sbostic break; 16151151Sbostic case 'N': 16251151Sbostic Nflag++; 16351151Sbostic break; 16451151Sbostic case 'S': 16551151Sbostic if ((sectorsize = atoi(optarg)) <= 0) 16651151Sbostic fatal("%s: bad sector size", optarg); 16751151Sbostic break; 16851151Sbostic #ifdef COMPAT 16951151Sbostic case 'T': 17051151Sbostic disktype = optarg; 17151151Sbostic break; 17251151Sbostic #endif 17351151Sbostic case 'a': 17451151Sbostic if ((maxcontig = atoi(optarg)) <= 0) 17551151Sbostic fatal("%s: bad max contiguous blocks\n", 17651151Sbostic optarg); 17751151Sbostic break; 17851151Sbostic case 'b': /* used for LFS */ 17951151Sbostic if ((bsize = atoi(optarg)) < MINBSIZE) 18051151Sbostic fatal("%s: bad block size", optarg); 18151151Sbostic break; 18251151Sbostic case 'c': 18351151Sbostic if ((cpg = atoi(optarg)) <= 0) 18451151Sbostic fatal("%s: bad cylinders/group", optarg); 18551151Sbostic cpgflg++; 18651151Sbostic break; 18751151Sbostic case 'd': 18851151Sbostic if ((rotdelay = atoi(optarg)) < 0) 18951151Sbostic fatal("%s: bad rotational delay\n", optarg); 19051151Sbostic break; 19151151Sbostic case 'e': 19251151Sbostic if ((maxbpg = atoi(optarg)) <= 0) 19351151Sbostic fatal("%s: bad blocks per file in a cyl group\n", 19451151Sbostic optarg); 19551151Sbostic break; 19651151Sbostic case 'f': 19751151Sbostic if ((fsize = atoi(optarg)) <= 0) 19851151Sbostic fatal("%s: bad frag size", optarg); 19951151Sbostic break; 20051151Sbostic case 'i': 20151151Sbostic if ((density = atoi(optarg)) <= 0) 20251151Sbostic fatal("%s: bad bytes per inode\n", optarg); 20351151Sbostic break; 20451151Sbostic case 'k': 20551151Sbostic if ((trackskew = atoi(optarg)) < 0) 20651151Sbostic fatal("%s: bad track skew", optarg); 20751151Sbostic break; 20851151Sbostic case 'l': 20951151Sbostic if ((interleave = atoi(optarg)) <= 0) 21051151Sbostic fatal("%s: bad interleave", optarg); 21151151Sbostic break; 21251151Sbostic case 'm': /* used for LFS */ 21351151Sbostic if ((minfree = atoi(optarg)) < 0 || minfree > 99) 21451151Sbostic fatal("%s: bad free space %%\n", optarg); 21551151Sbostic break; 21651151Sbostic case 'n': 21751151Sbostic if ((nrpos = atoi(optarg)) <= 0) 21851151Sbostic fatal("%s: bad rotational layout count\n", 21951151Sbostic optarg); 22051151Sbostic break; 22151151Sbostic case 'o': 22251151Sbostic if (strcmp(optarg, "space") == 0) 22351151Sbostic opt = FS_OPTSPACE; 22451151Sbostic else if (strcmp(optarg, "time") == 0) 22551151Sbostic opt = FS_OPTTIME; 22651151Sbostic else 22751151Sbostic fatal("%s: bad optimization preference %s", 22851151Sbostic optarg, "(options are `space' or `time')"); 22951151Sbostic break; 23051151Sbostic case 'p': 23151151Sbostic if ((trackspares = atoi(optarg)) < 0) 23251151Sbostic fatal("%s: bad spare sectors per track", 23351151Sbostic optarg); 23451151Sbostic break; 23551151Sbostic case 'r': 23651151Sbostic if ((rpm = atoi(optarg)) <= 0) 23751151Sbostic fatal("%s: bad revs/minute\n", optarg); 23851151Sbostic break; 23951151Sbostic case 's': /* used for LFS */ 24051151Sbostic if ((fssize = atoi(optarg)) <= 0) 24151151Sbostic fatal("%s: bad file system size", optarg); 24251151Sbostic break; 24351151Sbostic case 't': 24451151Sbostic if ((ntracks = atoi(optarg)) <= 0) 24551151Sbostic fatal("%s: bad total tracks", optarg); 24651151Sbostic break; 24751151Sbostic case 'u': 24851151Sbostic if ((nsectors = atoi(optarg)) <= 0) 24951151Sbostic fatal("%s: bad sectors/track", optarg); 25051151Sbostic break; 25151151Sbostic case 'x': 25251151Sbostic if ((cylspares = atoi(optarg)) < 0) 25351151Sbostic fatal("%s: bad spare sectors per cylinder", 25451151Sbostic optarg); 25551151Sbostic break; 25651151Sbostic case '?': 25751151Sbostic default: 25851151Sbostic usage(); 25951151Sbostic } 26051151Sbostic argc -= optind; 26151151Sbostic argv += optind; 26251151Sbostic 26351151Sbostic if (argc != 2 && (mfs || argc != 1)) 26451151Sbostic usage(); 26551151Sbostic 26651151Sbostic /* 26751151Sbostic * If the -N flag isn't specified, open the output file. If no path 26851151Sbostic * prefix, try /dev/r%s and then /dev/%s. 26951151Sbostic */ 27051151Sbostic special = argv[0]; 27151151Sbostic if (index(special, '/') == NULL) { 27251151Sbostic (void)sprintf(device, "%sr%s", _PATH_DEV, special); 27351151Sbostic if (stat(device, &st) == -1) 27451151Sbostic (void)sprintf(device, "%s%s", _PATH_DEV, special); 27551151Sbostic special = device; 27651151Sbostic } 27751151Sbostic if (!Nflag) { 27851151Sbostic fso = open(special, 27951151Sbostic (debug ? O_CREAT : 0) | O_WRONLY, DEFFILEMODE); 28051151Sbostic if (fso < 0) 28151151Sbostic fatal("%s: %s", special, strerror(errno)); 28251151Sbostic } else 28351151Sbostic fso = -1; 28451151Sbostic 28551151Sbostic /* Open the input file. */ 28651151Sbostic fsi = open(special, O_RDONLY); 28751151Sbostic if (fsi < 0) 28851151Sbostic fatal("%s: %s", special, strerror(errno)); 28951151Sbostic if (fstat(fsi, &st) < 0) 29051151Sbostic fatal("%s: %s", special, strerror(errno)); 29151151Sbostic 292*51865Sbostic if (!debug && !mfs && !S_ISCHR(st.st_mode)) 29351151Sbostic (void)printf("%s: %s: not a character-special device\n", 29451151Sbostic progname, special); 29551151Sbostic cp = index(argv[0], '\0') - 1; 29651151Sbostic if (!debug && (cp == 0 || (*cp < 'a' || *cp > 'h') && !isdigit(*cp))) 29751151Sbostic fatal("%s: can't figure out file system partition", argv[0]); 29851151Sbostic 29951151Sbostic #ifdef COMPAT 30051151Sbostic if (!mfs && disktype == NULL) 30151151Sbostic disktype = argv[1]; 30251151Sbostic #endif 30351151Sbostic if (debug) 30451151Sbostic lp = debug_readlabel(fsi); 30551151Sbostic else 30651151Sbostic lp = getdisklabel(special, fsi); 30751151Sbostic 30851151Sbostic if (isdigit(*cp)) 30951151Sbostic pp = &lp->d_partitions[0]; 31051151Sbostic else 31151151Sbostic pp = &lp->d_partitions[*cp - 'a']; 31251151Sbostic if (pp->p_size == 0) 31351151Sbostic fatal("%s: `%c' partition is unavailable", argv[0], *cp); 31451151Sbostic 31551151Sbostic /* If we're making a LFS, we break out here */ 31651151Sbostic if (lfs) 31751151Sbostic exit(make_lfs(fso, lp, pp, minfree, bsize, segsize)); 31851151Sbostic 31951151Sbostic if (fssize == 0) 32051151Sbostic fssize = pp->p_size; 32151151Sbostic if (fssize > pp->p_size && !mfs) 32251151Sbostic fatal("%s: maximum file system size on the `%c' partition is %d", 32351151Sbostic argv[0], *cp, pp->p_size); 32451151Sbostic if (rpm == 0) { 32551151Sbostic rpm = lp->d_rpm; 32651151Sbostic if (rpm <= 0) 32751151Sbostic rpm = 3600; 32851151Sbostic } 32951151Sbostic if (ntracks == 0) { 33051151Sbostic ntracks = lp->d_ntracks; 33151151Sbostic if (ntracks <= 0) 33251151Sbostic fatal("%s: no default #tracks", argv[0]); 33351151Sbostic } 33451151Sbostic if (nsectors == 0) { 33551151Sbostic nsectors = lp->d_nsectors; 33651151Sbostic if (nsectors <= 0) 33751151Sbostic fatal("%s: no default #sectors/track", argv[0]); 33851151Sbostic } 33951151Sbostic if (sectorsize == 0) { 34051151Sbostic sectorsize = lp->d_secsize; 34151151Sbostic if (sectorsize <= 0) 34251151Sbostic fatal("%s: no default sector size", argv[0]); 34351151Sbostic } 34451151Sbostic if (trackskew == -1) { 34551151Sbostic trackskew = lp->d_trackskew; 34651151Sbostic if (trackskew < 0) 34751151Sbostic trackskew = 0; 34851151Sbostic } 34951151Sbostic if (interleave == 0) { 35051151Sbostic interleave = lp->d_interleave; 35151151Sbostic if (interleave <= 0) 35251151Sbostic interleave = 1; 35351151Sbostic } 35451151Sbostic if (fsize == 0) { 35551151Sbostic fsize = pp->p_fsize; 35651151Sbostic if (fsize <= 0) 35751151Sbostic fsize = MAX(DFL_FRAGSIZE, lp->d_secsize); 35851151Sbostic } 35951151Sbostic if (bsize == 0) { 36051151Sbostic bsize = pp->p_frag * pp->p_fsize; 36151151Sbostic if (bsize <= 0) 36251151Sbostic bsize = MIN(DFL_BLKSIZE, 8 * fsize); 36351151Sbostic } 36451151Sbostic if (density == 0) 36551151Sbostic density = NFPI * fsize; 36651151Sbostic if (minfree < 10 && opt != FS_OPTSPACE) { 36751151Sbostic fprintf(stderr, "Warning: changing optimization to space "); 36851151Sbostic fprintf(stderr, "because minfree is less than 10%%\n"); 36951151Sbostic opt = FS_OPTSPACE; 37051151Sbostic } 37151151Sbostic if (trackspares == -1) { 37251151Sbostic trackspares = lp->d_sparespertrack; 37351151Sbostic if (trackspares < 0) 37451151Sbostic trackspares = 0; 37551151Sbostic } 37651151Sbostic nphyssectors = nsectors + trackspares; 37751151Sbostic if (cylspares == -1) { 37851151Sbostic cylspares = lp->d_sparespercyl; 37951151Sbostic if (cylspares < 0) 38051151Sbostic cylspares = 0; 38151151Sbostic } 38251151Sbostic secpercyl = nsectors * ntracks - cylspares; 38351151Sbostic if (secpercyl != lp->d_secpercyl) 38451151Sbostic fprintf(stderr, "%s (%d) %s (%lu)\n", 38551151Sbostic "Warning: calculated sectors per cylinder", secpercyl, 38651151Sbostic "disagrees with disk label", lp->d_secpercyl); 38751151Sbostic if (maxbpg == 0) 38851151Sbostic maxbpg = MAXBLKPG(bsize); 38951151Sbostic headswitch = lp->d_headswitch; 39051151Sbostic trackseek = lp->d_trkseek; 39151151Sbostic #ifdef notdef /* label may be 0 if faked up by kernel */ 39251151Sbostic bbsize = lp->d_bbsize; 39351151Sbostic sbsize = lp->d_sbsize; 39451151Sbostic #endif 39551151Sbostic oldpartition = *pp; 39651151Sbostic #ifdef tahoe 39751151Sbostic realsectorsize = sectorsize; 39851151Sbostic if (sectorsize != DEV_BSIZE) { /* XXX */ 39951151Sbostic int secperblk = DEV_BSIZE / sectorsize; 40051151Sbostic 40151151Sbostic sectorsize = DEV_BSIZE; 40251151Sbostic nsectors /= secperblk; 40351151Sbostic nphyssectors /= secperblk; 40451151Sbostic secpercyl /= secperblk; 40551151Sbostic fssize /= secperblk; 40651151Sbostic pp->p_size /= secperblk; 40751151Sbostic } 40851151Sbostic #endif 40951151Sbostic mkfs(pp, special, fsi, fso); 41051151Sbostic #ifdef tahoe 41151151Sbostic if (realsectorsize != DEV_BSIZE) 41251151Sbostic pp->p_size *= DEV_BSIZE / realsectorsize; 41351151Sbostic #endif 41451151Sbostic if (!Nflag && bcmp(pp, &oldpartition, sizeof(oldpartition))) 41551151Sbostic rewritelabel(special, fso, lp); 41651151Sbostic if (!Nflag) 41751151Sbostic close(fso); 41851151Sbostic close(fsi); 41951151Sbostic #ifdef MFS 42051151Sbostic if (mfs) { 42151151Sbostic struct mfs_args args; 42251151Sbostic char buf[50]; 42351151Sbostic 42451151Sbostic (void)sprintf(buf, "mfs:%d", getpid()); 42551151Sbostic args.name = buf; 42651151Sbostic args.base = membase; 42751151Sbostic args.size = fssize * sectorsize; 42851151Sbostic if (mount(MOUNT_MFS, argv[1], mntflags, &args) < 0) 42951151Sbostic fatal("%s: %s", argv[1], strerror(errno)); 43051151Sbostic } 43151151Sbostic #endif 43251151Sbostic exit(0); 43351151Sbostic } 43451151Sbostic 43551151Sbostic #ifdef COMPAT 43651151Sbostic char lmsg[] = "%s: can't read disk label; disk type must be specified"; 43751151Sbostic #else 43851151Sbostic char lmsg[] = "%s: can't read disk label"; 43951151Sbostic #endif 44051151Sbostic 44151151Sbostic static struct disklabel * 44251151Sbostic getdisklabel(s, fd) 44351151Sbostic char *s; 44451151Sbostic int fd; 44551151Sbostic { 44651151Sbostic static struct disklabel lab; 44751151Sbostic 44851151Sbostic if (ioctl(fd, DIOCGDINFO, (char *)&lab) < 0) { 44951151Sbostic #ifdef COMPAT 45051151Sbostic if (disktype) { 45151151Sbostic struct disklabel *lp, *getdiskbyname(); 45251151Sbostic 45351151Sbostic unlabeled++; 45451151Sbostic lp = getdiskbyname(disktype); 45551151Sbostic if (lp == NULL) 45651151Sbostic fatal("%s: unknown disk type", disktype); 45751151Sbostic return (lp); 45851151Sbostic } 45951151Sbostic #endif 46051151Sbostic (void)fprintf(stderr, 46151151Sbostic "%s: ioctl (GDINFO): %s\n", progname, strerror(errno)); 46251151Sbostic fatal(lmsg, s); 46351151Sbostic } 46451151Sbostic return (&lab); 46551151Sbostic } 46651151Sbostic 46751151Sbostic 46851151Sbostic static struct disklabel * 46951151Sbostic debug_readlabel(fd) 47051151Sbostic int fd; 47151151Sbostic { 47251151Sbostic static struct disklabel lab; 47351151Sbostic int n; 47451151Sbostic 47551151Sbostic if ((n = read(fd, &lab, sizeof(struct disklabel))) < 0) 47651151Sbostic fatal("unable to read disk label: %s", strerror(errno)); 47751151Sbostic else if (n < sizeof(struct disklabel)) 47851151Sbostic fatal("short read of disklabel: %d of %d bytes", n, 47951151Sbostic sizeof(struct disklabel)); 48051151Sbostic return(&lab); 48151151Sbostic } 48251151Sbostic 48351151Sbostic static void 48451151Sbostic rewritelabel(s, fd, lp) 48551151Sbostic char *s; 48651151Sbostic int fd; 48751151Sbostic register struct disklabel *lp; 48851151Sbostic { 48951151Sbostic #ifdef COMPAT 49051151Sbostic if (unlabeled) 49151151Sbostic return; 49251151Sbostic #endif 49351151Sbostic lp->d_checksum = 0; 49451151Sbostic lp->d_checksum = dkcksum(lp); 49551151Sbostic if (ioctl(fd, DIOCWDINFO, (char *)lp) < 0) { 49651151Sbostic (void)fprintf(stderr, 49751151Sbostic "%s: ioctl (WDINFO): %s\n", progname, strerror(errno)); 49851151Sbostic fatal("%s: can't rewrite disk label", s); 49951151Sbostic } 50051151Sbostic #if vax 50151151Sbostic if (lp->d_type == DTYPE_SMD && lp->d_flags & D_BADSECT) { 50251151Sbostic register i; 50351151Sbostic int cfd; 50451151Sbostic daddr_t alt; 50551151Sbostic char specname[64]; 50651151Sbostic char blk[1024]; 50751151Sbostic char *cp; 50851151Sbostic 50951151Sbostic /* 51051151Sbostic * Make name for 'c' partition. 51151151Sbostic */ 51251151Sbostic strcpy(specname, s); 51351151Sbostic cp = specname + strlen(specname) - 1; 51451151Sbostic if (!isdigit(*cp)) 51551151Sbostic *cp = 'c'; 51651151Sbostic cfd = open(specname, O_WRONLY); 51751151Sbostic if (cfd < 0) 51851151Sbostic fatal("%s: %s", specname, strerror(errno)); 51951151Sbostic bzero(blk, sizeof(blk)); 52051151Sbostic *(struct disklabel *)(blk + LABELOFFSET) = *lp; 52151151Sbostic alt = lp->d_ncylinders * lp->d_secpercyl - lp->d_nsectors; 52251151Sbostic for (i = 1; i < 11 && i < lp->d_nsectors; i += 2) { 52351151Sbostic if (lseek(cfd, (off_t)(alt + i) * lp->d_secsize, 52451151Sbostic L_SET) == -1) 52551151Sbostic fatal("lseek to badsector area: %s", 52651151Sbostic strerror(errno)); 52751151Sbostic if (write(cfd, blk, lp->d_secsize) < lp->d_secsize) 52851151Sbostic fprintf(stderr, 52951151Sbostic "%s: alternate label %d write: %s\n", 53051151Sbostic progname, i/2, strerror(errno)); 53151151Sbostic } 53251151Sbostic close(cfd); 53351151Sbostic } 53451151Sbostic #endif 53551151Sbostic } 53651151Sbostic 53751151Sbostic void 53851151Sbostic usage() 53951151Sbostic { 54051151Sbostic if (mfs) { 54151151Sbostic fprintf(stderr, 54251151Sbostic "usage: mfs [ -fsoptions ] special-device mount-point\n"); 54351151Sbostic } else 54451151Sbostic fprintf(stderr, 54551151Sbostic "usage: newfs [ -fsoptions ] special-device%s\n", 54651151Sbostic #ifdef COMPAT 54751151Sbostic " [device-type]"); 54851151Sbostic #else 54951151Sbostic ""); 55051151Sbostic #endif 55151151Sbostic fprintf(stderr, "where fsoptions are:\n"); 55251151Sbostic fprintf(stderr, "\t-B LFS segment size\n"); 55351151Sbostic fprintf(stderr, "\t-D debug\n"); 55451151Sbostic fprintf(stderr, "\t-F mount flags\n"); 55551151Sbostic fprintf(stderr, "\t-L create LFS file system\n"); 55651151Sbostic fprintf(stderr, 55751151Sbostic "\t-N do not create file system, just print out parameters\n"); 55851151Sbostic fprintf(stderr, "\t-S sector size\n"); 55951151Sbostic #ifdef COMPAT 56051151Sbostic fprintf(stderr, "\t-T disktype\n"); 56151151Sbostic #endif 56251151Sbostic fprintf(stderr, "\t-a maximum contiguous blocks\n"); 56351151Sbostic fprintf(stderr, "\t-b block size\n"); 56451151Sbostic fprintf(stderr, "\t-c cylinders/group\n"); 56551151Sbostic fprintf(stderr, "\t-d rotational delay between contiguous blocks\n"); 56651151Sbostic fprintf(stderr, "\t-e maximum blocks per file in a cylinder group\n"); 56751151Sbostic fprintf(stderr, "\t-f frag size\n"); 56851151Sbostic fprintf(stderr, "\t-i number of bytes per inode\n"); 56951151Sbostic fprintf(stderr, "\t-k sector 0 skew, per track\n"); 57051151Sbostic fprintf(stderr, "\t-l hardware sector interleave\n"); 57151151Sbostic fprintf(stderr, "\t-m minimum free space %%\n"); 57251151Sbostic fprintf(stderr, "\t-n number of distinguished rotational positions\n"); 57351151Sbostic fprintf(stderr, "\t-o optimization preference (`space' or `time')\n"); 57451151Sbostic fprintf(stderr, "\t-p spare sectors per track\n"); 57551151Sbostic fprintf(stderr, "\t-r revolutions/minute\n"); 57651151Sbostic fprintf(stderr, "\t-s file system size (sectors)\n"); 57751151Sbostic fprintf(stderr, "\t-t tracks/cylinder\n"); 57851151Sbostic fprintf(stderr, "\t-u sectors/track\n"); 57951151Sbostic fprintf(stderr, "\t-x spare sectors per cylinder\n"); 58051151Sbostic exit(1); 58151151Sbostic } 582