|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1980 Regents of the University of California. ! 3: * All rights reserved. The Berkeley software License Agreement ! 4: * specifies the terms and conditions for redistribution. ! 5: */ ! 6: ! 7: #ifndef lint ! 8: static char sccsid[] = "@(#)pass1.c 5.3 (Berkeley) 5/13/86"; ! 9: #endif not lint ! 10: ! 11: #include <sys/param.h> ! 12: #include <sys/inode.h> ! 13: #include <sys/fs.h> ! 14: #include "fsck.h" ! 15: ! 16: static daddr_t badblk; ! 17: static daddr_t dupblk; ! 18: int pass1check(); ! 19: ! 20: pass1() ! 21: { ! 22: register int c, i, j; ! 23: register DINODE *dp; ! 24: struct zlncnt *zlnp; ! 25: int ndb, partial, cgd; ! 26: struct inodesc idesc; ! 27: ino_t inumber; ! 28: ! 29: /* ! 30: * Set file system reserved blocks in used block map. ! 31: */ ! 32: for (c = 0; c < sblock.fs_ncg; c++) { ! 33: cgd = cgdmin(&sblock, c); ! 34: if (c == 0) { ! 35: i = cgbase(&sblock, c); ! 36: cgd += howmany(sblock.fs_cssize, sblock.fs_fsize); ! 37: } else ! 38: i = cgsblock(&sblock, c); ! 39: for (; i < cgd; i++) ! 40: setbmap(i); ! 41: } ! 42: /* ! 43: * Find all allocated blocks. ! 44: */ ! 45: bzero((char *)&idesc, sizeof(struct inodesc)); ! 46: idesc.id_type = ADDR; ! 47: idesc.id_func = pass1check; ! 48: inumber = 0; ! 49: n_files = n_blks = 0; ! 50: for (c = 0; c < sblock.fs_ncg; c++) { ! 51: for (i = 0; i < sblock.fs_ipg; i++, inumber++) { ! 52: if (inumber < ROOTINO) ! 53: continue; ! 54: dp = ginode(inumber); ! 55: if (!ALLOC(dp)) { ! 56: if (bcmp((char *)dp->di_db, (char *)zino.di_db, ! 57: NDADDR * sizeof(daddr_t)) || ! 58: bcmp((char *)dp->di_ib, (char *)zino.di_ib, ! 59: NIADDR * sizeof(daddr_t)) || ! 60: dp->di_mode || dp->di_size) { ! 61: pfatal("PARTIALLY ALLOCATED INODE I=%u", ! 62: inumber); ! 63: if (reply("CLEAR") == 1) { ! 64: zapino(dp); ! 65: inodirty(); ! 66: } ! 67: } ! 68: statemap[inumber] = USTATE; ! 69: continue; ! 70: } ! 71: lastino = inumber; ! 72: if (dp->di_size < 0) { ! 73: if (debug) ! 74: printf("bad size %d:", dp->di_size); ! 75: goto unknown; ! 76: } ! 77: if (!preen && (dp->di_mode & IFMT) == IFMT && ! 78: reply("HOLD BAD BLOCK") == 1) { ! 79: dp->di_size = sblock.fs_fsize; ! 80: dp->di_mode = IFREG|0600; ! 81: inodirty(); ! 82: } ! 83: ndb = howmany(dp->di_size, sblock.fs_bsize); ! 84: if (SPECIAL(dp)) ! 85: ndb++; ! 86: for (j = ndb; j < NDADDR; j++) ! 87: if (dp->di_db[j] != 0) { ! 88: if (debug) ! 89: printf("bad direct addr: %d\n", ! 90: dp->di_db[j]); ! 91: goto unknown; ! 92: } ! 93: for (j = 0, ndb -= NDADDR; ndb > 0; j++) ! 94: ndb /= NINDIR(&sblock); ! 95: for (; j < NIADDR; j++) ! 96: if (dp->di_ib[j] != 0) { ! 97: if (debug) ! 98: printf("bad indirect addr: %d\n", ! 99: dp->di_ib[j]); ! 100: goto unknown; ! 101: } ! 102: if (ftypeok(dp) == 0) ! 103: goto unknown; ! 104: n_files++; ! 105: lncntp[inumber] = dp->di_nlink; ! 106: if (dp->di_nlink <= 0) { ! 107: zlnp = (struct zlncnt *)malloc(sizeof *zlnp); ! 108: if (zlnp == NULL) { ! 109: pfatal("LINK COUNT TABLE OVERFLOW"); ! 110: if (reply("CONTINUE") == 0) ! 111: errexit(""); ! 112: } else { ! 113: zlnp->zlncnt = inumber; ! 114: zlnp->next = zlnhead; ! 115: zlnhead = zlnp; ! 116: } ! 117: } ! 118: statemap[inumber] = DIRCT(dp) ? DSTATE : FSTATE; ! 119: badblk = dupblk = 0; maxblk = 0; ! 120: idesc.id_number = inumber; ! 121: (void)ckinode(dp, &idesc); ! 122: idesc.id_entryno *= btodb(sblock.fs_fsize); ! 123: if (dp->di_blocks != idesc.id_entryno) { ! 124: pwarn("INCORRECT BLOCK COUNT I=%u (%ld should be %ld)", ! 125: inumber, dp->di_blocks, idesc.id_entryno); ! 126: if (preen) ! 127: printf(" (CORRECTED)\n"); ! 128: else if (reply("CORRECT") == 0) ! 129: continue; ! 130: dp->di_blocks = idesc.id_entryno; ! 131: inodirty(); ! 132: } ! 133: continue; ! 134: unknown: ! 135: pfatal("UNKNOWN FILE TYPE I=%u", inumber); ! 136: statemap[inumber] = FCLEAR; ! 137: if (reply("CLEAR") == 1) { ! 138: statemap[inumber] = USTATE; ! 139: zapino(dp); ! 140: inodirty(); ! 141: } ! 142: } ! 143: } ! 144: } ! 145: ! 146: pass1check(idesc) ! 147: register struct inodesc *idesc; ! 148: { ! 149: int res = KEEPON; ! 150: int anyout, nfrags; ! 151: daddr_t blkno = idesc->id_blkno; ! 152: register struct dups *dlp; ! 153: struct dups *new; ! 154: ! 155: if ((anyout = outrange(blkno, idesc->id_numfrags)) != 0) { ! 156: blkerr(idesc->id_number, "BAD", blkno); ! 157: if (++badblk >= MAXBAD) { ! 158: pwarn("EXCESSIVE BAD BLKS I=%u", ! 159: idesc->id_number); ! 160: if (preen) ! 161: printf(" (SKIPPING)\n"); ! 162: else if (reply("CONTINUE") == 0) ! 163: errexit(""); ! 164: return (STOP); ! 165: } ! 166: } ! 167: for (nfrags = idesc->id_numfrags; nfrags > 0; blkno++, nfrags--) { ! 168: if (anyout && outrange(blkno, 1)) { ! 169: res = SKIP; ! 170: } else if (!getbmap(blkno)) { ! 171: n_blks++; ! 172: setbmap(blkno); ! 173: } else { ! 174: blkerr(idesc->id_number, "DUP", blkno); ! 175: if (++dupblk >= MAXDUP) { ! 176: pwarn("EXCESSIVE DUP BLKS I=%u", ! 177: idesc->id_number); ! 178: if (preen) ! 179: printf(" (SKIPPING)\n"); ! 180: else if (reply("CONTINUE") == 0) ! 181: errexit(""); ! 182: return (STOP); ! 183: } ! 184: new = (struct dups *)malloc(sizeof(struct dups)); ! 185: if (new == NULL) { ! 186: pfatal("DUP TABLE OVERFLOW."); ! 187: if (reply("CONTINUE") == 0) ! 188: errexit(""); ! 189: return (STOP); ! 190: } ! 191: new->dup = blkno; ! 192: if (muldup == 0) { ! 193: duplist = muldup = new; ! 194: new->next = 0; ! 195: } else { ! 196: new->next = muldup->next; ! 197: muldup->next = new; ! 198: } ! 199: for (dlp = duplist; dlp != muldup; dlp = dlp->next) ! 200: if (dlp->dup == blkno) ! 201: break; ! 202: if (dlp == muldup && dlp->dup != blkno) ! 203: muldup = new; ! 204: } ! 205: /* ! 206: * count the number of blocks found in id_entryno ! 207: */ ! 208: idesc->id_entryno++; ! 209: } ! 210: return (res); ! 211: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.