|
|
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.4 (Berkeley) 4/9/87"; ! 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: dp->di_size + sblock.fs_bsize - 1 < 0) { ! 74: if (debug) ! 75: printf("bad size %d:", dp->di_size); ! 76: goto unknown; ! 77: } ! 78: if (!preen && (dp->di_mode & IFMT) == IFMT && ! 79: reply("HOLD BAD BLOCK") == 1) { ! 80: dp->di_size = sblock.fs_fsize; ! 81: dp->di_mode = IFREG|0600; ! 82: inodirty(); ! 83: } ! 84: ndb = howmany(dp->di_size, sblock.fs_bsize); ! 85: if (SPECIAL(dp)) ! 86: ndb++; ! 87: for (j = ndb; j < NDADDR; j++) ! 88: if (dp->di_db[j] != 0) { ! 89: if (debug) ! 90: printf("bad direct addr: %d\n", ! 91: dp->di_db[j]); ! 92: goto unknown; ! 93: } ! 94: for (j = 0, ndb -= NDADDR; ndb > 0; j++) ! 95: ndb /= NINDIR(&sblock); ! 96: for (; j < NIADDR; j++) ! 97: if (dp->di_ib[j] != 0) { ! 98: if (debug) ! 99: printf("bad indirect addr: %d\n", ! 100: dp->di_ib[j]); ! 101: goto unknown; ! 102: } ! 103: if (ftypeok(dp) == 0) ! 104: goto unknown; ! 105: n_files++; ! 106: lncntp[inumber] = dp->di_nlink; ! 107: if (dp->di_nlink <= 0) { ! 108: zlnp = (struct zlncnt *)malloc(sizeof *zlnp); ! 109: if (zlnp == NULL) { ! 110: pfatal("LINK COUNT TABLE OVERFLOW"); ! 111: if (reply("CONTINUE") == 0) ! 112: errexit(""); ! 113: } else { ! 114: zlnp->zlncnt = inumber; ! 115: zlnp->next = zlnhead; ! 116: zlnhead = zlnp; ! 117: } ! 118: } ! 119: statemap[inumber] = DIRCT(dp) ? DSTATE : FSTATE; ! 120: badblk = dupblk = 0; maxblk = 0; ! 121: idesc.id_number = inumber; ! 122: (void)ckinode(dp, &idesc); ! 123: idesc.id_entryno *= btodb(sblock.fs_fsize); ! 124: if (dp->di_blocks != idesc.id_entryno) { ! 125: pwarn("INCORRECT BLOCK COUNT I=%u (%ld should be %ld)", ! 126: inumber, dp->di_blocks, idesc.id_entryno); ! 127: if (preen) ! 128: printf(" (CORRECTED)\n"); ! 129: else if (reply("CORRECT") == 0) ! 130: continue; ! 131: dp->di_blocks = idesc.id_entryno; ! 132: inodirty(); ! 133: } ! 134: continue; ! 135: unknown: ! 136: pfatal("UNKNOWN FILE TYPE I=%u", inumber); ! 137: statemap[inumber] = FCLEAR; ! 138: if (reply("CLEAR") == 1) { ! 139: statemap[inumber] = USTATE; ! 140: zapino(dp); ! 141: inodirty(); ! 142: } ! 143: } ! 144: } ! 145: } ! 146: ! 147: pass1check(idesc) ! 148: register struct inodesc *idesc; ! 149: { ! 150: int res = KEEPON; ! 151: int anyout, nfrags; ! 152: daddr_t blkno = idesc->id_blkno; ! 153: register struct dups *dlp; ! 154: struct dups *new; ! 155: ! 156: if ((anyout = outrange(blkno, idesc->id_numfrags)) != 0) { ! 157: blkerr(idesc->id_number, "BAD", blkno); ! 158: if (++badblk >= MAXBAD) { ! 159: pwarn("EXCESSIVE BAD BLKS I=%u", ! 160: idesc->id_number); ! 161: if (preen) ! 162: printf(" (SKIPPING)\n"); ! 163: else if (reply("CONTINUE") == 0) ! 164: errexit(""); ! 165: return (STOP); ! 166: } ! 167: } ! 168: for (nfrags = idesc->id_numfrags; nfrags > 0; blkno++, nfrags--) { ! 169: if (anyout && outrange(blkno, 1)) { ! 170: res = SKIP; ! 171: } else if (!getbmap(blkno)) { ! 172: n_blks++; ! 173: setbmap(blkno); ! 174: } else { ! 175: blkerr(idesc->id_number, "DUP", blkno); ! 176: if (++dupblk >= MAXDUP) { ! 177: pwarn("EXCESSIVE DUP BLKS I=%u", ! 178: idesc->id_number); ! 179: if (preen) ! 180: printf(" (SKIPPING)\n"); ! 181: else if (reply("CONTINUE") == 0) ! 182: errexit(""); ! 183: return (STOP); ! 184: } ! 185: new = (struct dups *)malloc(sizeof(struct dups)); ! 186: if (new == NULL) { ! 187: pfatal("DUP TABLE OVERFLOW."); ! 188: if (reply("CONTINUE") == 0) ! 189: errexit(""); ! 190: return (STOP); ! 191: } ! 192: new->dup = blkno; ! 193: if (muldup == 0) { ! 194: duplist = muldup = new; ! 195: new->next = 0; ! 196: } else { ! 197: new->next = muldup->next; ! 198: muldup->next = new; ! 199: } ! 200: for (dlp = duplist; dlp != muldup; dlp = dlp->next) ! 201: if (dlp->dup == blkno) ! 202: break; ! 203: if (dlp == muldup && dlp->dup != blkno) ! 204: muldup = new; ! 205: } ! 206: /* ! 207: * count the number of blocks found in id_entryno ! 208: */ ! 209: idesc->id_entryno++; ! 210: } ! 211: return (res); ! 212: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.