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*32786Smckusick static char sccsid[] = "@(#)newfs.c 6.15 (Berkeley) 12/07/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 /* 8132309Smckusick * MAXBLKPG determines the maximum number of data blocks which are 8232309Smckusick * placed in a single cylinder group. The default is one indirect 8332309Smckusick * block worth of data blocks. 8432309Smckusick */ 8532309Smckusick #define MAXBLKPG(bsize) ((bsize) / sizeof(daddr_t)) 8632309Smckusick 8732309Smckusick /* 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 */ 12032309Smckusick 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 13310762Ssam main(argc, argv) 13414064Smckusick int argc; 13510762Ssam char *argv[]; 13610762Ssam { 13710762Ssam char *cp, *special; 13810762Ssam register struct partition *pp; 13930380Smckusick register struct disklabel *lp; 14030380Smckusick struct disklabel *getdisklabel(); 14130380Smckusick struct partition oldpartition; 14210762Ssam struct stat st; 14330380Smckusick int fsi, fso; 14410762Ssam register int i; 14510762Ssam int status; 14610762Ssam 14710762Ssam argc--, argv++; 14810762Ssam while (argc > 0 && argv[0][0] == '-') { 14910762Ssam for (cp = &argv[0][1]; *cp; cp++) 15010762Ssam switch (*cp) { 15110762Ssam 15216945Smckusick case 'N': 15316945Smckusick Nflag++; 15412334Shelge break; 15512334Shelge 15630380Smckusick case 'S': 15710762Ssam if (argc < 1) 15830380Smckusick fatal("-S: missing sector size"); 15910762Ssam argc--, argv++; 16030380Smckusick sectorsize = atoi(*argv); 16130380Smckusick if (sectorsize <= 0) 16230380Smckusick fatal("%s: bad sector size", *argv); 16310762Ssam goto next; 16410762Ssam 16530380Smckusick case 'a': 16610762Ssam if (argc < 1) 16732309Smckusick fatal("-a: missing max contiguous blocks\n"); 16810762Ssam argc--, argv++; 16932309Smckusick maxcontig = atoi(*argv); 17032309Smckusick if (maxcontig <= 0) 17132309Smckusick fatal("%s: bad max contiguous blocks\n", 17232309Smckusick *argv); 17310762Ssam goto next; 17410762Ssam 17510762Ssam case 'b': 17610762Ssam if (argc < 1) 17710762Ssam fatal("-b: missing block size"); 17810762Ssam argc--, argv++; 17910762Ssam bsize = atoi(*argv); 18030380Smckusick if (bsize < MINBSIZE) 18110762Ssam fatal("%s: bad block size", *argv); 18210762Ssam goto next; 18310762Ssam 18430380Smckusick case 'c': 18530380Smckusick if (argc < 1) 18630380Smckusick fatal("-c: missing cylinders/group"); 18730380Smckusick argc--, argv++; 18830380Smckusick cpg = atoi(*argv); 18930380Smckusick if (cpg <= 0) 19030380Smckusick fatal("%s: bad cylinders/group", *argv); 19132119Smckusick cpgflg++; 19230380Smckusick goto next; 19330380Smckusick 19430380Smckusick case 'd': 19530380Smckusick if (argc < 1) 19632309Smckusick fatal("-d: missing rotational delay\n"); 19730380Smckusick argc--, argv++; 19832309Smckusick rotdelay = atoi(*argv); 19932309Smckusick if (rotdelay < 0) 20032309Smckusick fatal("%s: bad rotational delay\n", 20132309Smckusick *argv); 20230380Smckusick goto next; 20330380Smckusick 20432309Smckusick case 'e': 20532309Smckusick if (argc < 1) 20632309Smckusick fatal("-e: missing blocks pre file in a cyl group\n"); 20732309Smckusick argc--, argv++; 20832309Smckusick maxbpg = atoi(*argv); 20932309Smckusick if (maxbpg <= 0) 21032309Smckusick fatal("%s: bad blocks per file in a cyl group\n", 21132309Smckusick *argv); 21232309Smckusick goto next; 21332309Smckusick 21410762Ssam case 'f': 21510762Ssam if (argc < 1) 21610762Ssam fatal("-f: missing frag size"); 21710762Ssam argc--, argv++; 21810762Ssam fsize = atoi(*argv); 21930380Smckusick if (fsize <= 0) 22010762Ssam fatal("%s: bad frag size", *argv); 22110762Ssam goto next; 22210762Ssam 22330380Smckusick case 'i': 22410762Ssam if (argc < 1) 22530380Smckusick fatal("-i: missing bytes per inode\n"); 22610762Ssam argc--, argv++; 22730380Smckusick density = atoi(*argv); 22830380Smckusick if (density <= 0) 22930380Smckusick fatal("%s: bad bytes per inode\n", 23030380Smckusick *argv); 23110762Ssam goto next; 23210762Ssam 23330386Smckusick case 'k': 23430386Smckusick if (argc < 1) 23530386Smckusick fatal("-k: track skew"); 23630386Smckusick argc--, argv++; 23730386Smckusick trackskew = atoi(*argv); 23830386Smckusick if (trackskew < 0) 23930386Smckusick fatal("%s: bad track skew", *argv); 24030386Smckusick goto next; 24130386Smckusick 24230386Smckusick case 'l': 24330386Smckusick if (argc < 1) 24430386Smckusick fatal("-l: interleave"); 24530386Smckusick argc--, argv++; 24630386Smckusick interleave = atoi(*argv); 24730386Smckusick if (interleave <= 0) 24830386Smckusick fatal("%s: bad interleave", *argv); 24930386Smckusick goto next; 25030386Smckusick 25111069Ssam case 'm': 25211069Ssam if (argc < 1) 25311069Ssam fatal("-m: missing free space %%\n"); 25411069Ssam argc--, argv++; 25511069Ssam minfree = atoi(*argv); 25611069Ssam if (minfree < 0 || minfree > 99) 25711069Ssam fatal("%s: bad free space %%\n", 25811069Ssam *argv); 25911069Ssam goto next; 26011069Ssam 26130380Smckusick case 'o': 26230380Smckusick if (argc < 1) 26330380Smckusick fatal("-o: missing optimization preference"); 26430380Smckusick argc--, argv++; 26530380Smckusick if (strcmp(*argv, "space") == 0) 26630380Smckusick opt = FS_OPTSPACE; 26730380Smckusick else if (strcmp(*argv, "time") == 0) 26830380Smckusick opt = FS_OPTTIME; 26930380Smckusick else 27030380Smckusick fatal("%s: bad optimization preference %s", 27130380Smckusick *argv, 27230380Smckusick "(options are `space' or `time')"); 27330380Smckusick goto next; 27430380Smckusick 27530386Smckusick case 'p': 27630386Smckusick if (argc < 1) 27730386Smckusick fatal("-p: spare sectors per track"); 27830386Smckusick argc--, argv++; 27930386Smckusick trackspares = atoi(*argv); 28030386Smckusick if (trackspares < 0) 28130386Smckusick fatal("%s: bad spare sectors per track", *argv); 28230386Smckusick goto next; 28330386Smckusick 28411069Ssam case 'r': 28511069Ssam if (argc < 1) 28611069Ssam fatal("-r: missing revs/minute\n"); 28711069Ssam argc--, argv++; 28811069Ssam rpm = atoi(*argv); 28930380Smckusick if (rpm <= 0) 29011069Ssam fatal("%s: bad revs/minute\n", *argv); 29111069Ssam goto next; 29211069Ssam 29330380Smckusick case 's': 29414884Smckusick if (argc < 1) 29530380Smckusick fatal("-s: missing file system size"); 29614884Smckusick argc--, argv++; 29730380Smckusick fssize = atoi(*argv); 29830380Smckusick if (fssize <= 0) 29930380Smckusick fatal("%s: bad file system size", 30014884Smckusick *argv); 30114884Smckusick goto next; 30214884Smckusick 30330380Smckusick case 't': 30430380Smckusick if (argc < 1) 30530380Smckusick fatal("-t: missing track total"); 30630380Smckusick argc--, argv++; 30730380Smckusick ntracks = atoi(*argv); 30830380Smckusick if (ntracks <= 0) 30930380Smckusick fatal("%s: bad total tracks", *argv); 31030380Smckusick goto next; 31130380Smckusick 31232309Smckusick case 'u': 31332309Smckusick if (argc < 1) 31432309Smckusick fatal("-u: missing sectors/track"); 31532309Smckusick argc--, argv++; 31632309Smckusick nsectors = atoi(*argv); 31732309Smckusick if (nsectors <= 0) 31832309Smckusick fatal("%s: bad sectors/track", *argv); 31932309Smckusick goto next; 32032309Smckusick 32132309Smckusick case 'x': 32232309Smckusick if (argc < 1) 32332309Smckusick fatal("-x: spare sectors per cylinder"); 32432309Smckusick argc--, argv++; 32532309Smckusick cylspares = atoi(*argv); 32632309Smckusick if (cylspares < 0) 32732309Smckusick fatal("%s: bad spare sectors per cylinder", *argv); 32832309Smckusick goto next; 32932309Smckusick 33010762Ssam default: 33132320Sbostic fatal("-%c: unknown flag", *cp); 33210762Ssam } 33310762Ssam next: 33410762Ssam argc--, argv++; 33510762Ssam } 33630380Smckusick if (argc < 1) { 33731680Skarels #ifdef COMPAT 33831680Skarels fprintf(stderr, 33931680Skarels "usage: newfs [ fsoptions ] special-device [device-type]\n"); 34031680Skarels #else 34130380Smckusick fprintf(stderr, "usage: newfs [ fsoptions ] special-device\n"); 34231680Skarels #endif 34330380Smckusick fprintf(stderr, "where fsoptions are:\n"); 34416945Smckusick fprintf(stderr, "\t-N do not create file system, %s\n", 34516945Smckusick "just print out parameters"); 34611057Ssam fprintf(stderr, "\t-b block size\n"); 34711057Ssam fprintf(stderr, "\t-f frag size\n"); 34811069Ssam fprintf(stderr, "\t-m minimum free space %%\n"); 34924702Smckusick fprintf(stderr, "\t-o optimization preference %s\n", 35024702Smckusick "(`space' or `time')"); 35132309Smckusick fprintf(stderr, "\t-a maximum contiguous blocks\n"); 35232309Smckusick fprintf(stderr, "\t-d rotational delay between %s\n", 35332309Smckusick "contiguous blocks"); 35432309Smckusick fprintf(stderr, "\t-e maximum blocks per file in a %s\n", 35532309Smckusick "cylinder group"); 35630398Smckusick fprintf(stderr, "\t-i number of bytes per inode\n"); 35730398Smckusick fprintf(stderr, "\t-c cylinders/group\n"); 35830398Smckusick fprintf(stderr, "\t-s file system size (sectors)\n"); 35911069Ssam fprintf(stderr, "\t-r revolutions/minute\n"); 36011057Ssam fprintf(stderr, "\t-S sector size\n"); 36132309Smckusick fprintf(stderr, "\t-u sectors/track\n"); 36230398Smckusick fprintf(stderr, "\t-t tracks/cylinder\n"); 36330398Smckusick fprintf(stderr, "\t-p spare sectors per track\n"); 36432309Smckusick fprintf(stderr, "\t-x spare sectors per cylinder\n"); 36530386Smckusick fprintf(stderr, "\t-l hardware sector interleave\n"); 36630386Smckusick fprintf(stderr, "\t-k sector 0 skew, per track\n"); 36710762Ssam exit(1); 36810762Ssam } 36910762Ssam special = argv[0]; 37014064Smckusick cp = rindex(special, '/'); 37114064Smckusick if (cp != 0) 37214064Smckusick special = cp + 1; 37314321Ssam if (*special == 'r' && special[1] != 'a' && special[1] != 'b') 37414064Smckusick special++; 37532463Sbostic (void)sprintf(device, "/dev/r%s", special); 37632463Sbostic special = device; 37730380Smckusick if (!Nflag) { 37830380Smckusick fso = open(special, O_WRONLY); 37930380Smckusick if (fso < 0) { 38030380Smckusick perror(special); 38130380Smckusick exit(1); 38230380Smckusick } 38330380Smckusick } else 38430380Smckusick fso = -1; 38530380Smckusick fsi = open(special, O_RDONLY); 38630380Smckusick if (fsi < 0) { 38730380Smckusick perror(special); 38830380Smckusick exit(1); 38930380Smckusick } 39030380Smckusick if (fstat(fsi, &st) < 0) { 39111069Ssam fprintf(stderr, "newfs: "); perror(special); 39210762Ssam exit(2); 39310762Ssam } 39414064Smckusick if ((st.st_mode & S_IFMT) != S_IFCHR) 39514064Smckusick fatal("%s: not a character device", special); 39610762Ssam cp = index(argv[0], '\0') - 1; 39730380Smckusick if (cp == 0 || (*cp < 'a' || *cp > 'h') && !isdigit(*cp)) 39810762Ssam fatal("%s: can't figure out file system partition", argv[0]); 39931680Skarels #ifdef COMPAT 40031680Skarels lp = getdisklabel(special, fsi, argv[1]); 40131680Skarels #else 40230380Smckusick lp = getdisklabel(special, fsi); 40331680Skarels #endif 40430380Smckusick if (isdigit(*cp)) 40530380Smckusick pp = &lp->d_partitions[0]; 40630380Smckusick else 40730380Smckusick pp = &lp->d_partitions[*cp - 'a']; 40830380Smckusick if (pp->p_size == 0) 40930380Smckusick fatal("%s: `%c' partition is unavailable", argv[0], *cp); 41030380Smckusick if (fssize == 0) 41110762Ssam fssize = pp->p_size; 41230380Smckusick if (fssize > pp->p_size) 41330380Smckusick fatal("%s: maximum file system size on the `%c' partition is %d", 41430380Smckusick argv[0], *cp, pp->p_size); 41530380Smckusick if (rpm == 0) { 41630380Smckusick rpm = lp->d_rpm; 41730380Smckusick if (rpm <= 0) 41830743Skarels rpm = 3600; 41910762Ssam } 42030380Smckusick if (ntracks == 0) { 42130380Smckusick ntracks = lp->d_ntracks; 42230380Smckusick if (ntracks <= 0) 42330743Skarels fatal("%s: no default #tracks", argv[0]); 42430380Smckusick } 42510762Ssam if (nsectors == 0) { 42630380Smckusick nsectors = lp->d_nsectors; 42730380Smckusick if (nsectors <= 0) 42830743Skarels fatal("%s: no default #sectors/track", argv[0]); 42910762Ssam } 43010762Ssam if (sectorsize == 0) { 43130380Smckusick sectorsize = lp->d_secsize; 43230380Smckusick if (sectorsize <= 0) 43330743Skarels fatal("%s: no default sector size", argv[0]); 43410762Ssam } 43530386Smckusick if (trackskew == -1) { 43630386Smckusick trackskew = lp->d_trackskew; 43730386Smckusick if (trackskew < 0) 43830743Skarels trackskew = 0; 43930386Smckusick } 44030386Smckusick if (interleave == 0) { 44130386Smckusick interleave = lp->d_interleave; 44230386Smckusick if (interleave <= 0) 44330743Skarels interleave = 1; 44430386Smckusick } 44510762Ssam if (fsize == 0) { 44610762Ssam fsize = pp->p_fsize; 44730380Smckusick if (fsize <= 0) 44830380Smckusick fsize = MAX(DFL_FRAGSIZE, lp->d_secsize); 44910762Ssam } 45030380Smckusick if (bsize == 0) { 45130380Smckusick bsize = pp->p_frag * pp->p_fsize; 45230380Smckusick if (bsize <= 0) 45330380Smckusick bsize = MIN(DFL_BLKSIZE, 8 * fsize); 45411069Ssam } 45524702Smckusick if (minfree < 10 && opt != FS_OPTSPACE) { 45630380Smckusick fprintf(stderr, "Warning: changing optimization to space "); 45730380Smckusick fprintf(stderr, "because minfree is less than 10%%\n"); 45824702Smckusick opt = FS_OPTSPACE; 45924702Smckusick } 46030386Smckusick if (trackspares == -1) { 46130386Smckusick trackspares = lp->d_sparespertrack; 46230386Smckusick if (trackspares < 0) 46330743Skarels trackspares = 0; 46430386Smckusick } 46530386Smckusick nphyssectors = nsectors + trackspares; 46630386Smckusick if (cylspares == -1) { 46730386Smckusick cylspares = lp->d_sparespercyl; 46830386Smckusick if (cylspares < 0) 46930743Skarels cylspares = 0; 47030386Smckusick } 47130386Smckusick secpercyl = nsectors * ntracks - cylspares; 47230380Smckusick if (secpercyl != lp->d_secpercyl) 47330380Smckusick fprintf(stderr, "%s (%d) %s (%d)\n", 47430380Smckusick "Warning: calculated sectors per cylinder", secpercyl, 47530380Smckusick "disagrees with disk label", lp->d_secpercyl); 47632321Smckusick if (maxbpg == 0) 47732321Smckusick maxbpg = MAXBLKPG(bsize); 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) { 555*32786Smckusick perror("ioctl (WDINFO)"); 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