Annotation of coherent/d/etc/fsck.tar, revision 1.1
1.1 ! root 1: fsck/Makefile 644 3 3 1224 5045007365 6404 #
! 2: # for Inetco : CFLAGS = -O -DHPCOHERENT
! 3: # for PDP-11 : CFLAGS = -O
! 4: # others : CFLAGS =
! 5: #
! 6:
! 7: DESTDIR=/interim/etc/
! 8: CFLAGS = -O
! 9: #
! 10: # for PDP-11 and IBM PC: LFLAGS = -i
! 11: # for Z8000 : LFLAGS =
! 12: #
! 13: LFLAGS = -i
! 14: OBJ=main.o init.o phase1.o phase1b.o phase2.o phase3.o phase4.o phase5.o\
! 15: phase6.o cleanup.o util.o printf.o link.o virtual.o is_fs.o
! 16:
! 17: fsck: $(OBJ)
! 18: $(CC) $(CFLAGS) $(LFLAGS) -o $(DESTDIR)fsck $(OBJ)
! 19:
! 20: #
! 21: # for IBM PC Coherent executable, use: -DNBLK=1
! 22: # for others, use : -DNBLK=8
! 23: #
! 24: # If you are running out of malloc space, try lowering the
! 25: # value of NBLK (no smaller than 1).
! 26: #
! 27:
! 28: util.o: util.c
! 29: $(CC) -c $(CFLAGS) $< -DNBLK=8
! 30:
! 31: $(OBJ): fsck.h
! 32: M PC: LFLAGS = -i
! 33: # for Z8000 : LFLAGS =
! 34: #
! 35: LFLAGS = -i
! 36: OBJ=main.o init.o phase1.o phase1b.o phase2.o phase3.o phase4.o phase5.o\
! 37: phase6.o cleanup.o util.o printf.o link.o virtual.o is_fs.o
! 38:
! 39: fsck: $(OBJ)
! 40: $(CC) $(CFLAGS) $(LFLAGS) -o $(DESTDIR)fsck $(OBJ)
! 41:
! 42: #
! 43: # for IBM PC Coherent executable, use: -DNBLK=1
! 44: # for others, use : -DNBLK=8
! 45: #
! 46: # If you are rfsck/RCS/ 755 3 3 0 5050254740 5304 fsck/RCS/Makefile,v 444 3 3 2644 5045006646 7303 head 1.3;
! 47: branch ;
! 48: access ;
! 49: symbols ;
! 50: locks bin:1.3;
! 51: comment @@;
! 52:
! 53:
! 54: 1.3
! 55: date 91.07.29.07.44.07; author bin; state Exp;
! 56: branches ;
! 57: next 1.2;
! 58:
! 59: 1.2
! 60: date 91.03.15.18.33.07; author bin; state Exp;
! 61: branches ;
! 62: next 1.1;
! 63:
! 64: 1.1
! 65: date 91.02.08.13.26.09; author bin; state Exp;
! 66: branches ;
! 67: next ;
! 68:
! 69:
! 70: desc
! 71: @initial version provided byinitial version provided by epstein
! 72: @
! 73:
! 74:
! 75: 1.3
! 76: log
! 77: @Updated by epstein for version 321.
! 78: @
! 79: text
! 80: @#
! 81: # for Inetco : CFLAGS = -O -DHPCOHERENT
! 82: # for PDP-11 : CFLAGS = -O
! 83: # others : CFLAGS =
! 84: #
! 85: CFLAGS = -O
! 86: #
! 87: # for PDP-11 and IBM PC: LFLAGS = -i
! 88: # for Z8000 : LFLAGS =
! 89: #
! 90: LFLAGS = -i
! 91: OBJ=main.o init.o phase1.o phase1b.o phase2.o phase3.o phase4.o phase5.o\
! 92: phase6.o cleanup.o util.o printf.o link.o virtual.o is_fs.o
! 93:
! 94: fsck: $(OBJ)
! 95: $(CC) $(CFLAGS) $(LFLAGS) -o fsck $(OBJ)
! 96:
! 97: #
! 98: # for IBM PC Coherent executable, use: -DNBLK=1
! 99: # for others, use : -DNBLK=8
! 100: #
! 101: # If you are running out of malloc space, try lowering the
! 102: # value of NBLK (no smaller than 1).
! 103: #
! 104:
! 105: util.o: util.c
! 106: $(CC) -c $(CFLAGS) util.c -DNBLK=8
! 107:
! 108: $(OBJ): fsck.h
! 109: @
! 110:
! 111:
! 112: 1.2
! 113: log
! 114: @bob h added destdir, ownership, permissions...
! 115: @
! 116: text
! 117: @a6 1
! 118: DESTDIR = /interim/etc/
! 119: d16 2
! 120: a17 4
! 121: $(CC) $(CFLAGS) $(LFLAGS) -o $(DESTDIR)fsck $(OBJ)
! 122: su root chown bin $(DESTDIR)$@@
! 123: su root chgrp bin $(DESTDIR)$@@
! 124: su root chmod 511 $(DESTDIR)$@@
! 125: @
! 126:
! 127:
! 128: 1.1
! 129: log
! 130: @Initial revision
! 131: @
! 132: text
! 133: @d7 1
! 134: d17 4
! 135: a20 2
! 136: $(CC) $(CFLAGS) $(LFLAGS) -o fsck $(OBJ)
! 137:
! 138: @
! 139: unning out of malloc space, try lowering the
! 140: # value of NBLK (no smaller than 1).
! 141: #
! 142:
! 143: util.o:fsck/RCS/READ_ME,v 444 3 3 1565 4754523421 6664 head 1.1;
! 144: access ;
! 145: symbols ;
! 146: locks ;
! 147: comment @@;
! 148:
! 149:
! 150: 1.1
! 151: date 91.02.08.13.26.37; author bin; state Exp;
! 152: branches ;
! 153: next ;
! 154:
! 155:
! 156: desc
! 157: @updated version provided by epstein
! 158: @
! 159:
! 160:
! 161:
! 162: 1.1
! 163: log
! 164: @Initial revision
! 165: @
! 166: text
! 167: @Ideas for improving the performance of fsck:
! 168:
! 169: (1) Utilize a different mechanism for storing the (struct direct)
! 170: entries throughout phase2.c, to remove implicit memory intensive
! 171: redundancy.
! 172:
! 173: (2) Encode the number of links per i-node count differently, in order
! 174: to save space taking advantage of the typical usage under Coherent.
! 175:
! 176: (3) Arrange space for the tables in a total needed way to avoid later
! 177: fragmentation problems affecting the memory requests for successive
! 178: file systems.
! 179:
! 180: (4) Devise a more clever buffering scheme for the blocks containing
! 181: i-nodes to understand the differences between phase1, phase2, and
! 182: phase4.
! 183: @
! 184: ove implicit memory intensive
! 185: redundancy.
! 186:
! 187: (2) Encode the number of links per i-node count differently, in order
! 188: to save space tfsck/RCS/cleanup.c,v 444 3 3 2652 4753557355 7452 head 1.1;
! 189: access ;
! 190: symbols ;
! 191: locks ;
! 192: comment @ * @;
! 193:
! 194:
! 195: 1.1
! 196: date 91.02.05.16.35.30; author bin; state Exp;
! 197: branches ;
! 198: next ;
! 199:
! 200:
! 201: desc
! 202: @provided by Mark Epstein
! 203: @
! 204:
! 205:
! 206:
! 207: 1.1
! 208: log
! 209: @Initial revision
! 210: @
! 211: text
! 212: @/*
! 213: * Cleanup functions for phases of fsck
! 214: */
! 215:
! 216: #include "fsck.h"
! 217:
! 218: cleanup()
! 219: {
! 220: int retval = 0;
! 221:
! 222: if (sbpfix == TRUE)
! 223: writesuper();
! 224: prtstats();
! 225: if (changeflg == TRUE)
! 226: retval = advise();
! 227: close(fsfd);
! 228: cleanV();
! 229: return(retval);
! 230: }
! 231:
! 232: writesuper()
! 233: {
! 234: register int i;
! 235:
! 236: canshort(sbp->s_isize);
! 237: candaddr(sbp->s_fsize);
! 238: canshort(sbp->s_nfree);
! 239: for(i=0; i<NICFREE; i++)
! 240: candaddr(sbp->s_free[i]);
! 241: canshort(sbp->s_ninode);
! 242: for(i=0; i<NICINOD; i++)
! 243: canino(sbp->s_inode[i]);
! 244: cantime(sbp->s_time);
! 245: candaddr(sbp->s_tfree);
! 246: canino(sbp->s_tinode);
! 247: canshort(sbp->s_m);
! 248: canshort(sbp->s_n);
! 249: canlong(sbp->s_unique);
! 250:
! 251: bwrite((daddr_t)SUPERI, sbp);
! 252: }
! 253:
! 254: prtstats()
! 255: {
! 256: if (!fflag)
! 257: printf("%u files ", numfiles);
! 258: printf("%U blocks ", fsize - isize - totfree);
! 259: printf("%U free\n", totfree);
! 260: if ( lostsize ) {
! 261: lostsize = (lostsize + BSIZE - 1)/BSIZE;
! 262: printf("Expect roughly %U missing block%s next\n", lostsize,
! 263: (lostsize!=1) ? "s" : "" );
! 264: printf("time fsck is run as a result of inodes ");
! 265: printf("being cleared.\n");
! 266: }
! 267: }
! 268:
! 269: advise()
! 270: {
! 271: int retval = 0;
! 272:
! 273: printf(" ***** File System %s was modified *****\n", fsname);
! 274: if ( mounted ) {
! 275: printf(" ***** BOOT Coherent (NO SYNC!) *****\n");
! 276: retval = 1;
! 277: }
! 278: return(retval);
! 279: }
! 280: @
! 281: ocks ", fsize - isize - totfree);
! 282: printf("%U free\n", totfree);
! 283: if ( lostsize ) {
! 284: fsck/RCS/fsck.h,v 444 3 3 14557 4771205357 6775 head 1.2;
! 285: access ;
! 286: symbols ;
! 287: locks bin:1.2;
! 288: comment @ * @;
! 289:
! 290:
! 291: 1.2
! 292: date 91.03.18.18.45.54; author bin; state Exp;
! 293: branches ;
! 294: next 1.1;
! 295:
! 296: 1.1
! 297: date 91.02.08.13.26.49; author bin; state Exp;
! 298: branches ;
! 299: next ;
! 300:
! 301:
! 302: desc
! 303: @updated version provided by epstein
! 304: @
! 305:
! 306:
! 307: 1.2
! 308: log
! 309: @update provided by epstein
! 310: @
! 311: text
! 312: @/*
! 313: * Header file for fsck -- File System Check Program
! 314: *
! 315: */
! 316:
! 317: #include <canon.h>
! 318: #include <sys/dir.h>
! 319: #include <sys/fblk.h>
! 320: #include <sys/filsys.h>
! 321: #include <sys/ino.h>
! 322: #include <sys/stat.h>
! 323: #include <sys/types.h>
! 324: #include <time.h>
! 325:
! 326: #if HPCOHERENT
! 327: typedef long fsize_t;
! 328: #endif
! 329:
! 330: /*
! 331: * Conditional Compilation Flags
! 332: */
! 333:
! 334: #define NOT_ALL_ZERO_INODE /* Dependent on whether or not an inode */
! 335: #ifdef ALL_ZERO_INODE /* is totally zeroed when unallocated */
! 336: #undef ALL_ZERO_INODE /* or simply a zero mode and zero link */
! 337: #endif
! 338:
! 339:
! 340: /*
! 341: * Definitions and Externs
! 342: */
! 343:
! 344: #define NUL 0 /* true zero ! */
! 345: #define NULL ((char *)0)
! 346:
! 347: #define YES 3 /* default actions */
! 348: #define NO 2
! 349: #define ASK 1
! 350:
! 351: #define NFILSYS 10 /* max number of file systems */
! 352: #define MAXCH 20 /* max length of filesys name */
! 353:
! 354: #define MAXBADOK 10 /* Max number of bad blocks before excessive */
! 355: extern int numbad; /* num bad blocks found so far this inode*/
! 356:
! 357: #define MAXDUPOK 10 /* Max number of dup blocks */
! 358: /* in a single inode before excessive */
! 359: #define DUPTBLSIZE 20 /* Max number of dup referenced blocks */
! 360: extern daddr_t dupblck[]; /* table of duplicate referenced blocks */
! 361: extern int totdups; /* number of dup blocks found so far */
! 362:
! 363: #define MAXBADFREE 10 /* max bad in free list before abort */
! 364: #define MAXDUPFREE 10 /* max dup in free list before abort */
! 365:
! 366: #define GOOD 1 /* returned by bad() in util.c */
! 367: #define BAD 0
! 368:
! 369: #define TRUE 1 /* errflag possibilities */
! 370: #define FALSE 0
! 371: extern int errflag; /* errflag indicates not to do phases */
! 372:
! 373: #define OK 1 /* used to indicate excessive bad/dup */
! 374: #define STOP 0 /* blocks in an inode in phase1.c */
! 375: #define BAD_DUP 2
! 376:
! 377: #define FIRSTIN 2 /* First real inode number */
! 378:
! 379: #define ND 10 /* Number of Direct Blocks */
! 380: #undef NI
! 381: #define NI 1
! 382: #define NII 1
! 383: #define NIII 1
! 384: #undef NADDR
! 385: #define NADDR (ND+NI+NII+NIII)
! 386: extern int offsets[]; /* table of offsets for level of indirection */
! 387: /* for the blocks in an inode */
! 388:
! 389: extern char nextchar(); /* used in util.c */
! 390: extern int fsfd; /* file system file descriptor */
! 391: extern int mdaction; /* default action for this invocation */
! 392: extern int daction; /* default action for current file system */
! 393: extern int writeflg; /* system write ok or read-only */
! 394: extern int qflag; /* quiet fsck flag */
! 395: extern int fflag; /* fast fsck flag */
! 396: extern int sflag; /* force free list salvation */
! 397: extern daddr_t fsize; /* file system size in blocks */
! 398: extern int isize; /* first block not in inode list */
! 399: /* isize is NOT unsigned so that comparisons */
! 400: /* with longs will not cast the long to */
! 401: /* unsigned thus producing confusing results */
! 402:
! 403: extern daddr_t totfree; /* running count of total free blocks */
! 404: extern unsigned ninodes;/* Number of inodes in the files system */
! 405: extern char *fsname; /* file system name */
! 406: extern fsize_t pinfo(); /* returns size of file, in phase2.c */
! 407: extern ino_t lostfound(); /* returns inumber of lost+found dir */
! 408: extern struct dinode *ptrino(); /* returns a ptr to inode, give number */
! 409: extern char databuf[]; /* buffer to read in block, used throughout */
! 410: extern char buf2[]; /* alternate data buffer */
! 411: extern daddr_t cdbn; /* current block number, used by nextblock() */
! 412: #define DSIZE (sizeof(struct direct))
! 413: extern char *lostname; /* name of lost+found directory */
! 414: extern char *nameit(); /* nameing function for lost dirs and files */
! 415: extern int depth; /* used during tree traversal in phase2.c */
! 416: extern struct direct *path[]; /* used during tree traversal in phase2.c */
! 417: extern char *typename(); /* return string to type of inode */
! 418: extern struct filsys *sbp; /* Super Block */
! 419: extern int sbpfix; /* flag for super block fixes */
! 420: extern struct stat stats; /* used by statit() in util.c */
! 421: extern dev_t rootdev; /* root device number */
! 422: extern dev_t fsysrdev; /* file system real device number */
! 423: extern int mounted; /* flag indicating mountedness of filesystem */
! 424: extern int changeflg; /* file system modified flag */
! 425: extern int fixerup; /* flag to rebuild free list */
! 426: extern char *fixit; /* Prompt message phase[45].c */
! 427: extern int numfiles; /* num files in system */
! 428: extern daddr_t imap(); /* function for disk block mapping in util.c */
! 429: extern fsize_t lostsize; /* Size of files cleared in phase4.c */
! 430: extern char *tmpfile; /* TMP File name for virtual.c */
! 431:
! 432: #define SUCCESS 1 /* used in connect() in phase3.c */
! 433: #define FAILURE 0
! 434:
! 435: #define MODEMASK 0x07
! 436: #define ALLOCMASK 0x06
! 437: #define UNALLOC 0x00
! 438: #define UNKNOWN 0x01
! 439: #define IDIR 0x02
! 440: #define IREG 0x03
! 441: #define ICHR 0x04
! 442: #define IBLK 0x05
! 443: #define IPIPE 0x06
! 444: #define IBAD_IDUP 0x08
! 445: #define VISITED 0x10
! 446: #define UNREFDIR 0x20
! 447: #define CHILDDIR 0x40
! 448: #define IFREELIST 0x80
! 449:
! 450: /*
! 451: * Macros for tables
! 452: */
! 453:
! 454: #define LOGNBPC 3 /* Log2 Number of Bits per Character */
! 455:
! 456: /* Actions for virtual block system */
! 457: enum vact { testBlock, markBlock, unmarkBlock, grabBlock,
! 458: testDup, markDup, unmarkDup, setDup,
! 459: Flags, setFlags, orFlags,
! 460: linkCtr, incLinkctr, setLinkctr };
! 461:
! 462: #define testblock(bn) findblock((unsigned long)(bn), testBlock)
! 463: #define markblock(bn) findblock((unsigned long)(bn), markBlock)
! 464: #define unmarkblock(bn) findblock((unsigned long)(bn), unmarkBlock)
! 465:
! 466: #define testdup(bn) findblock((unsigned long)(bn), testDup)
! 467: #define markdup(bn) findblock((unsigned long)(bn), markDup)
! 468: #define unmarkdup(bn) findblock((unsigned long)(bn), unmarkDup)
! 469:
! 470: #define flags(ino) findblock((unsigned long)(ino), Flags)
! 471: #define setflags(ino, data) findblock((unsigned long)(ino), setFlags, data)
! 472: #define orflags(ino, data) findblock((unsigned long)(ino), orFlags, data)
! 473:
! 474: #define linkctr(ino) findblock((unsigned long)(ino), linkCtr)
! 475: #define inclinkctr(ino) findblock((unsigned long)(ino), incLinkctr)
! 476: #define setlinkctr(ino, data) findblock((unsigned long)(ino), setLinkctr, data)
! 477:
! 478: #define badblks(ino) ( flags(ino)&IBAD_IDUP )
! 479:
! 480: /*
! 481: * Miscellany
! 482: */
! 483:
! 484: #define NBPC 8 /* number of bits per character */
! 485: #define MAXINTN 255 /* used for interleave table */
! 486: /* in phase6.c */
! 487: /*
! 488: * Stdio Stuff
! 489: */
! 490:
! 491: #define putchar(c) { char b = c; write(1, &b, 1); }
! 492: extern char *malloc();
! 493: extern char *calloc();
! 494:
! 495: @
! 496:
! 497:
! 498: 1.1
! 499: log
! 500: @Initial revision
! 501: @
! 502: text
! 503: @d85 1
! 504: @
! 505: ne inclinkctr(ino) findblock((unsigned long)(ino), incLinkctr)
! 506: #define setlinkctr(ino, data) findblock((unsigned long)(ino), setLinkctr, data)
! 507:
! 508: #fsck/RCS/init.c,v 444 3 3 14501 5045006666 6767 head 1.2;
! 509: branch ;
! 510: access ;
! 511: symbols ;
! 512: locks bin:1.2;
! 513: comment @ * @;
! 514:
! 515:
! 516: 1.2
! 517: date 91.07.29.07.44.33; author bin; state Exp;
! 518: branches ;
! 519: next 1.1;
! 520:
! 521: 1.1
! 522: date 91.02.05.16.36.03; author bin; state Exp;
! 523: branches ;
! 524: next ;
! 525:
! 526:
! 527: desc
! 528: @prov by epstein
! 529: @
! 530:
! 531:
! 532: 1.2
! 533: log
! 534: @Updated by epstein for version 321.
! 535: @
! 536: text
! 537: @/*
! 538: * Perform initialization for phases of fsck
! 539: */
! 540: #include "fsck.h"
! 541: #include <mnttab.h>
! 542: #include <mtab.h>
! 543:
! 544: int fsfd; /* file system file descriptor */
! 545: int writeflg; /* write ok or read-only flag */
! 546: daddr_t fsize = SUPERI+1; /* file system size in blocks */
! 547: /* Allows for read of Super Block */
! 548: int isize; /* First block not in inode list */
! 549: daddr_t totfree; /* Running total free block count */
! 550: unsigned ninodes; /* number of inodes */
! 551: int numfiles; /* number of files in file system */
! 552:
! 553: char superb[BSIZE]; /* Super Block */
! 554: struct filsys *sbp = superb;
! 555: int sbpfix; /* flag for super block fixes */
! 556:
! 557: int offsets[] = /* table of offsets for the levels */
! 558: { ND, ND+NI, ND+NI+NII, /* of indirection of blocks in the */
! 559: ND+NI+NII+NIII }; /* inode block list */
! 560:
! 561: daddr_t dupblck[DUPTBLSIZE]; /* duplicate referenced blocks */
! 562: int totdups; /* number of dup blocks so far */
! 563:
! 564: init()
! 565: {
! 566: int mode;
! 567: struct stat status;
! 568: unsigned short stmode;
! 569:
! 570: mode = (mdaction == NO) ? 0 : 2;
! 571:
! 572: if ( (fsfd = open(fsname, mode)) == (-1) ) {
! 573: mode = 0;
! 574: if ( (fsfd = open(fsname, mode)) == (-1) ) {
! 575: nonfatal("Can't open: %s", fsname);
! 576: return;
! 577: }
! 578: }
! 579:
! 580: if (mode == 0) {
! 581: daction = NO;
! 582: writeflg = FALSE;
! 583: } else {
! 584: daction = mdaction;
! 585: writeflg = TRUE;
! 586: }
! 587:
! 588: printf("%s: %s\n", fsname, (mode == 0) ? "(NO WRITE)" : "");
! 589:
! 590: if ( fstat(fsfd, &status) == (-1) ) {
! 591: nonfatal("Can't stat: %s", fsname);
! 592: return;
! 593: }
! 594:
! 595: stmode = status.st_mode & S_IFMT;
! 596: if ( (stmode != S_IFBLK) && (stmode != S_IFCHR) )
! 597: switch(query("file is not a block or character device; OK?")){
! 598: case YES:
! 599: break;
! 600: case NO:
! 601: errflag = TRUE;
! 602: return;
! 603: }
! 604:
! 605: domount();
! 606: sbpfix = FALSE;
! 607: readsuper();
! 608: checksuper();
! 609: if ( !errflag )
! 610: alloctables();
! 611: }
! 612:
! 613: /*
! 614: * Read in the super block and canonicalize
! 615: */
! 616:
! 617: readsuper()
! 618: {
! 619: register int i;
! 620:
! 621: bread((daddr_t)SUPERI, superb);
! 622: sbp = superb;
! 623:
! 624: canshort(sbp->s_isize);
! 625: candaddr(sbp->s_fsize);
! 626: canshort(sbp->s_nfree);
! 627: for(i=0; i<NICFREE; i++)
! 628: candaddr(sbp->s_free[i]);
! 629: canshort(sbp->s_ninode);
! 630: for(i=0; i<NICINOD; i++)
! 631: canino(sbp->s_inode[i]);
! 632: cantime(sbp->s_time);
! 633: candaddr(sbp->s_tfree);
! 634: canino(sbp->s_tinode);
! 635: canshort(sbp->s_m);
! 636: canshort(sbp->s_n);
! 637: canlong(sbp->s_unique);
! 638:
! 639: }
! 640:
! 641: /*
! 642: * Check super block for obvious inconsistencies
! 643: */
! 644:
! 645: checksuper()
! 646: {
! 647: fsize = sbp->s_fsize;
! 648: isize = sbp->s_isize;
! 649: totfree = fsize - isize;
! 650:
! 651: if ( (isize<=INODEI) || (isize>=fsize) || (fsize<=INODEI) ) {
! 652: badsuper("Size check: fsize %U isize %u", fsize, isize);
! 653: errflag = TRUE;
! 654: }
! 655:
! 656: if ( sbp->s_nfree > NICFREE )
! 657: badsuper("Too large free block count");
! 658:
! 659: if ( sbp->s_ninode > NICINOD )
! 660: badsuper("Too large free i-node count");
! 661: }
! 662:
! 663: /*
! 664: * Super Block Error Functions
! 665: */
! 666:
! 667: badsuper(x)
! 668: {
! 669: printf("%r\n", &x);
! 670: printf("fsck: %s: Bad Super Block: %u\n", fsname, SUPERI);
! 671: }
! 672:
! 673: /*
! 674: * Allocate the necessary buffers for tables
! 675: */
! 676:
! 677: alloctables()
! 678: {
! 679: unsigned num, numl;
! 680:
! 681: numl = 0;
! 682: if (!fflag) {
! 683: ninodes = (unsigned) (isize - INODEI) * INOPB;
! 684: numl = (unsigned) ninodes;
! 685: }
! 686:
! 687: num = (unsigned) ((fsize+NBPC-1)/NBPC) * sizeof(char);
! 688: initV(numl, numl, num, num); /* virtual allocation */
! 689:
! 690: numfiles = /* number of files in the file system */
! 691: totdups = 0; /* num dup blocks */
! 692: }
! 693:
! 694: /*
! 695: * domount() checks the files /etc/mnttab and /etc/mtab to find
! 696: * out where the file system is mounted (if at all). It then
! 697: * reports where (and when if possible) it was last mounted.
! 698: */
! 699: char *mnttab_name = "/etc/mnttab";
! 700: char *mtab_name = "/etc/mtab";
! 701: char *bttime_name = "/etc/boottime";
! 702:
! 703: domount()
! 704: {
! 705: int fd;
! 706: struct mnttab mnttab;
! 707: struct mtab mtab;
! 708: register char *name;
! 709: struct stat sbuf;
! 710: time_t boottime;
! 711: int nothing();
! 712: char devname[MNTNSIZ+6] = "/dev/";
! 713:
! 714: mounted = FALSE;
! 715: name = fsname; /* strip off all initial */
! 716: while (*name++ != '\0') ; /* directories in fsname */
! 717: while ( (*--name != '/') && (name>fsname) ) ;
! 718: if (*name == '/') name++;
! 719:
! 720: if ( stat(bttime_name, &sbuf) == -1 )
! 721: boottime = (time_t)0;
! 722: else
! 723: boottime = sbuf.st_mtime;
! 724:
! 725: if ( (fd=open(mnttab_name, 0)) != (-1) ) {
! 726: while ( read(fd, &mnttab, sizeof(mnttab))==sizeof(mnttab) )
! 727: if ( mnttab.mt_dev[0] && mnttab.mt_filsys[0] ) {
! 728: strncpy(&devname[5], mnttab.mt_filsys, MNTNSIZ);
! 729: devname[MNTNSIZ+5] = '\0';
! 730: statit(devname, nothing);
! 731: if (stats.st_rdev != fsysrdev)
! 732: continue;
! 733: statit(mnttab.mt_dev, nothing);
! 734: mounted = (stats.st_dev == fsysrdev);
! 735: prmnttab(&mnttab, boottime);
! 736: return;
! 737: }
! 738: }
! 739: if ( (fd=open(mtab_name, 0)) != (-1) ) {
! 740: while ( read(fd, &mtab, sizeof(mtab))==sizeof(mtab) )
! 741: if ( mtab.mt_name[0] && mtab.mt_special[0] ) {
! 742: strncpy(&devname[5], mtab.mt_special, MNAMSIZ);
! 743: devname[MNAMSIZ+5] = '\0';
! 744: statit(devname, nothing);
! 745: if (stats.st_rdev != fsysrdev)
! 746: continue;
! 747: statit(mtab.mt_name, nothing);
! 748: mounted = (stats.st_dev == fsysrdev);
! 749: prmtab(&mtab);
! 750: return;
! 751: }
! 752: }
! 753:
! 754: if (fsysrdev == rootdev)
! 755: mounted = TRUE;
! 756: else
! 757: mounted = FALSE;
! 758:
! 759: }
! 760:
! 761: prmnttab(ptr, boottime)
! 762: struct mnttab *ptr;
! 763: time_t boottime;
! 764: {
! 765: if (mounted) {
! 766: if (boottime < ptr->mt_time)
! 767: boottime = ptr->mt_time;
! 768: printf("%s mounted on %.*s as of %s", fsname, MNTNSIZ,
! 769: ptr->mt_dev, ctime(&boottime));
! 770: } else
! 771: printf("%s unmounted. Last mounted on %.*s -- %s",
! 772: fsname, MNTNSIZ, ptr->mt_dev,
! 773: ctime(&ptr->mt_time));
! 774: }
! 775:
! 776:
! 777: prmtab(ptr)
! 778: struct mtab *ptr;
! 779: {
! 780: if (mounted)
! 781: printf("%s mounted on %.*s\n", fsname, MNAMSIZ, ptr->mt_name);
! 782: else
! 783: printf("%s unmounted. Last mounted on %.*s\n", fsname,
! 784: MNAMSIZ, ptr->mt_name);
! 785: }
! 786:
! 787: nothing()
! 788: {}
! 789: @
! 790:
! 791:
! 792: 1.1
! 793: log
! 794: @Initial revision
! 795: @
! 796: text
! 797: @d176 1
! 798: d178 1
! 799: d191 11
! 800: a201 10
! 801: if (mnttab.mt_dev[0] != '\0')
! 802: if ( strcmp(name, mnttab.mt_filsys) == 0 ) {
! 803: statit(mnttab.mt_dev, nothing);
! 804: if (stats.st_dev == fsysrdev)
! 805: mounted = TRUE;
! 806: else
! 807: mounted = FALSE;
! 808: prmnttab(&mnttab, boottime);
! 809: return;
! 810: }
! 811: d205 11
! 812: a215 10
! 813: if (mtab.mt_name[0] != '\0')
! 814: if ( strcmp(name, mtab.mt_special) == 0 ) {
! 815: statit(mtab.mt_name, nothing);
! 816: if (stats.st_dev == fsysrdev)
! 817: mounted = TRUE;
! 818: else
! 819: mounted = FALSE;
! 820: prmtab(&mtab);
! 821: return;
! 822: }
! 823: @
! 824: mt_dev[0] != '\0')
! 825: if ( strcmp(name, mnttab.mt_filsys) == 0 ) {
! 826: statit(mnttab.mt_dev, nothing);
! 827: if (stats.st_dev == fsysrdev)
! 828: mounted = TRUE;
! 829: else
! 830: mounted = FAfsck/RCS/is_fs.c,v 444 3 3 4004 4753557413 7112 head 1.1;
! 831: access ;
! 832: symbols ;
! 833: locks ;
! 834: comment @ * @;
! 835:
! 836:
! 837: 1.1
! 838: date 91.02.05.16.36.22; author bin; state Exp;
! 839: branches ;
! 840: next ;
! 841:
! 842:
! 843: desc
! 844: @prov by epstein
! 845: @
! 846:
! 847:
! 848:
! 849: 1.1
! 850: log
! 851: @Initial revision
! 852: @
! 853: text
! 854: @#include <sys/stat.h>
! 855: #include <canon.h>
! 856: #include <sys/filsys.h>
! 857:
! 858: /*
! 859: * Check if a special file is a well-formed filesystem.
! 860: * This routine is derived from code in "mount.c".
! 861: * Return values:
! 862: * -1 Not a device, cannot open, read or seek failed
! 863: * 0 No filesystem
! 864: * 1 Legal filesystem
! 865: */
! 866: int
! 867: is_fs(special) char *special;
! 868: {
! 869: static struct filsys f;
! 870: struct stat sbuf;
! 871: register int fd;
! 872: register struct filsys *fp;
! 873: register daddr_t *dp;
! 874: register ino_t *ip, maxinode;
! 875:
! 876: if (stat(special, &sbuf) < 0)
! 877: return -1; /* cannot stat device */
! 878: else if ((sbuf.st_mode&S_IFMT) != S_IFBLK
! 879: && (sbuf.st_mode&S_IFMT) != S_IFCHR)
! 880: return -1; /* not a special file */
! 881: else if ((fd = open(special, 2)) < 0)
! 882: return -1; /* cannot open */
! 883: else if (lseek(fd, (long)SUPERI*BSIZE, 0) == -1L
! 884: || read(fd, &f, sizeof(f)) != sizeof(f)) {
! 885: close(fd);
! 886: return -1; /* seek or read failed */
! 887: } else
! 888: close(fd); /* so far so good */
! 889:
! 890: /* Canonical stuff. */
! 891: fp = &f;
! 892: canshort(fp->s_isize);
! 893: candaddr(fp->s_fsize);
! 894: canshort(fp->s_nfree);
! 895: for (dp = &fp->s_free[0]; dp < &fp->s_free[NICFREE]; dp += 1)
! 896: candaddr(*dp);
! 897: canshort(fp->s_ninode);
! 898: for (ip = &fp->s_inode[0]; ip < &fp->s_inode[NICINOD]; ip += 1)
! 899: canino(*ip);
! 900: candaddr(fp->s_tfree);
! 901: canino(fp->s_tinode);
! 902:
! 903: /* Test for rationality. */
! 904: maxinode = (fp->s_isize - INODEI) * INOPB + 1;
! 905: if (fp->s_isize >= fp->s_fsize)
! 906: return 0;
! 907: if ((fp->s_tfree < fp->s_nfree)
! 908: || (fp->s_tfree >= fp->s_fsize - fp->s_isize + 1))
! 909: return 0;
! 910: if ((fp->s_tinode < fp->s_ninode) || (fp->s_tinode >= maxinode-1 ))
! 911: return 0;
! 912: for (dp = &fp->s_free[0]; dp < &fp->s_free[fp->s_nfree]; dp += 1)
! 913: if ((*dp < fp->s_isize) || (*dp >= fp->s_fsize))
! 914: return 0;
! 915: for (ip = &fp->s_inode[0]; ip < &fp->s_inode[fp->s_ninode]; ip += 1)
! 916: if ((*ip < 1) || (*ip > maxinode))
! 917: return 0;
! 918: return 1;
! 919: }
! 920: @
! 921: INODEI) * INOPB + 1;
! 922: if (fp->s_isize >= fp->s_fsize)
! 923: return 0;
! 924: if ((fp->s_tfree < fp->s_nfree)
! 925: || (fp->s_tfree >= fp->s_fsize - fp->s_isize + 1))
! 926: return 0;
! 927: if ((fp->s_tinode < fp->s_ninode) || (fp->s_tinode >= maxinode-1 ))
! 928: return 0;
! 929: for (dp = &fp->s_free[0]; dp < &fp->s_free[fp->s_nfree]; dp += 1)
! 930: if ((*dp < fp->s_isize) || (*dp >= fp->s_fsize))
! 931: return 0;
! 932: for (ip = &fp->s_inode[0]; ip < &fp->s_inode[fp->s_ninode]; ip += 1)
! 933: if ((*ip < 1) || (*ip > maxinode))
! 934: return 0;
! 935: return 1;
! 936: fsck/RCS/link.c,v 444 3 3 3277 4753557430 6756 head 1.1;
! 937: access ;
! 938: symbols ;
! 939: locks ;
! 940: comment @ * @;
! 941:
! 942:
! 943: 1.1
! 944: date 91.02.05.16.36.34; author bin; state Exp;
! 945: branches ;
! 946: next ;
! 947:
! 948:
! 949: desc
! 950: @prov by epstein
! 951: @
! 952:
! 953:
! 954:
! 955: 1.1
! 956: log
! 957: @Initial revision
! 958: @
! 959: text
! 960: @/*
! 961: * Routines to handle the counting of links for each i-node
! 962: */
! 963:
! 964: #include "fsck.h"
! 965:
! 966: linkincr(inum)
! 967: ino_t inum;
! 968: {
! 969: if (inclinkctr(inum) == 0 )
! 970: fatal("Too many links in i-node, %d", inum);
! 971: }
! 972:
! 973: /*
! 974: * The following is the beginning of thinking of how to change
! 975: * the number of bits used in the link count tables from 8-per
! 976: * i-node to 2-per i-node, with additional tables for those
! 977: * i-nodes with more than 2 links. The changes would be to the
! 978: * definition of i_lnks, the macro linkctr(), the function linkincr(),
! 979: * and in init.c, the allocation of table space.
! 980: */
! 981:
! 982: #ifdef NEWLINKSTUFFF
! 983:
! 984: char *linkmap; /* table of inodes with one link */
! 985:
! 986: #define testlink(in) ( linkmap[((unsigned)bn)>>(LOGNBPC-1)] & \
! 987: 3 << (((unsigned)bn)&(NBPC>>1)) )
! 988: #define marklink(in) ( linkmap[((unsigned)bn)>>(LOGNBPC-1)] |= \
! 989: 1 << (((unsigned)bn)&(NBPC-2)) )
! 990: #define unmarklink(in) ( linkmap[((unsigned)bn)>>(LOGNBPC-1)] ^= \
! 991: 1 << (((unsigned)bn)&(NBPC-2)) )
! 992:
! 993: linkcntr(inum)
! 994: ino_t inum;
! 995: {
! 996: index = ((unsigned) inum) >> (LOGNBPC-1) ;
! 997: distance = ((unsigned) inum) & ((NBPC>>1) - 1) ;
! 998: mask = 3 << distance;
! 999: answer = ( linkmap[index] & mask ) >> distance;
! 1000:
! 1001: if ( answer < 3 )
! 1002: return(answer);
! 1003:
! 1004: hash = inum & 0xFF;
! 1005: bucket = &linktable[hash];
! 1006: bktinum = bucket->inumb;
! 1007:
! 1008: if ( bktinum == inum ) {
! 1009: answer = bucket->numlink;
! 1010: if ( answer == 0xFF )
! 1011: return( bigcntr(inum) );
! 1012: else
! 1013: return( answer + 3 );
! 1014: }
! 1015:
! 1016: if ( bktinum > inum )
! 1017: fatal("internal linktable corruption.");
! 1018:
! 1019:
! 1020: }
! 1021:
! 1022: linkincr(inum)
! 1023: ino_t inum;
! 1024: {
! 1025: }
! 1026:
! 1027: #endif
! 1028: @
! 1029: m) >> (LOGNBPC-1) ;
! 1030: distance = ((unsigned) inum) & ((NBPC>>1) - 1) ;
! 1031: mask = 3 << distance;
! 1032: answer = ( linkmap[index] & mask ) >> distance;
! 1033:
! 1034: if ( answer < 3 )
! 1035: return(answer);
! 1036:
! 1037: hash = inum & 0xFF;
! 1038: bucket = &linktable[hash];
! 1039: bktinum = bucket->inumb;
! 1040:
! 1041: if ( bktinum == inum ) {
! 1042: answer = bucket->numlink;
! 1043: if ( ansfsck/RCS/main.c,v 444 3 3 15241 5045006700 6737 head 1.3;
! 1044: branch ;
! 1045: access ;
! 1046: symbols ;
! 1047: locks bin:1.3;
! 1048: comment @ * @;
! 1049:
! 1050:
! 1051: 1.3
! 1052: date 91.07.29.07.44.44; author bin; state Exp;
! 1053: branches ;
! 1054: next 1.2;
! 1055:
! 1056: 1.2
! 1057: date 91.03.18.18.43.33; author bin; state Exp;
! 1058: branches ;
! 1059: next 1.1;
! 1060:
! 1061: 1.1
! 1062: date 91.02.05.16.36.45; author bin; state Exp;
! 1063: branches ;
! 1064: next ;
! 1065:
! 1066:
! 1067: desc
! 1068: @prov by epstein
! 1069: @
! 1070:
! 1071:
! 1072: 1.3
! 1073: log
! 1074: @Updated by epstein for version 321.
! 1075: @
! 1076: text
! 1077: @/*
! 1078: * fsck -- File System Check Program
! 1079: * an interactive file system check and repair program.
! 1080: *
! 1081: * Usage:
! 1082: * /etc/fsck [-y] [-n] [-q] [-f] [-{sS}] [-t TMPFILE] [filesystem ...]
! 1083: * audit and interactively repair inconsistent conditions for
! 1084: * file systems. Options -y and -n indicate an assumed response
! 1085: * to all questions asked by fsck. Default is to prompt operator
! 1086: * for yes/no response. Option -q is to quiet fsck from printing
! 1087: * certain messages, i.e. no size check messages, unreferenced
! 1088: * pipes will be silently removed, and counts in the superblock
! 1089: * will be automatically fixed and free list salvaged, if necessary.
! 1090: * Option -f is for a 'fast' check of the file system, i.e. only
! 1091: * check blocks, sizes, superblock counts, and the free list.
! 1092: * (-f) does not check pathnames, connectivity, or reference
! 1093: * counts. Option -s forces the reconstruction (or salvaging) of
! 1094: * both the free inode list and the free block list, even if there
! 1095: * are no file system problems. This will reorder the free block
! 1096: * list in the best order to limit additional fragmentation (respecting
! 1097: * interleaving as well). Note: Option -s will be ignored on mounted
! 1098: * file systems. The option -S acts in the same manner as -s except
! 1099: * that it will not be ignored on mounted file systems. Beware: -S
! 1100: * on mounted file systems should only be used if you intend to reboot
! 1101: * NO SYNC immediately afterwards. Option -t sets the temporary file
! 1102: * to use for disk caching of necessary tables on filesystems which are
! 1103: * too big to do in core. The temporary file defaults to "/dev/rram1",
! 1104: * which must be there.
! 1105: */
! 1106:
! 1107: #include "fsck.h"
! 1108:
! 1109: int errflag;
! 1110:
! 1111: int mdaction; /* default action for invocation */
! 1112: int daction; /* default action for file system */
! 1113: int gSflag=FALSE; /* force salvage flag ignored mounted */
! 1114: int gsflag=FALSE; /* force salvage flag ignored mounted */
! 1115: int sflag=FALSE; /* force salvage flag */
! 1116: int qflag=FALSE; /* fsck quiet flag */
! 1117: int fflag=FALSE; /* fsck fast flag */
! 1118:
! 1119: char *tmpfile = NULL; /* TMP file for virtual.c */
! 1120: char *checklistfile = "/etc/checklist"; /* default file for list of file */
! 1121: /* systems to fsck. */
! 1122: char *filelist[NFILSYS]; /* list of filesystems */
! 1123: char word[MAXCH]; /* hold single words */
! 1124: char *fsname; /* file system name */
! 1125:
! 1126: dev_t rootdev; /* root device number */
! 1127: dev_t fsysrdev; /* file system real device number */
! 1128: int mounted; /* flag for mounted file system */
! 1129:
! 1130: int changeflg; /* file system modified flag */
! 1131:
! 1132: main(argc, argv)
! 1133: char *argv[];
! 1134: {
! 1135: int yflag=0, nflag=0;
! 1136: int retval;
! 1137:
! 1138: while (argc>1 && *argv[1]=='-') {
! 1139: switch (argv[1][1]) {
! 1140: case 'q':
! 1141: qflag = TRUE;
! 1142: break;
! 1143: case 'y':
! 1144: yflag = 1;
! 1145: break;
! 1146: case 'n':
! 1147: nflag = 1;
! 1148: break;
! 1149: case 'f':
! 1150: fflag = TRUE;
! 1151: break;
! 1152: case 'S':
! 1153: gSflag = TRUE;
! 1154: break;
! 1155: case 's':
! 1156: gsflag = TRUE;
! 1157: break;
! 1158: case 't':
! 1159: tmpfile = argv[2];
! 1160: argc--;
! 1161: argv++;
! 1162: break;
! 1163: default:
! 1164: usage();
! 1165: break;
! 1166: }
! 1167:
! 1168: argc--;
! 1169: argv++;
! 1170: }
! 1171:
! 1172: if ( yflag+nflag > 1 )
! 1173: usage();
! 1174:
! 1175: mdaction = ( yflag ? YES :
! 1176: nflag ? NO : ASK );
! 1177:
! 1178: if ( argc > 1 )
! 1179: retval = allfsck(argv+1);
! 1180: else {
! 1181: getlist();
! 1182: retval = allfsck(filelist);
! 1183: }
! 1184: exit(retval);
! 1185: }
! 1186:
! 1187:
! 1188: /*
! 1189: * perform fsck on each of the individual filesystem in list
! 1190: */
! 1191:
! 1192: allfsck(fsl)
! 1193: register char **fsl;
! 1194: {
! 1195: int fatal();
! 1196: int retval = 0;
! 1197:
! 1198: sync();
! 1199: statit("/", fatal);
! 1200: rootdev = stats.st_dev;
! 1201: while (*fsl != NULL)
! 1202: retval |= fsck(*fsl++);
! 1203: return(retval);
! 1204: }
! 1205:
! 1206: /*
! 1207: * get the names of the filesystems from the default file
! 1208: * checklistfile (e.g. /etc/checklist)
! 1209: */
! 1210:
! 1211: getlist()
! 1212: {
! 1213: int fd;
! 1214: int index, size;
! 1215:
! 1216: if ( (fd = open(checklistfile, 0)) == (-1) )
! 1217: fatal("Can't open checklist file: %s", checklistfile);
! 1218:
! 1219: index = 0;
! 1220: while ( ((size = getword(fd)) != 0) && (index < NFILSYS) ) {
! 1221: filelist[index] = malloc( size );
! 1222: strcpy(filelist[index++], word);
! 1223: }
! 1224:
! 1225: if (size != 0)
! 1226: fatal("Too many file systems in checklist file: %s",
! 1227: checklistfile);
! 1228:
! 1229: filelist[index] = NULL;
! 1230:
! 1231: close(fd);
! 1232: }
! 1233:
! 1234: /*
! 1235: * read in the next "word" from file with descriptor fd
! 1236: * return the length of the word.
! 1237: */
! 1238:
! 1239: getword(fd)
! 1240: int fd;
! 1241: {
! 1242: int n = 0, num;
! 1243: char *cp = word;
! 1244: char ch;
! 1245:
! 1246: while ( ( (num=read(fd, &ch, 1)) == 1 ) &&
! 1247: ( (ch==' ')||(ch=='\t')||(ch=='\n')||(ch=='\r') ) );
! 1248:
! 1249: if (num != 1)
! 1250: return(0);
! 1251:
! 1252: do {
! 1253: *cp++ = ch;
! 1254: } while ( (++n < MAXCH) && (read(fd, &ch, 1) == 1) &&
! 1255: (ch != ' ') && (ch != '\t') && (ch != '\n') && (ch != '\r') );
! 1256:
! 1257: *cp = '\0';
! 1258:
! 1259: return(n+1);
! 1260: }
! 1261:
! 1262: /*
! 1263: * perform fsck on the given filesystem
! 1264: */
! 1265: fsck(name)
! 1266: char *name;
! 1267: {
! 1268: int retval = 1;
! 1269: int nonfatal();
! 1270:
! 1271: fsname = name; /* file system name */
! 1272: errflag = FALSE;
! 1273: statit(fsname, nonfatal);
! 1274: fsysrdev = stats.st_rdev;
! 1275: if ( errflag )
! 1276: return(retval);
! 1277: changeflg = FALSE;
! 1278: init();
! 1279: if ( sflag = ((gsflag && !mounted) || gSflag) )
! 1280: printf("Switch \"-s\" selected to automatically rebuild free lists\n");
! 1281: if (!sflag && gsflag)
! 1282: printf("Ignoring \"-s\" on mounted file system\n");
! 1283: if ( !errflag ) {
! 1284: phase1(); /* check blocks and sizes */
! 1285: if ( !fflag ) {
! 1286: phase2(); /* check pathnames */
! 1287: phase3(); /* check connectivity */
! 1288: phase4(); /* check reference counts */
! 1289: }
! 1290: phase5(); /* check free list */
! 1291: phase6(); /* salvage free list */
! 1292: retval = cleanup();
! 1293: }
! 1294: return(retval);
! 1295: }
! 1296:
! 1297: usage()
! 1298: {
! 1299: printf("\
! 1300: Usage: /etc/fsck [-y] [-n] [-q] [-f] [-{sS}] [-t TMPFILE] [filesystem ...]\n");
! 1301: _exit(1);
! 1302: }
! 1303: @
! 1304:
! 1305:
! 1306: 1.2
! 1307: log
! 1308: @update provided by epstein
! 1309: @
! 1310: text
! 1311: @d6 1
! 1312: a6 1
! 1313: * /etc/fsck [-y] [-n] [-q] [-f] [-s] [-t TMPFILE] [filesystem ...]
! 1314: d21 7
! 1315: a27 3
! 1316: * interleaving as well). Option -t sets the temporary file to use
! 1317: * for disk caching of necessary tables on filesystems which are too
! 1318: * big to do in core. The temporary file defaults to "/dev/rram1",
! 1319: d37 2
! 1320: d76 3
! 1321: d80 1
! 1322: a80 1
! 1323: sflag = TRUE;
! 1324: d203 4
! 1325: d224 1
! 1326: a224 1
! 1327: Usage: /etc/fsck [-y] [-n] [-q] [-f] [-s] [-t TMPFILE] [filesystem ...]\n");
! 1328: @
! 1329:
! 1330:
! 1331: 1.1
! 1332: log
! 1333: @Initial revision
! 1334: @
! 1335: text
! 1336: @d6 1
! 1337: a6 1
! 1338: * /etc/fsck [-y] [-n] [-q] [-f] [-t TMPFILE] [filesystem ...]
! 1339: d17 8
! 1340: a24 4
! 1341: * counts. Option -t sets the temporary file to use for disk caching
! 1342: * of necessary tables on filesystems which are too big to do in core.
! 1343: * The temporary file defaults to "/dev/rram1", which must be there.
! 1344: *
! 1345: d33 3
! 1346: a35 2
! 1347: int qflag=FALSE; /* fsck quiet flag */
! 1348: int fflag=FALSE; /* fsck fast flag */
! 1349: d70 3
! 1350: d211 1
! 1351: a211 1
! 1352: Usage: /etc/fsck [-y] [-n] [-q] [-f] [-t TMPFILE] [filesystem ...]\n");
! 1353: @
! 1354: g
! 1355: @Initial revision
! 1356: @
! 1357: text
! 1358: @d6 1
! 1359: a6 1
! 1360: * /etc/fsck [-y] [-n] [-q] [-f] [-t TMPFILE] [filesystem ...]
! 1361: d17 8
! 1362: a24 4
! 1363: * counts. Option -t sets the temporary file to use for disk caching
! 1364: * of necessary tables on filesystems which are too big to do in core.
! 1365: * The temporary file defaults to "/dev/rram1", which must be there.
! 1366: *
! 1367: d33 3
! 1368: a35 2
! 1369: int qflag=FALSfsck/RCS/phase1.c,v 444 3 3 16554 4771205175 7220 head 1.2;
! 1370: access ;
! 1371: symbols ;
! 1372: locks bin:1.2;
! 1373: comment @ * @;
! 1374:
! 1375:
! 1376: 1.2
! 1377: date 91.03.18.18.43.50; author bin; state Exp;
! 1378: branches ;
! 1379: next 1.1;
! 1380:
! 1381: 1.1
! 1382: date 91.02.05.16.36.59; author bin; state Exp;
! 1383: branches ;
! 1384: next ;
! 1385:
! 1386:
! 1387: desc
! 1388: @prov by epstein
! 1389: @
! 1390:
! 1391:
! 1392: 1.2
! 1393: log
! 1394: @update provided by epstein
! 1395: @
! 1396: text
! 1397: @/*
! 1398: * phase 1 of fsck - Check Blocks and Sizes
! 1399: */
! 1400:
! 1401: #include "fsck.h"
! 1402:
! 1403: char databuf[BSIZE]; /* buffer for blocks */
! 1404:
! 1405: int clrflg; /* indicates when to clear an inode */
! 1406: int dupflag; /* indicates whether there are any dups */
! 1407:
! 1408: int numbad; /* number of bad blocks in the inode */
! 1409: int numdup; /* number of duplicate blocks in inode */
! 1410: long numblks; /* number of data blks for size check */
! 1411: long sparsecnt; /* count for sparse blocks for size check */
! 1412:
! 1413: /* The following is a table of the number of direct blocks pointed at by the
! 1414: * four types of blocks direct, ..., triple-indirect, to help count sparse
! 1415: * blocks.
! 1416: */
! 1417:
! 1418: daddr_t blockcnt[] = {1, (daddr_t)NBN, (daddr_t)NBN*NBN, (daddr_t)NBN*NBN*NBN};
! 1419:
! 1420: phase1()
! 1421: {
! 1422: if (!qflag)
! 1423: printf("Phase 1 : Check Blocks and Sizes\n");
! 1424: dupflag = FALSE;
! 1425: inodescan();
! 1426: if (dupflag)
! 1427: phase1b();
! 1428: }
! 1429:
! 1430: inodescan()
! 1431: {
! 1432: register daddr_t bn;
! 1433: register struct dinode *dip;
! 1434: register ino_t ino;
! 1435: int i;
! 1436:
! 1437: ino = 1;
! 1438:
! 1439: for (bn=INODEI; bn<isize; bn++) {
! 1440: if (testblock(bn)) { /* block is bad via inode 1 */
! 1441: ino += INOPB;
! 1442: continue;
! 1443: }
! 1444: bread(bn, databuf);
! 1445: clrflg = FALSE;
! 1446: dip = (struct dinode *) databuf;
! 1447: for (i=0; i<INOPB; i++) {
! 1448: candino(dip);
! 1449: if (inuse(dip) == TRUE) {
! 1450: if (!fflag)
! 1451: checkmode(dip, ino);
! 1452: if ( checkblks(dip, ino) != STOP )
! 1453: if ( qflag == FALSE )
! 1454: checksize(dip, ino);
! 1455: }
! 1456: candino(dip);
! 1457: ino++;
! 1458: dip++;
! 1459: }
! 1460: if (clrflg)
! 1461: bwrite(bn, databuf);
! 1462: }
! 1463: }
! 1464:
! 1465: /*
! 1466: * Determine if the given inode is in use.
! 1467: */
! 1468:
! 1469: inuse(dip)
! 1470: register struct dinode *dip;
! 1471: {
! 1472: #ifdef NOT_ALL_ZERO_INODE
! 1473:
! 1474: if ( (dip->di_mode != 0) || (dip->di_nlink != 0) )
! 1475: return(TRUE);
! 1476: else
! 1477: return(FALSE);
! 1478: #endif
! 1479: #ifdef ALL_ZERO_INODE
! 1480:
! 1481: register char *ptr;
! 1482: register struct dinode *next;
! 1483:
! 1484: ptr = (char *) dip;
! 1485: next = dip + 1;
! 1486: while (ptr < next)
! 1487: if (*ptr++ != 0)
! 1488: return(TRUE);
! 1489:
! 1490: return(FALSE);
! 1491: #endif
! 1492: }
! 1493:
! 1494: /*
! 1495: * Check the mode of the given inode
! 1496: */
! 1497:
! 1498: checkmode(dip, ino)
! 1499: register struct dinode *dip;
! 1500: register ino_t ino;
! 1501: {
! 1502: register unsigned short mode;
! 1503:
! 1504: mode = dip->di_mode & IFMT;
! 1505:
! 1506: switch (mode) {
! 1507: case IFREG:
! 1508: setflags(ino, IREG);
! 1509: return;
! 1510: case IFDIR:
! 1511: setflags(ino, IDIR);
! 1512: return;
! 1513: case IFCHR:
! 1514: setflags(ino, ICHR);
! 1515: return;
! 1516: case IFBLK:
! 1517: setflags(ino, IBLK);
! 1518: return;
! 1519: case IFPIPE:
! 1520: setflags(ino, IPIPE);
! 1521: return;
! 1522: default:
! 1523: setflags(ino, UNKNOWN);
! 1524: break;
! 1525: }
! 1526:
! 1527: switch ( query("Unknown File Type i-number = %u (Clear)", ino) ){
! 1528: case NO:
! 1529: return;
! 1530: case YES:
! 1531: zeroinode(dip);
! 1532: setflags(ino, UNALLOC);
! 1533: clrflg = TRUE;
! 1534: break;
! 1535: }
! 1536: }
! 1537:
! 1538: /*
! 1539: * Zero the given inode
! 1540: */
! 1541:
! 1542: zeroinode(dip)
! 1543: struct dinode *dip;
! 1544: {
! 1545: register char *ptr;
! 1546: register struct dinode *next;
! 1547:
! 1548: lostsize += dip->di_size;
! 1549: next = dip+1;
! 1550: ptr = (char *) dip;
! 1551:
! 1552: while (ptr < next)
! 1553: *ptr++ = 0;
! 1554:
! 1555: }
! 1556:
! 1557: /*
! 1558: * Check the blocks associated with the given inode to determine
! 1559: * if any are bad or duplicate
! 1560: */
! 1561:
! 1562: checkblks(dip, ino)
! 1563: struct dinode *dip;
! 1564: ino_t ino;
! 1565: {
! 1566: daddr_t addrs[NADDR];
! 1567: register daddr_t bn;
! 1568: register int i, lev;
! 1569: register int mode;
! 1570:
! 1571: mode = dip->di_mode & IFMT;
! 1572:
! 1573: if ( (mode != IFREG) && (mode != IFDIR) )
! 1574: return(STOP);
! 1575:
! 1576: l3tol(addrs, dip->di_addr, NADDR);
! 1577:
! 1578: numbad = /* number of bad blocks so far */
! 1579: numdup = /* num dup blocks so far THIS INODE */
! 1580: numblks = /* num used data blocks for size chk */
! 1581: sparsecnt = 0; /* count of missed data blocks */
! 1582:
! 1583: for(i=0; i<NADDR; i++)
! 1584: for (lev=0; lev<4; lev++)
! 1585: if (i < offsets[lev]) {
! 1586: if ( (bn=addrs[i]) != 0 ) {
! 1587: if (doblocks(bn, ino, lev) != OK)
! 1588: return(STOP);
! 1589: } else
! 1590: sparsecnt += blockcnt[lev];
! 1591: break;
! 1592: }
! 1593: return(OK);
! 1594: }
! 1595:
! 1596: /*
! 1597: * Checks recursively the blocks pointed at via
! 1598: * the inode list of blocks. 'bn' is the block number,
! 1599: * 'ino' is the inode referencing it, and 'lev' is the
! 1600: * level 0 == direct ... 3 = triple-indirect
! 1601: */
! 1602:
! 1603: doblocks(bn, ino, lev)
! 1604: register daddr_t bn;
! 1605: ino_t ino;
! 1606: int lev;
! 1607: {
! 1608: char buf[BSIZE];
! 1609: register daddr_t *bnptr;
! 1610: register char *end;
! 1611: register int flag;
! 1612:
! 1613: if (lev-- == 0) { /* we have a direct block */
! 1614: numblks += sparsecnt + 1;
! 1615: sparsecnt = 0;
! 1616: return(dodirect(bn, ino));
! 1617: } else {
! 1618: end = &buf[BSIZE];
! 1619: if ( (flag=dodirect(bn, ino)) == OK ) {
! 1620: bread(bn, buf);
! 1621: bnptr = (long *) buf;
! 1622: while ( bnptr < end ) {
! 1623: bn = *bnptr++;
! 1624: candaddr(bn);
! 1625: if ( bn == 0 ) {
! 1626: sparsecnt += blockcnt[lev];
! 1627: continue;
! 1628: }
! 1629: if ( doblocks(bn, ino, lev) == STOP )
! 1630: return(STOP);
! 1631: }
! 1632: return(OK);
! 1633: } else
! 1634: return(flag);
! 1635: }
! 1636: }
! 1637:
! 1638: /*
! 1639: * Check the given block to determine if it is bad
! 1640: * or if it is a duplicate. 'ino' is the inode referencing it
! 1641: */
! 1642:
! 1643: dodirect(bn, ino)
! 1644: register daddr_t bn;
! 1645: register ino_t ino;
! 1646: {
! 1647: register int flag;
! 1648:
! 1649: if ( (flag=checkbad(bn, ino)) == OK )
! 1650: return( checkdup(bn, ino) );
! 1651: else
! 1652: return(flag);
! 1653: }
! 1654:
! 1655: /*
! 1656: * Check the given block number for being bad.
! 1657: */
! 1658:
! 1659: checkbad(bn, ino)
! 1660: register daddr_t bn;
! 1661: ino_t ino;
! 1662: {
! 1663: if ( (bn>=isize) && (bn<fsize) )
! 1664: return(OK);
! 1665:
! 1666: else if ( (bn<isize) && (bn>=INODEI) && (ino == 1) ) {
! 1667: /* bad block is in */
! 1668: totfree++; /* the inode blocks */
! 1669: return(OK);
! 1670: }
! 1671:
! 1672: if (!fflag)
! 1673: orflags(ino, IBAD_IDUP);
! 1674:
! 1675: printf("Bad block %U, i-number = %u\n", bn, ino);
! 1676:
! 1677: if (numbad++ < MAXBADOK)
! 1678: return(BAD_DUP);
! 1679:
! 1680: switch ( query("Excessive Bad Blocks i-number = %u (Continue)", ino) ){
! 1681: case NO:
! 1682: abort();
! 1683: case YES:
! 1684: return(STOP);
! 1685: }
! 1686: }
! 1687:
! 1688:
! 1689: /*
! 1690: * Check the given block number for duplicate reference.
! 1691: */
! 1692:
! 1693: checkdup(bn, ino)
! 1694: register daddr_t bn;
! 1695: ino_t ino;
! 1696: {
! 1697: if ( !testblock(bn) ) {
! 1698: markblock(bn);
! 1699: totfree--;
! 1700: return(OK);
! 1701: }
! 1702:
! 1703: dupflag = TRUE;
! 1704: if (!fflag)
! 1705: orflags(ino, IBAD_IDUP);
! 1706: printf("Dup Block %U, i-number = %u\n", bn, ino);
! 1707:
! 1708: if (totdups < DUPTBLSIZE)
! 1709: dupblck[totdups++] = bn;
! 1710: else {
! 1711: switch ( query("DUP Table Overflow (Continue)") ) {
! 1712: case NO:
! 1713: abort();
! 1714: case YES:
! 1715: return(BAD_DUP);
! 1716: }
! 1717: }
! 1718:
! 1719: if (numdup++ < MAXDUPOK)
! 1720: return(BAD_DUP);
! 1721:
! 1722: switch ( query("Excessive Dup Blocks i-number = %u (Continue)", ino) ) {
! 1723: case NO:
! 1724: abort();
! 1725: case YES:
! 1726: return(STOP);
! 1727: }
! 1728: }
! 1729:
! 1730: /*
! 1731: * Check For Possible File Size Error
! 1732: */
! 1733:
! 1734: checksize(dip, ino)
! 1735: register struct dinode *dip;
! 1736: ino_t ino;
! 1737: {
! 1738: register int mode;
! 1739: register fsize_t size;
! 1740:
! 1741: mode = dip->di_mode & IFMT;
! 1742: size = dip->di_size;
! 1743:
! 1744: if ( mode == IFREG )
! 1745: filesize(ino, size);
! 1746: else /* mode == IFDIR */
! 1747: dirsize(dip, ino, size);
! 1748: }
! 1749:
! 1750: dirsize(dip, ino, size)
! 1751: struct dinode *dip;
! 1752: ino_t ino;
! 1753: register fsize_t size;
! 1754: {
! 1755: if ( size <= 0 ) {
! 1756: switch ( query("\
! 1757: Bad Directory Size, size = %D, i-number = %u (Clear i-node)", size, ino) ) {
! 1758: case NO:
! 1759: break;
! 1760: case YES:
! 1761: zeroinode(dip);
! 1762: setflags(ino, UNALLOC);
! 1763: clrflg = TRUE;
! 1764: return;
! 1765: }
! 1766: }
! 1767:
! 1768: if ( size < (2*DSIZE) )
! 1769: printf("Directory Size too small i-number = %u\n", ino);
! 1770:
! 1771: if ( size % sizeof(struct direct) != 0 )
! 1772: printf("Directory Misaligned i-number = %u\n", ino);
! 1773:
! 1774: if (sizerr(size))
! 1775: printf("Possible Directory Size Error i-number = %u\n", ino);
! 1776: }
! 1777:
! 1778: filesize(ino, size)
! 1779: ino_t ino;
! 1780: register fsize_t size;
! 1781: {
! 1782: if (sizerr(size))
! 1783: printf("Possible File Size Error i-number = %u\n", ino);
! 1784: }
! 1785:
! 1786: sizerr(size)
! 1787: register fsize_t size;
! 1788: {
! 1789: register fsize_t calc;
! 1790:
! 1791: calc = (unsigned long)numblks*BSIZE;
! 1792: if ( (size > calc) || ( calc >= (size+BSIZE) ) )
! 1793: return(TRUE);
! 1794: else
! 1795: return(FALSE);
! 1796: }
! 1797: @
! 1798:
! 1799:
! 1800: 1.1
! 1801: log
! 1802: @Initial revision
! 1803: @
! 1804: text
! 1805: @d152 1
! 1806: d252 1
! 1807: a252 1
! 1808:
! 1809: @
! 1810: saligned i-number = %u\n", ino);
! 1811:
! 1812: if (sizerr(size))
! 1813: printf("Possible Directory Size Error i-number = %u\n", ino);
! 1814: }
! 1815:
! 1816: filesize(ino, size)
! 1817: ino_t infsck/RCS/phase1b.c,v 444 3 3 4676 4753557476 7362 head 1.1;
! 1818: access ;
! 1819: symbols ;
! 1820: locks ;
! 1821: comment @ * @;
! 1822:
! 1823:
! 1824: 1.1
! 1825: date 91.02.05.16.37.12; author bin; state Exp;
! 1826: branches ;
! 1827: next ;
! 1828:
! 1829:
! 1830: desc
! 1831: @prov by epstein
! 1832: @
! 1833:
! 1834:
! 1835:
! 1836: 1.1
! 1837: log
! 1838: @Initial revision
! 1839: @
! 1840: text
! 1841: @/*
! 1842: * Phase 1b of fsck - Rescan for more Dups
! 1843: */
! 1844:
! 1845: #include "fsck.h"
! 1846:
! 1847: extern int numdup; /* declared in phase1.c */
! 1848:
! 1849: phase1b()
! 1850: {
! 1851: if (!qflag)
! 1852: printf("Phase 1b: Rescan for more Dups\n");
! 1853: buildtable();
! 1854: iscanb();
! 1855: }
! 1856:
! 1857: buildtable()
! 1858: {
! 1859: unsigned cntr=0, numdiff=0;
! 1860: daddr_t bn;
! 1861:
! 1862: while (cntr<totdups) {
! 1863: bn = dupblck[cntr++];
! 1864: if (!testdup(bn)) {
! 1865: markdup(bn);
! 1866: numdiff++;
! 1867: }
! 1868: }
! 1869: totdups = numdiff;
! 1870: }
! 1871:
! 1872: iscanb()
! 1873: {
! 1874: register daddr_t bn;
! 1875: register struct dinode *dip;
! 1876: register ino_t ino;
! 1877: int i;
! 1878:
! 1879: ino = 1;
! 1880:
! 1881: for (bn=INODEI; bn<isize; bn++) {
! 1882: if (testblock(bn)) { /* block is bad via inode 1 */
! 1883: ino += INOPB;
! 1884: continue;
! 1885: }
! 1886: bread(bn, databuf);
! 1887: dip = (struct dinode *) databuf;
! 1888: for (i=0; i<INOPB; i++) {
! 1889: candino(dip);
! 1890: if (inuse(dip) == TRUE)
! 1891: ckblksb(dip, ino);
! 1892: if (totdups == 0)
! 1893: return;
! 1894: ino++;
! 1895: dip++;
! 1896: }
! 1897: }
! 1898: }
! 1899:
! 1900: /*
! 1901: * Check the blocks associated with the given inode to find the
! 1902: * remaining duplicate blocks
! 1903: */
! 1904:
! 1905: ckblksb(dip, ino)
! 1906: register struct dinode *dip;
! 1907: register ino_t ino;
! 1908: {
! 1909: daddr_t addrs[NADDR];
! 1910: int i, lev;
! 1911: int mode;
! 1912:
! 1913: mode = dip->di_mode & IFMT;
! 1914:
! 1915: if ( (mode != IFREG) && (mode != IFDIR) )
! 1916: return;
! 1917:
! 1918: l3tol(addrs, dip->di_addr, NADDR);
! 1919:
! 1920: numdup = 0; /* num dup blocks so far THIS INODE */
! 1921:
! 1922: for(i=0; i<NADDR; i++)
! 1923: for (lev=0; lev<4; lev++)
! 1924: if (i < offsets[lev]) {
! 1925: dblocksb(addrs[i], ino, lev);
! 1926: break;
! 1927: }
! 1928: }
! 1929:
! 1930: /*
! 1931: * Checks recursively the blocks pointed at via
! 1932: * the inode list of blocks. 'bn' is the block number,
! 1933: * 'ino' is the inode referencing it, and 'lev' is the
! 1934: * level 0 == direct ... 3 = triple-indirect
! 1935: */
! 1936:
! 1937: dblocksb(bn, ino, lev)
! 1938: daddr_t bn;
! 1939: ino_t ino;
! 1940: int lev;
! 1941: {
! 1942: char buf[BSIZE];
! 1943: int i;
! 1944: daddr_t *bnptr;
! 1945:
! 1946: if (bn == 0)
! 1947: return(OK);
! 1948:
! 1949: switch ( cdupb(bn, ino) ) {
! 1950: case OK:
! 1951: if (lev--==0)
! 1952: return(OK);
! 1953: bread(bn, buf);
! 1954: bnptr = (long *) buf;
! 1955: for (i=0; i<NBN; i++) {
! 1956: bn = bnptr[i];
! 1957: candaddr(bn);
! 1958: if ( dblocksb(bn, ino, lev) == STOP )
! 1959: return(STOP);
! 1960: }
! 1961: return(OK);
! 1962: case STOP:
! 1963: return(STOP);
! 1964: }
! 1965: }
! 1966:
! 1967: /*
! 1968: * Check the given block number for duplicate reference.
! 1969: */
! 1970:
! 1971: cdupb(bn, ino)
! 1972: daddr_t bn;
! 1973: ino_t ino;
! 1974: {
! 1975: if ( !testdup(bn) )
! 1976: return(OK);
! 1977:
! 1978: totdups--;
! 1979: unmarkdup(bn);
! 1980: if (!fflag)
! 1981: orflags(ino, IBAD_IDUP);
! 1982: printf("Dup Block %U, i-number = %u\n", bn, ino);
! 1983:
! 1984: return(STOP);
! 1985: }
! 1986: @
! 1987: )
! 1988: return(OK);
! 1989: bread(bn, buf);
! 1990: bnptr = (long *) buf;
! 1991: for (fsck/RCS/phase2.c,v 444 3 3 17750 4771205232 7212 head 1.2;
! 1992: access ;
! 1993: symbols ;
! 1994: locks bin:1.2;
! 1995: comment @ * @;
! 1996:
! 1997:
! 1998: 1.2
! 1999: date 91.03.18.18.44.18; author bin; state Exp;
! 2000: branches ;
! 2001: next 1.1;
! 2002:
! 2003: 1.1
! 2004: date 91.02.05.16.37.24; author bin; state Exp;
! 2005: branches ;
! 2006: next ;
! 2007:
! 2008:
! 2009: desc
! 2010: @prov by epstein
! 2011: @
! 2012:
! 2013:
! 2014: 1.2
! 2015: log
! 2016: @update provided by epstein
! 2017: @
! 2018: text
! 2019: @/*
! 2020: * phase 2 of fsck - Check Pathnames
! 2021: */
! 2022:
! 2023: #include "fsck.h"
! 2024: #include <pwd.h>
! 2025:
! 2026: #define MAXDEPTH 50
! 2027: struct direct *path[MAXDEPTH];
! 2028: int depth;
! 2029: int fixflag; /* flags when must rewrite databuf */
! 2030: daddr_t blocknum; /* Current block num read in */
! 2031:
! 2032: typedef struct list {
! 2033: struct direct d_entry;
! 2034: struct list *next;
! 2035: } list;
! 2036:
! 2037: char buf2[BSIZE]; /* buffer for blocks */
! 2038: daddr_t cdbn; /* current logical block number */
! 2039:
! 2040: /* Format errors, args to blkerr() */
! 2041:
! 2042: #define NULLNAME 5
! 2043: #define NULLPAD 6
! 2044: #define SLASHES 7
! 2045: #define DOT 8
! 2046: #define DOTDOT 9
! 2047:
! 2048: phase2()
! 2049: {
! 2050: if (!qflag)
! 2051: printf("Phase 2 : Check Pathnames\n");
! 2052: checkroot();
! 2053: depth = 0;
! 2054: checkpath(ROOTIN);
! 2055: }
! 2056:
! 2057:
! 2058: checkroot()
! 2059: {
! 2060: if ( (flags(ROOTIN)&MODEMASK) == UNALLOC )
! 2061: fatal("Root i-node is unallocated. Terminating");
! 2062:
! 2063: if ( (flags(ROOTIN)&MODEMASK) != IDIR ) {
! 2064: switch ( query("Root i-node is not a directory (FIX)") ){
! 2065: case YES:
! 2066: fixroot();
! 2067: break;
! 2068: case NO:
! 2069: abort();
! 2070: }
! 2071: }
! 2072:
! 2073: if ( badblks(ROOTIN) ){
! 2074: switch ( query("Dup/Bad blocks in root i-node (Continue)") ) {
! 2075: case YES:
! 2076: break;
! 2077: case NO:
! 2078: abort();
! 2079: }
! 2080: }
! 2081: linkincr(ROOTIN); /* (?) Feature (?) of mkfs is */
! 2082: /* that root inode of a file */
! 2083: /* system has a link count one */
! 2084: /* too large. */
! 2085: }
! 2086:
! 2087: fixroot()
! 2088: {
! 2089: register struct dinode *dip;
! 2090:
! 2091: if (!writeflg)
! 2092: fatal("File System Read-Only (NO WRITE)\n");
! 2093:
! 2094: setflags(ROOTIN, (flags(ROOTIN) & ~MODEMASK) | IDIR);
! 2095:
! 2096: /* Save change to disk */
! 2097:
! 2098: dip = ptrino(ROOTIN, databuf);
! 2099: dip->di_mode &= (~IFMT);
! 2100: dip->di_mode |= IFDIR;
! 2101: writeino(ROOTIN, databuf);
! 2102: }
! 2103:
! 2104: #define myinum ( (depth>0) ? path[depth-1]->d_ino : ROOTIN )
! 2105: #define popinum ( (depth>1) ? path[depth-2]->d_ino : ROOTIN )
! 2106:
! 2107: char *memory = "Can't malloc memory, phase 2";
! 2108:
! 2109: list *
! 2110: procfiles(addrs, length)
! 2111: daddr_t *addrs;
! 2112: fsize_t length;
! 2113: {
! 2114: register struct direct *elemnt;
! 2115: register list *first, *ptr;
! 2116:
! 2117: if ((first=ptr=(list *)malloc(sizeof(list)))==NULL)
! 2118: fatal(memory);
! 2119: first->d_entry.d_ino = 0;
! 2120: first->next = NULL;
! 2121: if ( length < DSIZE )
! 2122: return( first );
! 2123: cdbn = 0;
! 2124: nextblock(addrs);
! 2125: fixflag = FALSE;
! 2126: elemnt = (struct direct *) databuf;
! 2127: cdots(elemnt++, ".", myinum, DOT);
! 2128: ++numfiles;
! 2129: if ( (length-=DSIZE) < DSIZE )
! 2130: return( first );
! 2131: cdots(elemnt++, "..", popinum, DOTDOT);
! 2132: ++numfiles;
! 2133: length -= DSIZE;
! 2134:
! 2135: while ( length >= DSIZE ) {
! 2136: while ( (elemnt<&databuf[BSIZE]) && (length>=DSIZE) ) {
! 2137: if (chck(elemnt)==IDIR) {
! 2138: copy(elemnt, &ptr->d_entry,
! 2139: sizeof(struct direct));
! 2140: if ((ptr->next=(list *)malloc(sizeof(list))) ==
! 2141: NULL)
! 2142: fatal(memory);
! 2143: ptr = ptr->next;
! 2144: ptr->d_entry.d_ino = 0;
! 2145: ptr->next = NULL;
! 2146: }
! 2147: elemnt++;
! 2148: length -= DSIZE;
! 2149: }
! 2150: if (fixflag && (fixblock(addrs) == NUL) )
! 2151: fixblkerr();
! 2152: nextblock(addrs);
! 2153: fixflag = FALSE;
! 2154: elemnt = (struct direct *) databuf;
! 2155: }
! 2156: return(first);
! 2157: }
! 2158:
! 2159: candblock(dptr)
! 2160: register struct direct *dptr;
! 2161: {
! 2162: register int num, i;
! 2163:
! 2164: num = BSIZE/sizeof(struct direct);
! 2165: for (i=0; i<num; i++)
! 2166: canino(dptr[i].d_ino);
! 2167: }
! 2168:
! 2169: nextblock(addrs)
! 2170: register daddr_t *addrs;
! 2171: {
! 2172: register daddr_t bn;
! 2173:
! 2174: if ( (bn=imap(addrs, cdbn++)) == 0 ) {
! 2175: bclear(databuf, BSIZE);
! 2176: return;
! 2177: }
! 2178: bread(bn, databuf);
! 2179: candblock(databuf);
! 2180: blocknum = bn;
! 2181: }
! 2182:
! 2183: fixblock(addrs)
! 2184: daddr_t *addrs;
! 2185: {
! 2186: daddr_t bn;
! 2187:
! 2188: if ( (bn=imap(addrs, cdbn-1)) == 0 )
! 2189: return(NUL);
! 2190: candblock(databuf);
! 2191: bwrite(bn, databuf);
! 2192: return(TRUE);
! 2193: }
! 2194:
! 2195: fixblkerr()
! 2196: {
! 2197: fatal("Fixblock error.");
! 2198: }
! 2199:
! 2200: copy(from, to, size)
! 2201: register char *from, *to;
! 2202: register int size;
! 2203: {
! 2204: while (size--)
! 2205: *to++=*from++;
! 2206: }
! 2207:
! 2208: cdots(elemnt, dots, ino, type)
! 2209: register struct direct *elemnt;
! 2210: char *dots;
! 2211: ino_t ino; /* what the inode number should be */
! 2212: int type;
! 2213: {
! 2214: register char *name = elemnt->d_name;
! 2215: register ino_t inum;
! 2216:
! 2217: inum = elemnt->d_ino;
! 2218: if ( (strcmp(name, dots) != 0) || (inum != ino) ||
! 2219: (format(name) != GOOD) ) {
! 2220: blkerr(type);
! 2221: return;
! 2222: }
! 2223: linkincr(inum);
! 2224: }
! 2225:
! 2226: format(name)
! 2227: register char *name;
! 2228: {
! 2229: register char *ptr=name;
! 2230: register char *end=&name[DIRSIZ];
! 2231:
! 2232: while ( (ptr<end) && (*ptr++ != '\0') ) ;
! 2233:
! 2234: if ( (ptr-1) == name )
! 2235: return(NULLNAME);
! 2236:
! 2237: if (ptr<end) {
! 2238: while ( (ptr<end) && (*ptr++ == '\0') ) ;
! 2239: if (ptr!=end)
! 2240: return(NULLPAD);
! 2241: }
! 2242:
! 2243: ptr = name;
! 2244: while (ptr < end)
! 2245: if (*ptr++ == '/')
! 2246: return(SLASHES);
! 2247:
! 2248: return(GOOD);
! 2249: }
! 2250:
! 2251:
! 2252: blkerr(type)
! 2253: int type;
! 2254: {
! 2255: char *errname;
! 2256:
! 2257: switch(type) {
! 2258: case NULLNAME:
! 2259: errname = "Null name";
! 2260: break;
! 2261: case NULLPAD:
! 2262: errname = "Non null padded";
! 2263: break;
! 2264: case SLASHES:
! 2265: errname = "Embedded slashes in";
! 2266: break;
! 2267: case DOT:
! 2268: errname = "Inconsistent .";
! 2269: break;
! 2270: case DOTDOT:
! 2271: errname = "Inconsistent ..";
! 2272: break;
! 2273: default:
! 2274: errname = "Bad";
! 2275: break;
! 2276: }
! 2277:
! 2278: printf("%s entry in block %U in directory\n", errname, blocknum);
! 2279: pinfo(myinum);
! 2280: pname(path[--depth]->d_name);
! 2281: depth++;
! 2282: }
! 2283:
! 2284: chck(elemnt)
! 2285: register struct direct *elemnt;
! 2286: {
! 2287: register ino_t inum;
! 2288: register char *name;
! 2289: int type;
! 2290:
! 2291: inum = elemnt->d_ino;
! 2292: if ( inum == 0 )
! 2293: return(UNALLOC);
! 2294:
! 2295: name = elemnt->d_name;
! 2296: if ( (type=format(name)) != GOOD )
! 2297: blkerr(type);
! 2298:
! 2299: if (inum>ninodes) {
! 2300: if ( irange(inum, name) )
! 2301: zeroent(elemnt);
! 2302: return(UNALLOC);
! 2303: }
! 2304:
! 2305: if ( (flags(inum)&ALLOCMASK)==UNALLOC ) {
! 2306: if ( unalloc(inum, name) )
! 2307: zeroent(elemnt);
! 2308: return(UNALLOC);
! 2309: }
! 2310:
! 2311: if ( badblks(inum) ) {
! 2312: if ( baddup(inum, name) ) {
! 2313: zeroent(elemnt);
! 2314: return(UNALLOC);
! 2315: }
! 2316: if ( (flags(inum)&MODEMASK)==IDIR )
! 2317: return(UNALLOC);
! 2318: }
! 2319:
! 2320: linkincr(inum);
! 2321: numfiles++;
! 2322: return( flags(inum)&MODEMASK );
! 2323: }
! 2324:
! 2325: zeroent(elemnt)
! 2326: struct direct *elemnt;
! 2327: {
! 2328: elemnt->d_ino = 0;
! 2329: fixflag = TRUE;
! 2330: }
! 2331:
! 2332: pname(name)
! 2333: char *name;
! 2334: {
! 2335: int i=0;
! 2336:
! 2337: while (i<depth)
! 2338: prdirsize(path[i++]->d_name);
! 2339: prdirsize(name);
! 2340: putchar('\n');
! 2341: }
! 2342:
! 2343: prdirsize(name)
! 2344: char *name;
! 2345: {
! 2346: if (name[DIRSIZ-1] == '\0')
! 2347: printf("/%s", name);
! 2348: else
! 2349: printf("/%*s", DIRSIZ, name);
! 2350: }
! 2351:
! 2352: fsize_t
! 2353: pinfo(inum)
! 2354: ino_t inum;
! 2355: {
! 2356: register struct dinode *dip;
! 2357: register struct passwd *pwd;
! 2358:
! 2359: if ( (dip=ptrino(inum, buf2)) == NULL ) {
! 2360: printf("i-number = %u is in a bad inode block.\n", inum);
! 2361: return(0);
! 2362: }
! 2363:
! 2364: printf("i-number = %u, ", inum);
! 2365: if ( (pwd=getpwuid(dip->di_uid)) != NULL )
! 2366: printf("Owner=%s, ", pwd->pw_name);
! 2367: else
! 2368: printf("Owner=%u, ", dip->di_uid);
! 2369: printf(" Mode=0%o\n", dip->di_mode);
! 2370: printf("Size=%U, Mtime=%s", dip->di_size, ctime(&dip->di_mtime));
! 2371: return(dip->di_size);
! 2372: }
! 2373:
! 2374: char *remove = "(Remove)";
! 2375:
! 2376: irange(inum, name)
! 2377: ino_t inum;
! 2378: char *name;
! 2379: {
! 2380: printf("I-number is out of range I=%u\n", inum);
! 2381: pname(name);
! 2382: return(action(remove));
! 2383: }
! 2384:
! 2385: unalloc(inum, name)
! 2386: ino_t inum;
! 2387: char *name;
! 2388: {
! 2389: fsize_t size;
! 2390:
! 2391: printf("Unallocated\n");
! 2392: size = pinfo(inum);
! 2393: pname(name);
! 2394: if ( (daction != NO) && (size == 0) && (mounted == FALSE) ) {
! 2395: printf("%s [Forced - Yes]\n", remove);
! 2396: return(YES);
! 2397: }
! 2398: return(action(remove));
! 2399: }
! 2400:
! 2401: baddup(inum, name)
! 2402: ino_t inum;
! 2403: char *name;
! 2404: {
! 2405: register int mode = flags(inum)&MODEMASK;
! 2406:
! 2407: printf("Bad or Dup blocks in %s\n",(mode==IDIR) ? "Directory" : "File");
! 2408: pinfo(inum);
! 2409: pname(name);
! 2410: return(action(remove));
! 2411: }
! 2412:
! 2413: checkpath(ino)
! 2414: register ino_t ino;
! 2415: {
! 2416: static daddr_t addrs[NADDR];
! 2417: static struct dinode *dip;
! 2418: static list *temp;
! 2419: register list *ptr;
! 2420:
! 2421: if ( (flags(ino)&VISITED)==VISITED ) {
! 2422: circle(ino);
! 2423: return;
! 2424: } else
! 2425: orflags(ino, VISITED);
! 2426:
! 2427: dip = ptrino(ino, databuf);
! 2428: l3tol(addrs, dip->di_addr, NADDR);
! 2429:
! 2430: if ( (dip->di_mode&IFMT) != IFDIR )
! 2431: fatal("Tried to checkpath i-node %u which is not dir.\n", ino);
! 2432:
! 2433: ptr = procfiles(addrs, dip->di_size);
! 2434:
! 2435: while (ptr->d_entry.d_ino) {
! 2436: if (depth >= MAXDEPTH)
! 2437: toolong();
! 2438: path[depth++] = &ptr->d_entry;
! 2439: checkpath(ptr->d_entry.d_ino);
! 2440: depth--;
! 2441: temp = ptr;
! 2442: ptr = ptr->next;
! 2443: free(temp);
! 2444: }
! 2445: free(ptr);
! 2446: }
! 2447:
! 2448: circle(ino)
! 2449: ino_t ino;
! 2450: {
! 2451: printf("I-node %u is a multiply referenced directory i-node.\n", ino);
! 2452: }
! 2453:
! 2454: toolong()
! 2455: {
! 2456: printf("Name too long.\n");
! 2457: pname("\0");
! 2458: abort();
! 2459: }
! 2460:
! 2461:
! 2462: @
! 2463:
! 2464:
! 2465: 1.1
! 2466: log
! 2467: @Initial revision
! 2468: @
! 2469: text
! 2470: @d102 3
! 2471: d110 3
! 2472: d114 2
! 2473: a115 2
! 2474: numfiles += 2;
! 2475: length -= 2*DSIZE; /* for the . & .. entries */
! 2476: d127 1
! 2477: @
! 2478: r->d_entry.d_ino) {
! 2479: iffsck/RCS/phase3.c,v 444 3 3 12752 5050254731 7207 head 1.2;
! 2480: branch ;
! 2481: access ;
! 2482: symbols ;
! 2483: locks bin:1.2;
! 2484: comment @ * @;
! 2485:
! 2486:
! 2487: 1.2
! 2488: date 91.08.08.09.48.33; author bin; state Exp;
! 2489: branches ;
! 2490: next 1.1;
! 2491:
! 2492: 1.1
! 2493: date 91.02.05.16.37.54; author bin; state Exp;
! 2494: branches ;
! 2495: next ;
! 2496:
! 2497:
! 2498: desc
! 2499: @prov by epstein (post 310)
! 2500: @
! 2501:
! 2502:
! 2503: 1.2
! 2504: log
! 2505: @updated by epstein to properly handle directory allocations.
! 2506: @
! 2507: text
! 2508: @/*
! 2509: * phase 3 of fsck - Check Connectivity
! 2510: */
! 2511:
! 2512: #include "fsck.h"
! 2513:
! 2514: char *lostname = "lost+found";
! 2515:
! 2516: phase3()
! 2517: {
! 2518: ino_t i;
! 2519:
! 2520: if (!qflag)
! 2521: printf("Phase 3 : Check Connectivity\n");
! 2522: for (i=FIRSTIN; i<=ninodes; i++)
! 2523: if ( ((flags(i)&MODEMASK) == IDIR) &&
! 2524: (linkctr(i) == 0) ) {
! 2525: orflags(i, UNREFDIR);
! 2526: markchildren(i);
! 2527: }
! 2528:
! 2529: for (i=FIRSTIN; i<ninodes; i++)
! 2530: if ( (flags(i)&(UNREFDIR|CHILDDIR)) == UNREFDIR )
! 2531: unrefdir(i);
! 2532: }
! 2533:
! 2534: markchildren(ino)
! 2535: ino_t ino;
! 2536: {
! 2537: struct dinode *dip;
! 2538: struct direct *element;
! 2539: daddr_t addrs[NADDR];
! 2540: ino_t inumber;
! 2541: fsize_t length;
! 2542:
! 2543: if ( badblks(ino) )
! 2544: return;
! 2545: dip = ptrino(ino, databuf);
! 2546: if ( (length=dip->di_size) <= 0 )
! 2547: return;
! 2548: l3tol(addrs, dip->di_addr, NADDR);
! 2549: cdbn = 0;
! 2550: nextblock(addrs);
! 2551: element = (struct direct *) databuf;
! 2552: element += 2; /* skip over . and .. entries */
! 2553: if ( (length-=2*DSIZE) <= 0 )
! 2554: return;
! 2555:
! 2556: while ( length >= DSIZE ) {
! 2557: while ( (element<&databuf[BSIZE]) && (length>=DSIZE) ) {
! 2558: if ( ((inumber=element->d_ino) != 0) &&
! 2559: ((flags(inumber)&MODEMASK)==IDIR) &&
! 2560: (inumber!=ino) )
! 2561: orflags(inumber, CHILDDIR);
! 2562: element++;
! 2563: length -= DSIZE;
! 2564: }
! 2565: nextblock(addrs);
! 2566: element = (struct direct *) databuf;
! 2567: }
! 2568: }
! 2569:
! 2570: char *reconnect = "(Reconnect)";
! 2571:
! 2572: unrefdir(ino)
! 2573: ino_t ino;
! 2574: {
! 2575: printf("Unref Dir\n");
! 2576: if( (pinfo(ino) == 0) || (daction == NO) || (mounted == TRUE) ) {
! 2577: if ( action(reconnect) == FALSE )
! 2578: return;
! 2579: } else
! 2580: printf("%s FORCED\n", reconnect);
! 2581:
! 2582: connect(ino, IDIR);
! 2583: }
! 2584:
! 2585: #define CONNECT 1
! 2586: #define NOCONNECT 0
! 2587:
! 2588: connect(ino, type)
! 2589: ino_t ino;
! 2590: int type;
! 2591: {
! 2592: ino_t lostino;
! 2593: struct dinode *dip;
! 2594: daddr_t addrs[NADDR];
! 2595: fsize_t length;
! 2596: struct direct *element;
! 2597: int chgino = FALSE;
! 2598:
! 2599: if ( ((lostino=lostfound()) == NUL) ||
! 2600: ((flags(lostino)&MODEMASK) != IDIR) ||
! 2601: ( badblks(lostino) ) ) {
! 2602: nolost();
! 2603: if (type==IDIR)
! 2604: traverse(NOCONNECT, ino, lostino);
! 2605: return(FAILURE);
! 2606: }
! 2607:
! 2608: dip = ptrino(lostino, buf2);
! 2609: l3tol(addrs, dip->di_addr, NADDR);
! 2610: length = dip->di_size;
! 2611: cdbn = 0;
! 2612: while ( length>=DSIZE ) {
! 2613: nextblock(addrs);
! 2614: element = (struct direct *) databuf;
! 2615: while ( element<&databuf[BSIZE] ) {
! 2616: length -= DSIZE;
! 2617: if ( element->d_ino == 0 ) {
! 2618: element->d_ino = ino;
! 2619: strncpy(element->d_name, nameit(ino), DIRSIZ);
! 2620: if ( fixblock(addrs) == NUL )
! 2621: fixblkerr();
! 2622: linkincr(ino);
! 2623: numfiles++;
! 2624: if ( length<0 ) {
! 2625: dip->di_size -= length;
! 2626: chgino = TRUE;
! 2627: }
! 2628: if ( (type == IDIR) &&
! 2629: (connected(ino, lostino)==YES) ) {
! 2630: dip->di_nlink++;
! 2631: writeino(lostino, buf2);
! 2632: traverse(CONNECT, ino, lostino);
! 2633: } else if (chgino) {
! 2634: writeino(lostino, buf2);
! 2635: }
! 2636: return(SUCCESS);
! 2637: }
! 2638: element++;
! 2639: }
! 2640: }
! 2641:
! 2642: noroom();
! 2643: if (type == IDIR)
! 2644: traverse(NOCONNECT, ino, lostino);
! 2645: return(FAILURE);
! 2646: }
! 2647:
! 2648: traverse(flag, ino, lostino)
! 2649: int flag;
! 2650: ino_t ino, lostino;
! 2651: {
! 2652: struct direct dirlost, nothing, newtree;
! 2653:
! 2654: dirinit(&dirlost, lostino, lostname);
! 2655: dirinit(¬hing, 0, "??");
! 2656: dirinit(&newtree, ino, nameit(ino));
! 2657: depth = 0;
! 2658: if (flag == CONNECT)
! 2659: path[depth++] = &dirlost;
! 2660: else
! 2661: path[depth++] = ¬hing;
! 2662:
! 2663: path[depth++] = &newtree;
! 2664: checkpath(ino);
! 2665: }
! 2666:
! 2667: dirinit(element, ino, name)
! 2668: struct direct *element;
! 2669: ino_t ino;
! 2670: char *name;
! 2671: {
! 2672: element->d_ino = ino;
! 2673: strncpy(element->d_name, name, DIRSIZ);
! 2674: }
! 2675:
! 2676: connected(ino, lostino)
! 2677: ino_t ino; /* inumber just reconnected */
! 2678: ino_t lostino; /* inumber of lostfound directory */
! 2679: {
! 2680: struct dinode *dip;
! 2681: daddr_t addrs[NADDR];
! 2682: fsize_t length;
! 2683: struct direct *element;
! 2684:
! 2685: if ( badblks(ino) ) {
! 2686: badconnect(ino);
! 2687: return(NO);
! 2688: }
! 2689: dip = ptrino(ino, databuf);
! 2690: l3tol(addrs, dip->di_addr, NADDR);
! 2691: length = dip->di_size;
! 2692: cdbn = 0;
! 2693: while ( length >= DSIZE ) {
! 2694: nextblock(addrs);
! 2695: element = (struct direct *) databuf;
! 2696: while ( (element<&databuf[BSIZE]) && (length>=DSIZE) ) {
! 2697: if ( strcmp(element->d_name, "..") == 0 ) {
! 2698: printf("Dir i-number = %u connected. ", ino);
! 2699: printf("Parent was i-number = %u.\n",
! 2700: element->d_ino);
! 2701: element->d_ino = lostino;
! 2702: if ( fixblock(addrs) == NUL )
! 2703: fixblkerr();
! 2704: return(YES);
! 2705: }
! 2706: length -= DSIZE;
! 2707: element++;
! 2708: }
! 2709: }
! 2710: noparent(ino);
! 2711: return(NO);
! 2712: }
! 2713:
! 2714: badconnect(ino)
! 2715: ino_t ino;
! 2716: {
! 2717: printf("Dir i-number = %u connected. It has bad/dup blocks.\n", ino);
! 2718: }
! 2719:
! 2720: noparent(ino)
! 2721: ino_t ino;
! 2722: {
! 2723: printf("Dir i-number = %u connected. It has no .. entry.\n", ino);
! 2724: }
! 2725:
! 2726: ino_t
! 2727: lostfound()
! 2728: {
! 2729: static daddr_t addrs[NADDR];
! 2730: struct dinode *dip;
! 2731: struct direct *element;
! 2732: fsize_t length;
! 2733:
! 2734: dip = ptrino(ROOTIN, databuf);
! 2735: l3tol(addrs, dip->di_addr, NADDR);
! 2736: length = dip->di_size;
! 2737: cdbn = 0;
! 2738: while ( length>=DSIZE ) {
! 2739: nextblock(addrs);
! 2740: element = (struct direct *) databuf;
! 2741: while ( (element<&databuf[BSIZE]) && (length>=DSIZE) ) {
! 2742: if ( strcmp(element->d_name, lostname) == 0 )
! 2743: return(element->d_ino);
! 2744: length -= DSIZE;
! 2745: element++;
! 2746: }
! 2747: }
! 2748:
! 2749: return(NUL);
! 2750: }
! 2751:
! 2752: nolost()
! 2753: {
! 2754: printf("Sorry. No %s directory.\n", lostname);
! 2755:
! 2756: }
! 2757:
! 2758: noroom()
! 2759: {
! 2760: printf("Sorry. No space in %s directory.\n", lostname);
! 2761: }
! 2762:
! 2763: char namebuf[DIRSIZ];
! 2764:
! 2765: char *
! 2766: nameit(ino)
! 2767: register ino_t ino;
! 2768: {
! 2769: register int i = DIRSIZ-1;
! 2770:
! 2771: namebuf[i] = '\0';
! 2772: while ( (ino != 0) && (i>0) ) {
! 2773: namebuf[--i] = '0' + ino%10;
! 2774: ino = ino/10;
! 2775: }
! 2776: return(&namebuf[i]);
! 2777: }
! 2778: @
! 2779:
! 2780:
! 2781: 1.1
! 2782: log
! 2783: @Initial revision
! 2784: @
! 2785: text
! 2786: @d109 1
! 2787: a130 1
! 2788: length -= DSIZE;
! 2789: @
! 2790: eturn(element->d_ino);fsck/RCS/phase4.c,v 444 3 3 12033 4771205260 7202 head 1.2;
! 2791: access ;
! 2792: symbols ;
! 2793: locks bin:1.2;
! 2794: comment @ * @;
! 2795:
! 2796:
! 2797: 1.2
! 2798: date 91.03.18.18.44.48; author bin; state Exp;
! 2799: branches ;
! 2800: next 1.1;
! 2801:
! 2802: 1.1
! 2803: date 91.02.05.16.38.17; author bin; state Exp;
! 2804: branches ;
! 2805: next ;
! 2806:
! 2807:
! 2808: desc
! 2809: @prov by epstein (post 310)
! 2810: @
! 2811:
! 2812:
! 2813: 1.2
! 2814: log
! 2815: @update provided by epstein
! 2816: @
! 2817: text
! 2818: @/*
! 2819: * phase 4 of fsck - Check Reference Counts
! 2820: */
! 2821:
! 2822: #include "fsck.h"
! 2823:
! 2824: extern char *reconnect;
! 2825: fsize_t lostsize;
! 2826:
! 2827: phase4()
! 2828: {
! 2829: ino_t i;
! 2830: short actlink;
! 2831:
! 2832: if (!qflag)
! 2833: printf("Phase 4 : Check Reference Counts\n");
! 2834: for (i=FIRSTIN; i<=ninodes; i++) {
! 2835: if ( badblks(i) )
! 2836: if ( bddp(i) == YES )
! 2837: continue; /* inode zeroed */
! 2838:
! 2839: if ( (linkctr(i) == 0) &&
! 2840: ((flags(i)&MODEMASK) != IDIR) &&
! 2841: ((flags(i)&ALLOCMASK) != UNALLOC) )
! 2842: if ( unreflink(i) == YES )
! 2843: continue; /* inode zeroed */
! 2844:
! 2845: if ( (linkctr(i) == 0) &&
! 2846: ((flags(i)&ALLOCMASK) != UNALLOC) )
! 2847: if ( unrefclr(i) == YES )
! 2848: continue; /* inode zeroed */
! 2849:
! 2850: if ( (actlink=getlink(i)) == (-1) ) {
! 2851: i += INOPB-1;
! 2852: continue; /* bad inode block */
! 2853: }
! 2854:
! 2855: if ( actlink != linkctr(i) )
! 2856: linkprob(i, actlink); /* fix link count */
! 2857: }
! 2858:
! 2859: freeilist();
! 2860: }
! 2861:
! 2862: short
! 2863: getlink(inum)
! 2864: register ino_t inum;
! 2865: {
! 2866: register unsigned offset;
! 2867: static ibuf[BSIZE];
! 2868: register struct dinode *dip;
! 2869: register daddr_t bn;
! 2870:
! 2871: offset = iblocko(inum);
! 2872: if ( (offset==0) || (inum==FIRSTIN) ) {
! 2873: bn = iblockn(inum);
! 2874: if ( (testblock(bn)) && (inum!=FIRSTIN) )
! 2875: return(-1);
! 2876: bread(bn, ibuf);
! 2877: }
! 2878: dip = ((struct dinode *) ibuf) + offset;
! 2879: candino(dip);
! 2880: return(dip->di_nlink);
! 2881: }
! 2882:
! 2883: char *clearit = "(Clear i-node)";
! 2884:
! 2885: unreflink(ino)
! 2886: ino_t ino;
! 2887: {
! 2888: fsize_t size;
! 2889:
! 2890: if ( (qflag == TRUE) && ((flags(ino)&MODEMASK) == IPIPE) ) {
! 2891: doclear(ino);
! 2892: return(YES);
! 2893: }
! 2894:
! 2895: printf("Unref %s\n", typename(ino));
! 2896: size = pinfo(ino);
! 2897: if ( (daction != NO) && (size == 0) && (mounted == FALSE)
! 2898: && ((flags(ino)&MODEMASK) == IREG) ) {
! 2899: printf("%s [Forced - Yes]\n", clearit);
! 2900: doclear(ino);
! 2901: return(YES);
! 2902: }
! 2903: if ( action(reconnect) == TRUE )
! 2904: if( connect(ino, IREG) == FAILURE ) /* connect back in the */
! 2905: return(askclear(ino)); /* non dir inode */
! 2906:
! 2907: return(NO);
! 2908: }
! 2909:
! 2910: askclear(ino)
! 2911: ino_t ino;
! 2912: {
! 2913: if ( action(clearit) == TRUE ) {
! 2914: doclear(ino);
! 2915: return(YES);
! 2916: }
! 2917: return(NO);
! 2918: }
! 2919:
! 2920: doclear(ino)
! 2921: ino_t ino;
! 2922: {
! 2923: struct dinode *dip;
! 2924:
! 2925: dip = ptrino(ino, databuf);
! 2926: zeroinode(dip);
! 2927: writeino(ino, databuf);
! 2928: setflags(ino, UNALLOC);
! 2929: setlinkctr(ino, 0);
! 2930: }
! 2931:
! 2932: char *adjust = "(Adjust)";
! 2933:
! 2934: linkprob(ino, actlink)
! 2935: ino_t ino;
! 2936: short actlink;
! 2937: {
! 2938: printf("Link Count discrepancy in %s\n", typename(ino));
! 2939: pinfo(ino);
! 2940: printf("Count = %u, should be %u ", actlink, linkctr(ino));
! 2941: if ( action(adjust) == TRUE )
! 2942: chglink(ino);
! 2943: }
! 2944:
! 2945: chglink(ino)
! 2946: ino_t ino;
! 2947: {
! 2948: struct dinode *dip;
! 2949:
! 2950: dip = ptrino(ino, databuf);
! 2951: dip->di_nlink = linkctr(ino);
! 2952: writeino(ino, databuf);
! 2953: }
! 2954:
! 2955: unrefclr(ino)
! 2956: ino_t ino;
! 2957: {
! 2958: printf("Unref %s\n", typename(ino));
! 2959: pinfo(ino);
! 2960: return(askclear(ino));
! 2961: }
! 2962:
! 2963: bddp(ino)
! 2964: ino_t ino;
! 2965: {
! 2966: printf("Bad/Dup blocks in %s\n", typename(ino));
! 2967: pinfo(ino);
! 2968: return(askclear(ino));
! 2969: }
! 2970:
! 2971: char *fixit = "(FIX)";
! 2972:
! 2973: freeilist()
! 2974: {
! 2975: ino_t i, count=0;
! 2976: daddr_t bn;
! 2977:
! 2978: for (i=FIRSTIN; i<=ninodes; i++)
! 2979: if ( (flags(i)&ALLOCMASK) == UNALLOC )
! 2980: count++;
! 2981:
! 2982: for (bn=INODEI+1; bn<isize; bn++) /* block # INODEI can't */
! 2983: if ( testblock(bn) ) /* be bad since ROOTIN */
! 2984: count -= INOPB; /* is in it, otherwise */
! 2985: /* big time bad news. */
! 2986: if ( sbp->s_tinode != count )
! 2987: if ( (qflag==FALSE) && (daction!=NO) ) {
! 2988: printf("Free i-node count wrong in superblock. ");
! 2989: if ( action(fixit) == TRUE ) {
! 2990: sbp->s_tinode = count;
! 2991: sbpfix = TRUE;
! 2992: }
! 2993: } else {
! 2994: sbp->s_tinode = count;
! 2995: sbpfix = TRUE;
! 2996: }
! 2997:
! 2998: if ( (daction!=NO) &&
! 2999: ( (sflag==TRUE) || (sbpfix==TRUE) || (badilist()==BAD) ) )
! 3000: rebuild();
! 3001:
! 3002: }
! 3003:
! 3004: badilist()
! 3005: {
! 3006: ino_t i, inum;
! 3007: unsigned numfree;
! 3008: daddr_t bn;
! 3009:
! 3010: if ( (numfree=(unsigned) sbp->s_ninode) > NICINOD )
! 3011: return(BAD);
! 3012: for (i=0; i<numfree; i++) {
! 3013: inum = sbp->s_inode[i];
! 3014: bn = iblockn(inum);
! 3015: if ( (testblock(bn)) && (bn!=INODEI) )
! 3016: return(BAD);
! 3017: if ( (inum < FIRSTIN) || (inum > ninodes) )
! 3018: return(BAD);
! 3019: if ( (flags(inum)&ALLOCMASK) != UNALLOC )
! 3020: return(BAD);
! 3021: if ( flags(inum)&IFREELIST )
! 3022: return(BAD); /* dup in ifree list */
! 3023: orflags(inum, IFREELIST);
! 3024: }
! 3025: return(GOOD);
! 3026: }
! 3027:
! 3028: rebuild()
! 3029: {
! 3030: daddr_t bn;
! 3031: ino_t i;
! 3032: int index;
! 3033:
! 3034: sbpfix = TRUE;
! 3035: for (i=FIRSTIN, index=0; (i<=ninodes) && (index<NICINOD); i++) {
! 3036: if ( (flags(i)&ALLOCMASK) == UNALLOC ) {
! 3037: bn = iblockn(i);
! 3038: if ( (!testblock(bn)) || (bn==INODEI) )
! 3039: index++;
! 3040: }
! 3041: }
! 3042: sbp->s_ninode = index;
! 3043: for (i=FIRSTIN; (i<=ninodes) && (index>0); i++) {
! 3044: if ( (flags(i)&ALLOCMASK) == UNALLOC ) {
! 3045: bn = iblockn(i);
! 3046: if ( (!testblock(bn)) || (bn==INODEI) )
! 3047: sbp->s_inode[--index] = i;
! 3048: }
! 3049: }
! 3050: printf("Free i-node list in superblock rebuilt.\n");
! 3051: }
! 3052: @
! 3053:
! 3054:
! 3055: 1.1
! 3056: log
! 3057: @Initial revision
! 3058: @
! 3059: text
! 3060: @a16 1
! 3061: lostsize = 0;
! 3062: a108 1
! 3063: lostsize += dip->di_size;
! 3064: d181 2
! 3065: a182 1
! 3066: if ( (daction!=NO) && ((sbpfix==TRUE) || (badilist()==BAD)) )
! 3067: d214 2
! 3068: a215 2
! 3069: ino_t i = FIRSTIN;
! 3070: int index = 0;
! 3071: d218 1
! 3072: a218 1
! 3073: while ( (i<=ninodes) && (index<NICINOD) ) {
! 3074: d222 1
! 3075: a222 1
! 3076: sbp->s_inode[index++] = i;
! 3077: a223 1
! 3078: i++;
! 3079: a224 1
! 3080:
! 3081: d226 7
! 3082: @
! 3083: bn = iblockn(i);
! 3084: if ( (!testblock(bn)) || (bn==INODEI) )
! 3085: sbp->s_inode[--index] = i;
! 3086: }
! 3087: }
! 3088: printf("Free i-node list in superblock rebuilt.\n");
! 3089: }
! 3090: @
! 3091:
! 3092:
! 3093: 1.1
! 3094: log
! 3095: @Initial revision
! 3096: @
! 3097: text
! 3098: @a16 1
! 3099: lostsize = 0;
! 3100: a108 1
! 3101: lostsize += dip->di_size;
! 3102: d181 2
! 3103: a182 1
! 3104: if ( (daction!=NO) && ((sbpfix==TRUE) || (badilist()==BAD)) )
! 3105: d214 2
! 3106: a215 2
! 3107: ino_t i = FIRSTIN;
! 3108: int index = 0;
! 3109: d218 1
! 3110: a218 1
! 3111: while ( (i<=ninodes) && (index<NICINOD) ) {
! 3112: d222 1
! 3113: a222 1
! 3114: sbp->s_inode[index++] = i;
! 3115: a223fsck/RCS/phase5.c,v 444 3 3 7463 4771205275 7204 head 1.2;
! 3116: access ;
! 3117: symbols ;
! 3118: locks bin:1.2;
! 3119: comment @ * @;
! 3120:
! 3121:
! 3122: 1.2
! 3123: date 91.03.18.18.45.05; author bin; state Exp;
! 3124: branches ;
! 3125: next 1.1;
! 3126:
! 3127: 1.1
! 3128: date 91.02.05.16.38.33; author bin; state Exp;
! 3129: branches ;
! 3130: next ;
! 3131:
! 3132:
! 3133: desc
! 3134: @prov by epstein (phase5.c)
! 3135: @
! 3136:
! 3137:
! 3138: 1.2
! 3139: log
! 3140: @update provided by epstein
! 3141: @
! 3142: text
! 3143: @/*
! 3144: * phase 5 of fsck - Check Free List
! 3145: */
! 3146:
! 3147: #include "fsck.h"
! 3148:
! 3149: daddr_t badcnt; /* Number of bad blocks in free list */
! 3150: daddr_t dupcnt; /* Number of dup blocks in free list */
! 3151: int badflag; /* Bad free list flag */
! 3152: int fixerup; /* Flag to salvage free list */
! 3153:
! 3154: phase5()
! 3155: {
! 3156: struct fblk *fbp;
! 3157: unsigned size;
! 3158:
! 3159: if (!qflag)
! 3160: printf("Phase 5 : Check Free List\n");
! 3161: fbp = (struct fblk *) &sbp->s_nfree;
! 3162: size = (unsigned) ((fsize+NBPC-1)/NBPC) * sizeof(char);
! 3163: copyV(size);
! 3164: badcnt = dupcnt = 0;
! 3165: badflag = FALSE;
! 3166: freetrav(fbp);
! 3167: fixerup = FALSE;
! 3168: if (badflag || sflag)
! 3169: asksalvage();
! 3170: }
! 3171:
! 3172:
! 3173: #define IGNORE 3 /* Return Possibilities from chk() */
! 3174: #define ABORT 4 /* as well as perhaps GOOD and BAD */
! 3175:
! 3176: freetrav(fbp)
! 3177: struct fblk *fbp;
! 3178: {
! 3179: daddr_t total=0;
! 3180: int i, flag;
! 3181:
! 3182: while ( fbp->df_nfree != 0 ) {
! 3183: if ( (unsigned) fbp->df_nfree > NICFREE ) {
! 3184: badflag = TRUE;
! 3185: printf("Bad freeblock count.\n");
! 3186: break;
! 3187: }
! 3188: for (i=1; i<fbp->df_nfree; i++) {
! 3189: if ( (flag=chk(fbp->df_free[i])) == GOOD ) {
! 3190: total++;
! 3191: continue;
! 3192: }
! 3193: if (flag == BAD)
! 3194: continue;
! 3195: break; /* break for IGNORE or ABORT */
! 3196: }
! 3197: if ( (flag == IGNORE) || (flag == ABORT) )
! 3198: break;
! 3199: if ( chk(fbp->df_free[0]) != GOOD )
! 3200: break;
! 3201: total++;
! 3202: bread(fbp->df_free[0], databuf);
! 3203: fbp = (struct fblk *) databuf;
! 3204: if ( !canfblk(fbp) ) {
! 3205: badflag = TRUE;
! 3206: printf("Bad freeblock count.\n");
! 3207: break;
! 3208: }
! 3209: }
! 3210:
! 3211: #if 0
! 3212: printf("Total traversed free blocks = %U\n", total);
! 3213: printf("Total free blocks by Superblock = %U\n", sbp->s_tfree);
! 3214: printf("Running total free blocks = %U\n", totfree);
! 3215: #endif
! 3216:
! 3217: if ( flag == ABORT ) { /* To Terminate fsck on this */
! 3218: badflag = FALSE; /* File System, because of */
! 3219: return; /* excessive dup or bad blocks */
! 3220: }
! 3221:
! 3222: if ( sbp->s_tfree != totfree )
! 3223: if ( (qflag==FALSE) && (daction!=NO) ) {
! 3224: printf("Free Block count wrong in superblock. ");
! 3225: if ( action(fixit) == TRUE ) {
! 3226: sbp->s_tfree = totfree;
! 3227: sbpfix = TRUE;
! 3228: }
! 3229: } else {
! 3230: sbp->s_tfree = totfree;
! 3231: sbpfix = TRUE;
! 3232: }
! 3233:
! 3234: report("%U Bad Block%s in Free List\n", badcnt);
! 3235: report("%U Dup Block%s in Free List\n", dupcnt);
! 3236: report("%U Block%s missing\n", totfree - total);
! 3237:
! 3238: }
! 3239:
! 3240: report(message, num)
! 3241: char *message;
! 3242: daddr_t num;
! 3243: {
! 3244: if ( num != 0 ) {
! 3245: printf(message, num, ( (num>1) ? "s" : "" ) );
! 3246: badflag = TRUE;
! 3247: }
! 3248: }
! 3249:
! 3250: chk(bn)
! 3251: register daddr_t bn;
! 3252: {
! 3253: if ( (bn<isize) || (bn>=fsize) ) {
! 3254: badflag = TRUE;
! 3255: if (++badcnt > MAXBADFREE)
! 3256: return( stopit("bad") );
! 3257: return(BAD);
! 3258: }
! 3259:
! 3260: if ( testdup(bn) ) {
! 3261: badflag = TRUE;
! 3262: if (++dupcnt > MAXDUPFREE)
! 3263: return( stopit("dup") );
! 3264: return(BAD);
! 3265: } else {
! 3266: markdup(bn);
! 3267: return(GOOD);
! 3268: }
! 3269: }
! 3270:
! 3271: stopit(type)
! 3272: char *type;
! 3273: {
! 3274: printf("Excessive %s blocks in free list ", type);
! 3275: if ( query("(Continue)") == YES )
! 3276: return(IGNORE);
! 3277: else
! 3278: return(ABORT);
! 3279: }
! 3280:
! 3281:
! 3282: canfblk(fbp)
! 3283: register struct fblk *fbp;
! 3284: {
! 3285: register short i;
! 3286:
! 3287: canshort(fbp->df_nfree);
! 3288: if ( (unsigned) fbp->df_nfree > NICFREE )
! 3289: return(FALSE);
! 3290:
! 3291: for (i=0; i<fbp->df_nfree; i++)
! 3292: candaddr(fbp->df_free[i]);
! 3293: return(TRUE);
! 3294: }
! 3295:
! 3296: asksalvage()
! 3297: {
! 3298: if ( (daction!=NO) && (qflag || sflag) ) {
! 3299: fixerup = TRUE;
! 3300: return;
! 3301: }
! 3302: if ( action("Bad Free List (SALVAGE)") )
! 3303: fixerup = TRUE;
! 3304: }
! 3305: @
! 3306:
! 3307:
! 3308: 1.1
! 3309: log
! 3310: @Initial revision
! 3311: @
! 3312: text
! 3313: @d26 1
! 3314: a26 1
! 3315: if (badflag)
! 3316: d62 5
! 3317: a66 1
! 3318: canfblk(fbp);
! 3319: d69 5
! 3320: a73 3
! 3321: /* printf("Total traversed free blocks = %U\n", total); */
! 3322: /* printf("Total free blocks by Superblock = %U\n", sbp->s_tfree); */
! 3323: /* printf("Running total free blocks = %U\n", totfree); */
! 3324: d146 3
! 3325: d151 2
! 3326: a153 2
! 3327: }
! 3328:
! 3329: d156 1
! 3330: a156 1
! 3331: if ( qflag && (daction!=NO) ) {
! 3332: @
! 3333: ( (daction!=NO) && (qflag || sflag) ) {
! 3334: fixerup = TRUE;
! 3335: return;
! 3336: }
! 3337: if ( action("Bad Free List (SALVAGE)") )
! 3338: fixerup = TRUE;
! 3339: }
! 3340: @
! 3341:
! 3342:
! 3343: 1.1
! 3344: log
! 3345: @Initial revision
! 3346: @
! 3347: text
! 3348: @d26 1
! 3349: a26 1
! 3350: if (badflag)
! 3351: d62 5
! 3352: afsck/RCS/phase6.c,v 444 3 3 5736 4771205312 7176 head 1.2;
! 3353: access ;
! 3354: symbols ;
! 3355: locks bin:1.2;
! 3356: comment @ * @;
! 3357:
! 3358:
! 3359: 1.2
! 3360: date 91.03.18.18.45.18; author bin; state Exp;
! 3361: branches ;
! 3362: next 1.1;
! 3363:
! 3364: 1.1
! 3365: date 91.02.05.16.38.52; author bin; state Exp;
! 3366: branches ;
! 3367: next ;
! 3368:
! 3369:
! 3370: desc
! 3371: @prov by epstein (post 310)
! 3372: @
! 3373:
! 3374:
! 3375: 1.2
! 3376: log
! 3377: @update provided by epstein.
! 3378: @
! 3379: text
! 3380: @/*
! 3381: * phase 6 of fsck - Salvage Free List
! 3382: */
! 3383:
! 3384: #include "fsck.h"
! 3385:
! 3386: static unsigned char *maptab; /* table of interleave offsets */
! 3387: static daddr_t mapbot; /* minimum block number to interleave map */
! 3388: static daddr_t maptop; /* maximum block number to interleave map */
! 3389: static short m,n; /* interleave factors */
! 3390: #define DEF_N 1 /* default values */
! 3391: #define DEF_M 1
! 3392: daddr_t freeblks; /* number free blocks left to write out */
! 3393: daddr_t blknm; /* current block number we are working with */
! 3394: struct fblk *fblkp; /* pointer to free block list */
! 3395: daddr_t *dp; /* pointer to block entry in free list block */
! 3396:
! 3397: phase6()
! 3398: {
! 3399: if (!fixerup) {
! 3400: return;
! 3401: }
! 3402:
! 3403: if (!qflag)
! 3404: printf("Phase 6 : Salvage Free List\n");
! 3405: if ( maketable() == BAD )
! 3406: return;
! 3407: writefree();
! 3408: free(maptab);
! 3409: }
! 3410:
! 3411: maketable()
! 3412: {
! 3413: register int i;
! 3414: register int ratio;
! 3415:
! 3416: m = sbp->s_m;
! 3417: n = sbp->s_n;
! 3418:
! 3419: if ( (n > MAXINTN) || (m > n) || (n%m != 0) ) {
! 3420: printf("Invalid interleave factors in superblock.\n");
! 3421: printf("Default free-block list spacing assumed.\n");
! 3422: sbp->s_n = n = DEF_N;
! 3423: sbp->s_m = m = DEF_M;
! 3424: }
! 3425:
! 3426: if ( (maptab = malloc(n)) == NULL ) {
! 3427: printf("Can't malloc space for interleave table.\n");
! 3428: printf("Free-block list is not rebuilt.\n");
! 3429: return(BAD);
! 3430: }
! 3431:
! 3432: mapbot = (isize + n - 1)/n*n;
! 3433: maptop = fsize/n*n;
! 3434: ratio = n/m;
! 3435: for (i=0; i<n; i++)
! 3436: maptab[i] = (i/ratio) + (i%ratio)*m;
! 3437:
! 3438: return(GOOD);
! 3439: }
! 3440:
! 3441: writefree()
! 3442: {
! 3443: register daddr_t bn;
! 3444: daddr_t blk, bmap();
! 3445: short num;
! 3446:
! 3447: sbpfix = TRUE;
! 3448: freeblks = totfree;
! 3449: blknm = SUPERI;
! 3450: fblkp = (struct fblk *) &sbp->s_nfree;
! 3451: fblkp->df_nfree = num = (freeblks < NICFREE) ? freeblks : NICFREE;
! 3452: freeblks -= num;
! 3453: dp = &fblkp->df_free[num];
! 3454: for (bn=isize; bn<fsize; bn++) {
! 3455: blk = bmap(bn);
! 3456: if ( !testblock(blk) )
! 3457: if ( addfree(blk) == STOP )
! 3458: break;
! 3459: }
! 3460: }
! 3461:
! 3462: addfree(bn)
! 3463: daddr_t bn;
! 3464: {
! 3465: short num;
! 3466:
! 3467: *--dp = bn;
! 3468: if (dp > &fblkp->df_free[0])
! 3469: return(OK);
! 3470:
! 3471: if ( blknm != SUPERI ) {
! 3472: canwfblk(fblkp);
! 3473: bwrite(blknm, databuf);
! 3474: }
! 3475:
! 3476: bclear(databuf, BSIZE);
! 3477: if (freeblks == 0) {
! 3478: bwrite(bn, databuf);
! 3479: return(STOP);
! 3480: }
! 3481: blknm = bn;
! 3482: fblkp = (struct fblk *) databuf;
! 3483: fblkp->df_nfree = num = (freeblks < NICFREE) ? freeblks : NICFREE;
! 3484: freeblks -= num;
! 3485: dp = &fblkp->df_free[num];
! 3486: return(OK);
! 3487: }
! 3488:
! 3489: daddr_t
! 3490: bmap(blk)
! 3491: register daddr_t blk;
! 3492: {
! 3493: short i;
! 3494:
! 3495: if ( (blk>=mapbot) && (blk<maptop) ) {
! 3496: i = blk%n;
! 3497: blk -= i;
! 3498: blk += maptab[i];
! 3499: }
! 3500: return(blk);
! 3501: }
! 3502:
! 3503: canwfblk(fbp)
! 3504: register struct fblk *fbp;
! 3505: {
! 3506: register short i;
! 3507:
! 3508: for (i=0; i<fbp->df_nfree; i++)
! 3509: candaddr(fbp->df_free[i]);
! 3510: canshort(fbp->df_nfree);
! 3511: }
! 3512: @
! 3513:
! 3514:
! 3515: 1.1
! 3516: log
! 3517: @Initial revision
! 3518: @
! 3519: text
! 3520: @d7 1
! 3521: a7 1
! 3522: static char *maptab; /* table of interleave offsets */
! 3523: d114 1
! 3524: a114 1
! 3525: int i;
! 3526: d117 3
! 3527: a119 2
! 3528: i = ((unsigned)blk)%n;
! 3529: blk += maptab[i] - i;
! 3530: @
! 3531: rn(OK);
! 3532: }
! 3533:
! 3534: daddr_t
! 3535: bmap(blk)
! 3536: regisfsck/RCS/printf.c,v 444 3 3 7620 4753557667 7333 head 1.1;
! 3537: access ;
! 3538: symbols ;
! 3539: locks ;
! 3540: comment @ * @;
! 3541:
! 3542:
! 3543: 1.1
! 3544: date 91.02.05.16.39.10; author bin; state Exp;
! 3545: branches ;
! 3546: next ;
! 3547:
! 3548:
! 3549: desc
! 3550: @prov by epstein (post310)
! 3551: @
! 3552:
! 3553:
! 3554:
! 3555: 1.1
! 3556: log
! 3557: @Initial revision
! 3558: @
! 3559: text
! 3560: @/*
! 3561: * Standard output printf using putchar.
! 3562: * Non-portable things:
! 3563: * 1) alignment of arguments is assumed to be completely contiguous.
! 3564: * 2) the smallest number is assumed to negate to itself.
! 3565: * 3) All of long, int, char*, and double are assumed to
! 3566: * be held in an exact number of ints.
! 3567: */
! 3568:
! 3569: #define NULL ((char *)0)
! 3570: #define putchar(c) { char b = c; write(1, &b, 1); }
! 3571: #include <sys/mdata.h>
! 3572:
! 3573: union alltypes {
! 3574: char c;
! 3575: int i;
! 3576: unsigned u;
! 3577: long l;
! 3578: double d;
! 3579: char *s;
! 3580: };
! 3581:
! 3582: #define bump(p,s) (p+=sizeof(s)/sizeof(int))
! 3583:
! 3584: char *printi();
! 3585: char *printl();
! 3586:
! 3587: static char null[] = "{NULL}";
! 3588:
! 3589: printf(args)
! 3590: union alltypes args;
! 3591: {
! 3592: xprintf(&args);
! 3593: }
! 3594: xprintf(argp)
! 3595: union alltypes *argp;
! 3596: {
! 3597: register char *cbp;
! 3598: int *iap;
! 3599: register c;
! 3600: char *s;
! 3601: char *cbs;
! 3602: char adj, pad;
! 3603: int prec;
! 3604: int fwidth;
! 3605: int pwidth;
! 3606: register char *fmt;
! 3607: union alltypes elem;
! 3608: char cbuf[64];
! 3609:
! 3610: iap = (int *)argp;
! 3611: fmt = *(char **)iap;
! 3612: bump(iap, char*);
! 3613: for (;;) {
! 3614: while((c = *fmt++) != '%') {
! 3615: if(c == '\0') {
! 3616: return;
! 3617: }
! 3618: putchar(c);
! 3619: }
! 3620: pad = ' ';
! 3621: fwidth = -1;
! 3622: prec = -1;
! 3623: c = *fmt++;
! 3624: if (c == '-') {
! 3625: adj = 1;
! 3626: c = *fmt++;
! 3627: } else
! 3628: adj = 0;
! 3629: if (c == '0') {
! 3630: pad = '0';
! 3631: c = *fmt++;
! 3632: }
! 3633: if (c == '*') {
! 3634: fwidth = *iap++;
! 3635: c = *fmt++;
! 3636: } else
! 3637: for (fwidth = 0; c>='0' && c<='9'; c = *fmt++)
! 3638: fwidth = fwidth*10 + c-'0';
! 3639: if (c == '.') {
! 3640: c = *fmt++;
! 3641: if (c == '*') {
! 3642: prec = *iap++;
! 3643: c = *fmt++;
! 3644: } else
! 3645: for (prec=0; c>='0' && c<='9'; c=*fmt++)
! 3646: prec = prec*10 + c-'0';
! 3647: }
! 3648: if (c == 'l') {
! 3649: c = *fmt++;
! 3650: if (c=='d' || c=='o' || c=='u' || c=='x')
! 3651: c += 'A' - 'a';
! 3652: }
! 3653: cbp = cbs = cbuf;
! 3654: switch (c) {
! 3655:
! 3656: case 'd':
! 3657: elem.i = *iap++;
! 3658: if (elem.i < 0) {
! 3659: elem.i = -elem.i;
! 3660: *cbp++ = '-';
! 3661: }
! 3662: cbp = printi(cbp, elem.i, 10);
! 3663: break;
! 3664:
! 3665: case 'u':
! 3666: cbp = printi(cbp, *iap++, 10);
! 3667: break;
! 3668:
! 3669: case 'o':
! 3670: cbp = printi(cbp, *iap++, 8);
! 3671: break;
! 3672:
! 3673: case 'x':
! 3674: cbp = printi(cbp, *iap++, 16);
! 3675: break;
! 3676:
! 3677: case 'D':
! 3678: elem.l = *(long *)iap;
! 3679: bump(iap, long);
! 3680: if (elem.l < 0) {
! 3681: elem.l = -elem.l;
! 3682: *cbp++ = '-';
! 3683: }
! 3684: cbp = printl(cbp, elem.l, 10);
! 3685: break;
! 3686:
! 3687: case 'U':
! 3688: cbp = printl(cbp, *(long *)iap, 10);
! 3689: bump(iap, long);
! 3690: break;
! 3691:
! 3692: case 'O':
! 3693: cbp = printl(cbp, *(long *)iap, 8);
! 3694: bump(iap, long);
! 3695: break;
! 3696:
! 3697: case 'X':
! 3698: cbp = printl(cbp, *(long *)iap, 16);
! 3699: bump(iap, long);
! 3700: break;
! 3701:
! 3702:
! 3703: case 's':
! 3704: if ((s = *(char **)iap) == NULL)
! 3705: s = null;
! 3706: bump(iap, char*);
! 3707: /*
! 3708: * Do %s specially so it can be longer.
! 3709: */
! 3710: cbp = cbs = s;
! 3711: while (*cbp++ != '\0')
! 3712: if (prec>=0 && cbp-s>prec)
! 3713: break;
! 3714: cbp--;
! 3715: break;
! 3716:
! 3717: case 'c':
! 3718: elem.c = *iap++;
! 3719: *cbp++ = elem.c;
! 3720: break;
! 3721:
! 3722: case 'r':
! 3723: xprintf(*(char ***)iap);
! 3724: bump(iap, char**);
! 3725: break;
! 3726:
! 3727: default:
! 3728: putchar(c);
! 3729: continue;
! 3730: }
! 3731: if ((pwidth = fwidth + cbs-cbp) < 0)
! 3732: pwidth = 0;
! 3733: if (!adj)
! 3734: while (pwidth-- != 0)
! 3735: putchar(pad);
! 3736: while (cbs < cbp)
! 3737: putchar(*cbs++);
! 3738: if (adj)
! 3739: while (pwidth-- != 0)
! 3740: putchar(pad);
! 3741: }
! 3742: }
! 3743:
! 3744: static char digits[] = {
! 3745: '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
! 3746: 'A', 'B', 'C', 'D', 'E', 'F'
! 3747: };
! 3748:
! 3749: /*
! 3750: * Print an unsigned integer in base b.
! 3751: */
! 3752: static
! 3753: char *
! 3754: printi(cp, n, b)
! 3755: char *cp;
! 3756: register unsigned n;
! 3757: {
! 3758: register a;
! 3759: register char *ep;
! 3760: char pbuf[10];
! 3761:
! 3762: ep = &pbuf[10];
! 3763: *--ep = 0;
! 3764: for ( ; a = n/b; n=a)
! 3765: *--ep = digits[n%b];
! 3766: *--ep = digits[n];
! 3767: while (*ep)
! 3768: *cp++ = *ep++;
! 3769: return (cp);
! 3770: }
! 3771:
! 3772: /*
! 3773: * Print an unsigned long in base b.
! 3774: */
! 3775: static
! 3776: char *
! 3777: printl(cp, n, b)
! 3778: register char *cp;
! 3779: unsigned long n;
! 3780: register b;
! 3781: {
! 3782: char pbuf[13];
! 3783: unsigned long a;
! 3784: register char *ep;
! 3785:
! 3786: ep = &pbuf[13];
! 3787: *--ep = '\0';
! 3788: for ( ; (a = n/b) != 0; n = a)
! 3789: *--ep = digits[n%b];
! 3790: *--ep = digits[n];
! 3791: while (*ep)
! 3792: *cp++ = *ep++;
! 3793: return (cp);
! 3794: }
! 3795: @
! 3796: egister char *ep;
! 3797: char pbuf[10];
! 3798:
! 3799: ep = &pbuf[10];
! 3800: *--ep = 0;
! 3801: for ( ; a = n/b; n=a)
! 3802: *--ep = digits[n%b];
! 3803: *fsck/RCS/util.c,v 444 3 3 16442 5045006750 7001 head 1.2;
! 3804: branch ;
! 3805: access ;
! 3806: symbols ;
! 3807: locks bin:1.2;
! 3808: comment @ * @;
! 3809:
! 3810:
! 3811: 1.2
! 3812: date 91.07.29.07.45.21; author bin; state Exp;
! 3813: branches ;
! 3814: next 1.1;
! 3815:
! 3816: 1.1
! 3817: date 91.02.05.16.39.25; author bin; state Exp;
! 3818: branches ;
! 3819: next ;
! 3820:
! 3821:
! 3822: desc
! 3823: @prov by epstein (post 310)
! 3824: @
! 3825:
! 3826:
! 3827: 1.2
! 3828: log
! 3829: @Updated by epstein for version 321.
! 3830: @
! 3831: text
! 3832: @/*
! 3833: * general utility functions for phases of fsck
! 3834: */
! 3835:
! 3836: #include "fsck.h"
! 3837:
! 3838: struct stat stats; /* Used by statit() */
! 3839:
! 3840: statit(name, probfun)
! 3841: char *name;
! 3842: int (*probfun)();
! 3843: {
! 3844:
! 3845: if ( stat(name, &stats) == -1 ) {
! 3846: bclear(&stats, sizeof(struct stat));
! 3847: (*probfun)("Can not stat %s", name);
! 3848: }
! 3849: }
! 3850:
! 3851:
! 3852: query(x)
! 3853: {
! 3854: while(1) {
! 3855: printf("%r [yes/no]: ", &x);
! 3856:
! 3857: switch (daction) {
! 3858: case YES:
! 3859: printf("[default - YES]\n");
! 3860: return(YES);
! 3861: break;
! 3862: case NO:
! 3863: printf("[default - NO]\n");
! 3864: return(NO);
! 3865: break;
! 3866: case ASK:
! 3867: switch( nextchar() ) {
! 3868: case 'Y':
! 3869: return(YES);
! 3870: case 'N':
! 3871: return(NO);
! 3872: }
! 3873: }
! 3874: }
! 3875: }
! 3876:
! 3877: action(msg)
! 3878: char *msg;
! 3879: {
! 3880: switch( query(msg) ) {
! 3881: case YES:
! 3882: return(TRUE);
! 3883: case NO:
! 3884: return(FALSE);
! 3885: }
! 3886: }
! 3887:
! 3888: char
! 3889: nextchar()
! 3890: {
! 3891: char buff[8];
! 3892: int i, n, ch;
! 3893:
! 3894: if ( ((n=read(0,buff,8)) <= 0) || (n == 8) )
! 3895: fatal("Invalid Response");
! 3896:
! 3897: for(i=0; i<n; i++)
! 3898: if ( ((ch=buff[i])!=' ') && (ch!='\t') )
! 3899: break;
! 3900:
! 3901: if ( (ch>='a') && (ch<='z') )
! 3902: ch += 'A' - 'a';
! 3903:
! 3904: return(ch);
! 3905: }
! 3906:
! 3907: char *nfile = "FILE";
! 3908: char *ndir = "DIR";
! 3909: char *nchr = "Character Special";
! 3910: char *nblk = "Block Special";
! 3911: char *npipe = "PIPE";
! 3912: char *nunkwn = "Unknown I-node type";
! 3913:
! 3914: char *
! 3915: typename(ino)
! 3916: ino_t ino;
! 3917: {
! 3918: switch( flags(ino)&MODEMASK ) {
! 3919: case IREG:
! 3920: return(nfile);
! 3921: case IDIR:
! 3922: return(ndir);
! 3923: case ICHR:
! 3924: return(nchr);
! 3925: case IBLK:
! 3926: return(nblk);
! 3927: case IPIPE:
! 3928: return(npipe);
! 3929: default:
! 3930: return(nunkwn);
! 3931: }
! 3932: }
! 3933:
! 3934: abort()
! 3935: {
! 3936: fatal("abort.");
! 3937: }
! 3938:
! 3939: fatal(x)
! 3940: {
! 3941: printf("fsck: %r\n", &x);
! 3942: _exit(1);
! 3943: }
! 3944:
! 3945: nonfatal(x)
! 3946: {
! 3947: printf("fsck: %r\n", &x);
! 3948: errflag = TRUE;
! 3949: }
! 3950:
! 3951: /*
! 3952: * Inode Manipulation Routines
! 3953: * ptrino: returns a pointer to the wanted inode using the given
! 3954: * buffer to read in the block performing canonicalization.
! 3955: * writeino: writes the block containing the given inode to the
! 3956: * disk performing the necessary canonicalization
! 3957: * candino: canonicalize an inode
! 3958: *
! 3959: */
! 3960:
! 3961: struct dinode *
! 3962: ptrino(ino, buf)
! 3963: register ino_t ino;
! 3964: register char *buf;
! 3965: {
! 3966: register daddr_t bn;
! 3967: register struct dinode *dip;
! 3968:
! 3969: bn = iblockn(ino);
! 3970: if ( (testblock(bn)) && (bn!=INODEI) ) /* bad inode block */
! 3971: return(NULL);
! 3972: bread(bn, buf);
! 3973: dip = ((struct dinode *) buf) + iblocko(ino);
! 3974: candino(dip);
! 3975: return(dip);
! 3976: }
! 3977:
! 3978: writeino(ino, buf)
! 3979: ino_t ino;
! 3980: char *buf;
! 3981: {
! 3982: struct dinode *dip;
! 3983:
! 3984: dip = ((struct dinode *) buf) + iblocko(ino);
! 3985: candino(dip);
! 3986: bwrite((daddr_t) iblockn(ino), buf);
! 3987: }
! 3988:
! 3989: candino(dip)
! 3990: register struct dinode *dip;
! 3991: {
! 3992: canshort(dip->di_mode);
! 3993: canshort(dip->di_nlink);
! 3994: canshort(dip->di_uid);
! 3995: canshort(dip->di_gid);
! 3996: cansize(dip->di_size);
! 3997: cantime(dip->di_atime);
! 3998: cantime(dip->di_mtime);
! 3999: cantime(dip->di_ctime);
! 4000: }
! 4001:
! 4002: /*
! 4003: * Transfer a logical block number for an inode to a
! 4004: * physical block number, chasing indirects as necessary.
! 4005: * The inefficiency of this method is put up with since
! 4006: * this is only used for directory inodes, and they tend
! 4007: * not to use indirects. Pass in 'addrs' which is a pointer
! 4008: * to the 13 daddr_s in the inode, and the logical block
! 4009: * number you would like. (Stolen from dcheck.c)
! 4010: */
! 4011:
! 4012: static daddr_t ranges[] = {
! 4013: ND,
! 4014: ND + (daddr_t)NI*NBN,
! 4015: ND + (daddr_t)NI*NBN + (daddr_t)NII*NBN*NBN,
! 4016: ND + (daddr_t)NI*NBN + (daddr_t)NII*NBN*NBN + (daddr_t)NIII*NBN*NBN*NBN
! 4017: };
! 4018:
! 4019: static char index[] = {
! 4020: 0,
! 4021: ND,
! 4022: ND+NI,
! 4023: ND+NI+NII
! 4024: };
! 4025:
! 4026: static daddr_t coeff[] = {
! 4027: 1, (daddr_t)NBN, (daddr_t)NBN*NBN, (daddr_t)NBN*NBN*NBN
! 4028: };
! 4029:
! 4030: daddr_t
! 4031: imap(addrs, block)
! 4032: daddr_t *addrs;
! 4033: register daddr_t block;
! 4034: {
! 4035: int i;
! 4036: register daddr_t bpos;
! 4037: register daddr_t *bp;
! 4038: register daddr_t bn;
! 4039:
! 4040: for (i=0; i<4; i++)
! 4041: if (block < ranges[i]) {
! 4042: if (i != 0)
! 4043: block -= ranges[i-1];
! 4044: bpos = block/coeff[i];
! 4045: block %= coeff[i];
! 4046: bp = &addrs[(int)bpos + index[i]];
! 4047: if ( (bn=*bp) != 0 ) {
! 4048: /*
! 4049: * Map through indirects here
! 4050: */
! 4051: while (i-- > 0) {
! 4052: bread(bn, databuf);
! 4053: bpos = block/coeff[i];
! 4054: block %= coeff[i];
! 4055: bp = (daddr_t *)databuf + bpos;
! 4056: if ( (bn=*bp) == 0 )
! 4057: break;
! 4058: bn = *bp;
! 4059: candaddr(bn);
! 4060: }
! 4061: }
! 4062: return(bn);
! 4063: }
! 4064: return(0);
! 4065: }
! 4066:
! 4067: /*
! 4068: * Read the specified block number into the given buffer
! 4069: */
! 4070:
! 4071: char *rgblkerr = "Out of Range Block number: %U (CONTINUE)";
! 4072: char *skblkerr = "Can not Seek: Blk num: %U (CONTINUE)";
! 4073: char *rdblkerr = "Can not Read: Blk num: %U (CONTINUE)";
! 4074: char *wtblkerr = "Can not Write: Blk num: %U (CONTINUE)";
! 4075:
! 4076: bread(bn, buf)
! 4077: register daddr_t bn;
! 4078: register char *buf;
! 4079: {
! 4080: #ifdef DEBUG
! 4081: printf("Reading block number: %ld\n", bn);
! 4082: #endif
! 4083: if (bn<0 || bn >= fsize )
! 4084: switch( query(rgblkerr, bn) ) {
! 4085: case YES:
! 4086: bclear(buf, BSIZE);
! 4087: return;
! 4088: case NO:
! 4089: abort();
! 4090: }
! 4091:
! 4092: if ( (bn<isize) && getcache(bn, buf) ) {
! 4093: #if DEBUG
! 4094: bdump(buf);
! 4095: #endif
! 4096: return;
! 4097: }
! 4098:
! 4099: if ( lseek(fsfd, (unsigned long)bn*BSIZE, 0) == (-1L) )
! 4100: switch( query(skblkerr, bn) ) {
! 4101: case YES:
! 4102: bclear(buf, BSIZE);
! 4103: return;
! 4104: case NO:
! 4105: abort();
! 4106: }
! 4107:
! 4108: if ( read(fsfd, buf, BSIZE) != BSIZE )
! 4109: switch( query(rdblkerr, bn) ) {
! 4110: case YES:
! 4111: bclear(buf, BSIZE);
! 4112: return;
! 4113: case NO:
! 4114: abort();
! 4115: }
! 4116: #if DEBUG
! 4117: bdump(buf);
! 4118: #endif
! 4119: }
! 4120:
! 4121: /*
! 4122: * Write block number bn with data in buf
! 4123: */
! 4124:
! 4125: bwrite(bn, buf)
! 4126: daddr_t bn;
! 4127: char *buf;
! 4128: {
! 4129: #ifdef DEBUG
! 4130: printf("Writing block number: %ld\n", bn);
! 4131: #endif
! 4132: if (!writeflg)
! 4133: return;
! 4134:
! 4135: if (bn<0 || bn>=fsize)
! 4136: switch( query(rgblkerr, bn) ) {
! 4137: case YES:
! 4138: return;
! 4139: case NO:
! 4140: abort();
! 4141: }
! 4142:
! 4143: if ( lseek(fsfd, (fsize_t)BSIZE*bn, 0) == (-1L) )
! 4144: switch( query(skblkerr, bn) ) {
! 4145: case YES:
! 4146: return;
! 4147: case NO:
! 4148: abort();
! 4149: }
! 4150:
! 4151: if ( write(fsfd, buf, BSIZE) != BSIZE )
! 4152: switch( query(wtblkerr, bn) ) {
! 4153: case YES:
! 4154: return;
! 4155: case NO:
! 4156: abort();
! 4157: }
! 4158:
! 4159: if ( bn <= isize )
! 4160: chgcache(bn, buf);
! 4161: changeflg = TRUE;
! 4162: }
! 4163:
! 4164: /*
! 4165: * i-node block area caching routines
! 4166: */
! 4167:
! 4168: static char cache[NBLK * BSIZE];
! 4169: static int low = 0; high = -1;
! 4170:
! 4171: getcache(bn, buf)
! 4172: register daddr_t bn;
! 4173: register char *buf;
! 4174: {
! 4175: int totsize;
! 4176:
! 4177: if ( bn > isize )
! 4178: return(0);
! 4179:
! 4180: if ( (bn>=low) && (bn<=high) ) {
! 4181: blkmove(buf, &cache[BSIZE * (bn-low)]);
! 4182: return(1);
! 4183: }
! 4184:
! 4185: low = bn;
! 4186: if ( (high=bn+NBLK-1) > isize )
! 4187: high = isize;
! 4188: totsize = BSIZE * (high-low+1);
! 4189:
! 4190: if ( (lseek(fsfd, (unsigned long)bn*BSIZE, 0) == (-1L)) ||
! 4191: (read(fsfd, cache, totsize) != totsize) ) {
! 4192: low = 0; high = -1;
! 4193: return(0);
! 4194: }
! 4195:
! 4196: return( getcache(bn, buf) );
! 4197: }
! 4198:
! 4199: chgcache(bn, buf)
! 4200: register daddr_t bn;
! 4201: register char *buf;
! 4202: {
! 4203: if ( (bn>=low) && (bn<=high) )
! 4204: blkmove(&cache[BSIZE * (bn-low)], buf);
! 4205: }
! 4206:
! 4207: blkmove(to, from)
! 4208: register char *to, *from;
! 4209: {
! 4210: register int num=BSIZE;
! 4211:
! 4212: while ( num-- )
! 4213: *to++= *from++;
! 4214: }
! 4215:
! 4216: /*
! 4217: * Clear the given block of memory
! 4218: */
! 4219:
! 4220: bclear(bp, nb)
! 4221: register char *bp;
! 4222: register unsigned nb;
! 4223: {
! 4224: if (nb)
! 4225: do {
! 4226: *bp++ = 0;
! 4227: } while (--nb);
! 4228: }
! 4229:
! 4230:
! 4231: /*
! 4232: * Determine if the given block is bad
! 4233: */
! 4234:
! 4235: bad(bn)
! 4236: daddr_t bn;
! 4237: {
! 4238: if ( (bn >= isize) && (bn < fsize) )
! 4239: return(GOOD);
! 4240: else
! 4241: return(BAD);
! 4242: }
! 4243:
! 4244:
! 4245: #if DEBUG
! 4246:
! 4247: /*
! 4248: * Debug dump a block of data.
! 4249: */
! 4250:
! 4251: #define NUMPLIN 16
! 4252:
! 4253: bdump(buf)
! 4254: register unsigned char *buf;
! 4255: {
! 4256: register int i;
! 4257:
! 4258: for (i=0; i<BSIZE; i++) {
! 4259: if ( (i % NUMPLIN) == 0 )
! 4260: printf("\n0x%04x: ", i);
! 4261: printf(" %02x", *buf++);
! 4262: }
! 4263: printf("\n\n");
! 4264: }
! 4265:
! 4266: #endif
! 4267: @
! 4268:
! 4269:
! 4270: 1.1
! 4271: log
! 4272: @Initial revision
! 4273: @
! 4274: text
! 4275: @d261 4
! 4276: a264 1
! 4277: if ( (bn<isize) && getcache(bn, buf) )
! 4278: d266 1
! 4279: d285 3
! 4280: d412 24
! 4281: @
! 4282: iven block is bad
! 4283: */
! 4284:
! 4285: bad(bn)
! 4286: daddr_t bn;
! 4287: {
! 4288: if ( (bn >= isize) && (bn < fsize) )
! 4289: return(GOOD);
! 4290: else
! 4291: return(BAD);
! 4292: }
! 4293:
! 4294:
! 4295: #if DEBUG
! 4296:
! 4297: /*
! 4298: * Debug dump a block of data.
! 4299: */
! 4300:
! 4301: #define NUMPLIN 16
! 4302:
! 4303: bdump(buf)
! 4304: register unsignefsck/RCS/virtual.c,v 444 3 3 16557 4753557734 7543 head 1.1;
! 4305: access ;
! 4306: symbols ;
! 4307: locks ;
! 4308: comment @ * @;
! 4309:
! 4310:
! 4311: 1.1
! 4312: date 91.02.05.16.39.42; author bin; state Exp;
! 4313: branches ;
! 4314: next ;
! 4315:
! 4316:
! 4317: desc
! 4318: @prov by epstein (post 310)
! 4319: @
! 4320:
! 4321:
! 4322:
! 4323: 1.1
! 4324: log
! 4325: @Initial revision
! 4326: @
! 4327: text
! 4328: @/*
! 4329: * Virtual memory for fsck. Uses hash algorithm
! 4330: * rather than LRU to get it up fast.
! 4331: */
! 4332: #include <assert.h>
! 4333: #include <sys/stat.h>
! 4334: #include "fsck.h"
! 4335:
! 4336: #define VBLKB 9 /* bytes in virtual block as power of 2 */
! 4337: #define VBLK (1 << VBLKB) /* bytes in a virtual block */
! 4338: #define MBKSB 6 /* number of virtual blocks as power of 2 */
! 4339: #define MBKS (1 << MBKSB) /* number of virtual blocks */
! 4340:
! 4341: #define DVTMP "/dev/rram1" /* Default Virtual Temp Filename */
! 4342: #define DVTMPCLS "/dev/rram1close" /* Default Virtual Temp File Close */
! 4343: #define MAJORRAM 8 /* Major Device Number for the Ram Disk */
! 4344:
! 4345: struct mapper {
! 4346: unsigned dirty:1;
! 4347: unsigned what_in:15; /* which block is in memory */
! 4348: };
! 4349:
! 4350: static unsigned long flagdsp, blkdsp, dupdsp, duplim;
! 4351: static struct mapper map[MBKS];
! 4352: static unsigned char data[MBKS][VBLK];
! 4353: static int tmp;
! 4354:
! 4355: static char *dvtmp = DVTMP;
! 4356: static char *dvtmpcls = DVTMPCLS;
! 4357:
! 4358: /*
! 4359: * Init file system for virtual arrays.
! 4360: * Data is ordered links, flags, blocks then dups.
! 4361: */
! 4362: initV(links, flags, blocks, dups)
! 4363: unsigned links, flags, blocks, dups;
! 4364: {
! 4365: register long bp;
! 4366: struct stat st;
! 4367: unsigned datasiz;
! 4368:
! 4369: flagdsp = links;
! 4370: blkdsp = flagdsp + flags;
! 4371: dupdsp = blkdsp + blocks;
! 4372: duplim = dupdsp + dups;
! 4373:
! 4374: memset(map, 0, sizeof(map)); /* zero ram arrays */
! 4375: memset(data, 0, sizeof(data));
! 4376:
! 4377: tmp = -1;
! 4378:
! 4379: datasiz = sizeof(data);
! 4380: if ( duplim < datasiz )
! 4381: return;
! 4382:
! 4383: if ( tmpfile == NULL ) {
! 4384: switch ( is_fs(dvtmp) ) {
! 4385: case -1:
! 4386: fatal(
! 4387: "Can't access ram disk \"%s\", use the -t option", dvtmp);
! 4388: case 0:
! 4389: break;
! 4390: case 1:
! 4391: fatal(
! 4392: "Possible file system on ram disk \"%s\", use the -t option", dvtmp);
! 4393: }
! 4394: if ( (-1 == stat(dvtmp, &st)) || !(st.st_mode&S_IFCHR) ||
! 4395: (major(st.st_rdev) != MAJORRAM) )
! 4396: fatal("Ram disk \"%s\" not mknod'ed properly",
! 4397: dvtmp);
! 4398: if ( -1 == (tmp = open(dvtmp, 2)) )
! 4399: fatal("Cannot open read/write Ram Disk \"%s\"", dvtmp);
! 4400:
! 4401: /* Ram disk driver may not promise zeroed start.
! 4402: * This code may go later. Extra write not important. */
! 4403: for(bp = 0; bp < duplim; bp += VBLK) /* zero disk stuff */
! 4404: if ( VBLK != write(tmp, data[0], VBLK) )
! 4405: fatal("Error writing to tmp file");
! 4406: } else {
! 4407: if ( -1 == (tmp = open(tmpfile, 2)) ) {
! 4408: if ( -1 == (tmp = creat(tmpfile, 0600)) )
! 4409: fatal("Cannot create temp file \"%s\"",
! 4410: tmpfile);
! 4411: close(tmp);
! 4412: tmp = open(tmpfile, 2);
! 4413: unlink(tmpfile);
! 4414: }
! 4415: if ( -1 == fstat(tmp, &st) )
! 4416: fatal("Can't stat temp file \"%s\"", tmpfile);
! 4417: if ( st.st_dev == fsysrdev )
! 4418: fatal("Temp File must not be on file system to fsck");
! 4419: }
! 4420: }
! 4421:
! 4422: /*
! 4423: * cleanup virtual system
! 4424: */
! 4425: cleanV()
! 4426: {
! 4427: struct stat st;
! 4428:
! 4429: if ( tmp == -1 ) /* No Virtual Temp File Opened */
! 4430: return;
! 4431:
! 4432: close(tmp);
! 4433: if ( tmpfile != NULL ) /* Virtual File not Default RAMDisk */
! 4434: return;
! 4435: /* Virtual File is Default RAMDisk */
! 4436: if ( (-1 == stat(dvtmpcls, &st)) || !(st.st_mode&S_IFCHR) ||
! 4437: (major(st.st_rdev) != MAJORRAM) ||
! 4438: ((minor(st.st_rdev)&0x7F) != 0) )
! 4439: fatal("Ram disk close \"%s\" not mknod'ed properly", dvtmpcls);
! 4440: if ( -1 == (tmp = open(dvtmpcls, 2)) )
! 4441: fatal("Cannot open Ram Disk Close \"%s\"", dvtmpcls);
! 4442: if ( close(tmp) < 0 )
! 4443: fatal("Cannot close Ram Disk Close \"%s\"", dvtmpcls);
! 4444: }
! 4445:
! 4446: /*
! 4447: * All actions for virtual array
! 4448: */
! 4449: findblock(bp, action, odata)
! 4450: long bp; /* data address */
! 4451: enum vact action; /* what to do */
! 4452: unsigned odata; /* optional data */
! 4453: {
! 4454: unsigned which, what_in, byte_no, bit;
! 4455: unsigned long diskad;
! 4456: unsigned char *byte;
! 4457: extern long lseek();
! 4458:
! 4459: switch(action) { /* use displacment to correct part of file */
! 4460: case testBlock:
! 4461: case markBlock:
! 4462: case unmarkBlock:
! 4463: bit = 1 << (bp & 7);
! 4464: bp >>= 3;
! 4465: case grabBlock: /* 8 at a time for copy */
! 4466: assert(bp >= 0);
! 4467: bp += blkdsp;
! 4468: assert(bp < dupdsp);
! 4469: break;
! 4470: case testDup:
! 4471: case markDup:
! 4472: case unmarkDup:
! 4473: bit = 1 << (bp & 7);
! 4474: bp >>= 3;
! 4475: case setDup: /* 8 at a time for copy */
! 4476: assert(bp >= 0);
! 4477: bp += dupdsp;
! 4478: assert(bp < duplim);
! 4479: break;
! 4480: case Flags:
! 4481: case setFlags:
! 4482: case orFlags:
! 4483: assert(bp > 0);
! 4484: bp += flagdsp - 1;
! 4485: assert(bp < blkdsp);
! 4486: break;
! 4487: case linkCtr:
! 4488: case incLinkctr:
! 4489: case setLinkctr:
! 4490: assert(bp > 0);
! 4491: bp--;
! 4492: assert(bp < flagdsp);
! 4493: }
! 4494:
! 4495: byte_no = bp & (VBLK - 1);
! 4496: bp >>= VBLKB;
! 4497: which = bp & (MBKS - 1);
! 4498: bp >>= MBKSB;
! 4499: what_in = bp & 0x7fff;
! 4500:
! 4501: if((diskad = map[which].what_in) != what_in) {
! 4502: if(map[which].dirty) {
! 4503: diskad <<= VBLKB + MBKSB;
! 4504: diskad += which << VBLKB;
! 4505: if(-1 == lseek(tmp, diskad, 0))
! 4506: fatal("Error seeking tmp file");
! 4507: if(VBLK != write(tmp, data[which], VBLK))
! 4508: fatal("Error writing tmp file");
! 4509: }
! 4510: diskad = what_in;
! 4511: diskad <<= VBLKB + MBKSB;
! 4512: diskad += which << VBLKB;
! 4513: if(-1 == lseek(tmp, diskad, 0))
! 4514: fatal("Error seeking tmp file");
! 4515: if(VBLK != read(tmp, data[which], VBLK))
! 4516: memset(data[which], 0, VBLK);
! 4517: map[which].what_in = what_in;
! 4518: map[which].dirty = 0; /* clean */
! 4519: }
! 4520: byte = &data[which][byte_no];
! 4521:
! 4522: switch(action) {
! 4523: case testBlock:
! 4524: case testDup:
! 4525: return(*byte & bit);
! 4526: case markBlock:
! 4527: case markDup:
! 4528: map[which].dirty = 1;
! 4529: return(*byte |= bit);
! 4530: case unmarkBlock:
! 4531: case unmarkDup:
! 4532: map[which].dirty = 1;
! 4533: return(*byte ^= bit);
! 4534: case linkCtr:
! 4535: case Flags:
! 4536: case grabBlock:
! 4537: return(*byte);
! 4538: case setLinkctr:
! 4539: case setFlags:
! 4540: case setDup:
! 4541: map[which].dirty = 1;
! 4542: return(*byte = odata);
! 4543: case orFlags:
! 4544: map[which].dirty = 1;
! 4545: return(*byte |= odata);
! 4546: case incLinkctr:
! 4547: map[which].dirty = 1;
! 4548: return(++*byte);
! 4549: default:
! 4550: fatal("Bad action in virtual system");
! 4551: }
! 4552: }
! 4553:
! 4554: /*
! 4555: * copy virtual memory blockmap to dupmap
! 4556: * read and write groups to avoid possable thrashing.
! 4557: */
! 4558: void
! 4559: copyV(size)
! 4560: unsigned size;
! 4561: {
! 4562: char buf[128];
! 4563: register int i;
! 4564: long bp, bs;
! 4565:
! 4566: for(bs = bp = 0; bp < size; ) {
! 4567: for(i = 0; (i < 128) && (bp < size); i++, bp++)
! 4568: buf[i] = findblock(bp, grabBlock);
! 4569:
! 4570: for(i = 0; (i < 128) && (bs < size); i++, bs++)
! 4571: findblock(bs, setDup, buf[i]);
! 4572: }
! 4573: }
! 4574:
! 4575: #ifdef TEST
! 4576: fatal(s)
! 4577: char *s;
! 4578: {
! 4579: fprintf(stderr, "%s\n", s);
! 4580: exit(1);
! 4581: }
! 4582:
! 4583: static char buf[80];
! 4584: gbuf()
! 4585: {
! 4586: if(NULL == gets(buf)) {
! 4587: unlink("vtmp");
! 4588: exit(0);
! 4589: }
! 4590: return(buf[0]);
! 4591: }
! 4592:
! 4593: main()
! 4594: {
! 4595: unsigned long b;
! 4596: char data;
! 4597:
! 4598: initV(10000, 10000, 20000);
! 4599: for(;;) {
! 4600: printf("b = block, d = dup, f = flags, l = linkctr\n");
! 4601: switch(gbuf()) {
! 4602: case 'l':
! 4603: printf("s = set, d = display, i = increment: then loc\n");
! 4604: gbuf();
! 4605: sscanf(buf + 2, "%ld", &b);
! 4606: switch(buf[0]) {
! 4607: case 's':
! 4608: setlinkctr(b, 0); /* no data */
! 4609: case 'd':
! 4610: printf("%d\n", linkctr(b));
! 4611: break;
! 4612: case 'i':
! 4613: printf("%d\n", inclinkctr(b));
! 4614: }
! 4615: break;
! 4616: case 'f':
! 4617: printf("d = display, s = set, o = or: then loc\n");
! 4618: gbuf();
! 4619: sscanf(buf + 2, "%ld %c", &b, &data);
! 4620: switch(buf[0]) {
! 4621: case 's':
! 4622: setflags(b, data);
! 4623: case 'd':
! 4624: break;
! 4625: case 'o':
! 4626: orflags(b, data);
! 4627: }
! 4628: printf("%c\n", flags(b));
! 4629: break;
! 4630: case 'b':
! 4631: printf("t = test, m = mark, u = unmark: then loc\n");
! 4632: gbuf();
! 4633: sscanf(buf + 2, "%ld", &b);
! 4634: switch(buf[0]) {
! 4635: case 'm':
! 4636: markblock(b);
! 4637: case 't':
! 4638: break;
! 4639: case 'u':
! 4640: unmarkblock(b);
! 4641: }
! 4642: printf("%c\n", testblock(b) ? '1' : '0');
! 4643: break;
! 4644: case 'd':
! 4645: printf("t = test, m = mark, u = unmark: then loc\n");
! 4646: gbuf();
! 4647: sscanf(buf + 2, "%ld", &b);
! 4648: switch(buf[0]) {
! 4649: case 'm':
! 4650: markdup(b);
! 4651: case 't':
! 4652: break;
! 4653: case 'u':
! 4654: unmarkdup(b);
! 4655: }
! 4656: printf("%c\n", testdup(b) ? '1' : '0');
! 4657: break;
! 4658: }
! 4659: }
! 4660: }
! 4661: #endif
! 4662:
! 4663: @
! 4664: loc\n");
! 4665: gbuf();
! 4666: sscanf(buf + 2, "%ld", &b);
! 4667: switch(buf[0]) {
! 4668: case 'm':
! 4669: markblock(b);
! 4670: case 't':
! 4671: break;
! 4672: case 'u':
! 4673: ufsck/READ_ME 644 3 3 1227 4664524112 5766 Ideas for improving the performance of fsck:
! 4674:
! 4675: (1) Utilize a different mechanism for storing the (struct direct)
! 4676: entries throughout phase2.c, to remove implicit memory intensive
! 4677: redundancy.
! 4678:
! 4679: (2) Encode the number of links per i-node count differently, in order
! 4680: to save space taking advantage of the typical usage under Coherent.
! 4681:
! 4682: (3) Arrange space for the tables in a total needed way to avoid later
! 4683: fragmentation problems affecting the memory requests for successive
! 4684: file systems.
! 4685:
! 4686: (4) Devise a more clever buffering scheme for the blocks containing
! 4687: i-nodes to understand the differences between phase1, phase2, and
! 4688: phase4.
! 4689: emove implicit memory intensive
! 4690: redundancy.
! 4691:
! 4692: (2) Encode the number of links per i-node count differently, in order
! 4693: to save space taking advantage of the typical usage under Coherent.
! 4694:
! 4695: (3) Arrange space for the tables in a total needed way to avoid later
! 4696: fragmentation problems affecting the memory requests for successive
! 4697: file systems.
! 4698:
! 4699: (4fsck/cleanup.c 644 3 3 2324 4664524112 6541 /*
! 4700: * Cleanup functions for phases of fsck
! 4701: */
! 4702:
! 4703: #include "fsck.h"
! 4704:
! 4705: cleanup()
! 4706: {
! 4707: int retval = 0;
! 4708:
! 4709: if (sbpfix == TRUE)
! 4710: writesuper();
! 4711: prtstats();
! 4712: if (changeflg == TRUE)
! 4713: retval = advise();
! 4714: close(fsfd);
! 4715: cleanV();
! 4716: return(retval);
! 4717: }
! 4718:
! 4719: writesuper()
! 4720: {
! 4721: register int i;
! 4722:
! 4723: canshort(sbp->s_isize);
! 4724: candaddr(sbp->s_fsize);
! 4725: canshort(sbp->s_nfree);
! 4726: for(i=0; i<NICFREE; i++)
! 4727: candaddr(sbp->s_free[i]);
! 4728: canshort(sbp->s_ninode);
! 4729: for(i=0; i<NICINOD; i++)
! 4730: canino(sbp->s_inode[i]);
! 4731: cantime(sbp->s_time);
! 4732: candaddr(sbp->s_tfree);
! 4733: canino(sbp->s_tinode);
! 4734: canshort(sbp->s_m);
! 4735: canshort(sbp->s_n);
! 4736: canlong(sbp->s_unique);
! 4737:
! 4738: bwrite((daddr_t)SUPERI, sbp);
! 4739: }
! 4740:
! 4741: prtstats()
! 4742: {
! 4743: if (!fflag)
! 4744: printf("%u files ", numfiles);
! 4745: printf("%U blocks ", fsize - isize - totfree);
! 4746: printf("%U free\n", totfree);
! 4747: if ( lostsize ) {
! 4748: lostsize = (lostsize + BSIZE - 1)/BSIZE;
! 4749: printf("Expect roughly %U missing block%s next\n", lostsize,
! 4750: (lostsize!=1) ? "s" : "" );
! 4751: printf("time fsck is run as a result of inodes ");
! 4752: printf("being cleared.\n");
! 4753: }
! 4754: }
! 4755:
! 4756: advise()
! 4757: {
! 4758: int retval = 0;
! 4759:
! 4760: printf(" ***** File System %s was modified *****\n", fsname);
! 4761: if ( mounted ) {
! 4762: printf(" ***** BOOT Coherent (NO SYNC!) *****\n");
! 4763: retval = 1;
! 4764: }
! 4765: return(retval);
! 4766: }
! 4767: blocks ", fsize - isize - totfree);
! 4768: printf("%U free\n", totfree);
! 4769: if ( lostsize ) {
! 4770: lostsize = (lostsize + BSIZE - 1)/BSIZE;
! 4771: printf("Expect roughly %U missing block%s next\n", lostsize,
! 4772: (lostsize!=1) ? "s" : "" );
! 4773: printf("time fsck is run as a result of inodes ");
! 4774: printf("being clearedfsck/fsck.h 644 3 3 14003 5033723044 6056 /*
! 4775: * Header file for fsck -- File System Check Program
! 4776: *
! 4777: */
! 4778:
! 4779: #include <canon.h>
! 4780: #include <sys/dir.h>
! 4781: #include <sys/fblk.h>
! 4782: #include <sys/filsys.h>
! 4783: #include <sys/ino.h>
! 4784: #include <sys/stat.h>
! 4785: #include <sys/types.h>
! 4786: #include <time.h>
! 4787:
! 4788: #if HPCOHERENT
! 4789: typedef long fsize_t;
! 4790: #endif
! 4791:
! 4792: /*
! 4793: * Conditional Compilation Flags
! 4794: */
! 4795:
! 4796: #define NOT_ALL_ZERO_INODE /* Dependent on whether or not an inode */
! 4797: #ifdef ALL_ZERO_INODE /* is totally zeroed when unallocated */
! 4798: #undef ALL_ZERO_INODE /* or simply a zero mode and zero link */
! 4799: #endif
! 4800:
! 4801:
! 4802: /*
! 4803: * Definitions and Externs
! 4804: */
! 4805:
! 4806: #define NUL 0 /* true zero ! */
! 4807: #define NULL ((char *)0)
! 4808:
! 4809: #define YES 3 /* default actions */
! 4810: #define NO 2
! 4811: #define ASK 1
! 4812:
! 4813: #define NFILSYS 10 /* max number of file systems */
! 4814: #define MAXCH 20 /* max length of filesys name */
! 4815:
! 4816: #define MAXBADOK 10 /* Max number of bad blocks before excessive */
! 4817: extern int numbad; /* num bad blocks found so far this inode*/
! 4818:
! 4819: #define MAXDUPOK 10 /* Max number of dup blocks */
! 4820: /* in a single inode before excessive */
! 4821: #define DUPTBLSIZE 20 /* Max number of dup referenced blocks */
! 4822: extern daddr_t dupblck[]; /* table of duplicate referenced blocks */
! 4823: extern int totdups; /* number of dup blocks found so far */
! 4824:
! 4825: #define MAXBADFREE 10 /* max bad in free list before abort */
! 4826: #define MAXDUPFREE 10 /* max dup in free list before abort */
! 4827:
! 4828: #define GOOD 1 /* returned by bad() in util.c */
! 4829: #define BAD 0
! 4830:
! 4831: #define TRUE 1 /* errflag possibilities */
! 4832: #define FALSE 0
! 4833: extern int errflag; /* errflag indicates not to do phases */
! 4834:
! 4835: #define OK 1 /* used to indicate excessive bad/dup */
! 4836: #define STOP 0 /* blocks in an inode in phase1.c */
! 4837: #define BAD_DUP 2
! 4838:
! 4839: #define FIRSTIN 2 /* First real inode number */
! 4840:
! 4841: #define ND 10 /* Number of Direct Blocks */
! 4842: #undef NI
! 4843: #define NI 1
! 4844: #define NII 1
! 4845: #define NIII 1
! 4846: #undef NADDR
! 4847: #define NADDR (ND+NI+NII+NIII)
! 4848: extern int offsets[]; /* table of offsets for level of indirection */
! 4849: /* for the blocks in an inode */
! 4850:
! 4851: extern char nextchar(); /* used in util.c */
! 4852: extern int fsfd; /* file system file descriptor */
! 4853: extern int mdaction; /* default action for this invocation */
! 4854: extern int daction; /* default action for current file system */
! 4855: extern int writeflg; /* system write ok or read-only */
! 4856: extern int qflag; /* quiet fsck flag */
! 4857: extern int fflag; /* fast fsck flag */
! 4858: extern int sflag; /* force free list salvation */
! 4859: extern daddr_t fsize; /* file system size in blocks */
! 4860: extern int isize; /* first block not in inode list */
! 4861: /* isize is NOT unsigned so that comparisons */
! 4862: /* with longs will not cast the long to */
! 4863: /* unsigned thus producing confusing results */
! 4864:
! 4865: extern daddr_t totfree; /* running count of total free blocks */
! 4866: extern unsigned ninodes;/* Number of inodes in the files system */
! 4867: extern char *fsname; /* file system name */
! 4868: extern fsize_t pinfo(); /* returns size of file, in phase2.c */
! 4869: extern ino_t lostfound(); /* returns inumber of lost+found dir */
! 4870: extern struct dinode *ptrino(); /* returns a ptr to inode, give number */
! 4871: extern char databuf[]; /* buffer to read in block, used throughout */
! 4872: extern char buf2[]; /* alternate data buffer */
! 4873: extern daddr_t cdbn; /* current block number, used by nextblock() */
! 4874: #define DSIZE (sizeof(struct direct))
! 4875: extern char *lostname; /* name of lost+found directory */
! 4876: extern char *nameit(); /* nameing function for lost dirs and files */
! 4877: extern int depth; /* used during tree traversal in phase2.c */
! 4878: extern struct direct *path[]; /* used during tree traversal in phase2.c */
! 4879: extern char *typename(); /* return string to type of inode */
! 4880: extern struct filsys *sbp; /* Super Block */
! 4881: extern int sbpfix; /* flag for super block fixes */
! 4882: extern struct stat stats; /* used by statit() in util.c */
! 4883: extern dev_t rootdev; /* root device number */
! 4884: extern dev_t fsysrdev; /* file system real device number */
! 4885: extern int mounted; /* flag indicating mountedness of filesystem */
! 4886: extern int changeflg; /* file system modified flag */
! 4887: extern int fixerup; /* flag to rebuild free list */
! 4888: extern char *fixit; /* Prompt message phase[45].c */
! 4889: extern int numfiles; /* num files in system */
! 4890: extern daddr_t imap(); /* function for disk block mapping in util.c */
! 4891: extern fsize_t lostsize; /* Size of files cleared in phase4.c */
! 4892: extern char *tmpfile; /* TMP File name for virtual.c */
! 4893:
! 4894: #define SUCCESS 1 /* used in connect() in phase3.c */
! 4895: #define FAILURE 0
! 4896:
! 4897: #define MODEMASK 0x07
! 4898: #define ALLOCMASK 0x06
! 4899: #define UNALLOC 0x00
! 4900: #define UNKNOWN 0x01
! 4901: #define IDIR 0x02
! 4902: #define IREG 0x03
! 4903: #define ICHR 0x04
! 4904: #define IBLK 0x05
! 4905: #define IPIPE 0x06
! 4906: #define IBAD_IDUP 0x08
! 4907: #define VISITED 0x10
! 4908: #define UNREFDIR 0x20
! 4909: #define CHILDDIR 0x40
! 4910: #define IFREELIST 0x80
! 4911:
! 4912: /*
! 4913: * Macros for tables
! 4914: */
! 4915:
! 4916: #define LOGNBPC 3 /* Log2 Number of Bits per Character */
! 4917:
! 4918: /* Actions for virtual block system */
! 4919: enum vact { testBlock, markBlock, unmarkBlock, grabBlock,
! 4920: testDup, markDup, unmarkDup, setDup,
! 4921: Flags, setFlags, orFlags,
! 4922: linkCtr, incLinkctr, setLinkctr };
! 4923:
! 4924: #define testblock(bn) findblock((unsigned long)(bn), testBlock)
! 4925: #define markblock(bn) findblock((unsigned long)(bn), markBlock)
! 4926: #define unmarkblock(bn) findblock((unsigned long)(bn), unmarkBlock)
! 4927:
! 4928: #define testdup(bn) findblock((unsigned long)(bn), testDup)
! 4929: #define markdup(bn) findblock((unsigned long)(bn), markDup)
! 4930: #define unmarkdup(bn) findblock((unsigned long)(bn), unmarkDup)
! 4931:
! 4932: #define flags(ino) findblock((unsigned long)(ino), Flags)
! 4933: #define setflags(ino, data) findblock((unsigned long)(ino), setFlags, data)
! 4934: #define orflags(ino, data) findblock((unsigned long)(ino), orFlags, data)
! 4935:
! 4936: #define linkctr(ino) findblock((unsigned long)(ino), linkCtr)
! 4937: #define inclinkctr(ino) findblock((unsigned long)(ino), incLinkctr)
! 4938: #define setlinkctr(ino, data) findblock((unsigned long)(ino), setLinkctr, data)
! 4939:
! 4940: #define badblks(ino) ( flags(ino)&IBAD_IDUP )
! 4941:
! 4942: /*
! 4943: * Miscellany
! 4944: */
! 4945:
! 4946: #define NBPC 8 /* number of bits per character */
! 4947: #define MAXINTN 255 /* used for interleave table */
! 4948: /* in phase6.c */
! 4949: /*
! 4950: * Stdio Stuff
! 4951: */
! 4952:
! 4953: #define putchar(c) { char b = c; write(1, &b, 1); }
! 4954: extern char *malloc();
! 4955: extern char *calloc();
! 4956:
! 4957: findblock((unsigned long)(ino), linkCtr)
! 4958: #define inclinkctr(ino) findblock((unsigned long)(ino), incLinkctr)
! 4959: #define setlinkctr(ino, data) findblock((unsigned long)(ino), setLinkctr, data)
! 4960:
! 4961: #define badblks(ino) ( flags(ino)&IBAD_IDUP )
! 4962:
! 4963: /*
! 4964: * Miscellany
! 4965: */
! 4966:
! 4967: #define NBPC 8 /* number of bits per character */
! 4968: #define MAXINTN 255 /* used for interleave table */
! 4969: /* in phase6.c */
! 4970: /*
! 4971: * Stdio Stuff
! 4972: */
! 4973:
! 4974: #define putchar(c) { char b = c; write(1, &b, 1); }
! 4975: extern char *malloc();
! 4976: extern char *calloc()fsck/init.c 644 3 3 12651 5041132573 6075 /*
! 4977: * Perform initialization for phases of fsck
! 4978: */
! 4979: #include "fsck.h"
! 4980: #include <mnttab.h>
! 4981: #include <mtab.h>
! 4982:
! 4983: int fsfd; /* file system file descriptor */
! 4984: int writeflg; /* write ok or read-only flag */
! 4985: daddr_t fsize = SUPERI+1; /* file system size in blocks */
! 4986: /* Allows for read of Super Block */
! 4987: int isize; /* First block not in inode list */
! 4988: daddr_t totfree; /* Running total free block count */
! 4989: unsigned ninodes; /* number of inodes */
! 4990: int numfiles; /* number of files in file system */
! 4991:
! 4992: char superb[BSIZE]; /* Super Block */
! 4993: struct filsys *sbp = superb;
! 4994: int sbpfix; /* flag for super block fixes */
! 4995:
! 4996: int offsets[] = /* table of offsets for the levels */
! 4997: { ND, ND+NI, ND+NI+NII, /* of indirection of blocks in the */
! 4998: ND+NI+NII+NIII }; /* inode block list */
! 4999:
! 5000: daddr_t dupblck[DUPTBLSIZE]; /* duplicate referenced blocks */
! 5001: int totdups; /* number of dup blocks so far */
! 5002:
! 5003: init()
! 5004: {
! 5005: int mode;
! 5006: struct stat status;
! 5007: unsigned short stmode;
! 5008:
! 5009: mode = (mdaction == NO) ? 0 : 2;
! 5010:
! 5011: if ( (fsfd = open(fsname, mode)) == (-1) ) {
! 5012: mode = 0;
! 5013: if ( (fsfd = open(fsname, mode)) == (-1) ) {
! 5014: nonfatal("Can't open: %s", fsname);
! 5015: return;
! 5016: }
! 5017: }
! 5018:
! 5019: if (mode == 0) {
! 5020: daction = NO;
! 5021: writeflg = FALSE;
! 5022: } else {
! 5023: daction = mdaction;
! 5024: writeflg = TRUE;
! 5025: }
! 5026:
! 5027: printf("%s: %s\n", fsname, (mode == 0) ? "(NO WRITE)" : "");
! 5028:
! 5029: if ( fstat(fsfd, &status) == (-1) ) {
! 5030: nonfatal("Can't stat: %s", fsname);
! 5031: return;
! 5032: }
! 5033:
! 5034: stmode = status.st_mode & S_IFMT;
! 5035: if ( (stmode != S_IFBLK) && (stmode != S_IFCHR) )
! 5036: switch(query("file is not a block or character device; OK?")){
! 5037: case YES:
! 5038: break;
! 5039: case NO:
! 5040: errflag = TRUE;
! 5041: return;
! 5042: }
! 5043:
! 5044: domount();
! 5045: sbpfix = FALSE;
! 5046: readsuper();
! 5047: checksuper();
! 5048: if ( !errflag )
! 5049: alloctables();
! 5050: }
! 5051:
! 5052: /*
! 5053: * Read in the super block and canonicalize
! 5054: */
! 5055:
! 5056: readsuper()
! 5057: {
! 5058: register int i;
! 5059:
! 5060: bread((daddr_t)SUPERI, superb);
! 5061: sbp = superb;
! 5062:
! 5063: canshort(sbp->s_isize);
! 5064: candaddr(sbp->s_fsize);
! 5065: canshort(sbp->s_nfree);
! 5066: for(i=0; i<NICFREE; i++)
! 5067: candaddr(sbp->s_free[i]);
! 5068: canshort(sbp->s_ninode);
! 5069: for(i=0; i<NICINOD; i++)
! 5070: canino(sbp->s_inode[i]);
! 5071: cantime(sbp->s_time);
! 5072: candaddr(sbp->s_tfree);
! 5073: canino(sbp->s_tinode);
! 5074: canshort(sbp->s_m);
! 5075: canshort(sbp->s_n);
! 5076: canlong(sbp->s_unique);
! 5077:
! 5078: }
! 5079:
! 5080: /*
! 5081: * Check super block for obvious inconsistencies
! 5082: */
! 5083:
! 5084: checksuper()
! 5085: {
! 5086: fsize = sbp->s_fsize;
! 5087: isize = sbp->s_isize;
! 5088: totfree = fsize - isize;
! 5089:
! 5090: if ( (isize<=INODEI) || (isize>=fsize) || (fsize<=INODEI) ) {
! 5091: badsuper("Size check: fsize %U isize %u", fsize, isize);
! 5092: errflag = TRUE;
! 5093: }
! 5094:
! 5095: if ( sbp->s_nfree > NICFREE )
! 5096: badsuper("Too large free block count");
! 5097:
! 5098: if ( sbp->s_ninode > NICINOD )
! 5099: badsuper("Too large free i-node count");
! 5100: }
! 5101:
! 5102: /*
! 5103: * Super Block Error Functions
! 5104: */
! 5105:
! 5106: badsuper(x)
! 5107: {
! 5108: printf("%r\n", &x);
! 5109: printf("fsck: %s: Bad Super Block: %u\n", fsname, SUPERI);
! 5110: }
! 5111:
! 5112: /*
! 5113: * Allocate the necessary buffers for tables
! 5114: */
! 5115:
! 5116: alloctables()
! 5117: {
! 5118: unsigned num, numl;
! 5119:
! 5120: numl = 0;
! 5121: if (!fflag) {
! 5122: ninodes = (unsigned) (isize - INODEI) * INOPB;
! 5123: numl = (unsigned) ninodes;
! 5124: }
! 5125:
! 5126: num = (unsigned) ((fsize+NBPC-1)/NBPC) * sizeof(char);
! 5127: initV(numl, numl, num, num); /* virtual allocation */
! 5128:
! 5129: numfiles = /* number of files in the file system */
! 5130: totdups = 0; /* num dup blocks */
! 5131: }
! 5132:
! 5133: /*
! 5134: * domount() checks the files /etc/mnttab and /etc/mtab to find
! 5135: * out where the file system is mounted (if at all). It then
! 5136: * reports where (and when if possible) it was last mounted.
! 5137: */
! 5138: char *mnttab_name = "/etc/mnttab";
! 5139: char *mtab_name = "/etc/mtab";
! 5140: char *bttime_name = "/etc/boottime";
! 5141:
! 5142: domount()
! 5143: {
! 5144: int fd;
! 5145: struct mnttab mnttab;
! 5146: struct mtab mtab;
! 5147: register char *name;
! 5148: struct stat sbuf;
! 5149: time_t boottime;
! 5150: int nothing();
! 5151: char devname[MNTNSIZ+6] = "/dev/";
! 5152:
! 5153: mounted = FALSE;
! 5154: name = fsname; /* strip off all initial */
! 5155: while (*name++ != '\0') ; /* directories in fsname */
! 5156: while ( (*--name != '/') && (name>fsname) ) ;
! 5157: if (*name == '/') name++;
! 5158:
! 5159: if ( stat(bttime_name, &sbuf) == -1 )
! 5160: boottime = (time_t)0;
! 5161: else
! 5162: boottime = sbuf.st_mtime;
! 5163:
! 5164: if ( (fd=open(mnttab_name, 0)) != (-1) ) {
! 5165: while ( read(fd, &mnttab, sizeof(mnttab))==sizeof(mnttab) )
! 5166: if ( mnttab.mt_dev[0] && mnttab.mt_filsys[0] ) {
! 5167: strncpy(&devname[5], mnttab.mt_filsys, MNTNSIZ);
! 5168: devname[MNTNSIZ+5] = '\0';
! 5169: statit(devname, nothing);
! 5170: if (stats.st_rdev != fsysrdev)
! 5171: continue;
! 5172: statit(mnttab.mt_dev, nothing);
! 5173: mounted = (stats.st_dev == fsysrdev);
! 5174: prmnttab(&mnttab, boottime);
! 5175: return;
! 5176: }
! 5177: }
! 5178: if ( (fd=open(mtab_name, 0)) != (-1) ) {
! 5179: while ( read(fd, &mtab, sizeof(mtab))==sizeof(mtab) )
! 5180: if ( mtab.mt_name[0] && mtab.mt_special[0] ) {
! 5181: strncpy(&devname[5], mtab.mt_special, MNAMSIZ);
! 5182: devname[MNAMSIZ+5] = '\0';
! 5183: statit(devname, nothing);
! 5184: if (stats.st_rdev != fsysrdev)
! 5185: continue;
! 5186: statit(mtab.mt_name, nothing);
! 5187: mounted = (stats.st_dev == fsysrdev);
! 5188: prmtab(&mtab);
! 5189: return;
! 5190: }
! 5191: }
! 5192:
! 5193: if (fsysrdev == rootdev)
! 5194: mounted = TRUE;
! 5195: else
! 5196: mounted = FALSE;
! 5197:
! 5198: }
! 5199:
! 5200: prmnttab(ptr, boottime)
! 5201: struct mnttab *ptr;
! 5202: time_t boottime;
! 5203: {
! 5204: if (mounted) {
! 5205: if (boottime < ptr->mt_time)
! 5206: boottime = ptr->mt_time;
! 5207: printf("%s mounted on %.*s as of %s", fsname, MNTNSIZ,
! 5208: ptr->mt_dev, ctime(&boottime));
! 5209: } else
! 5210: printf("%s unmounted. Last mounted on %.*s -- %s",
! 5211: fsname, MNTNSIZ, ptr->mt_dev,
! 5212: ctime(&ptr->mt_time));
! 5213: }
! 5214:
! 5215:
! 5216: prmtab(ptr)
! 5217: struct mtab *ptr;
! 5218: {
! 5219: if (mounted)
! 5220: printf("%s mounted on %.*s\n", fsname, MNAMSIZ, ptr->mt_name);
! 5221: else
! 5222: printf("%s unmounted. Last mounted on %.*s\n", fsname,
! 5223: MNAMSIZ, ptr->mt_name);
! 5224: }
! 5225:
! 5226: nothing()
! 5227: {}
! 5228: ) {
! 5229: if (boottime < ptr->mt_time)
! 5230: boottime = ptr->mt_time;
! 5231: printf("%s mounted on fsck/is_fs.c 644 3 3 3467 4705135657 6236 #include <sys/stat.h>
! 5232: #include <canon.h>
! 5233: #include <sys/filsys.h>
! 5234:
! 5235: /*
! 5236: * Check if a special file is a well-formed filesystem.
! 5237: * This routine is derived from code in "mount.c".
! 5238: * Return values:
! 5239: * -1 Not a device, cannot open, read or seek failed
! 5240: * 0 No filesystem
! 5241: * 1 Legal filesystem
! 5242: */
! 5243: int
! 5244: is_fs(special) char *special;
! 5245: {
! 5246: static struct filsys f;
! 5247: struct stat sbuf;
! 5248: register int fd;
! 5249: register struct filsys *fp;
! 5250: register daddr_t *dp;
! 5251: register ino_t *ip, maxinode;
! 5252:
! 5253: if (stat(special, &sbuf) < 0)
! 5254: return -1; /* cannot stat device */
! 5255: else if ((sbuf.st_mode&S_IFMT) != S_IFBLK
! 5256: && (sbuf.st_mode&S_IFMT) != S_IFCHR)
! 5257: return -1; /* not a special file */
! 5258: else if ((fd = open(special, 2)) < 0)
! 5259: return -1; /* cannot open */
! 5260: else if (lseek(fd, (long)SUPERI*BSIZE, 0) == -1L
! 5261: || read(fd, &f, sizeof(f)) != sizeof(f)) {
! 5262: close(fd);
! 5263: return -1; /* seek or read failed */
! 5264: } else
! 5265: close(fd); /* so far so good */
! 5266:
! 5267: /* Canonical stuff. */
! 5268: fp = &f;
! 5269: canshort(fp->s_isize);
! 5270: candaddr(fp->s_fsize);
! 5271: canshort(fp->s_nfree);
! 5272: for (dp = &fp->s_free[0]; dp < &fp->s_free[NICFREE]; dp += 1)
! 5273: candaddr(*dp);
! 5274: canshort(fp->s_ninode);
! 5275: for (ip = &fp->s_inode[0]; ip < &fp->s_inode[NICINOD]; ip += 1)
! 5276: canino(*ip);
! 5277: candaddr(fp->s_tfree);
! 5278: canino(fp->s_tinode);
! 5279:
! 5280: /* Test for rationality. */
! 5281: maxinode = (fp->s_isize - INODEI) * INOPB + 1;
! 5282: if (fp->s_isize >= fp->s_fsize)
! 5283: return 0;
! 5284: if ((fp->s_tfree < fp->s_nfree)
! 5285: || (fp->s_tfree >= fp->s_fsize - fp->s_isize + 1))
! 5286: return 0;
! 5287: if ((fp->s_tinode < fp->s_ninode) || (fp->s_tinode >= maxinode-1 ))
! 5288: return 0;
! 5289: for (dp = &fp->s_free[0]; dp < &fp->s_free[fp->s_nfree]; dp += 1)
! 5290: if ((*dp < fp->s_isize) || (*dp >= fp->s_fsize))
! 5291: return 0;
! 5292: for (ip = &fp->s_inode[0]; ip < &fp->s_inode[fp->s_ninode]; ip += 1)
! 5293: if ((*ip < 1) || (*ip > maxinode))
! 5294: return 0;
! 5295: return 1;
! 5296: }
! 5297: - INODEI) * INOPB + 1;
! 5298: if (fp->s_isize >= fp->s_fsize)
! 5299: return 0;
! 5300: if ((fp->s_tfree < fp->s_nfree)
! 5301: || (fp->s_tfree >= fp->s_fsize - fp->s_isize + 1))
! 5302: return 0;
! 5303: if ((fp->s_tinode < fp->s_ninode)fsck/link.c 644 3 3 2762 4664524116 6061 /*
! 5304: * Routines to handle the counting of links for each i-node
! 5305: */
! 5306:
! 5307: #include "fsck.h"
! 5308:
! 5309: linkincr(inum)
! 5310: ino_t inum;
! 5311: {
! 5312: if (inclinkctr(inum) == 0 )
! 5313: fatal("Too many links in i-node, %d", inum);
! 5314: }
! 5315:
! 5316: /*
! 5317: * The following is the beginning of thinking of how to change
! 5318: * the number of bits used in the link count tables from 8-per
! 5319: * i-node to 2-per i-node, with additional tables for those
! 5320: * i-nodes with more than 2 links. The changes would be to the
! 5321: * definition of i_lnks, the macro linkctr(), the function linkincr(),
! 5322: * and in init.c, the allocation of table space.
! 5323: */
! 5324:
! 5325: #ifdef NEWLINKSTUFFF
! 5326:
! 5327: char *linkmap; /* table of inodes with one link */
! 5328:
! 5329: #define testlink(in) ( linkmap[((unsigned)bn)>>(LOGNBPC-1)] & \
! 5330: 3 << (((unsigned)bn)&(NBPC>>1)) )
! 5331: #define marklink(in) ( linkmap[((unsigned)bn)>>(LOGNBPC-1)] |= \
! 5332: 1 << (((unsigned)bn)&(NBPC-2)) )
! 5333: #define unmarklink(in) ( linkmap[((unsigned)bn)>>(LOGNBPC-1)] ^= \
! 5334: 1 << (((unsigned)bn)&(NBPC-2)) )
! 5335:
! 5336: linkcntr(inum)
! 5337: ino_t inum;
! 5338: {
! 5339: index = ((unsigned) inum) >> (LOGNBPC-1) ;
! 5340: distance = ((unsigned) inum) & ((NBPC>>1) - 1) ;
! 5341: mask = 3 << distance;
! 5342: answer = ( linkmap[index] & mask ) >> distance;
! 5343:
! 5344: if ( answer < 3 )
! 5345: return(answer);
! 5346:
! 5347: hash = inum & 0xFF;
! 5348: bucket = &linktable[hash];
! 5349: bktinum = bucket->inumb;
! 5350:
! 5351: if ( bktinum == inum ) {
! 5352: answer = bucket->numlink;
! 5353: if ( answer == 0xFF )
! 5354: return( bigcntr(inum) );
! 5355: else
! 5356: return( answer + 3 );
! 5357: }
! 5358:
! 5359: if ( bktinum > inum )
! 5360: fatal("internal linktable corruption.");
! 5361:
! 5362:
! 5363: }
! 5364:
! 5365: linkincr(inum)
! 5366: ino_t inum;
! 5367: {
! 5368: }
! 5369:
! 5370: #endif
! 5371: num) >> (LOGNBfsck/main.c 644 3 3 12436 5041134504 6053 /*
! 5372: * fsck -- File System Check Program
! 5373: * an interactive file system check and repair program.
! 5374: *
! 5375: * Usage:
! 5376: * /etc/fsck [-y] [-n] [-q] [-f] [-{sS}] [-t TMPFILE] [filesystem ...]
! 5377: * audit and interactively repair inconsistent conditions for
! 5378: * file systems. Options -y and -n indicate an assumed response
! 5379: * to all questions asked by fsck. Default is to prompt operator
! 5380: * for yes/no response. Option -q is to quiet fsck from printing
! 5381: * certain messages, i.e. no size check messages, unreferenced
! 5382: * pipes will be silently removed, and counts in the superblock
! 5383: * will be automatically fixed and free list salvaged, if necessary.
! 5384: * Option -f is for a 'fast' check of the file system, i.e. only
! 5385: * check blocks, sizes, superblock counts, and the free list.
! 5386: * (-f) does not check pathnames, connectivity, or reference
! 5387: * counts. Option -s forces the reconstruction (or salvaging) of
! 5388: * both the free inode list and the free block list, even if there
! 5389: * are no file system problems. This will reorder the free block
! 5390: * list in the best order to limit additional fragmentation (respecting
! 5391: * interleaving as well). Note: Option -s will be ignored on mounted
! 5392: * file systems. The option -S acts in the same manner as -s except
! 5393: * that it will not be ignored on mounted file systems. Beware: -S
! 5394: * on mounted file systems should only be used if you intend to reboot
! 5395: * NO SYNC immediately afterwards. Option -t sets the temporary file
! 5396: * to use for disk caching of necessary tables on filesystems which are
! 5397: * too big to do in core. The temporary file defaults to "/dev/rram1",
! 5398: * which must be there.
! 5399: */
! 5400:
! 5401: #include "fsck.h"
! 5402:
! 5403: int errflag;
! 5404:
! 5405: int mdaction; /* default action for invocation */
! 5406: int daction; /* default action for file system */
! 5407: int gSflag=FALSE; /* force salvage flag ignored mounted */
! 5408: int gsflag=FALSE; /* force salvage flag ignored mounted */
! 5409: int sflag=FALSE; /* force salvage flag */
! 5410: int qflag=FALSE; /* fsck quiet flag */
! 5411: int fflag=FALSE; /* fsck fast flag */
! 5412:
! 5413: char *tmpfile = NULL; /* TMP file for virtual.c */
! 5414: char *checklistfile = "/etc/checklist"; /* default file for list of file */
! 5415: /* systems to fsck. */
! 5416: char *filelist[NFILSYS]; /* list of filesystems */
! 5417: char word[MAXCH]; /* hold single words */
! 5418: char *fsname; /* file system name */
! 5419:
! 5420: dev_t rootdev; /* root device number */
! 5421: dev_t fsysrdev; /* file system real device number */
! 5422: int mounted; /* flag for mounted file system */
! 5423:
! 5424: int changeflg; /* file system modified flag */
! 5425:
! 5426: main(argc, argv)
! 5427: char *argv[];
! 5428: {
! 5429: int yflag=0, nflag=0;
! 5430: int retval;
! 5431:
! 5432: while (argc>1 && *argv[1]=='-') {
! 5433: switch (argv[1][1]) {
! 5434: case 'q':
! 5435: qflag = TRUE;
! 5436: break;
! 5437: case 'y':
! 5438: yflag = 1;
! 5439: break;
! 5440: case 'n':
! 5441: nflag = 1;
! 5442: break;
! 5443: case 'f':
! 5444: fflag = TRUE;
! 5445: break;
! 5446: case 'S':
! 5447: gSflag = TRUE;
! 5448: break;
! 5449: case 's':
! 5450: gsflag = TRUE;
! 5451: break;
! 5452: case 't':
! 5453: tmpfile = argv[2];
! 5454: argc--;
! 5455: argv++;
! 5456: break;
! 5457: default:
! 5458: usage();
! 5459: break;
! 5460: }
! 5461:
! 5462: argc--;
! 5463: argv++;
! 5464: }
! 5465:
! 5466: if ( yflag+nflag > 1 )
! 5467: usage();
! 5468:
! 5469: mdaction = ( yflag ? YES :
! 5470: nflag ? NO : ASK );
! 5471:
! 5472: if ( argc > 1 )
! 5473: retval = allfsck(argv+1);
! 5474: else {
! 5475: getlist();
! 5476: retval = allfsck(filelist);
! 5477: }
! 5478: exit(retval);
! 5479: }
! 5480:
! 5481:
! 5482: /*
! 5483: * perform fsck on each of the individual filesystem in list
! 5484: */
! 5485:
! 5486: allfsck(fsl)
! 5487: register char **fsl;
! 5488: {
! 5489: int fatal();
! 5490: int retval = 0;
! 5491:
! 5492: sync();
! 5493: statit("/", fatal);
! 5494: rootdev = stats.st_dev;
! 5495: while (*fsl != NULL)
! 5496: retval |= fsck(*fsl++);
! 5497: return(retval);
! 5498: }
! 5499:
! 5500: /*
! 5501: * get the names of the filesystems from the default file
! 5502: * checklistfile (e.g. /etc/checklist)
! 5503: */
! 5504:
! 5505: getlist()
! 5506: {
! 5507: int fd;
! 5508: int index, size;
! 5509:
! 5510: if ( (fd = open(checklistfile, 0)) == (-1) )
! 5511: fatal("Can't open checklist file: %s", checklistfile);
! 5512:
! 5513: index = 0;
! 5514: while ( ((size = getword(fd)) != 0) && (index < NFILSYS) ) {
! 5515: filelist[index] = malloc( size );
! 5516: strcpy(filelist[index++], word);
! 5517: }
! 5518:
! 5519: if (size != 0)
! 5520: fatal("Too many file systems in checklist file: %s",
! 5521: checklistfile);
! 5522:
! 5523: filelist[index] = NULL;
! 5524:
! 5525: close(fd);
! 5526: }
! 5527:
! 5528: /*
! 5529: * read in the next "word" from file with descriptor fd
! 5530: * return the length of the word.
! 5531: */
! 5532:
! 5533: getword(fd)
! 5534: int fd;
! 5535: {
! 5536: int n = 0, num;
! 5537: char *cp = word;
! 5538: char ch;
! 5539:
! 5540: while ( ( (num=read(fd, &ch, 1)) == 1 ) &&
! 5541: ( (ch==' ')||(ch=='\t')||(ch=='\n')||(ch=='\r') ) );
! 5542:
! 5543: if (num != 1)
! 5544: return(0);
! 5545:
! 5546: do {
! 5547: *cp++ = ch;
! 5548: } while ( (++n < MAXCH) && (read(fd, &ch, 1) == 1) &&
! 5549: (ch != ' ') && (ch != '\t') && (ch != '\n') && (ch != '\r') );
! 5550:
! 5551: *cp = '\0';
! 5552:
! 5553: return(n+1);
! 5554: }
! 5555:
! 5556: /*
! 5557: * perform fsck on the given filesystem
! 5558: */
! 5559: fsck(name)
! 5560: char *name;
! 5561: {
! 5562: int retval = 1;
! 5563: int nonfatal();
! 5564:
! 5565: fsname = name; /* file system name */
! 5566: errflag = FALSE;
! 5567: statit(fsname, nonfatal);
! 5568: fsysrdev = stats.st_rdev;
! 5569: if ( errflag )
! 5570: return(retval);
! 5571: changeflg = FALSE;
! 5572: init();
! 5573: if ( sflag = ((gsflag && !mounted) || gSflag) )
! 5574: printf("Switch \"-s\" selected to automatically rebuild free lists\n");
! 5575: if (!sflag && gsflag)
! 5576: printf("Ignoring \"-s\" on mounted file system\n");
! 5577: if ( !errflag ) {
! 5578: phase1(); /* check blocks and sizes */
! 5579: if ( !fflag ) {
! 5580: phase2(); /* check pathnames */
! 5581: phase3(); /* check connectivity */
! 5582: phase4(); /* check reference counts */
! 5583: }
! 5584: phase5(); /* check free list */
! 5585: phase6(); /* salvage free list */
! 5586: retval = cleanup();
! 5587: }
! 5588: return(retval);
! 5589: }
! 5590:
! 5591: usage()
! 5592: {
! 5593: printf("\
! 5594: Usage: /etc/fsck [-y] [-n] [-q] [-f] [-{sS}] [-t TMPFILE] [filesystem ...]\n");
! 5595: _exit(1);
! 5596: }
! 5597: sflag && gsflag)
! 5598: printf("Ignoring \"-s\" on mounted file system\n");
! 5599: if ( !errflag ) {
! 5600: phase1(); /* check blocks and sizes */
! 5601: if ( !fflag ) {
! 5602: phase2(); /* check pathnames */
! 5603: phase3(); /* check connectivity fsck/objects/ 755 3 3 0 5045007474 6312 fsck/objects/main.o 644 3 3 4453 5045007122 7477 &