121159Sdist /* 221159Sdist * Copyright (c) 1983 Regents of the University of California. 321159Sdist * All rights reserved. The Berkeley software License Agreement 421159Sdist * specifies the terms and conditions for redistribution. 521159Sdist */ 621159Sdist 710762Ssam #ifndef lint 821159Sdist char copyright[] = 921159Sdist "@(#) Copyright (c) 1983 Regents of the University of California.\n\ 1021159Sdist All rights reserved.\n"; 1121159Sdist #endif not lint 1210762Ssam 1321159Sdist #ifndef lint 14*32309Smckusick static char sccsid[] = "@(#)newfs.c 6.11 (Berkeley) 10/01/87"; 1521159Sdist #endif not lint 1621159Sdist 1710762Ssam /* 1811069Ssam * newfs: friendly front end to mkfs 1910762Ssam */ 2010762Ssam #include <sys/param.h> 2110762Ssam #include <sys/stat.h> 2210762Ssam #include <sys/fs.h> 2313603Ssam #include <sys/dir.h> 2430380Smckusick #include <sys/ioctl.h> 2530380Smckusick #include <sys/disklabel.h> 2630380Smckusick #include <sys/file.h> 2710762Ssam 2810762Ssam #include <stdio.h> 2930380Smckusick #include <ctype.h> 3010762Ssam 3131680Skarels #define COMPAT /* allow non-labeled disks */ 3231680Skarels 3330380Smckusick /* 3430380Smckusick * The following two constants set the default block and fragment sizes. 3530380Smckusick * Both constants must be a power of 2 and meet the following constraints: 3630380Smckusick * MINBSIZE <= DESBLKSIZE <= MAXBSIZE 3730380Smckusick * sectorsize <= DESFRAGSIZE <= DESBLKSIZE 3830380Smckusick * DESBLKSIZE / DESFRAGSIZE <= 8 3930380Smckusick */ 4030380Smckusick #define DFL_FRAGSIZE 1024 4130380Smckusick #define DFL_BLKSIZE 8192 4211183Ssam 4330380Smckusick /* 4430380Smckusick * Cylinder groups may have up to MAXCPG cylinders. The actual 4530380Smckusick * number used depends upon how much information can be stored 4630380Smckusick * on a single cylinder. The default is to used 16 cylinders 4730380Smckusick * per group. 4830380Smckusick */ 4930380Smckusick #define DESCPG 16 /* desired fs_cpg */ 5030380Smckusick 5130380Smckusick /* 5230380Smckusick * MINFREE gives the minimum acceptable percentage of file system 5330380Smckusick * blocks which may be free. If the freelist drops below this level 5430380Smckusick * only the superuser may continue to allocate blocks. This may 5530380Smckusick * be set to 0 if no reserve of free blocks is deemed necessary, 5630380Smckusick * however throughput drops by fifty percent if the file system 5730380Smckusick * is run at between 90% and 100% full; thus the default value of 5830380Smckusick * fs_minfree is 10%. With 10% free space, fragmentation is not a 5930380Smckusick * problem, so we choose to optimize for time. 6030380Smckusick */ 6130380Smckusick #define MINFREE 10 6230380Smckusick #define DEFAULTOPT FS_OPTTIME 6330380Smckusick 6430380Smckusick /* 6530380Smckusick * ROTDELAY gives the minimum number of milliseconds to initiate 6630380Smckusick * another disk transfer on the same cylinder. It is used in 6730380Smckusick * determining the rotationally optimal layout for disk blocks 6830380Smckusick * within a file; the default of fs_rotdelay is 4ms. 6930380Smckusick */ 7030380Smckusick #define ROTDELAY 4 7130380Smckusick 7230380Smckusick /* 7330380Smckusick * MAXCONTIG sets the default for the maximum number of blocks 7430380Smckusick * that may be allocated sequentially. Since UNIX drivers are 7530380Smckusick * not capable of scheduling multi-block transfers, this defaults 7630380Smckusick * to 1 (ie no contiguous blocks are allocated). 7730380Smckusick */ 7830380Smckusick #define MAXCONTIG 1 7930380Smckusick 8030380Smckusick /* 81*32309Smckusick * MAXBLKPG determines the maximum number of data blocks which are 82*32309Smckusick * placed in a single cylinder group. The default is one indirect 83*32309Smckusick * block worth of data blocks. 84*32309Smckusick */ 85*32309Smckusick #define MAXBLKPG(bsize) ((bsize) / sizeof(daddr_t)) 86*32309Smckusick 87*32309Smckusick /* 8830380Smckusick * Each file system has a number of inodes statically allocated. 8930380Smckusick * We allocate one inode slot per NBPI bytes, expecting this 9030380Smckusick * to be far more than we will ever need. 9130380Smckusick */ 9230380Smckusick #define NBPI 2048 9330380Smckusick 9430380Smckusick int Nflag; /* run without writing file system */ 9510762Ssam int fssize; /* file system size */ 9610762Ssam int ntracks; /* # tracks/cylinder */ 9710762Ssam int nsectors; /* # sectors/track */ 9830386Smckusick int nphyssectors; /* # sectors/track including spares */ 9930380Smckusick int secpercyl; /* sectors per cylinder */ 10030386Smckusick int trackspares = -1; /* spare sectors per track */ 10130386Smckusick int cylspares = -1; /* spare sectors per cylinder */ 10210762Ssam int sectorsize; /* bytes/sector */ 10330691Skarels #ifdef tahoe 10430691Skarels int realsectorsize; /* bytes/sector in hardware */ 10530691Skarels #endif 10611069Ssam int rpm; /* revolutions/minute of drive */ 10730386Smckusick int interleave; /* hardware sector interleave */ 10830386Smckusick int trackskew = -1; /* sector 0 skew, per track */ 10930386Smckusick int headswitch; /* head switch time, usec */ 11030386Smckusick int trackseek; /* track-to-track seek, usec */ 11130862Skarels int fsize = 0; /* fragment size */ 11230862Skarels int bsize = 0; /* block size */ 11330380Smckusick int cpg = DESCPG; /* cylinders/cylinder group */ 11432119Smckusick int cpgflg; /* cylinders/cylinder group flag was given */ 11530380Smckusick int minfree = MINFREE; /* free space threshold */ 11630380Smckusick int opt = DEFAULTOPT; /* optimization preference (space or time) */ 11730380Smckusick int density = NBPI; /* number of bytes per inode */ 11830380Smckusick int maxcontig = MAXCONTIG; /* max contiguous blocks to allocate */ 11930380Smckusick int rotdelay = ROTDELAY; /* rotational delay between blocks */ 120*32309Smckusick int maxbpg; /* maximum blocks per file in a cyl group */ 12130691Skarels int bbsize = BBSIZE; /* boot block size */ 12230691Skarels int sbsize = SBSIZE; /* superblock size */ 12331680Skarels #ifdef COMPAT 12431680Skarels int unlabelled; 12531680Skarels #endif 12610762Ssam 12710762Ssam char device[MAXPATHLEN]; 12810762Ssam 12930380Smckusick extern int errno; 13010762Ssam char *index(); 13110762Ssam char *rindex(); 13210762Ssam char *sprintf(); 13310762Ssam 13410762Ssam main(argc, argv) 13514064Smckusick int argc; 13610762Ssam char *argv[]; 13710762Ssam { 13810762Ssam char *cp, *special; 13910762Ssam register struct partition *pp; 14030380Smckusick register struct disklabel *lp; 14130380Smckusick struct disklabel *getdisklabel(); 14230380Smckusick struct partition oldpartition; 14310762Ssam struct stat st; 14430380Smckusick int fsi, fso; 14510762Ssam register int i; 14610762Ssam int status; 14710762Ssam 14810762Ssam argc--, argv++; 14910762Ssam while (argc > 0 && argv[0][0] == '-') { 15010762Ssam for (cp = &argv[0][1]; *cp; cp++) 15110762Ssam switch (*cp) { 15210762Ssam 15316945Smckusick case 'N': 15416945Smckusick Nflag++; 15512334Shelge break; 15612334Shelge 15730380Smckusick case 'S': 15810762Ssam if (argc < 1) 15930380Smckusick fatal("-S: missing sector size"); 16010762Ssam argc--, argv++; 16130380Smckusick sectorsize = atoi(*argv); 16230380Smckusick if (sectorsize <= 0) 16330380Smckusick fatal("%s: bad sector size", *argv); 16410762Ssam goto next; 16510762Ssam 16630380Smckusick case 'a': 16710762Ssam if (argc < 1) 168*32309Smckusick fatal("-a: missing max contiguous blocks\n"); 16910762Ssam argc--, argv++; 170*32309Smckusick maxcontig = atoi(*argv); 171*32309Smckusick if (maxcontig <= 0) 172*32309Smckusick fatal("%s: bad max contiguous blocks\n", 173*32309Smckusick *argv); 17410762Ssam goto next; 17510762Ssam 17610762Ssam case 'b': 17710762Ssam if (argc < 1) 17810762Ssam fatal("-b: missing block size"); 17910762Ssam argc--, argv++; 18010762Ssam bsize = atoi(*argv); 18130380Smckusick if (bsize < MINBSIZE) 18210762Ssam fatal("%s: bad block size", *argv); 18310762Ssam goto next; 18410762Ssam 18530380Smckusick case 'c': 18630380Smckusick if (argc < 1) 18730380Smckusick fatal("-c: missing cylinders/group"); 18830380Smckusick argc--, argv++; 18930380Smckusick cpg = atoi(*argv); 19030380Smckusick if (cpg <= 0) 19130380Smckusick fatal("%s: bad cylinders/group", *argv); 19232119Smckusick cpgflg++; 19330380Smckusick goto next; 19430380Smckusick 19530380Smckusick case 'd': 19630380Smckusick if (argc < 1) 197*32309Smckusick fatal("-d: missing rotational delay\n"); 19830380Smckusick argc--, argv++; 199*32309Smckusick rotdelay = atoi(*argv); 200*32309Smckusick if (rotdelay < 0) 201*32309Smckusick fatal("%s: bad rotational delay\n", 202*32309Smckusick *argv); 20330380Smckusick goto next; 20430380Smckusick 205*32309Smckusick case 'e': 206*32309Smckusick if (argc < 1) 207*32309Smckusick fatal("-e: missing blocks pre file in a cyl group\n"); 208*32309Smckusick argc--, argv++; 209*32309Smckusick maxbpg = atoi(*argv); 210*32309Smckusick if (maxbpg <= 0) 211*32309Smckusick fatal("%s: bad blocks per file in a cyl group\n", 212*32309Smckusick *argv); 213*32309Smckusick goto next; 214*32309Smckusick 21510762Ssam case 'f': 21610762Ssam if (argc < 1) 21710762Ssam fatal("-f: missing frag size"); 21810762Ssam argc--, argv++; 21910762Ssam fsize = atoi(*argv); 22030380Smckusick if (fsize <= 0) 22110762Ssam fatal("%s: bad frag size", *argv); 22210762Ssam goto next; 22310762Ssam 22430380Smckusick case 'i': 22510762Ssam if (argc < 1) 22630380Smckusick fatal("-i: missing bytes per inode\n"); 22710762Ssam argc--, argv++; 22830380Smckusick density = atoi(*argv); 22930380Smckusick if (density <= 0) 23030380Smckusick fatal("%s: bad bytes per inode\n", 23130380Smckusick *argv); 23210762Ssam goto next; 23310762Ssam 23430386Smckusick case 'k': 23530386Smckusick if (argc < 1) 23630386Smckusick fatal("-k: track skew"); 23730386Smckusick argc--, argv++; 23830386Smckusick trackskew = atoi(*argv); 23930386Smckusick if (trackskew < 0) 24030386Smckusick fatal("%s: bad track skew", *argv); 24130386Smckusick goto next; 24230386Smckusick 24330386Smckusick case 'l': 24430386Smckusick if (argc < 1) 24530386Smckusick fatal("-l: interleave"); 24630386Smckusick argc--, argv++; 24730386Smckusick interleave = atoi(*argv); 24830386Smckusick if (interleave <= 0) 24930386Smckusick fatal("%s: bad interleave", *argv); 25030386Smckusick goto next; 25130386Smckusick 25211069Ssam case 'm': 25311069Ssam if (argc < 1) 25411069Ssam fatal("-m: missing free space %%\n"); 25511069Ssam argc--, argv++; 25611069Ssam minfree = atoi(*argv); 25711069Ssam if (minfree < 0 || minfree > 99) 25811069Ssam fatal("%s: bad free space %%\n", 25911069Ssam *argv); 26011069Ssam goto next; 26111069Ssam 26230380Smckusick case 'o': 26330380Smckusick if (argc < 1) 26430380Smckusick fatal("-o: missing optimization preference"); 26530380Smckusick argc--, argv++; 26630380Smckusick if (strcmp(*argv, "space") == 0) 26730380Smckusick opt = FS_OPTSPACE; 26830380Smckusick else if (strcmp(*argv, "time") == 0) 26930380Smckusick opt = FS_OPTTIME; 27030380Smckusick else 27130380Smckusick fatal("%s: bad optimization preference %s", 27230380Smckusick *argv, 27330380Smckusick "(options are `space' or `time')"); 27430380Smckusick goto next; 27530380Smckusick 27630386Smckusick case 'p': 27730386Smckusick if (argc < 1) 27830386Smckusick fatal("-p: spare sectors per track"); 27930386Smckusick argc--, argv++; 28030386Smckusick trackspares = atoi(*argv); 28130386Smckusick if (trackspares < 0) 28230386Smckusick fatal("%s: bad spare sectors per track", *argv); 28330386Smckusick goto next; 28430386Smckusick 28511069Ssam case 'r': 28611069Ssam if (argc < 1) 28711069Ssam fatal("-r: missing revs/minute\n"); 28811069Ssam argc--, argv++; 28911069Ssam rpm = atoi(*argv); 29030380Smckusick if (rpm <= 0) 29111069Ssam fatal("%s: bad revs/minute\n", *argv); 29211069Ssam goto next; 29311069Ssam 29430380Smckusick case 's': 29514884Smckusick if (argc < 1) 29630380Smckusick fatal("-s: missing file system size"); 29714884Smckusick argc--, argv++; 29830380Smckusick fssize = atoi(*argv); 29930380Smckusick if (fssize <= 0) 30030380Smckusick fatal("%s: bad file system size", 30114884Smckusick *argv); 30214884Smckusick goto next; 30314884Smckusick 30430380Smckusick case 't': 30530380Smckusick if (argc < 1) 30630380Smckusick fatal("-t: missing track total"); 30730380Smckusick argc--, argv++; 30830380Smckusick ntracks = atoi(*argv); 30930380Smckusick if (ntracks <= 0) 31030380Smckusick fatal("%s: bad total tracks", *argv); 31130380Smckusick goto next; 31230380Smckusick 313*32309Smckusick case 'u': 314*32309Smckusick if (argc < 1) 315*32309Smckusick fatal("-u: missing sectors/track"); 316*32309Smckusick argc--, argv++; 317*32309Smckusick nsectors = atoi(*argv); 318*32309Smckusick if (nsectors <= 0) 319*32309Smckusick fatal("%s: bad sectors/track", *argv); 320*32309Smckusick goto next; 321*32309Smckusick 322*32309Smckusick case 'x': 323*32309Smckusick if (argc < 1) 324*32309Smckusick fatal("-x: spare sectors per cylinder"); 325*32309Smckusick argc--, argv++; 326*32309Smckusick cylspares = atoi(*argv); 327*32309Smckusick if (cylspares < 0) 328*32309Smckusick fatal("%s: bad spare sectors per cylinder", *argv); 329*32309Smckusick goto next; 330*32309Smckusick 33110762Ssam default: 33210762Ssam fatal("-%c: unknown flag", cp); 33310762Ssam } 33410762Ssam next: 33510762Ssam argc--, argv++; 33610762Ssam } 33730380Smckusick if (argc < 1) { 33831680Skarels #ifdef COMPAT 33931680Skarels fprintf(stderr, 34031680Skarels "usage: newfs [ fsoptions ] special-device [device-type]\n"); 34131680Skarels #else 34230380Smckusick fprintf(stderr, "usage: newfs [ fsoptions ] special-device\n"); 34331680Skarels #endif 34430380Smckusick fprintf(stderr, "where fsoptions are:\n"); 34516945Smckusick fprintf(stderr, "\t-N do not create file system, %s\n", 34616945Smckusick "just print out parameters"); 34711057Ssam fprintf(stderr, "\t-b block size\n"); 34811057Ssam fprintf(stderr, "\t-f frag size\n"); 34911069Ssam fprintf(stderr, "\t-m minimum free space %%\n"); 35024702Smckusick fprintf(stderr, "\t-o optimization preference %s\n", 35124702Smckusick "(`space' or `time')"); 352*32309Smckusick fprintf(stderr, "\t-a maximum contiguous blocks\n"); 353*32309Smckusick fprintf(stderr, "\t-d rotational delay between %s\n", 354*32309Smckusick "contiguous blocks"); 355*32309Smckusick fprintf(stderr, "\t-e maximum blocks per file in a %s\n", 356*32309Smckusick "cylinder group"); 35730398Smckusick fprintf(stderr, "\t-i number of bytes per inode\n"); 35830398Smckusick fprintf(stderr, "\t-c cylinders/group\n"); 35930398Smckusick fprintf(stderr, "\t-s file system size (sectors)\n"); 36011069Ssam fprintf(stderr, "\t-r revolutions/minute\n"); 36111057Ssam fprintf(stderr, "\t-S sector size\n"); 362*32309Smckusick fprintf(stderr, "\t-u sectors/track\n"); 36330398Smckusick fprintf(stderr, "\t-t tracks/cylinder\n"); 36430398Smckusick fprintf(stderr, "\t-p spare sectors per track\n"); 365*32309Smckusick fprintf(stderr, "\t-x spare sectors per cylinder\n"); 36630386Smckusick fprintf(stderr, "\t-l hardware sector interleave\n"); 36730386Smckusick fprintf(stderr, "\t-k sector 0 skew, per track\n"); 36810762Ssam exit(1); 36910762Ssam } 370*32309Smckusick if (maxbpg == 0) 371*32309Smckusick maxbpg = MAXBLKPG(bsize); 37210762Ssam special = argv[0]; 37314064Smckusick cp = rindex(special, '/'); 37414064Smckusick if (cp != 0) 37514064Smckusick special = cp + 1; 37614321Ssam if (*special == 'r' && special[1] != 'a' && special[1] != 'b') 37714064Smckusick special++; 37814064Smckusick special = sprintf(device, "/dev/r%s", special); 37930380Smckusick if (!Nflag) { 38030380Smckusick fso = open(special, O_WRONLY); 38130380Smckusick if (fso < 0) { 38230380Smckusick perror(special); 38330380Smckusick exit(1); 38430380Smckusick } 38530380Smckusick } else 38630380Smckusick fso = -1; 38730380Smckusick fsi = open(special, O_RDONLY); 38830380Smckusick if (fsi < 0) { 38930380Smckusick perror(special); 39030380Smckusick exit(1); 39130380Smckusick } 39230380Smckusick if (fstat(fsi, &st) < 0) { 39311069Ssam fprintf(stderr, "newfs: "); perror(special); 39410762Ssam exit(2); 39510762Ssam } 39614064Smckusick if ((st.st_mode & S_IFMT) != S_IFCHR) 39714064Smckusick fatal("%s: not a character device", special); 39810762Ssam cp = index(argv[0], '\0') - 1; 39930380Smckusick if (cp == 0 || (*cp < 'a' || *cp > 'h') && !isdigit(*cp)) 40010762Ssam fatal("%s: can't figure out file system partition", argv[0]); 40131680Skarels #ifdef COMPAT 40231680Skarels lp = getdisklabel(special, fsi, argv[1]); 40331680Skarels #else 40430380Smckusick lp = getdisklabel(special, fsi); 40531680Skarels #endif 40630380Smckusick if (isdigit(*cp)) 40730380Smckusick pp = &lp->d_partitions[0]; 40830380Smckusick else 40930380Smckusick pp = &lp->d_partitions[*cp - 'a']; 41030380Smckusick if (pp->p_size == 0) 41130380Smckusick fatal("%s: `%c' partition is unavailable", argv[0], *cp); 41230380Smckusick if (fssize == 0) 41310762Ssam fssize = pp->p_size; 41430380Smckusick if (fssize > pp->p_size) 41530380Smckusick fatal("%s: maximum file system size on the `%c' partition is %d", 41630380Smckusick argv[0], *cp, pp->p_size); 41730380Smckusick if (rpm == 0) { 41830380Smckusick rpm = lp->d_rpm; 41930380Smckusick if (rpm <= 0) 42030743Skarels rpm = 3600; 42110762Ssam } 42230380Smckusick if (ntracks == 0) { 42330380Smckusick ntracks = lp->d_ntracks; 42430380Smckusick if (ntracks <= 0) 42530743Skarels fatal("%s: no default #tracks", argv[0]); 42630380Smckusick } 42710762Ssam if (nsectors == 0) { 42830380Smckusick nsectors = lp->d_nsectors; 42930380Smckusick if (nsectors <= 0) 43030743Skarels fatal("%s: no default #sectors/track", argv[0]); 43110762Ssam } 43210762Ssam if (sectorsize == 0) { 43330380Smckusick sectorsize = lp->d_secsize; 43430380Smckusick if (sectorsize <= 0) 43530743Skarels fatal("%s: no default sector size", argv[0]); 43610762Ssam } 43730386Smckusick if (trackskew == -1) { 43830386Smckusick trackskew = lp->d_trackskew; 43930386Smckusick if (trackskew < 0) 44030743Skarels trackskew = 0; 44130386Smckusick } 44230386Smckusick if (interleave == 0) { 44330386Smckusick interleave = lp->d_interleave; 44430386Smckusick if (interleave <= 0) 44530743Skarels interleave = 1; 44630386Smckusick } 44710762Ssam if (fsize == 0) { 44810762Ssam fsize = pp->p_fsize; 44930380Smckusick if (fsize <= 0) 45030380Smckusick fsize = MAX(DFL_FRAGSIZE, lp->d_secsize); 45110762Ssam } 45230380Smckusick if (bsize == 0) { 45330380Smckusick bsize = pp->p_frag * pp->p_fsize; 45430380Smckusick if (bsize <= 0) 45530380Smckusick bsize = MIN(DFL_BLKSIZE, 8 * fsize); 45611069Ssam } 45724702Smckusick if (minfree < 10 && opt != FS_OPTSPACE) { 45830380Smckusick fprintf(stderr, "Warning: changing optimization to space "); 45930380Smckusick fprintf(stderr, "because minfree is less than 10%%\n"); 46024702Smckusick opt = FS_OPTSPACE; 46124702Smckusick } 46230386Smckusick if (trackspares == -1) { 46330386Smckusick trackspares = lp->d_sparespertrack; 46430386Smckusick if (trackspares < 0) 46530743Skarels trackspares = 0; 46630386Smckusick } 46730386Smckusick nphyssectors = nsectors + trackspares; 46830386Smckusick if (cylspares == -1) { 46930386Smckusick cylspares = lp->d_sparespercyl; 47030386Smckusick if (cylspares < 0) 47130743Skarels cylspares = 0; 47230386Smckusick } 47330386Smckusick secpercyl = nsectors * ntracks - cylspares; 47430380Smckusick if (secpercyl != lp->d_secpercyl) 47530380Smckusick fprintf(stderr, "%s (%d) %s (%d)\n", 47630380Smckusick "Warning: calculated sectors per cylinder", secpercyl, 47730380Smckusick "disagrees with disk label", lp->d_secpercyl); 47830386Smckusick headswitch = lp->d_headswitch; 47930386Smckusick trackseek = lp->d_trkseek; 48030691Skarels bbsize = lp->d_bbsize; 48130691Skarels sbsize = lp->d_sbsize; 48230380Smckusick oldpartition = *pp; 48330691Skarels #ifdef tahoe 48430691Skarels realsectorsize = sectorsize; 48530862Skarels if (sectorsize != DEV_BSIZE) { /* XXX */ 48630691Skarels int secperblk = DEV_BSIZE / sectorsize; 48730691Skarels 48830691Skarels sectorsize = DEV_BSIZE; 48930691Skarels nsectors /= secperblk; 49030691Skarels nphyssectors /= secperblk; 49130691Skarels secpercyl /= secperblk; 49230691Skarels fssize /= secperblk; 49330691Skarels pp->p_size /= secperblk; 49430691Skarels } 49530691Skarels #endif 49630380Smckusick mkfs(pp, special, fsi, fso); 49730691Skarels #ifdef tahoe 49830691Skarels if (realsectorsize != DEV_BSIZE) 49930691Skarels pp->p_size *= DEV_BSIZE / realsectorsize; 50030691Skarels #endif 50130380Smckusick if (!Nflag && bcmp(pp, &oldpartition, sizeof(oldpartition))) 50230380Smckusick rewritelabel(special, fso, lp); 50330380Smckusick exit(0); 50430380Smckusick } 50530380Smckusick 50631680Skarels #ifdef COMPAT 50730380Smckusick struct disklabel * 50831680Skarels getdisklabel(s, fd, type) 50931680Skarels char *s, *type; 51031680Skarels int fd; 51131680Skarels { 51231680Skarels static struct disklabel lab; 51331680Skarels struct disklabel *getdiskbyname(); 51431680Skarels 51531680Skarels if (ioctl(fd, DIOCGDINFO, (char *)&lab) < 0) { 51631680Skarels if (type == NULL) { 51731680Skarels perror("ioctl (GDINFO)"); 51831680Skarels fatal( 51931680Skarels "%s: can't read disk label; disk type must be specified", s); 52031680Skarels } 52131680Skarels unlabelled++; 52231680Skarels return (getdiskbyname(type)); 52331680Skarels } 52431680Skarels return (&lab); 52531680Skarels } 52631680Skarels #else 52731680Skarels struct disklabel * 52830380Smckusick getdisklabel(s, fd) 52930380Smckusick char *s; 53031680Skarels int fd; 53130380Smckusick { 53230380Smckusick static struct disklabel lab; 53330380Smckusick 53430380Smckusick if (ioctl(fd, DIOCGDINFO, (char *)&lab) < 0) { 53530380Smckusick perror("ioctl (GDINFO)"); 53630380Smckusick fatal("%s: can't read disk label", s); 53710762Ssam } 53830380Smckusick return (&lab); 53930380Smckusick } 54031680Skarels #endif 54110762Ssam 54230380Smckusick rewritelabel(s, fd, lp) 54330380Smckusick char *s; 54430380Smckusick int fd; 54530380Smckusick register struct disklabel *lp; 54630380Smckusick { 54730380Smckusick 54831680Skarels #ifdef COMPAT 54931680Skarels if (unlabelled) 55031680Skarels return; 55131680Skarels #endif 55230380Smckusick lp->d_checksum = 0; 55330380Smckusick lp->d_checksum = dkcksum(lp); 55430380Smckusick if (ioctl(fd, DIOCWDINFO, (char *)lp) < 0) { 55530380Smckusick perror("ioctl (GWINFO)"); 55630380Smckusick fatal("%s: can't rewrite disk label", s); 55710762Ssam } 55830446Skarels #if vax 55930446Skarels if (lp->d_type == DTYPE_SMD && lp->d_flags & D_BADSECT) { 56030446Skarels register i; 56130691Skarels int cfd; 56230446Skarels daddr_t alt; 56330691Skarels char specname[64]; 56430691Skarels char blk[1024]; 56531045Ssam char *cp; 56630446Skarels 56730691Skarels /* 56830691Skarels * Make name for 'c' partition. 56930691Skarels */ 57030691Skarels strcpy(specname, s); 57130691Skarels cp = specname + strlen(specname) - 1; 57230691Skarels if (!isdigit(*cp)) 57330691Skarels *cp = 'c'; 57430691Skarels cfd = open(specname, O_WRONLY); 57530691Skarels if (cfd < 0) { 57630691Skarels perror(specname); 57730691Skarels exit(2); 57830691Skarels } 57930691Skarels bzero(blk, sizeof(blk)); 58030691Skarels *(struct disklabel *)(blk + LABELOFFSET) = *lp; 58130446Skarels alt = lp->d_ncylinders * lp->d_secpercyl - lp->d_nsectors; 58230446Skarels for (i = 1; i < 11 && i < lp->d_nsectors; i += 2) { 58331680Skarels if (lseek(cfd, (off_t)(alt + i) * lp->d_secsize, L_SET) == -1) { 58431680Skarels perror("lseek to badsector area"); 58531680Skarels exit(30); 58631680Skarels } 58730691Skarels if (write(cfd, blk, lp->d_secsize) < lp->d_secsize) { 58830446Skarels int oerrno = errno; 58930446Skarels fprintf(stderr, "alternate label %d ", i/2); 59030446Skarels errno = oerrno; 59130446Skarels perror("write"); 59230446Skarels } 59330380Smckusick } 59430380Smckusick } 59530446Skarels #endif 59610762Ssam } 59710762Ssam 59810762Ssam /*VARARGS*/ 59910762Ssam fatal(fmt, arg1, arg2) 60010762Ssam char *fmt; 60110762Ssam { 60210762Ssam 60311069Ssam fprintf(stderr, "newfs: "); 60410762Ssam fprintf(stderr, fmt, arg1, arg2); 60510762Ssam putc('\n', stderr); 60610762Ssam exit(10); 60710762Ssam } 608