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