|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1983, 1989 The Regents of the University of California. ! 3: * All rights reserved. ! 4: * ! 5: * Redistribution and use in source and binary forms are permitted provided ! 6: * that: (1) source distributions retain this entire copyright notice and ! 7: * comment, and (2) distributions including binaries display the following ! 8: * acknowledgement: ``This product includes software developed by the ! 9: * University of California, Berkeley and its contributors'' in the ! 10: * documentation or other materials provided with the distribution and in ! 11: * all advertising materials mentioning features or use of this software. ! 12: * Neither the name of the University nor the names of its contributors may ! 13: * be used to endorse or promote products derived from this software without ! 14: * specific prior written permission. ! 15: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED ! 16: * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF ! 17: * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ! 18: */ ! 19: ! 20: #ifndef lint ! 21: static char sccsid[] = "@(#)newfs.c 6.22.1.1 (Berkeley) 12/18/90"; ! 22: #endif /* not lint */ ! 23: ! 24: #ifndef lint ! 25: char copyright[] = ! 26: "@(#) Copyright (c) 1983, 1989 Regents of the University of California.\n\ ! 27: All rights reserved.\n"; ! 28: #endif /* not lint */ ! 29: ! 30: /* ! 31: * newfs: friendly front end to mkfs ! 32: */ ! 33: #include <sys/param.h> ! 34: #include <sys/stat.h> ! 35: #include <ufs/fs.h> ! 36: #include <ufs/dir.h> ! 37: #include <sys/ioctl.h> ! 38: #include <sys/disklabel.h> ! 39: #include <sys/file.h> ! 40: #include <sys/mount.h> ! 41: ! 42: #include <stdio.h> ! 43: #include <ctype.h> ! 44: #include <paths.h> ! 45: ! 46: #define COMPAT /* allow non-labeled disks */ ! 47: ! 48: /* ! 49: * The following two constants set the default block and fragment sizes. ! 50: * Both constants must be a power of 2 and meet the following constraints: ! 51: * MINBSIZE <= DESBLKSIZE <= MAXBSIZE ! 52: * sectorsize <= DESFRAGSIZE <= DESBLKSIZE ! 53: * DESBLKSIZE / DESFRAGSIZE <= 8 ! 54: */ ! 55: #define DFL_FRAGSIZE 1024 ! 56: #define DFL_BLKSIZE 8192 ! 57: ! 58: /* ! 59: * Cylinder groups may have up to many cylinders. The actual ! 60: * number used depends upon how much information can be stored ! 61: * on a single cylinder. The default is to use 16 cylinders ! 62: * per group. ! 63: */ ! 64: #define DESCPG 16 /* desired fs_cpg */ ! 65: ! 66: /* ! 67: * MINFREE gives the minimum acceptable percentage of file system ! 68: * blocks which may be free. If the freelist drops below this level ! 69: * only the superuser may continue to allocate blocks. This may ! 70: * be set to 0 if no reserve of free blocks is deemed necessary, ! 71: * however throughput drops by fifty percent if the file system ! 72: * is run at between 90% and 100% full; thus the default value of ! 73: * fs_minfree is 10%. With 10% free space, fragmentation is not a ! 74: * problem, so we choose to optimize for time. ! 75: */ ! 76: #define MINFREE 10 ! 77: #define DEFAULTOPT FS_OPTTIME ! 78: ! 79: /* ! 80: * ROTDELAY gives the minimum number of milliseconds to initiate ! 81: * another disk transfer on the same cylinder. It is used in ! 82: * determining the rotationally optimal layout for disk blocks ! 83: * within a file; the default of fs_rotdelay is 4ms. ! 84: */ ! 85: #define ROTDELAY 4 ! 86: ! 87: /* ! 88: * MAXCONTIG sets the default for the maximum number of blocks ! 89: * that may be allocated sequentially. Since UNIX drivers are ! 90: * not capable of scheduling multi-block transfers, this defaults ! 91: * to 1 (ie no contiguous blocks are allocated). ! 92: */ ! 93: #define MAXCONTIG 1 ! 94: ! 95: /* ! 96: * MAXBLKPG determines the maximum number of data blocks which are ! 97: * placed in a single cylinder group. The default is one indirect ! 98: * block worth of data blocks. ! 99: */ ! 100: #define MAXBLKPG(bsize) ((bsize) / sizeof(daddr_t)) ! 101: ! 102: /* ! 103: * Each file system has a number of inodes statically allocated. ! 104: * We allocate one inode slot per NFPI fragments, expecting this ! 105: * to be far more than we will ever need. ! 106: */ ! 107: #define NFPI 4 ! 108: ! 109: /* ! 110: * For each cylinder we keep track of the availability of blocks at different ! 111: * rotational positions, so that we can lay out the data to be picked ! 112: * up with minimum rotational latency. NRPOS is the default number of ! 113: * rotational positions that we distinguish. With NRPOS of 8 the resolution ! 114: * of our summary information is 2ms for a typical 3600 rpm drive. ! 115: */ ! 116: #define NRPOS 8 /* number distinct rotational positions */ ! 117: ! 118: ! 119: int mfs; /* run as the memory based filesystem */ ! 120: int Nflag; /* run without writing file system */ ! 121: int fssize; /* file system size */ ! 122: int ntracks; /* # tracks/cylinder */ ! 123: int nsectors; /* # sectors/track */ ! 124: int nphyssectors; /* # sectors/track including spares */ ! 125: int secpercyl; /* sectors per cylinder */ ! 126: int trackspares = -1; /* spare sectors per track */ ! 127: int cylspares = -1; /* spare sectors per cylinder */ ! 128: int sectorsize; /* bytes/sector */ ! 129: #ifdef tahoe ! 130: int realsectorsize; /* bytes/sector in hardware */ ! 131: #endif ! 132: int rpm; /* revolutions/minute of drive */ ! 133: int interleave; /* hardware sector interleave */ ! 134: int trackskew = -1; /* sector 0 skew, per track */ ! 135: int headswitch; /* head switch time, usec */ ! 136: int trackseek; /* track-to-track seek, usec */ ! 137: int fsize = 0; /* fragment size */ ! 138: int bsize = 0; /* block size */ ! 139: int cpg = DESCPG; /* cylinders/cylinder group */ ! 140: int cpgflg; /* cylinders/cylinder group flag was given */ ! 141: int minfree = MINFREE; /* free space threshold */ ! 142: int opt = DEFAULTOPT; /* optimization preference (space or time) */ ! 143: int density; /* number of bytes per inode */ ! 144: int maxcontig = MAXCONTIG; /* max contiguous blocks to allocate */ ! 145: int rotdelay = ROTDELAY; /* rotational delay between blocks */ ! 146: int maxbpg; /* maximum blocks per file in a cyl group */ ! 147: int nrpos = NRPOS; /* # of distinguished rotational positions */ ! 148: int bbsize = BBSIZE; /* boot block size */ ! 149: int sbsize = SBSIZE; /* superblock size */ ! 150: int mntflags; /* flags to be passed to mount */ ! 151: u_long memleft; /* virtual memory available */ ! 152: caddr_t membase; /* start address of memory based filesystem */ ! 153: #ifdef COMPAT ! 154: char *disktype; ! 155: int unlabelled; ! 156: #endif ! 157: ! 158: char device[MAXPATHLEN]; ! 159: char *progname; ! 160: ! 161: extern int errno; ! 162: char *index(); ! 163: char *rindex(); ! 164: ! 165: main(argc, argv) ! 166: int argc; ! 167: char *argv[]; ! 168: { ! 169: char *cp, *special, *rindex(); ! 170: register struct partition *pp; ! 171: register struct disklabel *lp; ! 172: struct disklabel *getdisklabel(); ! 173: struct partition oldpartition; ! 174: struct mfs_args args; ! 175: struct stat st; ! 176: int fsi, fso; ! 177: register int i; ! 178: int status; ! 179: char buf[BUFSIZ]; ! 180: ! 181: if ((progname = rindex(*argv, '/') + 1) == (char *)1) ! 182: progname = *argv; ! 183: if (!strcmp(progname, "mfs")) { ! 184: Nflag++; ! 185: mfs++; ! 186: } ! 187: argc--, argv++; ! 188: while (argc > 0 && argv[0][0] == '-') { ! 189: for (cp = &argv[0][1]; *cp; cp++) ! 190: switch (*cp) { ! 191: ! 192: case 'F': ! 193: if (!mfs) ! 194: fatal("-F: unknown flag"); ! 195: if (argc < 1) ! 196: fatal("-F: mount flags"); ! 197: argc--, argv++; ! 198: mntflags = atoi(*argv); ! 199: if (mntflags == 0) ! 200: fatal("%s: bad mount flags", *argv); ! 201: goto next; ! 202: ! 203: case 'N': ! 204: Nflag++; ! 205: break; ! 206: ! 207: case 'S': ! 208: if (argc < 1) ! 209: fatal("-S: missing sector size"); ! 210: argc--, argv++; ! 211: sectorsize = atoi(*argv); ! 212: if (sectorsize <= 0) ! 213: fatal("%s: bad sector size", *argv); ! 214: goto next; ! 215: ! 216: #ifdef COMPAT ! 217: case 'T': ! 218: if (argc < 1) ! 219: fatal("-T: missing disk type"); ! 220: argc--, argv++; ! 221: disktype = *argv; ! 222: goto next; ! 223: #endif ! 224: ! 225: case 'a': ! 226: if (argc < 1) ! 227: fatal("-a: missing max contiguous blocks\n"); ! 228: argc--, argv++; ! 229: maxcontig = atoi(*argv); ! 230: if (maxcontig <= 0) ! 231: fatal("%s: bad max contiguous blocks\n", ! 232: *argv); ! 233: goto next; ! 234: ! 235: case 'b': ! 236: if (argc < 1) ! 237: fatal("-b: missing block size"); ! 238: argc--, argv++; ! 239: bsize = atoi(*argv); ! 240: if (bsize < MINBSIZE) ! 241: fatal("%s: bad block size", *argv); ! 242: goto next; ! 243: ! 244: case 'c': ! 245: if (argc < 1) ! 246: fatal("-c: missing cylinders/group"); ! 247: argc--, argv++; ! 248: cpg = atoi(*argv); ! 249: if (cpg <= 0) ! 250: fatal("%s: bad cylinders/group", *argv); ! 251: cpgflg++; ! 252: goto next; ! 253: ! 254: case 'd': ! 255: if (argc < 1) ! 256: fatal("-d: missing rotational delay\n"); ! 257: argc--, argv++; ! 258: rotdelay = atoi(*argv); ! 259: if (rotdelay < 0) ! 260: fatal("%s: bad rotational delay\n", ! 261: *argv); ! 262: goto next; ! 263: ! 264: case 'e': ! 265: if (argc < 1) ! 266: fatal("-e: missing blocks pre file in a cyl group\n"); ! 267: argc--, argv++; ! 268: maxbpg = atoi(*argv); ! 269: if (maxbpg <= 0) ! 270: fatal("%s: bad blocks per file in a cyl group\n", ! 271: *argv); ! 272: goto next; ! 273: ! 274: case 'f': ! 275: if (argc < 1) ! 276: fatal("-f: missing frag size"); ! 277: argc--, argv++; ! 278: fsize = atoi(*argv); ! 279: if (fsize <= 0) ! 280: fatal("%s: bad frag size", *argv); ! 281: goto next; ! 282: ! 283: case 'i': ! 284: if (argc < 1) ! 285: fatal("-i: missing bytes per inode\n"); ! 286: argc--, argv++; ! 287: density = atoi(*argv); ! 288: if (density <= 0) ! 289: fatal("%s: bad bytes per inode\n", ! 290: *argv); ! 291: goto next; ! 292: ! 293: case 'k': ! 294: if (argc < 1) ! 295: fatal("-k: track skew"); ! 296: argc--, argv++; ! 297: trackskew = atoi(*argv); ! 298: if (trackskew < 0) ! 299: fatal("%s: bad track skew", *argv); ! 300: goto next; ! 301: ! 302: case 'l': ! 303: if (argc < 1) ! 304: fatal("-l: interleave"); ! 305: argc--, argv++; ! 306: interleave = atoi(*argv); ! 307: if (interleave <= 0) ! 308: fatal("%s: bad interleave", *argv); ! 309: goto next; ! 310: ! 311: case 'm': ! 312: if (argc < 1) ! 313: fatal("-m: missing free space %%\n"); ! 314: argc--, argv++; ! 315: minfree = atoi(*argv); ! 316: if (minfree < 0 || minfree > 99) ! 317: fatal("%s: bad free space %%\n", ! 318: *argv); ! 319: goto next; ! 320: ! 321: case 'n': ! 322: if (argc < 1) ! 323: fatal("-n: missing rotational layout count\n"); ! 324: argc--, argv++; ! 325: nrpos = atoi(*argv); ! 326: if (nrpos <= 0) ! 327: fatal("%s: bad rotational layout count\n", ! 328: *argv); ! 329: goto next; ! 330: ! 331: case 'o': ! 332: if (argc < 1) ! 333: fatal("-o: missing optimization preference"); ! 334: argc--, argv++; ! 335: if (strcmp(*argv, "space") == 0) ! 336: opt = FS_OPTSPACE; ! 337: else if (strcmp(*argv, "time") == 0) ! 338: opt = FS_OPTTIME; ! 339: else ! 340: fatal("%s: bad optimization preference %s", ! 341: *argv, ! 342: "(options are `space' or `time')"); ! 343: goto next; ! 344: ! 345: case 'p': ! 346: if (argc < 1) ! 347: fatal("-p: spare sectors per track"); ! 348: argc--, argv++; ! 349: trackspares = atoi(*argv); ! 350: if (trackspares < 0) ! 351: fatal("%s: bad spare sectors per track", *argv); ! 352: goto next; ! 353: ! 354: case 'r': ! 355: if (argc < 1) ! 356: fatal("-r: missing revs/minute\n"); ! 357: argc--, argv++; ! 358: rpm = atoi(*argv); ! 359: if (rpm <= 0) ! 360: fatal("%s: bad revs/minute\n", *argv); ! 361: goto next; ! 362: ! 363: case 's': ! 364: if (argc < 1) ! 365: fatal("-s: missing file system size"); ! 366: argc--, argv++; ! 367: fssize = atoi(*argv); ! 368: if (fssize <= 0) ! 369: fatal("%s: bad file system size", ! 370: *argv); ! 371: goto next; ! 372: ! 373: case 't': ! 374: if (argc < 1) ! 375: fatal("-t: missing track total"); ! 376: argc--, argv++; ! 377: ntracks = atoi(*argv); ! 378: if (ntracks <= 0) ! 379: fatal("%s: bad total tracks", *argv); ! 380: goto next; ! 381: ! 382: case 'u': ! 383: if (argc < 1) ! 384: fatal("-u: missing sectors/track"); ! 385: argc--, argv++; ! 386: nsectors = atoi(*argv); ! 387: if (nsectors <= 0) ! 388: fatal("%s: bad sectors/track", *argv); ! 389: goto next; ! 390: ! 391: case 'x': ! 392: if (argc < 1) ! 393: fatal("-x: spare sectors per cylinder"); ! 394: argc--, argv++; ! 395: cylspares = atoi(*argv); ! 396: if (cylspares < 0) ! 397: fatal("%s: bad spare sectors per cylinder", *argv); ! 398: goto next; ! 399: ! 400: default: ! 401: fatal("-%c: unknown flag", *cp); ! 402: } ! 403: next: ! 404: argc--, argv++; ! 405: } ! 406: if (argc < 1) { ! 407: if (mfs) ! 408: fprintf(stderr, ! 409: "usage: mfs [ fsoptions ] special-device %s\n", ! 410: "mount-point"); ! 411: else ! 412: #ifdef COMPAT ! 413: fprintf(stderr, "usage: %s\n", ! 414: "newfs [ fsoptions ] special-device [device-type]"); ! 415: #else ! 416: fprintf(stderr, ! 417: "usage: newfs [ fsoptions ] special-device\n"); ! 418: #endif ! 419: fprintf(stderr, "where fsoptions are:\n"); ! 420: fprintf(stderr, "\t-N do not create file system, %s\n", ! 421: "just print out parameters"); ! 422: #ifdef COMPAT ! 423: fprintf(stderr, "\t-T disktype\n"); ! 424: #endif ! 425: fprintf(stderr, "\t-b block size\n"); ! 426: fprintf(stderr, "\t-f frag size\n"); ! 427: fprintf(stderr, "\t-m minimum free space %%\n"); ! 428: fprintf(stderr, "\t-o optimization preference %s\n", ! 429: "(`space' or `time')"); ! 430: fprintf(stderr, "\t-a maximum contiguous blocks\n"); ! 431: fprintf(stderr, "\t-d rotational delay between %s\n", ! 432: "contiguous blocks"); ! 433: fprintf(stderr, "\t-e maximum blocks per file in a %s\n", ! 434: "cylinder group"); ! 435: fprintf(stderr, "\t-i number of bytes per inode\n"); ! 436: fprintf(stderr, "\t-c cylinders/group\n"); ! 437: fprintf(stderr, "\t-n number of distinguished %s\n", ! 438: "rotational positions"); ! 439: fprintf(stderr, "\t-s file system size (sectors)\n"); ! 440: fprintf(stderr, "\t-r revolutions/minute\n"); ! 441: fprintf(stderr, "\t-S sector size\n"); ! 442: fprintf(stderr, "\t-u sectors/track\n"); ! 443: fprintf(stderr, "\t-t tracks/cylinder\n"); ! 444: fprintf(stderr, "\t-p spare sectors per track\n"); ! 445: fprintf(stderr, "\t-x spare sectors per cylinder\n"); ! 446: fprintf(stderr, "\t-l hardware sector interleave\n"); ! 447: fprintf(stderr, "\t-k sector 0 skew, per track\n"); ! 448: exit(1); ! 449: } ! 450: special = argv[0]; ! 451: cp = rindex(special, '/'); ! 452: if (cp != 0) ! 453: special = cp + 1; ! 454: if (*special == 'r' ! 455: #if defined(vax) || defined(tahoe) ! 456: && special[1] != 'a' && special[1] != 'b' ! 457: #endif ! 458: #if defined(hp300) ! 459: && special[1] != 'd' ! 460: #endif ! 461: ) ! 462: special++; ! 463: (void)sprintf(device, "%s/r%s", _PATH_DEV, special); ! 464: special = device; ! 465: if (!Nflag) { ! 466: fso = open(special, O_WRONLY); ! 467: if (fso < 0) { ! 468: perror(special); ! 469: exit(2); ! 470: } ! 471: } else ! 472: fso = -1; ! 473: fsi = open(special, O_RDONLY); ! 474: if (fsi < 0) { ! 475: perror(special); ! 476: exit(3); ! 477: } ! 478: if (fstat(fsi, &st) < 0) { ! 479: fprintf(stderr, "%s: ", progname); perror(special); ! 480: exit(4); ! 481: } ! 482: if ((st.st_mode & S_IFMT) != S_IFCHR) ! 483: fatal("%s: not a character device", special); ! 484: cp = index(argv[0], '\0') - 1; ! 485: if (cp == 0 || (*cp < 'a' || *cp > 'h') && !isdigit(*cp)) ! 486: fatal("%s: can't figure out file system partition", argv[0]); ! 487: #ifdef COMPAT ! 488: if (!mfs && disktype == NULL) ! 489: disktype = argv[1]; ! 490: #endif ! 491: lp = getdisklabel(special, fsi); ! 492: if (isdigit(*cp)) ! 493: pp = &lp->d_partitions[0]; ! 494: else ! 495: pp = &lp->d_partitions[*cp - 'a']; ! 496: if (pp->p_size == 0) ! 497: fatal("%s: `%c' partition is unavailable", argv[0], *cp); ! 498: if (fssize == 0) ! 499: fssize = pp->p_size; ! 500: if (fssize > pp->p_size && !mfs) ! 501: fatal("%s: maximum file system size on the `%c' partition is %d", ! 502: argv[0], *cp, pp->p_size); ! 503: if (rpm == 0) { ! 504: rpm = lp->d_rpm; ! 505: if (rpm <= 0) ! 506: rpm = 3600; ! 507: } ! 508: if (ntracks == 0) { ! 509: ntracks = lp->d_ntracks; ! 510: if (ntracks <= 0) ! 511: fatal("%s: no default #tracks", argv[0]); ! 512: } ! 513: if (nsectors == 0) { ! 514: nsectors = lp->d_nsectors; ! 515: if (nsectors <= 0) ! 516: fatal("%s: no default #sectors/track", argv[0]); ! 517: } ! 518: if (sectorsize == 0) { ! 519: sectorsize = lp->d_secsize; ! 520: if (sectorsize <= 0) ! 521: fatal("%s: no default sector size", argv[0]); ! 522: } ! 523: if (trackskew == -1) { ! 524: trackskew = lp->d_trackskew; ! 525: if (trackskew < 0) ! 526: trackskew = 0; ! 527: } ! 528: if (interleave == 0) { ! 529: interleave = lp->d_interleave; ! 530: if (interleave <= 0) ! 531: interleave = 1; ! 532: } ! 533: if (fsize == 0) { ! 534: fsize = pp->p_fsize; ! 535: if (fsize <= 0) ! 536: fsize = MAX(DFL_FRAGSIZE, lp->d_secsize); ! 537: } ! 538: if (bsize == 0) { ! 539: bsize = pp->p_frag * pp->p_fsize; ! 540: if (bsize <= 0) ! 541: bsize = MIN(DFL_BLKSIZE, 8 * fsize); ! 542: } ! 543: if (density == 0) ! 544: density = NFPI * fsize; ! 545: if (minfree < 10 && opt != FS_OPTSPACE) { ! 546: fprintf(stderr, "Warning: changing optimization to space "); ! 547: fprintf(stderr, "because minfree is less than 10%%\n"); ! 548: opt = FS_OPTSPACE; ! 549: } ! 550: if (trackspares == -1) { ! 551: trackspares = lp->d_sparespertrack; ! 552: if (trackspares < 0) ! 553: trackspares = 0; ! 554: } ! 555: nphyssectors = nsectors + trackspares; ! 556: if (cylspares == -1) { ! 557: cylspares = lp->d_sparespercyl; ! 558: if (cylspares < 0) ! 559: cylspares = 0; ! 560: } ! 561: secpercyl = nsectors * ntracks - cylspares; ! 562: if (secpercyl != lp->d_secpercyl) ! 563: fprintf(stderr, "%s (%d) %s (%d)\n", ! 564: "Warning: calculated sectors per cylinder", secpercyl, ! 565: "disagrees with disk label", lp->d_secpercyl); ! 566: if (maxbpg == 0) ! 567: maxbpg = MAXBLKPG(bsize); ! 568: headswitch = lp->d_headswitch; ! 569: trackseek = lp->d_trkseek; ! 570: /* Reno fix: label may be 0 if faked up by kernel */ ! 571: #ifdef notdef ! 572: bbsize = lp->d_bbsize; ! 573: sbsize = lp->d_sbsize; ! 574: #endif ! 575: oldpartition = *pp; ! 576: #ifdef tahoe ! 577: realsectorsize = sectorsize; ! 578: if (sectorsize != DEV_BSIZE) { /* XXX */ ! 579: int secperblk = DEV_BSIZE / sectorsize; ! 580: ! 581: sectorsize = DEV_BSIZE; ! 582: nsectors /= secperblk; ! 583: nphyssectors /= secperblk; ! 584: secpercyl /= secperblk; ! 585: fssize /= secperblk; ! 586: pp->p_size /= secperblk; ! 587: } ! 588: #endif ! 589: mkfs(pp, special, fsi, fso); ! 590: #ifdef tahoe ! 591: if (realsectorsize != DEV_BSIZE) ! 592: pp->p_size *= DEV_BSIZE / realsectorsize; ! 593: #endif ! 594: if (!Nflag && bcmp(pp, &oldpartition, sizeof(oldpartition))) ! 595: rewritelabel(special, fso, lp); ! 596: if (!Nflag) ! 597: close(fso); ! 598: close(fsi); ! 599: if (mfs) { ! 600: sprintf(buf, "mfs:%d", getpid()); ! 601: args.name = buf; ! 602: args.base = membase; ! 603: args.size = fssize * sectorsize; ! 604: if (mount(MOUNT_MFS, argv[1], mntflags, &args) < 0) { ! 605: perror("mfs: mount"); ! 606: exit(5); ! 607: } ! 608: } ! 609: exit(0); ! 610: } ! 611: ! 612: #ifdef COMPAT ! 613: char lmsg[] = "%s: can't read disk label; disk type must be specified"; ! 614: #else ! 615: char lmsg[] = "%s: can't read disk label"; ! 616: #endif ! 617: ! 618: struct disklabel * ! 619: getdisklabel(s, fd) ! 620: char *s; ! 621: int fd; ! 622: { ! 623: static struct disklabel lab; ! 624: ! 625: if (ioctl(fd, DIOCGDINFO, (char *)&lab) < 0) { ! 626: #ifdef COMPAT ! 627: if (disktype) { ! 628: struct disklabel *getdiskbyname(); ! 629: ! 630: unlabelled++; ! 631: return (getdiskbyname(disktype)); ! 632: } ! 633: #endif ! 634: perror("ioctl (GDINFO)"); ! 635: fatal(lmsg, s); ! 636: } ! 637: return (&lab); ! 638: } ! 639: ! 640: rewritelabel(s, fd, lp) ! 641: char *s; ! 642: int fd; ! 643: register struct disklabel *lp; ! 644: { ! 645: ! 646: #ifdef COMPAT ! 647: if (unlabelled) ! 648: return; ! 649: #endif ! 650: lp->d_checksum = 0; ! 651: lp->d_checksum = dkcksum(lp); ! 652: if (ioctl(fd, DIOCWDINFO, (char *)lp) < 0) { ! 653: perror("ioctl (WDINFO)"); ! 654: fatal("%s: can't rewrite disk label", s); ! 655: } ! 656: #if vax ! 657: if (lp->d_type == DTYPE_SMD && lp->d_flags & D_BADSECT) { ! 658: register i; ! 659: int cfd; ! 660: daddr_t alt; ! 661: char specname[64]; ! 662: char blk[1024]; ! 663: char *cp; ! 664: ! 665: /* ! 666: * Make name for 'c' partition. ! 667: */ ! 668: strcpy(specname, s); ! 669: cp = specname + strlen(specname) - 1; ! 670: if (!isdigit(*cp)) ! 671: *cp = 'c'; ! 672: cfd = open(specname, O_WRONLY); ! 673: if (cfd < 0) { ! 674: perror(specname); ! 675: exit(6); ! 676: } ! 677: bzero(blk, sizeof(blk)); ! 678: *(struct disklabel *)(blk + LABELOFFSET) = *lp; ! 679: alt = lp->d_ncylinders * lp->d_secpercyl - lp->d_nsectors; ! 680: for (i = 1; i < 11 && i < lp->d_nsectors; i += 2) { ! 681: if (lseek(cfd, (off_t)(alt + i) * lp->d_secsize, L_SET) == -1) { ! 682: perror("lseek to badsector area"); ! 683: exit(7); ! 684: } ! 685: if (write(cfd, blk, lp->d_secsize) < lp->d_secsize) { ! 686: int oerrno = errno; ! 687: fprintf(stderr, "alternate label %d ", i/2); ! 688: errno = oerrno; ! 689: perror("write"); ! 690: } ! 691: } ! 692: close(cfd); ! 693: } ! 694: #endif ! 695: } ! 696: ! 697: /*VARARGS*/ ! 698: fatal(fmt, arg1, arg2) ! 699: char *fmt; ! 700: { ! 701: ! 702: fprintf(stderr, "%s: ", progname); ! 703: fprintf(stderr, fmt, arg1, arg2); ! 704: putc('\n', stderr); ! 705: exit(8); ! 706: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.