|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1980, 1986 The Regents of the University of California. ! 3: * All rights reserved. ! 4: * ! 5: * Redistribution and use in source and binary forms are permitted provided ! 6: * that: (1) source distributions retain this entire copyright notice and ! 7: * comment, and (2) distributions including binaries display the following ! 8: * acknowledgement: ``This product includes software developed by the ! 9: * University of California, Berkeley and its contributors'' in the ! 10: * documentation or other materials provided with the distribution and in ! 11: * all advertising materials mentioning features or use of this software. ! 12: * Neither the name of the University nor the names of its contributors may ! 13: * be used to endorse or promote products derived from this software without ! 14: * specific prior written permission. ! 15: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED ! 16: * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF ! 17: * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ! 18: */ ! 19: ! 20: #ifndef lint ! 21: static char sccsid[] = "@(#)pass1.c 5.15 (Berkeley) 7/20/90"; ! 22: #endif /* not lint */ ! 23: ! 24: #include <sys/param.h> ! 25: #include <ufs/dinode.h> ! 26: #include <ufs/fs.h> ! 27: #include <stdlib.h> ! 28: #include <string.h> ! 29: #include "fsck.h" ! 30: ! 31: static daddr_t badblk; ! 32: static daddr_t dupblk; ! 33: int pass1check(); ! 34: struct dinode *getnextinode(); ! 35: ! 36: pass1() ! 37: { ! 38: register int c, i, j; ! 39: register struct dinode *dp; ! 40: struct zlncnt *zlnp; ! 41: int ndb, cgd; ! 42: struct inodesc idesc; ! 43: ino_t inumber; ! 44: ! 45: /* ! 46: * Set file system reserved blocks in used block map. ! 47: */ ! 48: for (c = 0; c < sblock.fs_ncg; c++) { ! 49: cgd = cgdmin(&sblock, c); ! 50: if (c == 0) { ! 51: i = cgbase(&sblock, c); ! 52: cgd += howmany(sblock.fs_cssize, sblock.fs_fsize); ! 53: } else ! 54: i = cgsblock(&sblock, c); ! 55: for (; i < cgd; i++) ! 56: setbmap(i); ! 57: } ! 58: /* ! 59: * Find all allocated blocks. ! 60: */ ! 61: bzero((char *)&idesc, sizeof(struct inodesc)); ! 62: idesc.id_type = ADDR; ! 63: idesc.id_func = pass1check; ! 64: inumber = 0; ! 65: n_files = n_blks = 0; ! 66: resetinodebuf(); ! 67: for (c = 0; c < sblock.fs_ncg; c++) { ! 68: for (i = 0; i < sblock.fs_ipg; i++, inumber++) { ! 69: if (inumber < ROOTINO) ! 70: continue; ! 71: dp = getnextinode(inumber); ! 72: if ((dp->di_mode & IFMT) == 0) { ! 73: if (bcmp((char *)dp->di_db, (char *)zino.di_db, ! 74: NDADDR * sizeof(daddr_t)) || ! 75: bcmp((char *)dp->di_ib, (char *)zino.di_ib, ! 76: NIADDR * sizeof(daddr_t)) || ! 77: dp->di_mode || dp->di_size) { ! 78: pfatal("PARTIALLY ALLOCATED INODE I=%lu", ! 79: inumber); ! 80: if (reply("CLEAR") == 1) { ! 81: dp = ginode(inumber); ! 82: clearinode(dp); ! 83: inodirty(); ! 84: } ! 85: } ! 86: statemap[inumber] = USTATE; ! 87: continue; ! 88: } ! 89: lastino = inumber; ! 90: if (/* dp->di_size < 0 || */ ! 91: dp->di_size + sblock.fs_bsize - 1 < dp->di_size) { ! 92: if (debug) ! 93: printf("bad size %lu:", dp->di_size); ! 94: goto unknown; ! 95: } ! 96: if (!preen && (dp->di_mode & IFMT) == IFMT && ! 97: reply("HOLD BAD BLOCK") == 1) { ! 98: dp = ginode(inumber); ! 99: dp->di_size = sblock.fs_fsize; ! 100: dp->di_mode = IFREG|0600; ! 101: inodirty(); ! 102: } ! 103: ndb = howmany(dp->di_size, sblock.fs_bsize); ! 104: if (ndb < 0) { ! 105: if (debug) ! 106: printf("bad size %lu ndb %d:", ! 107: dp->di_size, ndb); ! 108: goto unknown; ! 109: } ! 110: if ((dp->di_mode & IFMT) == IFBLK || ! 111: (dp->di_mode & IFMT) == IFCHR) ! 112: ndb++; ! 113: for (j = ndb; j < NDADDR; j++) ! 114: if (dp->di_db[j] != 0) { ! 115: if (debug) ! 116: printf("bad direct addr: %ld\n", ! 117: dp->di_db[j]); ! 118: goto unknown; ! 119: } ! 120: for (j = 0, ndb -= NDADDR; ndb > 0; j++) ! 121: ndb /= NINDIR(&sblock); ! 122: for (; j < NIADDR; j++) ! 123: if (dp->di_ib[j] != 0) { ! 124: if (debug) ! 125: printf("bad indirect addr: %ld\n", ! 126: dp->di_ib[j]); ! 127: goto unknown; ! 128: } ! 129: if (ftypeok(dp) == 0) ! 130: goto unknown; ! 131: n_files++; ! 132: lncntp[inumber] = dp->di_nlink; ! 133: if (dp->di_nlink <= 0) { ! 134: zlnp = (struct zlncnt *)malloc(sizeof *zlnp); ! 135: if (zlnp == NULL) { ! 136: pfatal("LINK COUNT TABLE OVERFLOW"); ! 137: if (reply("CONTINUE") == 0) ! 138: errexit(""); ! 139: } else { ! 140: zlnp->zlncnt = inumber; ! 141: zlnp->next = zlnhead; ! 142: zlnhead = zlnp; ! 143: } ! 144: } ! 145: if ((dp->di_mode & IFMT) == IFDIR) { ! 146: if (dp->di_size == 0) ! 147: statemap[inumber] = DCLEAR; ! 148: else ! 149: statemap[inumber] = DSTATE; ! 150: cacheino(dp, inumber); ! 151: } else ! 152: statemap[inumber] = FSTATE; ! 153: badblk = dupblk = 0; ! 154: idesc.id_number = inumber; ! 155: (void)ckinode(dp, &idesc); ! 156: idesc.id_entryno *= btodb(sblock.fs_fsize); ! 157: if (dp->di_blocks != idesc.id_entryno) { ! 158: pwarn("INCORRECT BLOCK COUNT I=%lu (%ld should be %ld)", ! 159: inumber, dp->di_blocks, idesc.id_entryno); ! 160: if (preen) ! 161: printf(" (CORRECTED)\n"); ! 162: else if (reply("CORRECT") == 0) ! 163: continue; ! 164: dp = ginode(inumber); ! 165: dp->di_blocks = idesc.id_entryno; ! 166: inodirty(); ! 167: } ! 168: continue; ! 169: unknown: ! 170: pfatal("UNKNOWN FILE TYPE I=%lu", inumber); ! 171: statemap[inumber] = FCLEAR; ! 172: if (reply("CLEAR") == 1) { ! 173: statemap[inumber] = USTATE; ! 174: dp = ginode(inumber); ! 175: clearinode(dp); ! 176: inodirty(); ! 177: } ! 178: } ! 179: } ! 180: freeinodebuf(); ! 181: } ! 182: ! 183: pass1check(idesc) ! 184: register struct inodesc *idesc; ! 185: { ! 186: int res = KEEPON; ! 187: int anyout, nfrags; ! 188: daddr_t blkno = idesc->id_blkno; ! 189: register struct dups *dlp; ! 190: struct dups *new; ! 191: ! 192: if ((anyout = chkrange(blkno, idesc->id_numfrags)) != 0) { ! 193: blkerror(idesc->id_number, "BAD", blkno); ! 194: if (++badblk >= MAXBAD) { ! 195: pwarn("EXCESSIVE BAD BLKS I=%lu", ! 196: idesc->id_number); ! 197: if (preen) ! 198: printf(" (SKIPPING)\n"); ! 199: else if (reply("CONTINUE") == 0) ! 200: errexit(""); ! 201: return (STOP); ! 202: } ! 203: } ! 204: for (nfrags = idesc->id_numfrags; nfrags > 0; blkno++, nfrags--) { ! 205: if (anyout && chkrange(blkno, 1)) { ! 206: res = SKIP; ! 207: } else if (!testbmap(blkno)) { ! 208: n_blks++; ! 209: setbmap(blkno); ! 210: } else { ! 211: blkerror(idesc->id_number, "DUP", blkno); ! 212: if (++dupblk >= MAXDUP) { ! 213: pwarn("EXCESSIVE DUP BLKS I=%lu", ! 214: idesc->id_number); ! 215: if (preen) ! 216: printf(" (SKIPPING)\n"); ! 217: else if (reply("CONTINUE") == 0) ! 218: errexit(""); ! 219: return (STOP); ! 220: } ! 221: new = (struct dups *)malloc(sizeof(struct dups)); ! 222: if (new == NULL) { ! 223: pfatal("DUP TABLE OVERFLOW."); ! 224: if (reply("CONTINUE") == 0) ! 225: errexit(""); ! 226: return (STOP); ! 227: } ! 228: new->dup = blkno; ! 229: if (muldup == 0) { ! 230: duplist = muldup = new; ! 231: new->next = 0; ! 232: } else { ! 233: new->next = muldup->next; ! 234: muldup->next = new; ! 235: } ! 236: for (dlp = duplist; dlp != muldup; dlp = dlp->next) ! 237: if (dlp->dup == blkno) ! 238: break; ! 239: if (dlp == muldup && dlp->dup != blkno) ! 240: muldup = new; ! 241: } ! 242: /* ! 243: * count the number of blocks found in id_entryno ! 244: */ ! 245: idesc->id_entryno++; ! 246: } ! 247: return (res); ! 248: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.